mirror of
https://github.com/Xahau/xahau.js.git
synced 2026-04-29 15:37:50 +00:00
207 lines
6.2 KiB
JavaScript
207 lines
6.2 KiB
JavaScript
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
}
|
|
Object.defineProperty(o, k2, desc);
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.BinaryParser = void 0;
|
|
const assert = __importStar(require("assert"));
|
|
const enums_1 = require("../enums");
|
|
const buffer_1 = require("buffer/");
|
|
/**
|
|
* BinaryParser is used to compute fields and values from a HexString
|
|
*/
|
|
class BinaryParser {
|
|
/**
|
|
* Initialize bytes to a hex string
|
|
*
|
|
* @param hexBytes a hex string
|
|
*/
|
|
constructor(hexBytes) {
|
|
this.bytes = buffer_1.Buffer.from(hexBytes, 'hex');
|
|
}
|
|
/**
|
|
* Peek the first byte of the BinaryParser
|
|
*
|
|
* @returns The first byte of the BinaryParser
|
|
*/
|
|
peek() {
|
|
assert.ok(this.bytes.byteLength !== 0);
|
|
return this.bytes[0];
|
|
}
|
|
/**
|
|
* Consume the first n bytes of the BinaryParser
|
|
*
|
|
* @param n the number of bytes to skip
|
|
*/
|
|
skip(n) {
|
|
assert.ok(n <= this.bytes.byteLength);
|
|
this.bytes = this.bytes.slice(n);
|
|
}
|
|
/**
|
|
* read the first n bytes from the BinaryParser
|
|
*
|
|
* @param n The number of bytes to read
|
|
* @return The bytes
|
|
*/
|
|
read(n) {
|
|
assert.ok(n <= this.bytes.byteLength);
|
|
const slice = this.bytes.slice(0, n);
|
|
this.skip(n);
|
|
return slice;
|
|
}
|
|
/**
|
|
* Read an integer of given size
|
|
*
|
|
* @param n The number of bytes to read
|
|
* @return The number represented by those bytes
|
|
*/
|
|
readUIntN(n) {
|
|
assert.ok(0 < n && n <= 4, 'invalid n');
|
|
return this.read(n).reduce((a, b) => (a << 8) | b) >>> 0;
|
|
}
|
|
readUInt8() {
|
|
return this.readUIntN(1);
|
|
}
|
|
readUInt16() {
|
|
return this.readUIntN(2);
|
|
}
|
|
readUInt32() {
|
|
return this.readUIntN(4);
|
|
}
|
|
size() {
|
|
return this.bytes.byteLength;
|
|
}
|
|
end(customEnd) {
|
|
const length = this.bytes.byteLength;
|
|
return length === 0 || (customEnd !== undefined && length <= customEnd);
|
|
}
|
|
/**
|
|
* Reads variable length encoded bytes
|
|
*
|
|
* @return The variable length bytes
|
|
*/
|
|
readVariableLength() {
|
|
return this.read(this.readVariableLengthLength());
|
|
}
|
|
/**
|
|
* Reads the length of the variable length encoded bytes
|
|
*
|
|
* @return The length of the variable length encoded bytes
|
|
*/
|
|
readVariableLengthLength() {
|
|
const b1 = this.readUInt8();
|
|
if (b1 <= 192) {
|
|
return b1;
|
|
}
|
|
else if (b1 <= 240) {
|
|
const b2 = this.readUInt8();
|
|
return 193 + (b1 - 193) * 256 + b2;
|
|
}
|
|
else if (b1 <= 254) {
|
|
const b2 = this.readUInt8();
|
|
const b3 = this.readUInt8();
|
|
return 12481 + (b1 - 241) * 65536 + b2 * 256 + b3;
|
|
}
|
|
throw new Error('Invalid variable length indicator');
|
|
}
|
|
/**
|
|
* Reads the field ordinal from the BinaryParser
|
|
*
|
|
* @return Field ordinal
|
|
*/
|
|
readFieldOrdinal() {
|
|
let type = this.readUInt8();
|
|
let nth = type & 15;
|
|
type >>= 4;
|
|
if (type === 0) {
|
|
type = this.readUInt8();
|
|
if (type === 0 || type < 16) {
|
|
throw new Error('Cannot read FieldOrdinal, type_code out of range');
|
|
}
|
|
}
|
|
if (nth === 0) {
|
|
nth = this.readUInt8();
|
|
if (nth === 0 || nth < 16) {
|
|
throw new Error('Cannot read FieldOrdinal, field_code out of range');
|
|
}
|
|
}
|
|
return (type << 16) | nth;
|
|
}
|
|
/**
|
|
* Read the field from the BinaryParser
|
|
*
|
|
* @return The field represented by the bytes at the head of the BinaryParser
|
|
*/
|
|
readField() {
|
|
return enums_1.Field.fromString(this.readFieldOrdinal().toString());
|
|
}
|
|
/**
|
|
* Read a given type from the BinaryParser
|
|
*
|
|
* @param type The type that you want to read from the BinaryParser
|
|
* @return The instance of that type read from the BinaryParser
|
|
*/
|
|
readType(type) {
|
|
return type.fromParser(this);
|
|
}
|
|
/**
|
|
* Get the type associated with a given field
|
|
*
|
|
* @param field The field that you wan to get the type of
|
|
* @return The type associated with the given field
|
|
*/
|
|
typeForField(field) {
|
|
return field.associatedType;
|
|
}
|
|
/**
|
|
* Read value of the type specified by field from the BinaryParser
|
|
*
|
|
* @param field The field that you want to get the associated value for
|
|
* @return The value associated with the given field
|
|
*/
|
|
readFieldValue(field) {
|
|
const type = this.typeForField(field);
|
|
if (!type) {
|
|
throw new Error(`unsupported: (${field.name}, ${field.type.name})`);
|
|
}
|
|
const sizeHint = field.isVariableLengthEncoded
|
|
? this.readVariableLengthLength()
|
|
: undefined;
|
|
const value = type.fromParser(this, sizeHint);
|
|
if (value === undefined) {
|
|
throw new Error(`fromParser for (${field.name}, ${field.type.name}) -> undefined `);
|
|
}
|
|
return value;
|
|
}
|
|
/**
|
|
* Get the next field and value from the BinaryParser
|
|
*
|
|
* @return The field and value
|
|
*/
|
|
readFieldAndValue() {
|
|
const field = this.readField();
|
|
return [field, this.readFieldValue(field)];
|
|
}
|
|
}
|
|
exports.BinaryParser = BinaryParser;
|
|
//# sourceMappingURL=binary-parser.js.map
|