mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-21 04:35:49 +00:00
refactored ./src/types/path-set (#84)
Refactored PathSet, Path, and Hop types. Constructing these types with Buffers, and using class instead of makeClass.
This commit is contained in:
@@ -87,6 +87,7 @@ module.exports = {
|
|||||||
'@typescript-eslint/no-unsafe-call': 'off',
|
'@typescript-eslint/no-unsafe-call': 'off',
|
||||||
'@typescript-eslint/no-unsafe-member-access': 'off',
|
'@typescript-eslint/no-unsafe-member-access': 'off',
|
||||||
'@typescript-eslint/no-unsafe-assignment': 'off',
|
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||||
|
"spaced-comment": ["error", "always"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,6 +16,16 @@ class BinaryParser {
|
|||||||
this.bytes = Buffer.from(hexBytes, "hex");
|
this.bytes = Buffer.from(hexBytes, "hex");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Peek the first byte of the BinaryParser
|
||||||
|
*
|
||||||
|
* @returns The first byte of the BinaryParser
|
||||||
|
*/
|
||||||
|
peek(): number {
|
||||||
|
assert(this.bytes.byteLength !== 0);
|
||||||
|
return this.bytes[0];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consume the first n bytes of the BinaryParser
|
* Consume the first n bytes of the BinaryParser
|
||||||
*
|
*
|
||||||
@@ -33,7 +43,10 @@ class BinaryParser {
|
|||||||
* @return The bytes
|
* @return The bytes
|
||||||
*/
|
*/
|
||||||
read(n: number): Buffer {
|
read(n: number): Buffer {
|
||||||
assert(n <= this.bytes.byteLength, n + " greater than " + this.bytes.byteLength);
|
assert(
|
||||||
|
n <= this.bytes.byteLength,
|
||||||
|
n + " greater than " + this.bytes.byteLength
|
||||||
|
);
|
||||||
|
|
||||||
const slice = this.bytes.slice(0, n);
|
const slice = this.bytes.slice(0, n);
|
||||||
this.skip(n);
|
this.skip(n);
|
||||||
|
|||||||
@@ -1,120 +1,250 @@
|
|||||||
/* eslint-disable no-unused-expressions */
|
import { AccountID } from "./account-id";
|
||||||
|
import { Currency } from "./currency";
|
||||||
import { makeClass } from "../utils/make-class";
|
import { BinaryParser } from "../serdes/binary-parser";
|
||||||
const { SerializedType, ensureArrayLikeIs } = require("./serialized-type");
|
import { SerializedTypeClass } from "./serialized-type";
|
||||||
const { Currency } = require("./currency");
|
|
||||||
const { AccountID } = require("./account-id");
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constants for separating Paths in a PathSet
|
||||||
|
*/
|
||||||
const PATHSET_END_BYTE = 0x00;
|
const PATHSET_END_BYTE = 0x00;
|
||||||
const PATH_SEPARATOR_BYTE = 0xff;
|
const PATH_SEPARATOR_BYTE = 0xff;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant for masking types of a Hop
|
||||||
|
*/
|
||||||
const TYPE_ACCOUNT = 0x01;
|
const TYPE_ACCOUNT = 0x01;
|
||||||
const TYPE_CURRENCY = 0x10;
|
const TYPE_CURRENCY = 0x10;
|
||||||
const TYPE_ISSUER = 0x20;
|
const TYPE_ISSUER = 0x20;
|
||||||
|
|
||||||
const Hop = makeClass(
|
/**
|
||||||
{
|
* The object representation of a Hop, an issuer AccountID, an account AccountID, and a Currency
|
||||||
statics: {
|
*/
|
||||||
from(value) {
|
interface HopObject {
|
||||||
if (value instanceof this) {
|
issuer?: string;
|
||||||
|
account?: string;
|
||||||
|
currency?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize and Deserialize a Hop
|
||||||
|
*/
|
||||||
|
class Hop extends SerializedTypeClass {
|
||||||
|
/**
|
||||||
|
* Create a Hop from a HopObject
|
||||||
|
*
|
||||||
|
* @param value Either a hop or HopObject to create a hop with
|
||||||
|
* @returns a Hop
|
||||||
|
*/
|
||||||
|
static from(value: Hop | HopObject): Hop {
|
||||||
|
if (value instanceof Hop) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
const hop = new Hop();
|
|
||||||
value.issuer && (hop.issuer = AccountID.from(value.issuer));
|
|
||||||
value.account && (hop.account = AccountID.from(value.account));
|
|
||||||
value.currency && (hop.currency = Currency.from(value.currency));
|
|
||||||
return hop;
|
|
||||||
},
|
|
||||||
parse(parser, type) {
|
|
||||||
const hop = new Hop();
|
|
||||||
type & TYPE_ACCOUNT && (hop.account = AccountID.fromParser(parser));
|
|
||||||
type & TYPE_CURRENCY && (hop.currency = Currency.fromParser(parser));
|
|
||||||
type & TYPE_ISSUER && (hop.issuer = AccountID.fromParser(parser));
|
|
||||||
return hop;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
toJSON() {
|
|
||||||
const type = this.type();
|
|
||||||
const ret = <any>{};
|
|
||||||
type & TYPE_ACCOUNT && (ret.account = this.account.toJSON());
|
|
||||||
type & TYPE_ISSUER && (ret.issuer = this.issuer.toJSON());
|
|
||||||
type & TYPE_CURRENCY && (ret.currency = this.currency.toJSON());
|
|
||||||
return ret;
|
|
||||||
},
|
|
||||||
type() {
|
|
||||||
let type = 0;
|
|
||||||
this.issuer && (type += TYPE_ISSUER);
|
|
||||||
this.account && (type += TYPE_ACCOUNT);
|
|
||||||
this.currency && (type += TYPE_CURRENCY);
|
|
||||||
return type;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
const Path = makeClass(
|
const bytes: Array<Buffer> = [Buffer.from([0])];
|
||||||
{
|
|
||||||
inherits: Array,
|
|
||||||
statics: {
|
|
||||||
from(value) {
|
|
||||||
return ensureArrayLikeIs(Path, value).withChildren(Hop);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
toJSON() {
|
|
||||||
return this.map((k) => k.toJSON());
|
|
||||||
},
|
|
||||||
},
|
|
||||||
undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
const PathSet = makeClass(
|
if (value.account) {
|
||||||
{
|
bytes.push(AccountID.from(value.account).toBytes());
|
||||||
mixins: SerializedType,
|
bytes[0][0] |= TYPE_ACCOUNT;
|
||||||
inherits: Array,
|
}
|
||||||
statics: {
|
|
||||||
from(value) {
|
if (value.currency) {
|
||||||
return ensureArrayLikeIs(PathSet, value).withChildren(Path);
|
bytes.push(Currency.from(value.currency).toBytes());
|
||||||
},
|
bytes[0][0] |= TYPE_CURRENCY;
|
||||||
fromParser(parser) {
|
}
|
||||||
const pathSet = new this();
|
|
||||||
let path;
|
if (value.issuer) {
|
||||||
while (!parser.end()) {
|
bytes.push(AccountID.from(value.issuer).toBytes());
|
||||||
|
bytes[0][0] |= TYPE_ISSUER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Hop(Buffer.concat(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a Hop from a BinaryParser
|
||||||
|
*
|
||||||
|
* @param parser BinaryParser to read the Hop from
|
||||||
|
* @returns a Hop
|
||||||
|
*/
|
||||||
|
static fromParser(parser: BinaryParser): Hop {
|
||||||
const type = parser.readUInt8();
|
const type = parser.readUInt8();
|
||||||
if (type === PATHSET_END_BYTE) {
|
const bytes: Array<Buffer> = [Buffer.from([type])];
|
||||||
|
|
||||||
|
if (type & TYPE_ACCOUNT) {
|
||||||
|
bytes.push(parser.read(AccountID.width));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & TYPE_CURRENCY) {
|
||||||
|
bytes.push(parser.read(Currency.width));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & TYPE_ISSUER) {
|
||||||
|
bytes.push(parser.read(AccountID.width));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Hop(Buffer.concat(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the JSON interpretation of this hop
|
||||||
|
*
|
||||||
|
* @returns a HopObject, an JS object with optional account, issuer, and currency
|
||||||
|
*/
|
||||||
|
toJSON(): HopObject {
|
||||||
|
const hopParser = new BinaryParser(this.bytes.toString("hex"));
|
||||||
|
const type = hopParser.readUInt8();
|
||||||
|
|
||||||
|
const result: HopObject = {};
|
||||||
|
if (type & TYPE_ACCOUNT) {
|
||||||
|
result.account = AccountID.fromParser(hopParser).toJSON();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & TYPE_CURRENCY) {
|
||||||
|
result.currency = Currency.fromParser(hopParser).toJSON();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & TYPE_ISSUER) {
|
||||||
|
result.issuer = AccountID.fromParser(hopParser).toJSON();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get a number representing the type of this hop
|
||||||
|
*
|
||||||
|
* @returns a number to be bitwise and-ed with TYPE_ constants to describe the types in the hop
|
||||||
|
*/
|
||||||
|
type(): number {
|
||||||
|
return this.bytes[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for serializing/deserializing Paths
|
||||||
|
*/
|
||||||
|
class Path extends SerializedTypeClass {
|
||||||
|
/**
|
||||||
|
* construct a Path from an array of Hops
|
||||||
|
*
|
||||||
|
* @param value Path or array of HopObjects to construct a Path
|
||||||
|
* @returns the Path
|
||||||
|
*/
|
||||||
|
static from(value: Path | Array<HopObject>): Path {
|
||||||
|
if (value instanceof Path) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytes: Array<Buffer> = [];
|
||||||
|
value.forEach((hop: HopObject) => {
|
||||||
|
bytes.push(Hop.from(hop).toBytes());
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Path(Buffer.concat(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a Path from a BinaryParser
|
||||||
|
*
|
||||||
|
* @param parser BinaryParser to read Path from
|
||||||
|
* @returns the Path represented by the bytes read from the BinaryParser
|
||||||
|
*/
|
||||||
|
static fromParser(parser: BinaryParser): Path {
|
||||||
|
const bytes: Array<Buffer> = [];
|
||||||
|
while (!parser.end()) {
|
||||||
|
bytes.push(Hop.fromParser(parser).toBytes());
|
||||||
|
|
||||||
|
if (
|
||||||
|
parser.peek() === PATHSET_END_BYTE ||
|
||||||
|
parser.peek() === PATH_SEPARATOR_BYTE
|
||||||
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (type === PATH_SEPARATOR_BYTE) {
|
|
||||||
path = null;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (!path) {
|
return new Path(Buffer.concat(bytes));
|
||||||
path = new Path();
|
|
||||||
pathSet.push(path);
|
|
||||||
}
|
}
|
||||||
path.push(Hop.parse(parser, type));
|
|
||||||
}
|
/**
|
||||||
return pathSet;
|
* Get the JSON representation of this Path
|
||||||
},
|
*
|
||||||
},
|
* @returns an Array of HopObject constructed from this.bytes
|
||||||
|
*/
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return this.map((k) => k.toJSON());
|
const json: Array<HopObject> = [];
|
||||||
},
|
const pathParser = new BinaryParser(this.bytes.toString("hex"));
|
||||||
toBytesSink(sink) {
|
|
||||||
let n = 0;
|
while (!pathParser.end()) {
|
||||||
this.forEach((path) => {
|
json.push(Hop.fromParser(pathParser).toJSON());
|
||||||
if (n++ !== 0) {
|
|
||||||
sink.put([PATH_SEPARATOR_BYTE]);
|
|
||||||
}
|
}
|
||||||
path.forEach((hop) => {
|
|
||||||
sink.put([hop.type()]);
|
return json;
|
||||||
hop.account && hop.account.toBytesSink(sink);
|
}
|
||||||
hop.currency && hop.currency.toBytesSink(sink);
|
}
|
||||||
hop.issuer && hop.issuer.toBytesSink(sink);
|
|
||||||
|
/**
|
||||||
|
* Deserialize and Serialize the PathSet type
|
||||||
|
*/
|
||||||
|
class PathSet extends SerializedTypeClass {
|
||||||
|
/**
|
||||||
|
* Construct a PathSet from an Array of Arrays representing paths
|
||||||
|
*
|
||||||
|
* @param value A PathSet or Array of Array of HopObjects
|
||||||
|
* @returns the PathSet constructed from value
|
||||||
|
*/
|
||||||
|
static from(value: PathSet | Array<Array<HopObject>>): PathSet {
|
||||||
|
if (value instanceof PathSet) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytes: Array<Buffer> = [];
|
||||||
|
|
||||||
|
value.forEach((path: Array<HopObject>) => {
|
||||||
|
bytes.push(Path.from(path).toBytes());
|
||||||
|
bytes.push(Buffer.from([PATH_SEPARATOR_BYTE]));
|
||||||
});
|
});
|
||||||
});
|
|
||||||
sink.put([PATHSET_END_BYTE]);
|
bytes[bytes.length - 1] = Buffer.from([PATHSET_END_BYTE]);
|
||||||
},
|
|
||||||
},
|
return new PathSet(Buffer.concat(bytes));
|
||||||
undefined
|
}
|
||||||
);
|
|
||||||
|
/**
|
||||||
|
* Construct a PathSet from a BinaryParser
|
||||||
|
*
|
||||||
|
* @param parser A BinaryParser to read PathSet from
|
||||||
|
* @returns the PathSet read from parser
|
||||||
|
*/
|
||||||
|
static fromParser(parser: BinaryParser): PathSet {
|
||||||
|
const bytes: Array<Buffer> = [];
|
||||||
|
|
||||||
|
while (!parser.end()) {
|
||||||
|
bytes.push(Path.fromParser(parser).toBytes());
|
||||||
|
bytes.push(parser.read(1));
|
||||||
|
|
||||||
|
if (bytes[bytes.length - 1][0] == PATHSET_END_BYTE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PathSet(Buffer.concat(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the JSON representation of this PathSet
|
||||||
|
*
|
||||||
|
* @returns an Array of Array of HopObjects, representing this PathSet
|
||||||
|
*/
|
||||||
|
toJSON(): Array<Array<HopObject>> {
|
||||||
|
const json: Array<Array<HopObject>> = [];
|
||||||
|
const pathParser = new BinaryParser(this.bytes.toString("hex"));
|
||||||
|
|
||||||
|
while (!pathParser.end()) {
|
||||||
|
json.push(Path.fromParser(pathParser).toJSON());
|
||||||
|
pathParser.skip(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export { PathSet };
|
export { PathSet };
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import { BinaryParser } from "../serdes/binary-parser";
|
|||||||
* Derived UInt class for serializing/deserializing 16 bit UInt
|
* Derived UInt class for serializing/deserializing 16 bit UInt
|
||||||
*/
|
*/
|
||||||
class UInt16 extends UInt {
|
class UInt16 extends UInt {
|
||||||
protected static readonly width: number = 16 / 8 //2
|
protected static readonly width: number = 16 / 8; // 2
|
||||||
static readonly defaultUInt16: UInt16 = new UInt16(Buffer.alloc(UInt16.width))
|
static readonly defaultUInt16: UInt16 = new UInt16(
|
||||||
|
Buffer.alloc(UInt16.width)
|
||||||
|
);
|
||||||
|
|
||||||
constructor(bytes: Buffer) {
|
constructor(bytes: Buffer) {
|
||||||
super(bytes ?? UInt16.defaultUInt16.bytes)
|
super(bytes ?? UInt16.defaultUInt16.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromParser(parser: BinaryParser): UInt {
|
static fromParser(parser: BinaryParser): UInt {
|
||||||
@@ -22,11 +24,11 @@ class UInt16 extends UInt {
|
|||||||
* @param val UInt16 object or number
|
* @param val UInt16 object or number
|
||||||
*/
|
*/
|
||||||
static from(val: UInt16 | number): UInt16 {
|
static from(val: UInt16 | number): UInt16 {
|
||||||
if(val instanceof UInt16) {
|
if (val instanceof UInt16) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
let buf = Buffer.alloc(UInt16.width);
|
const buf = Buffer.alloc(UInt16.width);
|
||||||
buf.writeUInt16BE(val);
|
buf.writeUInt16BE(val);
|
||||||
return new UInt16(buf);
|
return new UInt16(buf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import { BinaryParser } from "../serdes/binary-parser";
|
|||||||
* Derived UInt class for serializing/deserializing 32 bit UInt
|
* Derived UInt class for serializing/deserializing 32 bit UInt
|
||||||
*/
|
*/
|
||||||
class UInt32 extends UInt {
|
class UInt32 extends UInt {
|
||||||
protected static readonly width: number = 32 / 8 //4
|
protected static readonly width: number = 32 / 8; // 4
|
||||||
static readonly defaultUInt32: UInt32 = new UInt32(Buffer.alloc(UInt32.width))
|
static readonly defaultUInt32: UInt32 = new UInt32(
|
||||||
|
Buffer.alloc(UInt32.width)
|
||||||
|
);
|
||||||
|
|
||||||
constructor(bytes: Buffer) {
|
constructor(bytes: Buffer) {
|
||||||
super(bytes ?? UInt32.defaultUInt32.bytes)
|
super(bytes ?? UInt32.defaultUInt32.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromParser(parser: BinaryParser): UInt {
|
static fromParser(parser: BinaryParser): UInt {
|
||||||
@@ -22,11 +24,11 @@ class UInt32 extends UInt {
|
|||||||
* @param val UInt32 object or number
|
* @param val UInt32 object or number
|
||||||
*/
|
*/
|
||||||
static from(val: UInt32 | number): UInt32 {
|
static from(val: UInt32 | number): UInt32 {
|
||||||
if(val instanceof UInt32) {
|
if (val instanceof UInt32) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
let buf = Buffer.alloc(UInt32.width);
|
const buf = Buffer.alloc(UInt32.width);
|
||||||
buf.writeUInt32BE(val);
|
buf.writeUInt32BE(val);
|
||||||
return new UInt32(buf);
|
return new UInt32(buf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,13 @@ const HEX_REGEX = /^[A-F0-9]{16}$/;
|
|||||||
* Derived UInt class for serializing/deserializing 64 bit UInt
|
* Derived UInt class for serializing/deserializing 64 bit UInt
|
||||||
*/
|
*/
|
||||||
class UInt64 extends UInt {
|
class UInt64 extends UInt {
|
||||||
protected static readonly width: number = 64 / 8 //8
|
protected static readonly width: number = 64 / 8; // 8
|
||||||
static readonly defaultUInt64: UInt64 = new UInt64(Buffer.alloc(UInt64.width))
|
static readonly defaultUInt64: UInt64 = new UInt64(
|
||||||
|
Buffer.alloc(UInt64.width)
|
||||||
|
);
|
||||||
|
|
||||||
constructor(bytes: Buffer) {
|
constructor(bytes: Buffer) {
|
||||||
super(bytes ?? UInt64.defaultUInt64.bytes)
|
super(bytes ?? UInt64.defaultUInt64.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromParser(parser: BinaryParser): UInt {
|
static fromParser(parser: BinaryParser): UInt {
|
||||||
@@ -25,26 +27,25 @@ class UInt64 extends UInt {
|
|||||||
* @returns A UInt64 object
|
* @returns A UInt64 object
|
||||||
*/
|
*/
|
||||||
static from(val: UInt64 | string | bigint | number): UInt64 {
|
static from(val: UInt64 | string | bigint | number): UInt64 {
|
||||||
if(val instanceof UInt64) {
|
if (val instanceof UInt64) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
let buf = Buffer.alloc(UInt64.width);
|
let buf = Buffer.alloc(UInt64.width);
|
||||||
|
|
||||||
if(typeof val === "number") {
|
if (typeof val === "number") {
|
||||||
if(val < 0) {
|
if (val < 0) {
|
||||||
throw new Error("value must be an unsigned integer");
|
throw new Error("value must be an unsigned integer");
|
||||||
}
|
}
|
||||||
buf.writeBigUInt64BE(BigInt(val));
|
buf.writeBigUInt64BE(BigInt(val));
|
||||||
|
} else if (typeof val === "string") {
|
||||||
|
if (!HEX_REGEX.test(val)) {
|
||||||
|
throw new Error(val + "is not a valid hex-string");
|
||||||
}
|
}
|
||||||
else if (typeof val === "string") {
|
buf = Buffer.from(val, "hex");
|
||||||
if(!HEX_REGEX.test(val)) {
|
} else {
|
||||||
throw new Error(val + "is not a valid hex-string")
|
// typeof val === bigint
|
||||||
}
|
buf.writeBigUInt64BE(val);
|
||||||
buf = Buffer.from(val, "hex")
|
|
||||||
}
|
|
||||||
else { // typeof val === bigint
|
|
||||||
buf.writeBigUInt64BE(val)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UInt64(buf);
|
return new UInt64(buf);
|
||||||
@@ -56,7 +57,7 @@ class UInt64 extends UInt {
|
|||||||
* @returns a hex-string
|
* @returns a hex-string
|
||||||
*/
|
*/
|
||||||
toJSON(): string {
|
toJSON(): string {
|
||||||
return this.bytes.toString('hex').toUpperCase();
|
return this.bytes.toString("hex").toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import { BinaryParser } from "../serdes/binary-parser";
|
|||||||
* Derived UInt class for serializing/deserializing 8 bit UInt
|
* Derived UInt class for serializing/deserializing 8 bit UInt
|
||||||
*/
|
*/
|
||||||
class UInt8 extends UInt {
|
class UInt8 extends UInt {
|
||||||
protected static readonly width: number = 8 / 8 //1
|
protected static readonly width: number = 8 / 8; // 1
|
||||||
static readonly defaultUInt8: UInt8 = new UInt8(Buffer.alloc(UInt8.width))
|
static readonly defaultUInt8: UInt8 = new UInt8(Buffer.alloc(UInt8.width));
|
||||||
|
|
||||||
constructor(bytes: Buffer) {
|
constructor(bytes: Buffer) {
|
||||||
super(bytes ?? UInt8.defaultUInt8.bytes)
|
super(bytes ?? UInt8.defaultUInt8.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromParser(parser: BinaryParser): UInt {
|
static fromParser(parser: BinaryParser): UInt {
|
||||||
@@ -22,11 +22,11 @@ class UInt8 extends UInt {
|
|||||||
* @param val UInt8 object or number
|
* @param val UInt8 object or number
|
||||||
*/
|
*/
|
||||||
static from(val: UInt8 | number): UInt8 {
|
static from(val: UInt8 | number): UInt8 {
|
||||||
if(val instanceof UInt8) {
|
if (val instanceof UInt8) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
let buf = Buffer.alloc(UInt8.width);
|
const buf = Buffer.alloc(UInt8.width);
|
||||||
buf.writeUInt8(val);
|
buf.writeUInt8(val);
|
||||||
return new UInt8(buf);
|
return new UInt8(buf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ import { ComparableClass } from "./serialized-type";
|
|||||||
* @returns -1, 0, or 1, depending on how the two objects compare
|
* @returns -1, 0, or 1, depending on how the two objects compare
|
||||||
*/
|
*/
|
||||||
function compare(n1: number | bigint, n2: number | bigint): number {
|
function compare(n1: number | bigint, n2: number | bigint): number {
|
||||||
return n1 < n2 ? -1 : n1 == n2 ? 0 : 1
|
return n1 < n2 ? -1 : n1 == n2 ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for serializing and deserializing unsigned integers.
|
* Base class for serializing and deserializing unsigned integers.
|
||||||
*/
|
*/
|
||||||
abstract class UInt extends ComparableClass {
|
abstract class UInt extends ComparableClass {
|
||||||
protected static width: number
|
protected static width: number;
|
||||||
|
|
||||||
constructor(bytes: Buffer) {
|
constructor(bytes: Buffer) {
|
||||||
super(bytes)
|
super(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,10 +37,8 @@ abstract class UInt extends ComparableClass {
|
|||||||
* @returns number or string represented by this.bytes
|
* @returns number or string represented by this.bytes
|
||||||
*/
|
*/
|
||||||
toJSON(): number | string {
|
toJSON(): number | string {
|
||||||
let val = this.valueOf()
|
const val = this.valueOf();
|
||||||
return typeof val === "number"
|
return typeof val === "number" ? val : val.toString();
|
||||||
? val
|
|
||||||
: val.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { BytesList } from "../serdes/binary-serializer";
|
|||||||
*/
|
*/
|
||||||
class Vector256 extends SerializedTypeClass {
|
class Vector256 extends SerializedTypeClass {
|
||||||
constructor(bytes: Buffer) {
|
constructor(bytes: Buffer) {
|
||||||
super(bytes)
|
super(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,7 +19,7 @@ class Vector256 extends SerializedTypeClass {
|
|||||||
* @returns a Vector256 object
|
* @returns a Vector256 object
|
||||||
*/
|
*/
|
||||||
static fromParser(parser: BinaryParser, hint?: number): Vector256 {
|
static fromParser(parser: BinaryParser, hint?: number): Vector256 {
|
||||||
let bytesList = new BytesList();
|
const bytesList = new BytesList();
|
||||||
const bytes = hint ?? parser.size();
|
const bytes = hint ?? parser.size();
|
||||||
const hashes = bytes / 32;
|
const hashes = bytes / 32;
|
||||||
for (let i = 0; i < hashes; i++) {
|
for (let i = 0; i < hashes; i++) {
|
||||||
@@ -35,12 +35,12 @@ class Vector256 extends SerializedTypeClass {
|
|||||||
* @returns a Vector256 object
|
* @returns a Vector256 object
|
||||||
*/
|
*/
|
||||||
static from(value: Vector256 | Array<string>): Vector256 {
|
static from(value: Vector256 | Array<string>): Vector256 {
|
||||||
if(value instanceof Vector256) {
|
if (value instanceof Vector256) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bytesList = new BytesList();
|
const bytesList = new BytesList();
|
||||||
value.forEach(hash => {
|
value.forEach((hash) => {
|
||||||
Hash256.from(hash).toBytesSink(bytesList);
|
Hash256.from(hash).toBytesSink(bytesList);
|
||||||
});
|
});
|
||||||
return new Vector256(bytesList.toBytes());
|
return new Vector256(bytesList.toBytes());
|
||||||
@@ -52,15 +52,20 @@ class Vector256 extends SerializedTypeClass {
|
|||||||
* @returns An Array of strings representing the Hash256 objects
|
* @returns An Array of strings representing the Hash256 objects
|
||||||
*/
|
*/
|
||||||
toJSON(): Array<string> {
|
toJSON(): Array<string> {
|
||||||
if(this.bytes.byteLength % 32 !== 0) {
|
if (this.bytes.byteLength % 32 !== 0) {
|
||||||
throw new Error("Invalid bytes for Vector256")
|
throw new Error("Invalid bytes for Vector256");
|
||||||
}
|
}
|
||||||
|
|
||||||
let result: Array<string> = []
|
const result: Array<string> = [];
|
||||||
for(let i = 0; i < this.bytes.byteLength; i += 32) {
|
for (let i = 0; i < this.bytes.byteLength; i += 32) {
|
||||||
result.push(this.bytes.slice(i,i+32).toString('hex').toUpperCase())
|
result.push(
|
||||||
|
this.bytes
|
||||||
|
.slice(i, i + 32)
|
||||||
|
.toString("hex")
|
||||||
|
.toUpperCase()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user