Browse Source

fixed types

master
jojapoppa 8 months ago
parent
commit
58d2e13a8d
10 changed files with 1200 additions and 2 deletions
  1. +0
    -1
      .gitignore
  2. +5
    -0
      dist/index.d.ts
  3. +14
    -0
      dist/index.js
  4. +177
    -0
      dist/reader.d.ts
  5. +415
    -0
      dist/reader.js
  6. +19
    -0
      dist/varint.d.ts
  7. +53
    -0
      dist/varint.js
  8. +139
    -0
      dist/writer.d.ts
  9. +377
    -0
      dist/writer.js
  10. +1
    -1
      package.json

+ 0
- 1
.gitignore View File

@@ -166,5 +166,4 @@ fabric.properties
build
jsbuild
prebuilds
dist/
.idea

+ 5
- 0
dist/index.d.ts View File

@@ -0,0 +1,5 @@
import * as BigInteger from 'big-integer';
export { Reader } from './reader';
export { Writer } from './writer';
export { Varint } from './varint';
export { BigInteger };

+ 14
- 0
dist/index.js View File

@@ -0,0 +1,14 @@
"use strict";
// Copyright (c) 2018-2021, The TurtleCoin Developers
//
// Please see the included LICENSE file for more information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.BigInteger = exports.Varint = exports.Writer = exports.Reader = void 0;
const BigInteger = require("big-integer");
exports.BigInteger = BigInteger;
var reader_1 = require("./reader");
Object.defineProperty(exports, "Reader", { enumerable: true, get: function () { return reader_1.Reader; } });
var writer_1 = require("./writer");
Object.defineProperty(exports, "Writer", { enumerable: true, get: function () { return writer_1.Writer; } });
var varint_1 = require("./varint");
Object.defineProperty(exports, "Varint", { enumerable: true, get: function () { return varint_1.Varint; } });

+ 177
- 0
dist/reader.d.ts View File

@@ -0,0 +1,177 @@
/// <reference types="node" />
import { Writer } from './writer';
import * as BigInteger from 'big-integer';
import { Writable } from 'stream';
/**
* Allows for easy reading of blob encoded data
* @noInehritDoc
*/
export declare class Reader extends Writable {
private m_current_offset;
private m_buffer;
/**
* Constructs a new Reader instance
* @param blob either another copy of a reader, writer, a Buffer, or a hexadecimal string representation of the data
* @param encoding the encoding to use for the resulting string
*/
constructor(blob?: Reader | Writer | Buffer | string, encoding?: BufferEncoding);
/**
* @returns the entire reader buffer
*/
get buffer(): Buffer;
/**
* @returns the length of the blob in bytes
*/
get length(): number;
/**
* @returns the current offset of the read buffer
*/
get offset(): number;
/**
* @returns the number of bytes remaining in the stream that have not been read
*/
get unreadBytes(): number;
/**
* @returns the subset of the buffer that has not been read yet
*/
get unreadBuffer(): Buffer;
/**
* Extends the Stream.Writable interface such that we can be piped to
* @param chunk
* @param encoding
* @param callback
* @ignore
*/
_write(chunk: Buffer | Uint8Array | string, encoding: BufferEncoding, callback: () => void): void;
/**
* Appends the data given to the end of the current buffer of the instance of the reader
* @param blob either another copy of a reader, writer, a Buffer, or a hexadecimal string representation of the data
* @param encoding the string encoding used
*/
append(blob: Reader | Writer | Buffer | Uint8Array | string, encoding?: BufferEncoding): void;
/**
* Reads the supplied number of bytes
* @param [count=1] the number of bytes to read
* @returns a buffer containing the requested number of bytes
*/
bytes(count?: number): Buffer;
/**
* Compacts the current reader buffer by trimming data before the current offset, or
* if specified, the given offset and re-setting the current reading offset to 0
* @param offset the offset to compact from
*/
compact(offset?: number): void;
/**
* Reads the next hash of the given length from the stream and returns the value in hexadecimal notation
* @param length the length of the hash in bytes
* @param encoding the encoding to use for the resulting string
* @returns the hash as a string
*/
hash(length?: number, encoding?: BufferEncoding): string;
/**
* Reads the next supplied number of bytes and returns the result in hexadecimal notation
* @param [count=1] the number of bytes to read
* @param encoding the encoding to use for the resulting string
* @returns a string containing the bytes in hexadecimal
*/
hex(count?: number, encoding?: BufferEncoding): string;
/**
* Reads the number of bits as a signed integer
* @param bits the number of bits to read
* @param [be] whether to use big endian
* @returns the value read
*/
int_t(bits: number, be?: boolean): BigInteger.BigInteger;
/**
* Reads a int8_t
* @returns the value
*/
int8_t(): BigInteger.BigInteger;
/**
* Reads a int16_t
* @param [be] whether to use big endian
* @returns the value
*/
int16_t(be?: boolean): BigInteger.BigInteger;
/**
* Reads a int32_t
* @param [be] whether to use big endian
* @returns the value
*/
int32_t(be?: boolean): BigInteger.BigInteger;
/**
* Resets the reader offset to the given offset of the buffer
* @param offset the offset to reset the reader to
*/
reset(offset?: number): void;
/**
* Skips the specified number of bytes in the stream
* @param [count=1] the number of bytes to skip
*/
skip(count?: number): void;
/**
* Reads the next Date from the stream
* @param [be] whether to use big endian
*/
time_t(be?: boolean): Date;
/**
* Returns the current read buffer as a string
* @param encoding
*/
toString(encoding?: BufferEncoding): string;
/**
* Reads the number of bits as an unsigned integer
* @param bits the number of bits to read
* @param [be] whether to use big endian
* @returns the value read
*/
uint_t(bits: number, be?: boolean): BigInteger.BigInteger;
/**
* Reads a uint8_t
* @returns the value
*/
uint8_t(): BigInteger.BigInteger;
/**
* Reads a uint16_t
* @param [be] whether to use big endian
* @returns the value
*/
uint16_t(be?: boolean): BigInteger.BigInteger;
/**
* Reads a uint32_t
* @param [be] whether to use big endian
* @returns the value
*/
uint32_t(be?: boolean): BigInteger.BigInteger;
/**
* Reads a uint64_t
* @param [be] whether to use big endian
* @returns the value
*/
uint64_t(be?: boolean): BigInteger.BigInteger;
/**
* Reads a uint128_t
* @param [be] whether to use big endian
* @returns the value
*/
uint128_t(be?: boolean): BigInteger.BigInteger;
/**
* Reads a uint256_t
* @param [be] whether to use big endian
* @returns the value
*/
uint256_t(be?: boolean): BigInteger.BigInteger;
/**
* Reads a uint512_t
* @param [be] whether to use big endian
* @returns the value
*/
uint512_t(be?: boolean): BigInteger.BigInteger;
/**
* Reads a varint encoded value from the stream
* @param [peek] if we are only peeking, we will not advance the reader cursor
* @param [levin] whether we are reading a levin packed varint
* @returns the value
*/
varint(peek?: boolean, levin?: boolean): BigInteger.BigInteger;
}

+ 415
- 0
dist/reader.js View File

@@ -0,0 +1,415 @@
"use strict";
// Copyright (c) 2018-2021, The TurtleCoin Developers
//
// Please see the included LICENSE file for more information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.Reader = void 0;
const varint_1 = require("./varint");
const writer_1 = require("./writer");
const BigInteger = require("big-integer");
const stream_1 = require("stream");
/**
* Allows for easy reading of blob encoded data
* @noInehritDoc
*/
class Reader extends stream_1.Writable {
/**
* Constructs a new Reader instance
* @param blob either another copy of a reader, writer, a Buffer, or a hexadecimal string representation of the data
* @param encoding the encoding to use for the resulting string
*/
constructor(blob = Buffer.alloc(0), encoding = 'hex') {
super();
this.m_current_offset = 0;
this.m_buffer = Buffer.alloc(0);
if (blob instanceof Reader) {
return blob;
}
else if (blob instanceof writer_1.Writer) {
this.m_buffer = blob.buffer;
}
else if (blob instanceof Buffer) {
this.m_buffer = blob;
}
else if (typeof blob === 'string') {
this.m_buffer = Buffer.from(blob, encoding);
}
else {
throw new Error('Unknown data type');
}
this.m_current_offset = 0;
}
/**
* @returns the entire reader buffer
*/
get buffer() {
return this.m_buffer;
}
/**
* @returns the length of the blob in bytes
*/
get length() {
return this.m_buffer.length;
}
/**
* @returns the current offset of the read buffer
*/
get offset() {
return this.m_current_offset;
}
/**
* @returns the number of bytes remaining in the stream that have not been read
*/
get unreadBytes() {
const unreadBytes = this.length - this.offset;
return (unreadBytes >= 0) ? unreadBytes : 0;
}
/**
* @returns the subset of the buffer that has not been read yet
*/
get unreadBuffer() {
return this.m_buffer.slice(this.offset);
}
/**
* Extends the Stream.Writable interface such that we can be piped to
* @param chunk
* @param encoding
* @param callback
* @ignore
*/
_write(chunk, encoding, callback) {
this.append(chunk);
callback();
}
/**
* Appends the data given to the end of the current buffer of the instance of the reader
* @param blob either another copy of a reader, writer, a Buffer, or a hexadecimal string representation of the data
* @param encoding the string encoding used
*/
append(blob, encoding = 'hex') {
let buffer;
if (blob instanceof Reader) {
buffer = blob.buffer;
}
else if (blob instanceof writer_1.Writer) {
buffer = blob.buffer;
}
else if (blob instanceof Buffer) {
buffer = blob;
}
else if (blob instanceof Uint8Array) {
buffer = Buffer.from(blob);
}
else if (typeof blob === 'string' && blob.length % 2 === 0) {
buffer = Buffer.from(blob, encoding);
}
else {
throw new Error('Unknown data type');
}
this.m_buffer = Buffer.concat([this.m_buffer, buffer]);
}
/**
* Reads the supplied number of bytes
* @param [count=1] the number of bytes to read
* @returns a buffer containing the requested number of bytes
*/
bytes(count = 1) {
const start = this.offset;
this.m_current_offset += count;
return this.m_buffer.slice(start, this.offset);
}
/**
* Compacts the current reader buffer by trimming data before the current offset, or
* if specified, the given offset and re-setting the current reading offset to 0
* @param offset the offset to compact from
*/
compact(offset) {
if (typeof offset === 'undefined') {
this.m_buffer = this.buffer.slice(this.offset);
}
else {
this.m_buffer = this.buffer.slice(offset);
}
this.m_current_offset = 0;
}
/**
* Reads the next hash of the given length from the stream and returns the value in hexadecimal notation
* @param length the length of the hash in bytes
* @param encoding the encoding to use for the resulting string
* @returns the hash as a string
*/
hash(length = 32, encoding = 'hex') {
const start = this.offset;
this.m_current_offset += length;
return this.m_buffer.slice(start, this.m_current_offset).toString(encoding);
}
/**
* Reads the next supplied number of bytes and returns the result in hexadecimal notation
* @param [count=1] the number of bytes to read
* @param encoding the encoding to use for the resulting string
* @returns a string containing the bytes in hexadecimal
*/
hex(count = 1, encoding = 'hex') {
const start = this.offset;
this.m_current_offset += count;
return this.m_buffer.slice(start, this.offset).toString(encoding);
}
/**
* Reads the number of bits as a signed integer
* @param bits the number of bits to read
* @param [be] whether to use big endian
* @returns the value read
*/
int_t(bits, be = false) {
if (bits % 8 !== 0) {
throw new Error('bits must be a multiple of 8');
}
const bytes = bits / 8;
if (this.unreadBytes < bytes) {
throw new Error('Not enough bytes remaining in the buffer');
}
const start = this.offset;
this.m_current_offset += bytes;
switch (bytes) {
case 1:
return BigInteger(this.m_buffer.readInt8(start));
case 2:
if (be) {
return BigInteger(this.m_buffer.readInt16BE(start));
}
else {
return BigInteger(this.m_buffer.readInt16LE(start));
}
case 4:
if (be) {
return BigInteger(this.m_buffer.readInt32BE(start));
}
else {
return BigInteger(this.m_buffer.readInt32LE(start));
}
default:
throw new Error('cannot read int64_t');
}
}
/**
* Reads a int8_t
* @returns the value
*/
int8_t() {
return this.int_t(8);
}
/**
* Reads a int16_t
* @param [be] whether to use big endian
* @returns the value
*/
int16_t(be = false) {
return this.int_t(16, be);
}
/**
* Reads a int32_t
* @param [be] whether to use big endian
* @returns the value
*/
int32_t(be = false) {
return this.int_t(32, be);
}
/**
* Resets the reader offset to the given offset of the buffer
* @param offset the offset to reset the reader to
*/
reset(offset = 0) {
this.m_current_offset = offset;
}
/**
* Skips the specified number of bytes in the stream
* @param [count=1] the number of bytes to skip
*/
skip(count = 1) {
this.m_current_offset += count;
}
/**
* Reads the next Date from the stream
* @param [be] whether to use big endian
*/
time_t(be = false) {
const buffer = (be) ? this.bytes(8).swap64() : this.bytes(8);
const epoch = BigInteger(buffer.toString('hex'), 16).toJSNumber();
return new Date(epoch * 1000);
}
/**
* Returns the current read buffer as a string
* @param encoding
*/
toString(encoding = 'hex') {
return this.buffer.toString(encoding);
}
/**
* Reads the number of bits as an unsigned integer
* @param bits the number of bits to read
* @param [be] whether to use big endian
* @returns the value read
*/
uint_t(bits, be = false) {
be = be || false;
if (bits % 8 !== 0) {
throw new Error('bits must be a multiple of 8');
}
const bytes = bits / 8;
if (this.unreadBytes < bytes) {
throw new Error('Not enough bytes remaining in the buffer');
}
const start = this.offset;
this.m_current_offset += bytes;
if (be) {
return readUIntBE(this.buffer, bytes, start);
}
else {
return readUIntLE(this.buffer, bytes, start);
}
}
/**
* Reads a uint8_t
* @returns the value
*/
uint8_t() {
return this.uint_t(8);
}
/**
* Reads a uint16_t
* @param [be] whether to use big endian
* @returns the value
*/
uint16_t(be = false) {
return this.uint_t(16, be);
}
/**
* Reads a uint32_t
* @param [be] whether to use big endian
* @returns the value
*/
uint32_t(be = false) {
return this.uint_t(32, be);
}
/**
* Reads a uint64_t
* @param [be] whether to use big endian
* @returns the value
*/
uint64_t(be = false) {
return this.uint_t(64, be);
}
/**
* Reads a uint128_t
* @param [be] whether to use big endian
* @returns the value
*/
uint128_t(be = false) {
return this.uint_t(128, be);
}
/**
* Reads a uint256_t
* @param [be] whether to use big endian
* @returns the value
*/
uint256_t(be = false) {
return this.uint_t(256, be);
}
/**
* Reads a uint512_t
* @param [be] whether to use big endian
* @returns the value
*/
uint512_t(be = false) {
return this.uint_t(512, be);
}
/**
* Reads a varint encoded value from the stream
* @param [peek] if we are only peeking, we will not advance the reader cursor
* @param [levin] whether we are reading a levin packed varint
* @returns the value
*/
varint(peek = false, levin = false) {
const start = this.m_current_offset;
if (!levin) {
do {
if (this.m_buffer.readUInt8(this.m_current_offset) < 128) {
this.m_current_offset++;
const tmp = this.m_buffer.slice(start, this.offset);
if (peek) {
this.m_current_offset = start;
}
return varint_1.Varint.decode(tmp);
}
this.m_current_offset++;
} while (true);
}
else {
let value = this.uint8_t().toJSNumber();
const sizeMask = value & 0x03;
value = BigInteger(value);
let bytesLeft = 0;
switch (sizeMask) {
case 0:
bytesLeft = 0;
break;
case 1:
bytesLeft = 1;
break;
case 2:
bytesLeft = 3;
break;
case 3:
bytesLeft = 7;
break;
}
for (let i = 1; i <= bytesLeft; ++i) {
const nv = this.uint8_t().shiftLeft(i * 8);
value = value.or(nv);
}
return value.shiftRight(2);
}
}
}
exports.Reader = Reader;
/* Helper methods */
/**
* @ignore
* @param buffer
* @param bytes
* @param offset
* @param noAssert
*/
function readUIntBE(buffer, bytes, offset = 0, noAssert = false) {
if (buffer.length < offset + bytes) {
if (noAssert) {
return BigInteger.zero;
}
throw new RangeError('Out of bounds');
}
const slice = buffer.slice(offset, offset + bytes);
return BigInteger(slice.toString('hex'), 16);
}
/**
* @ignore
* @param buffer
* @param bytes
* @param offset
* @param noAssert
*/
function readUIntLE(buffer, bytes, offset = 0, noAssert = false) {
if (buffer.length < offset + bytes) {
if (noAssert) {
return BigInteger.zero;
}
throw new RangeError('Out of bounds');
}
const buf = buffer.slice(offset, offset + bytes);
const tempBuffer = Buffer.alloc(bytes);
let position = bytes - 1;
for (const slice of buf) {
tempBuffer[position] = slice;
position -= 1;
}
return BigInteger(tempBuffer.toString('hex'), 16);
}

+ 19
- 0
dist/varint.d.ts View File

@@ -0,0 +1,19 @@
/// <reference types="node" />
import * as BigInteger from 'big-integer';
/**
* Varint encoding helper module
*/
export declare class Varint {
/**
* Decodes a varint from a buffer object
* @param buf the buffer object containing the value to be decoded
* @returns the numeric value
*/
static decode(buf: Buffer): BigInteger.BigInteger;
/**
* Encodes a value into a varint encoded buffer object
* @param num the numeric value
* @returns a Buffer containing the varint encoded value
*/
static encode(num: BigInteger.BigInteger): Buffer;
}

+ 53
- 0
dist/varint.js View File

@@ -0,0 +1,53 @@
"use strict";
// Copyright (c) 2018-2021, The TurtleCoin Developers
//
// Please see the included LICENSE file for more information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.Varint = void 0;
const BigInteger = require("big-integer");
/**
* Varint encoding helper module
*/
class Varint {
/**
* Decodes a varint from a buffer object
* @param buf the buffer object containing the value to be decoded
* @returns the numeric value
*/
static decode(buf) {
let counter = 0;
let shift = 0;
let b;
let result = BigInteger.zero;
do {
if (counter >= buf.length) {
throw new RangeError('Could not decode varint');
}
b = buf[counter++];
const value = (shift < 28) ? (b & 0x7f) << shift : (b & 0x7f) * Math.pow(2, shift);
result = result.add(value);
shift += 7;
} while (b >= 0x80);
return result;
}
/**
* Encodes a value into a varint encoded buffer object
* @param num the numeric value
* @returns a Buffer containing the varint encoded value
*/
static encode(num) {
const out = [];
let offset = 0;
while (num.greaterOrEquals(Math.pow(2, 31))) {
out[offset++] = num.and(0xFF).or(0x80).toJSNumber();
num = num.divide(128);
}
while (num.and(~0x7F).greater(0)) {
out[offset++] = num.and(0xFF).or(0x80).toJSNumber();
num = num.shiftRight(7);
}
out[offset] = num.or(0).toJSNumber();
return Buffer.from(out);
}
}
exports.Varint = Varint;

+ 139
- 0
dist/writer.d.ts View File

@@ -0,0 +1,139 @@
/// <reference types="node" />
import { Reader } from './reader';
import * as BigInteger from 'big-integer';
import { Readable } from 'stream';
/**
* Allows for easy writing of blob encoded data
* @noInehritDoc
*/
export declare class Writer extends Readable {
private m_buffer;
private m_readIndex;
/**
* The current data in the writer in a hexadecimal string format
*/
get blob(): string;
/**
* The current data in the writer as a Buffer object
*/
get buffer(): Buffer;
/**
* The length of the current data in bytes
*/
get length(): number;
/** @ignore */
private get readIndex();
/** @ignore */
_read(size: number): void;
/**
* Clears the current object of all existing data
*/
clear(): void;
/**
* Writes a 32-byte hash value to the data
* @param hash
* @param encoding the encoding of the string
*/
hash(hash: Buffer | string, encoding?: BufferEncoding): boolean;
/**
* Writes a hexadecimal string to the data
* @param hex
* @param encoding the encoding of the string
*/
hex(hex: Buffer | string, encoding?: BufferEncoding): boolean;
/**
* Writes a signed integer to the data
* @param value
* @param [bits] the number of bits to use
* @param [be] whether the value should be written in big endian
*/
int_t(value: BigInteger.BigInteger | number, bits?: number, be?: boolean): boolean;
/**
* Writes a int8_t to the data
* @param value
*/
int8_t(value: BigInteger.BigInteger | number): boolean;
/**
* Writes a int16_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
int16_t(value: BigInteger.BigInteger | number, be?: boolean): boolean;
/**
* Writes a int32_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
int32_t(value: BigInteger.BigInteger | number, be?: boolean): boolean;
/**
* Writes a date object into the data stream
* @param value
* @param [be] whether the value should be written in big endian
*/
time_t(value: Date, be?: boolean): void;
/**
* Returns the current read buffer as a string
* @param encoding
*/
toString(encoding?: BufferEncoding): string;
/**
* Writes an unsigned integer to the data
* @param value
* @param [bits] the number of bits to use
* @param [be] whether the value should be written in big endian
*/
uint_t(value: BigInteger.BigInteger | number, bits?: number, be?: boolean): boolean;
/**
* Writes a uint8_t to the data
* @param value
*/
uint8_t(value: BigInteger.BigInteger | number): boolean;
/**
* Writes a uint16_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint16_t(value: BigInteger.BigInteger | number, be?: boolean): boolean;
/**
* Writes a uint32_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint32_t(value: BigInteger.BigInteger | number, be?: boolean): boolean;
/**
* Writes a uint64_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint64_t(value: BigInteger.BigInteger | number, be?: boolean): boolean;
/**
* Writes a uint128_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint128_t(value: BigInteger.BigInteger | number, be?: boolean): boolean;
/**
* Writes a uint256_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint256_t(value: BigInteger.BigInteger | number, be?: boolean): boolean;
/**
* Writes a uint512_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint512_t(value: BigInteger.BigInteger | number, be?: boolean): boolean;
/**
* Writes a varint encoded value to the data
* @param value
* @param [levin] whether the value should be levin varint encoded
*/
varint(value: BigInteger.BigInteger | number, levin?: boolean): boolean;
/**
* Writes an arbitrary type of input to the data
* @param payload the payload to write
* @param encoding the encoding used in the string based data
*/
write(payload: Buffer | Writer | Reader | string | any, encoding?: BufferEncoding): boolean;
}

+ 377
- 0
dist/writer.js View File

@@ -0,0 +1,377 @@
"use strict";
// Copyright (c) 2018-2021, The TurtleCoin Developers
//
// Please see the included LICENSE file for more information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.Writer = void 0;
const varint_1 = require("./varint");
const reader_1 = require("./reader");
const BigInteger = require("big-integer");
const stream_1 = require("stream");
/**
* Allows for easy writing of blob encoded data
* @noInehritDoc
*/
class Writer extends stream_1.Readable {
constructor() {
super(...arguments);
this.m_buffer = Buffer.alloc(0);
this.m_readIndex = 0;
}
/**
* The current data in the writer in a hexadecimal string format
*/
get blob() {
return this.toString();
}
/**
* The current data in the writer as a Buffer object
*/
get buffer() {
return this.m_buffer;
}
/**
* The length of the current data in bytes
*/
get length() {
return this.m_buffer.length;
}
/** @ignore */
get readIndex() {
return this.m_readIndex;
}
/** @ignore */
_read(size) {
let okToSend = true;
while (okToSend) {
let slice = Buffer.alloc(0);
if (this.readIndex + size > this.length) {
slice = this.m_buffer.slice(this.readIndex);
}
else {
slice = this.m_buffer.slice(this.readIndex, this.readIndex + size);
}
if (slice.length > 0) {
this.push(slice);
}
else {
this.push(null);
okToSend = false;
}
this.m_readIndex += slice.length;
}
}
/**
* Clears the current object of all existing data
*/
clear() {
this.m_buffer = Buffer.alloc(0);
}
/**
* Writes a 32-byte hash value to the data
* @param hash
* @param encoding the encoding of the string
*/
hash(hash, encoding = 'hex') {
if (hash instanceof Buffer && hash.length === 32) {
return this.write(hash);
}
else if (typeof hash === 'string' && hash.length === 64) {
return this.write(hash, encoding);
}
return false;
}
/**
* Writes a hexadecimal string to the data
* @param hex
* @param encoding the encoding of the string
*/
hex(hex, encoding = 'hex') {
if (hex instanceof Buffer) {
return this.write(hex);
}
else if (typeof hex === 'string') {
return this.write(hex, encoding);
}
return false;
}
/**
* Writes a signed integer to the data
* @param value
* @param [bits] the number of bits to use
* @param [be] whether the value should be written in big endian
*/
int_t(value, bits, be = false) {
if (bits && bits % 8 !== 0) {
throw new Error('bits must be a multiple of 8');
}
if (typeof value === 'number') {
value = BigInteger(value);
}
if (!bits) {
bits = determineBits(value);
}
const bytes = bits / 8;
const buf = Buffer.alloc(bytes);
switch (bytes) {
case 1:
buf.writeInt8(value.toJSNumber(), 0);
break;
case 2:
if (be) {
buf.writeInt16BE(value.toJSNumber(), 0);
}
else {
buf.writeInt16LE(value.toJSNumber(), 0);
}
break;
case 4:
if (be) {
buf.writeInt32BE(value.toJSNumber(), 0);
}
else {
buf.writeInt32LE(value.toJSNumber(), 0);
}
break;
default:
return false;
}
this.write(buf);
return true;
}
/**
* Writes a int8_t to the data
* @param value
*/
int8_t(value) {
return this.int_t(value, 8);
}
/**
* Writes a int16_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
int16_t(value, be = false) {
return this.int_t(value, 16, be);
}
/**
* Writes a int32_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
int32_t(value, be = false) {
return this.int_t(value, 32, be);
}
/**
* Writes a date object into the data stream
* @param value
* @param [be] whether the value should be written in big endian
*/
time_t(value, be = false) {
/* We can only write an integer here, so make sure that's what we have */
const num = BigInteger(Math.floor(value.getTime() / 1000));
const hex = num.toString(16).padStart(16, '0');
const buffer = (be)
? Buffer.from(hex, 'hex').swap64()
: Buffer.from(hex, 'hex');
this.write(buffer);
}
/**
* Returns the current read buffer as a string
* @param encoding
*/
toString(encoding = 'hex') {
return this.buffer.toString(encoding);
}
/**
* Writes an unsigned integer to the data
* @param value
* @param [bits] the number of bits to use
* @param [be] whether the value should be written in big endian
*/
uint_t(value, bits, be = false) {
be = be || false;
if (typeof value === 'number') {
value = BigInteger(value);
}
if (value.lesser(0)) {
throw new RangeError('cannot store signed value in unsigned type');
}
if (!bits) {
bits = determineBits(value);
}
if (bits % 8 !== 0) {
throw new Error('bits must be a multiple of 8');
}
const bytes = bits / 8;
const buf = (be) ? writeUIntBE(value, bytes) : writeUIntLE(value, bytes);
this.write(buf);
return true;
}
/**
* Writes a uint8_t to the data
* @param value
*/
uint8_t(value) {
return this.uint_t(value, 8);
}
/**
* Writes a uint16_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint16_t(value, be = false) {
return this.uint_t(value, 16, be);
}
/**
* Writes a uint32_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint32_t(value, be = false) {
return this.uint_t(value, 32, be);
}
/**
* Writes a uint64_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint64_t(value, be = false) {
return this.uint_t(value, 64, be);
}
/**
* Writes a uint128_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint128_t(value, be = false) {
return this.uint_t(value, 128, be);
}
/**
* Writes a uint256_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint256_t(value, be = false) {
return this.uint_t(value, 256, be);
}
/**
* Writes a uint512_t to the data
* @param value
* @param [be] whether the value should be written in big endian
*/
uint512_t(value, be = false) {
return this.uint_t(value, 512, be);
}
/**
* Writes a varint encoded value to the data
* @param value
* @param [levin] whether the value should be levin varint encoded
*/
varint(value, levin = false) {
if (typeof value === 'number') {
value = BigInteger(value);
}
if (!levin) {
this.write(Buffer.from(varint_1.Varint.encode(value)));
return true;
}
else {
if (value.greater(BigInteger('1073741823'))) {
throw new RangeError('value out of range');
}
value = value.toJSNumber();
let tempValue = value << 2;
let byteCount = 0;
if (value <= 63) {
tempValue |= 0;
byteCount = 1;
}
else if (value <= 16383) {
tempValue |= 1;
byteCount = 2;
}
else {
tempValue |= 2;
byteCount = 4;
}
for (let i = 0; i < byteCount; i++) {
this.uint8_t((tempValue >> i * 8) & 0xFF);
}
return true;
}
}
/**
* Writes an arbitrary type of input to the data
* @param payload the payload to write
* @param encoding the encoding used in the string based data
*/
write(payload, encoding = 'hex') {
const write = (buffer) => {
this.m_buffer = Buffer.concat([this.m_buffer, buffer]);
return true;
};
if (payload instanceof Writer) {
return write(payload.buffer);
}
else if (payload instanceof reader_1.Reader) {
return write(payload.buffer);
}
else if (payload instanceof Buffer) {
return write(payload);
}
else if (typeof payload === 'string') {
return write(Buffer.from(payload, encoding));
}
else { // if it's not a string, it needs to be
return write(Buffer.from(JSON.stringify(payload)));
}
}
}
exports.Writer = Writer;
/* Helper methods */
/** @ignore */
function determineBits(value) {
const bytes = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024];
for (const byte of bytes) {
let check = BigInteger.zero;
if (value.greater(-1)) {
check = BigInteger(2).pow(byte * 8)
.subtract(1);
}
else {
check = BigInteger(2).pow((byte * 8) - 1)
.subtract(1)
.abs();
}
if (value.compare(check) <= 0) {
return byte * 8;
}
}
throw new RangeError('value is out of range');
}
/**
* @ignore
* @param value
* @param bytes
*/
function writeUIntBE(value, bytes) {
const hex = value.toString(16).padStart(bytes * 2, '0');
return Buffer.from(hex, 'hex');
}
/**
* @ignore
* @param value
* @param bytes
*/
function writeUIntLE(value, bytes) {
const hex = value.toString(16).padStart(bytes * 2, '0');
const buffer = Buffer.from(hex, 'hex');
const tempBuffer = Buffer.alloc(bytes);
let position = bytes - 1;
for (const slice of buffer) {
tempBuffer[position] = slice;
position -= 1;
}
return tempBuffer;
}

+ 1
- 1
package.json View File

@@ -1,5 +1,5 @@
{
"name": "@fedoragold/bytestream",
"name": "fedoragold-bytestream",
"version": "0.0.17",
"description": "bytestream serialization helper for handling over the wire encoded byte streams",
"main": "dist/index.js",


Loading…
Cancel
Save