@andrew_l/tl-pack
Version:
 <!-- omit in toc -->  <!-- omit in toc -->  • 32.3 kB
JavaScript
'use strict';
const pako = require('pako');
const toolkit = require('@andrew_l/toolkit');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
const pako__default = /*#__PURE__*/_interopDefaultCompat(pako);
var CORE_TYPES = /* @__PURE__ */ ((CORE_TYPES2) => {
CORE_TYPES2[CORE_TYPES2["None"] = 0] = "None";
CORE_TYPES2[CORE_TYPES2["Binary"] = 1] = "Binary";
CORE_TYPES2[CORE_TYPES2["BoolFalse"] = 2] = "BoolFalse";
CORE_TYPES2[CORE_TYPES2["BoolTrue"] = 3] = "BoolTrue";
CORE_TYPES2[CORE_TYPES2["Null"] = 4] = "Null";
CORE_TYPES2[CORE_TYPES2["Date"] = 5] = "Date";
CORE_TYPES2[CORE_TYPES2["Vector"] = 6] = "Vector";
CORE_TYPES2[CORE_TYPES2["VectorDynamic"] = 7] = "VectorDynamic";
CORE_TYPES2[CORE_TYPES2["Int32"] = 8] = "Int32";
CORE_TYPES2[CORE_TYPES2["Int16"] = 9] = "Int16";
CORE_TYPES2[CORE_TYPES2["Int8"] = 10] = "Int8";
CORE_TYPES2[CORE_TYPES2["UInt32"] = 11] = "UInt32";
CORE_TYPES2[CORE_TYPES2["UInt16"] = 12] = "UInt16";
CORE_TYPES2[CORE_TYPES2["UInt8"] = 13] = "UInt8";
CORE_TYPES2[CORE_TYPES2["Float"] = 14] = "Float";
CORE_TYPES2[CORE_TYPES2["Double"] = 15] = "Double";
CORE_TYPES2[CORE_TYPES2["Map"] = 16] = "Map";
CORE_TYPES2[CORE_TYPES2["DictValue"] = 17] = "DictValue";
CORE_TYPES2[CORE_TYPES2["DictIndex"] = 18] = "DictIndex";
CORE_TYPES2[CORE_TYPES2["String"] = 19] = "String";
CORE_TYPES2[CORE_TYPES2["Repeat"] = 20] = "Repeat";
CORE_TYPES2[CORE_TYPES2["Checksum"] = 21] = "Checksum";
CORE_TYPES2[CORE_TYPES2["GZIP"] = 25] = "GZIP";
return CORE_TYPES2;
})(CORE_TYPES || {});
const MAX_BUFFER_SIZE = 2144337920;
function createDictionary(values) {
return new Dictionary(values);
}
class Dictionary {
_count = 0;
_wordToIndex;
_words;
_offset;
constructor(values, offset = 0) {
this._words = [];
this._wordToIndex = /* @__PURE__ */ new Map();
this._offset = offset;
if (Array.isArray(values) && values.length) {
values.forEach((word) => {
if (this._wordToIndex.has(word)) return;
this._wordToIndex.set(word, this._count++);
this._words.push(word);
});
}
}
get size() {
return this._count;
}
/**
* Returns inserted index or nothing
*/
maybeInsert(word) {
if (this._wordToIndex.has(word)) return null;
this._wordToIndex.set(word, this._count++);
this._words.push(word);
return this._count + this._offset;
}
getValue(index) {
return this._words[index - this._offset] ?? null;
}
getIndex(value) {
const idx = this._wordToIndex.get(value);
if (idx === void 0) {
return null;
}
return idx + this._offset;
}
hasValue(value) {
return this._wordToIndex.has(value);
}
hasIndex(index) {
return this._words[index - this._offset] !== void 0;
}
}
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const fromCharCode = String.fromCharCode;
const int32 = new Int32Array(2);
const float32 = new Float32Array(int32.buffer);
const float64 = new Float64Array(int32.buffer);
function byteArrayAllocate(length) {
return new Uint8Array(length);
}
function coreType(value) {
switch (typeof value) {
case "string": {
return CORE_TYPES.String;
}
case "boolean": {
return value ? CORE_TYPES.BoolTrue : CORE_TYPES.BoolFalse;
}
case "number": {
if (Math.trunc(value) === value) {
if (value >= 0 && value <= 255) {
return CORE_TYPES.UInt8;
} else if (value >= 0 && value <= 65535) {
return CORE_TYPES.UInt16;
} else if (value >= 0 && value <= 4294967295) {
return CORE_TYPES.UInt32;
} else if (value >= -128 && value <= 127) {
return CORE_TYPES.Int8;
} else if (value >= -32768 && value <= 32767) {
return CORE_TYPES.Int16;
} else if (value >= -2147483648 && value <= 2147483647) {
return CORE_TYPES.Int32;
}
}
return CORE_TYPES.Double;
}
case "object": {
if (value === null) return CORE_TYPES.Null;
if (value instanceof Date) {
return CORE_TYPES.Date;
}
if (Array.isArray(value)) {
return CORE_TYPES.Vector;
}
if (toolkit.isPlainObject(value)) {
return CORE_TYPES.Map;
}
}
}
return CORE_TYPES.None;
}
function utf8Read(target, length, offset) {
let result;
if (length < 16) {
if (result = utf8ReadShort(target, length, offset)) return result;
}
if (length > 64 && decoder)
return decoder.decode(target.subarray(offset, offset += length));
const end = offset + length;
const units = [];
result = "";
while (offset < end) {
const byte1 = target[offset++];
if ((byte1 & 128) === 0) {
units.push(byte1);
} else if ((byte1 & 224) === 192) {
const byte2 = target[offset++] & 63;
units.push((byte1 & 31) << 6 | byte2);
} else if ((byte1 & 240) === 224) {
const byte2 = target[offset++] & 63;
const byte3 = target[offset++] & 63;
units.push((byte1 & 31) << 12 | byte2 << 6 | byte3);
} else if ((byte1 & 248) === 240) {
const byte2 = target[offset++] & 63;
const byte3 = target[offset++] & 63;
const byte4 = target[offset++] & 63;
let unit = (byte1 & 7) << 18 | byte2 << 12 | byte3 << 6 | byte4;
if (unit > 65535) {
unit -= 65536;
units.push(unit >>> 10 & 1023 | 55296);
unit = 56320 | unit & 1023;
}
units.push(unit);
} else {
units.push(byte1);
}
if (units.length >= 4096) {
result += fromCharCode.apply(String, units);
units.length = 0;
}
}
if (units.length > 0) {
result += fromCharCode.apply(String, units);
}
return result;
}
function utf8ReadShort(target, length, offset) {
if (length < 4) {
if (length < 2) {
if (length === 0) return "";
else {
let a = target[offset++];
if ((a & 128) > 1) {
offset -= 1;
return;
}
return fromCharCode(a);
}
} else {
let a = target[offset++];
let b = target[offset++];
if ((a & 128) > 0 || (b & 128) > 0) {
offset -= 2;
return;
}
if (length < 3) return fromCharCode(a, b);
let c = target[offset++];
if ((c & 128) > 0) {
offset -= 3;
return;
}
return fromCharCode(a, b, c);
}
} else {
let a = target[offset++];
let b = target[offset++];
let c = target[offset++];
let d = target[offset++];
if ((a & 128) > 0 || (b & 128) > 0 || (c & 128) > 0 || (d & 128) > 0) {
offset -= 4;
return;
}
if (length < 6) {
if (length === 4) return fromCharCode(a, b, c, d);
else {
let e = target[offset++];
if ((e & 128) > 0) {
offset -= 5;
return;
}
return fromCharCode(a, b, c, d, e);
}
} else if (length < 8) {
let e = target[offset++];
let f = target[offset++];
if ((e & 128) > 0 || (f & 128) > 0) {
offset -= 6;
return;
}
if (length < 7) return fromCharCode(a, b, c, d, e, f);
let g = target[offset++];
if ((g & 128) > 0) {
offset -= 7;
return;
}
return fromCharCode(a, b, c, d, e, f, g);
} else {
let e = target[offset++];
let f = target[offset++];
let g = target[offset++];
let h = target[offset++];
if ((e & 128) > 0 || (f & 128) > 0 || (g & 128) > 0 || (h & 128) > 0) {
offset -= 8;
return;
}
if (length < 10) {
if (length === 8) return fromCharCode(a, b, c, d, e, f, g, h);
else {
let i = target[offset++];
if ((i & 128) > 0) {
offset -= 9;
return;
}
return fromCharCode(a, b, c, d, e, f, g, h, i);
}
} else if (length < 12) {
let i = target[offset++];
let j = target[offset++];
if ((i & 128) > 0 || (j & 128) > 0) {
offset -= 10;
return;
}
if (length < 11) return fromCharCode(a, b, c, d, e, f, g, h, i, j);
let k = target[offset++];
if ((k & 128) > 0) {
offset -= 11;
return;
}
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k);
} else {
let i = target[offset++];
let j = target[offset++];
let k = target[offset++];
let l = target[offset++];
if ((i & 128) > 0 || (j & 128) > 0 || (k & 128) > 0 || (l & 128) > 0) {
offset -= 12;
return;
}
if (length < 14) {
if (length === 12)
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l);
else {
let m = target[offset++];
if ((m & 128) > 0) {
offset -= 13;
return;
}
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m);
}
} else {
let m = target[offset++];
let n = target[offset++];
if ((m & 128) > 0 || (n & 128) > 0) {
offset -= 14;
return;
}
if (length < 15)
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
let o = target[offset++];
if ((o & 128) > 0) {
offset -= 15;
return;
}
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
}
}
}
}
}
const utf8Write = function(target, value, offset) {
return value.length < 64 ? utf8WriteShort(target, value, offset) : encoder.encodeInto(value, target.subarray(offset)).written;
};
const utf8WriteShort = (target, value, offset) => {
let i, c1, c2, strPosition = offset;
const strLength = value.length;
for (i = 0; i < strLength; i++) {
c1 = value.charCodeAt(i);
if (c1 < 128) {
target[strPosition++] = c1;
} else if (c1 < 2048) {
target[strPosition++] = c1 >> 6 | 192;
target[strPosition++] = c1 & 63 | 128;
} else if ((c1 & 64512) === 55296 && ((c2 = value.charCodeAt(i + 1)) & 64512) === 56320) {
c1 = 65536 + ((c1 & 1023) << 10) + (c2 & 1023);
i++;
target[strPosition++] = c1 >> 18 | 240;
target[strPosition++] = c1 >> 12 & 63 | 128;
target[strPosition++] = c1 >> 6 & 63 | 128;
target[strPosition++] = c1 & 63 | 128;
} else {
target[strPosition++] = c1 >> 12 | 224;
target[strPosition++] = c1 >> 6 & 63 | 128;
target[strPosition++] = c1 & 63 | 128;
}
}
return strPosition - offset;
};
class BinaryReader {
target;
_last;
_lastObject;
dictionary;
dictionaryExtended;
extensions;
_repeat;
_checksumOffset;
offset;
length;
/**
* Small utility class to read binary data.
*/
constructor(data, options) {
this.target = data;
this.offset = 0;
this._checksumOffset = 0;
this.length = data.length;
this.extensions = /* @__PURE__ */ new Map();
if (options && options.extensions) {
options.extensions.forEach((ext) => {
this.extensions.set(ext.token, ext);
});
}
if (!options) {
this.dictionary = new Dictionary();
} else if (options.dictionary instanceof Dictionary) {
this.dictionary = options.dictionary;
} else if (Array.isArray(options.dictionary)) {
this.dictionary = new Dictionary(options.dictionary);
} else {
this.dictionary = new Dictionary();
}
this.dictionaryExtended = new Dictionary(void 0, this.dictionary.size);
}
readByte() {
this.assertRead(1);
this._last = this.target[this.offset++];
return this._last;
}
readInt32(signed = true) {
this.assertRead(4);
this._last = this.target[this.offset++] | this.target[this.offset++] << 8 | this.target[this.offset++] << 16 | this.target[this.offset++] << 24;
if (!signed) {
this._last = this._last >>> 0;
}
return this._last;
}
readInt16(signed = true) {
this.assertRead(2);
this._last = this.target[this.offset++] | this.target[this.offset++] << 8;
if (signed) {
this._last = this._last << 16 >> 16;
}
return this._last;
}
readInt8(signed = true) {
this.assertRead(1);
this._last = this.target[this.offset++];
if (signed) {
this._last = this._last << 24 >> 24;
}
return this._last;
}
/**
* Reads a real floating point (4 bytes) value.
* @returns {number}
*/
readFloat() {
this.assertRead(4);
int32[0] = this.readInt32();
this._last = float32[0];
return this._last;
}
/**
* Reads a real floating point (8 bytes) value.
* @returns {BigInteger}
*/
readDouble() {
this.assertRead(8);
int32[0] = this.readInt32();
int32[1] = this.readInt32();
this._last = float64[0];
return this._last;
}
/**
* Read the given amount of bytes, or -1 to read all remaining.
* @param length {number}
*/
assertRead(length) {
if (this.length < this.offset + +length) {
const left = this.target.length - this.offset;
const result = this.target.subarray(this.offset, this.offset + left);
const err = new Error(
`No more data left to read (need ${length}, got ${left}: ${result}); last read ${this._last}`
);
err.incomplete = true;
Error.captureStackTrace(err, this.assertRead);
throw err;
}
}
assertConstructor(constructorId) {
const byte = this.readByte();
if (byte !== constructorId) {
throw new Error(
`Invalid constructor code, expected = ${CORE_TYPES[constructorId]}, got = ${CORE_TYPES[byte] || byte}, offset = ${this.offset - 1}`
);
}
}
/**
* Gets the byte array representing the current buffer as a whole.
*/
getBuffer() {
return this.target;
}
readNull() {
const value = this.readByte();
if (value === CORE_TYPES.Null) {
return null;
}
throw new Error(`Invalid boolean code ${value.toString(16)}`);
}
readLength() {
const firstByte = this.readByte();
if (firstByte === 254) {
return this.readByte() | this.readByte() << 8 | this.readByte() << 16;
}
return firstByte;
}
readAll() {
const result = [];
while (this.length > this.offset) {
result.push(this.readObject());
}
return result;
}
readBytes() {
const length = this.readLength();
this.assertRead(length);
const bytes = this.target.subarray(this.offset, this.offset + length);
this.offset += bytes.length;
this._last = bytes;
return bytes;
}
/**
* Reads encoded string.
*/
readString() {
const length = this.readLength();
this.assertRead(length);
const result = utf8Read(this.target, length, this.offset);
this.offset += length;
this._last = result;
return result;
}
/**
* Reads a boolean value.
*/
readBool() {
const value = this.readByte();
if (value === CORE_TYPES.BoolTrue) {
return true;
} else if (value === CORE_TYPES.BoolFalse) {
return false;
} else {
throw new Error(`Invalid boolean code ${value.toString(16)}`);
}
}
/**
* Reads and converts Unix time
* into a Javascript {Date} object.
*/
readDate() {
const value = this.readDouble();
return new Date(value);
}
/**
* Reads a object.
*/
readObject() {
if (this._repeat) {
if (this._repeat.pool > 0) {
--this._repeat.pool;
return this._repeat.value;
} else {
this._repeat = void 0;
}
}
const constructorId = this.readByte();
const ext = this.extensions.get(constructorId);
let value;
if (ext) {
value = ext.decode.call(this);
} else {
value = this._lastObject = this.readCore(constructorId);
}
return value;
}
readObjectGzip() {
const bytes = this.readGzip();
const reader = new BinaryReader(bytes);
reader.extensions = this.extensions;
reader.dictionary = this.dictionary;
reader.dictionaryExtended = this.dictionaryExtended;
return reader.readObject();
}
readGzip() {
return pako__default.inflateRaw(this.readBytes());
}
readCore(constructorId) {
switch (constructorId) {
case CORE_TYPES.None:
return this.readObject();
case CORE_TYPES.GZIP:
return this.readObjectGzip();
case CORE_TYPES.BoolTrue:
return true;
case CORE_TYPES.BoolFalse:
return false;
case CORE_TYPES.Vector:
return this.readVector(false);
case CORE_TYPES.VectorDynamic:
return this.readVectorDynamic(false);
case CORE_TYPES.Null:
return null;
case CORE_TYPES.Binary:
return this.readBytes();
case CORE_TYPES.String:
return this.readString();
case CORE_TYPES.Date:
return this.readDate();
case CORE_TYPES.Int32:
return this.readInt32();
case CORE_TYPES.Int16:
return this.readInt16();
case CORE_TYPES.Int8:
return this.readInt8();
case CORE_TYPES.UInt32:
return this.readInt32(false);
case CORE_TYPES.UInt16:
return this.readInt16(false);
case CORE_TYPES.UInt8:
return this.readInt8(false);
case CORE_TYPES.Float:
return this.readFloat();
case CORE_TYPES.Double:
return this.readDouble();
case CORE_TYPES.Map:
return this.readMap(false);
case CORE_TYPES.Checksum:
return void this.readChecksum(false);
case CORE_TYPES.DictIndex: {
const idx = this.readLength();
return this.getDictionaryValue(idx);
}
case CORE_TYPES.DictValue: {
const value = this.readString();
this.dictionaryExtended.maybeInsert(value);
return value;
}
case CORE_TYPES.Repeat: {
const size = this.readLength();
this._repeat = { pool: size - 1, value: this._lastObject };
return this._lastObject;
}
}
throw new Error(
`Invalid constructor = ${CORE_TYPES[constructorId] || constructorId}, offset = ${this.offset - 1}`
);
}
getDictionaryValue(index) {
let value = null;
if (this.dictionary) {
value = this.dictionary.getValue(index);
}
if (value === null) {
value = this.dictionaryExtended.getValue(index);
}
return value;
}
readDictionary() {
const constructorId = this.readByte();
let key = null;
switch (constructorId) {
case CORE_TYPES.DictIndex: {
const idx = this.readLength();
key = this.getDictionaryValue(idx);
break;
}
case CORE_TYPES.DictValue: {
key = this.readString();
this.dictionaryExtended.maybeInsert(key);
break;
}
case CORE_TYPES.None: {
key = null;
break;
}
default: {
this.seek(-1);
}
}
return key;
}
readMap(checkConstructor = true) {
if (checkConstructor) {
this.assertConstructor(CORE_TYPES.Map);
}
const temp = {};
let key = this.readDictionary();
while (key !== null) {
temp[key] = this.readObject();
key = this.readDictionary();
}
return temp;
}
decode(value) {
this.target = value;
this._last = void 0;
this._lastObject = void 0;
this._repeat = void 0;
this.offset = 0;
this._checksumOffset = 0;
this.length = value.length;
return this.readObject();
}
/**
* Reads a vector (a list) of objects.
*/
readVector(checkConstructor = true) {
if (checkConstructor) {
this.assertConstructor(CORE_TYPES.Vector);
}
const count = this.readLength();
const temp = [];
for (let i = 0; i < count; i++) {
temp.push(this.readObject());
}
return temp;
}
/**
* Reads a vector (a list) of objects.
*/
readVectorDynamic(checkConstructor = true) {
if (checkConstructor) {
this.assertConstructor(CORE_TYPES.VectorDynamic);
}
const temp = [];
let complete = false;
while (this.length > this.offset) {
const constructorId = this.readByte();
if (constructorId === CORE_TYPES.None) {
complete = true;
break;
}
const ext = this.extensions.get(constructorId);
let value;
if (ext) {
value = ext.decode.call(this);
} else {
value = this.readCore(constructorId);
}
temp.push(value);
}
if (!complete) {
const err = new Error(`DynamicVector incomplete.`);
err.incomplete = true;
Error.captureStackTrace(err, this.readDictionary);
throw err;
}
this._last = temp;
return temp;
}
readChecksum(checkConstructor = true) {
const offset = this.offset;
if (checkConstructor) {
this.assertConstructor(CORE_TYPES.Checksum);
}
const bytes = this.target.slice(this._checksumOffset, offset);
const checksum = this.readLength();
let sum = 0;
for (const val of bytes) {
sum += val;
}
if (checksum - sum !== 0) {
throw new Error(
`Invalid checksum = ${checksum - sum}, offset = ${offset}`
);
}
this._checksumOffset = this.offset;
}
/**
* Tells the current position on the stream.
*/
tellPosition() {
return this.offset;
}
/**
* Sets the current position on the stream.
*/
setPosition(position) {
this.offset = position;
}
/**
* Seeks the stream position given an offset from the current position.
* The offset may be negative.
*/
seek(offset) {
this.offset += offset;
}
}
const noop = Symbol();
const NO_CONSTRUCTOR = /* @__PURE__ */ new Set([
CORE_TYPES.BoolFalse,
CORE_TYPES.BoolTrue,
CORE_TYPES.Null
]);
const SUPPORT_COMPRESSION = /* @__PURE__ */ new Set([CORE_TYPES.String]);
class BinaryWriter {
withGzip;
target;
dictionary;
dictionaryExtended;
extensions;
_last = noop;
_checksumOffset;
_repeat;
offset;
constructor(options) {
this.offset = 0;
this._checksumOffset = 0;
this.extensions = /* @__PURE__ */ new Map();
this.withGzip = !!options && !!options.gzip;
this.target = byteArrayAllocate(8192);
if (options && options.extensions) {
options.extensions.forEach((ext) => {
this.extensions.set(ext.token, ext);
});
}
if (!options) {
this.dictionary = new Dictionary();
} else if (options.dictionary instanceof Dictionary) {
this.dictionary = options.dictionary;
} else if (Array.isArray(options.dictionary)) {
this.dictionary = new Dictionary(options.dictionary);
} else {
this.dictionary = new Dictionary();
}
this.dictionaryExtended = new Dictionary(void 0, this.dictionary.size);
}
allocate(size) {
const position = this.offset + size;
if (this.safeEnd < position) {
this.makeRoom(position);
}
return this;
}
makeRoom(end) {
let start = 0;
let newSize = 0;
let target = this.target;
if (end > 16777216) {
if (end - start > MAX_BUFFER_SIZE)
throw new Error(
"Packed buffer would be larger than maximum buffer size"
);
newSize = Math.min(
MAX_BUFFER_SIZE,
Math.round(
Math.max((end - start) * (end > 67108864 ? 1.25 : 2), 4194304) / 4096
) * 4096
);
} else {
newSize = (Math.max(end - start << 2, target.length - 1) >> 12) + 1 << 12;
}
const newBuffer = byteArrayAllocate(newSize);
end = Math.min(end, target.length);
newBuffer.set(target.slice(start, end));
this.target = newBuffer;
}
get safeEnd() {
return this.target.length - 10;
}
getBuffer() {
return this.target.subarray(0, this.offset);
}
writeByte(value) {
this.allocate(1);
this.target[this.offset++] = value;
return this;
}
writeBool(value) {
if (value) {
this.writeByte(CORE_TYPES.BoolTrue);
} else {
this.writeByte(CORE_TYPES.BoolFalse);
}
return this;
}
writeNull() {
this.writeByte(CORE_TYPES.Null);
return this;
}
writeInt32(value, signed = true) {
this.allocate(4);
if (signed) {
this.target[this.offset++] = value;
this.target[this.offset++] = value >> 8;
this.target[this.offset++] = value >> 16;
this.target[this.offset++] = value >> 24;
} else {
this.target[this.offset++] = value;
this.target[this.offset++] = value >> 8;
this.target[this.offset++] = value >> 16;
this.target[this.offset++] = value >> 24;
}
return this;
}
writeInt16(value, signed = true) {
this.allocate(2);
if (signed) {
this.target[this.offset++] = value;
this.target[this.offset++] = value >> 8;
} else {
this.target[this.offset++] = value;
this.target[this.offset++] = value >> 8;
}
return this;
}
writeInt8(value, signed = true) {
this.allocate(1);
this.target[this.offset++] = value;
return this;
}
writeFloat(value) {
this.allocate(4);
float32[0] = value;
this.writeInt32(int32[0]);
return this;
}
writeDouble(value) {
this.allocate(8);
float64[0] = value;
this.writeInt32(int32[0], false);
this.writeInt32(int32[1], false);
return this;
}
writeDate(value) {
let timestamp = 0;
if (value instanceof Date) {
timestamp = value.getTime();
} else if (typeof value === "number") {
timestamp = value;
}
this.writeDouble(timestamp);
return this;
}
writeString(value) {
const strLength = value.length;
let start = this.offset;
let require = strLength << 2;
if (require < 254) {
require += 1;
this.offset += 1;
} else {
require += 4;
this.offset += 4;
}
this.allocate(require);
const bytes = utf8Write(this.target, value, this.offset);
if (require < 254) {
this.target[start++] = bytes;
} else {
this.target[start++] = 254;
this.target[start++] = bytes % 256;
this.target[start++] = (bytes >> 8) % 256;
this.target[start++] = (bytes >> 16) % 256;
}
this.offset += bytes;
return this;
}
writeChecksum(withConstructor = true) {
const bytes = this.target.slice(this._checksumOffset, this.offset);
let sum = 0;
for (const val of bytes) {
sum += val;
}
if (withConstructor) {
this.writeByte(CORE_TYPES.Checksum);
}
this.writeLength(sum);
this._checksumOffset = this.offset;
return this;
}
writeBytes(value) {
const length = value.length;
this.writeLength(length);
this.allocate(length);
this.target.set(value, this.offset);
this.offset += length;
return this;
}
writeLength(value) {
if (value < 254) {
this.allocate(1);
this.target[this.offset++] = value;
} else {
this.allocate(4);
this.target[this.offset++] = 254;
this.target[this.offset++] = value % 256;
this.target[this.offset++] = (value >> 8) % 256;
this.target[this.offset++] = (value >> 16) % 256;
}
return this;
}
writeVector(value) {
const length = value.length;
this.writeLength(length);
for (let i = 0; i < length; i++) {
if (value[i] === void 0) {
this.writeNull();
} else {
this.writeObject(value[i]);
}
}
return this;
}
writeMap(object) {
for (const key in object) {
if (object[key] === void 0) continue;
this._last = noop;
this.wireDictionary(key);
this.writeObject(object[key]);
}
this.writeByte(CORE_TYPES.None);
return this;
}
wireDictionary(value) {
let idx = null;
if (this.dictionary) {
idx = this.dictionary.getIndex(value);
}
if (idx === null) {
idx = this.dictionaryExtended.getIndex(value);
}
if (idx === null) {
this.dictionaryExtended.maybeInsert(value);
this.writeCore(CORE_TYPES.DictValue, value);
} else {
this.writeCore(CORE_TYPES.DictIndex, idx);
}
return this;
}
writeGzip(value) {
const compressed = pako__default.deflateRaw(value, { level: 9 });
this.writeBytes(compressed);
return this;
}
encode(value) {
this.offset = 0;
this._checksumOffset = 0;
this._last = noop;
this._repeat = void 0;
this.target = byteArrayAllocate(256);
this.writeObject(value);
return this.getBuffer();
}
startDynamicVector() {
this.writeByte(CORE_TYPES.VectorDynamic);
return this;
}
endDynamicVector() {
this.writeByte(CORE_TYPES.None);
return this;
}
_writeCustom(value) {
const start = this.offset;
this.allocate(1);
this.offset++;
let edgeExt;
for (const ext of this.extensions.values()) {
if (ext.token === -1) {
edgeExt = ext;
continue;
}
ext.encode.call(this, value);
const processed = start + 1 < this.offset;
if (processed) {
const end = this.offset;
this.offset = start;
this.writeByte(ext.token);
this.offset = end;
return true;
}
}
this.offset = start;
if (edgeExt) {
edgeExt.encode.call(this, value);
return start < this.offset;
}
return false;
}
writeObject(value) {
if (value === void 0) return this;
const constructorId = coreType(value);
if (constructorId === CORE_TYPES.None) {
if (this._writeCustom(value)) {
return this;
}
throw new TypeError(`Invalid core type of ${value}`);
}
if (this._last === value) {
this.writeRepeat();
} else {
this._last = value;
this._repeat = void 0;
this.writeCore(constructorId, value);
}
return this;
}
writeObjectGzip(value) {
const writer = new BinaryWriter();
writer.extensions = this.extensions;
writer.dictionary = this.dictionary;
writer.dictionaryExtended = this.dictionaryExtended;
writer.writeObject(value);
this.writeCore(CORE_TYPES.GZIP, writer.getBuffer());
return this;
}
writeCore(constructorId, value) {
if (this.withGzip && SUPPORT_COMPRESSION.has(constructorId)) {
this.writeObjectGzip(value);
return this;
} else if (!NO_CONSTRUCTOR.has(constructorId)) {
this.writeByte(constructorId);
}
switch (constructorId) {
case CORE_TYPES.GZIP: {
return this.writeGzip(value);
}
case CORE_TYPES.DictIndex: {
return this.writeLength(value);
}
case CORE_TYPES.DictValue: {
return this.writeString(value);
}
case CORE_TYPES.BoolFalse: {
return this.writeBool(value);
}
case CORE_TYPES.BoolTrue: {
return this.writeBool(value);
}
case CORE_TYPES.Date: {
return this.writeDate(value);
}
case CORE_TYPES.Int32: {
return this.writeInt32(value);
}
case CORE_TYPES.Int16: {
return this.writeInt16(value);
}
case CORE_TYPES.Int8: {
return this.writeInt8(value);
}
case CORE_TYPES.UInt32: {
return this.writeInt32(value, false);
}
case CORE_TYPES.UInt16: {
return this.writeInt16(value, false);
}
case CORE_TYPES.UInt8: {
return this.writeInt8(value, false);
}
case CORE_TYPES.Double: {
return this.writeDouble(value);
}
case CORE_TYPES.Float: {
return this.writeFloat(value);
}
case CORE_TYPES.Null: {
return this.writeNull();
}
case CORE_TYPES.String: {
if (value.length <= 16) {
this.offset--;
return this.wireDictionary(value);
}
return this.writeString(value);
}
case CORE_TYPES.Vector: {
return this.writeVector(value);
}
case CORE_TYPES.Map: {
return this.writeMap(value);
}
}
return this;
}
writeRepeat() {
if (!this._repeat) {
this.writeByte(CORE_TYPES.Repeat);
this._repeat = { count: 0, offset: this.offset };
}
this.offset = this._repeat.offset;
this._repeat.count++;
this.writeLength(this._repeat.count);
return this;
}
}
exports.BinaryReader = BinaryReader;
exports.BinaryWriter = BinaryWriter;
exports.CORE_TYPES = CORE_TYPES;
exports.MAX_BUFFER_SIZE = MAX_BUFFER_SIZE;
exports.createDictionary = createDictionary;
//# sourceMappingURL=tl-pack.DfL54MjP.cjs.map