encoding seems to work now

This commit is contained in:
Moon Man 2024-01-28 08:58:59 -05:00
parent f2bd5e4795
commit e41193e489
3 changed files with 79 additions and 72 deletions

6
dist/bert.d.ts vendored
View File

@ -137,13 +137,13 @@ export declare class Bert {
encode: (obj: any, copy?: boolean) => Buffer; encode: (obj: any, copy?: boolean) => Buffer;
decode: (buffer: Buffer) => any; decode: (buffer: Buffer) => any;
encode_string: (obj: string, buffer: Buffer) => Buffer; encode_string: (obj: string, buffer: Buffer) => Buffer;
encode_boolean: (obj: boolean, buffer: Buffer) => any; encode_boolean: (obj: boolean, buffer: Buffer) => Buffer;
encode_number: (obj: number, buffer: Buffer) => Buffer; encode_number: (obj: number, buffer: Buffer) => Buffer;
encode_float: (obj: number, buffer: Buffer) => Buffer; encode_float: (obj: number, buffer: Buffer) => Buffer;
encode_object: (obj: any, buffer: Buffer) => any; encode_object: (obj: any, buffer: Buffer) => Buffer;
encode_atom: (obj: any, buffer: Buffer) => Buffer; encode_atom: (obj: any, buffer: Buffer) => Buffer;
encode_binary: (obj: Buffer, buffer: Buffer) => Buffer; encode_binary: (obj: Buffer, buffer: Buffer) => Buffer;
encode_undefined: (_obj: Buffer, buffer: Buffer) => any; encode_undefined: (_obj: Buffer, buffer: Buffer) => Buffer;
encode_tuple: (obj: Buffer, buffer: Buffer) => Buffer; encode_tuple: (obj: Buffer, buffer: Buffer) => Buffer;
encode_array: (obj: any[], buffer: Buffer) => Buffer; encode_array: (obj: any[], buffer: Buffer) => Buffer;
encode_map: (obj: Record<string, any>, buffer: Buffer) => Buffer; encode_map: (obj: Record<string, any>, buffer: Buffer) => Buffer;

67
dist/bert.js vendored
View File

@ -39,22 +39,23 @@ export class Bert {
toTuple = toTuple; toTuple = toTuple;
#encode = (obj, buffer) => this[`encode_${typeof obj}`](obj, buffer); #encode = (obj, buffer) => this[`encode_${typeof obj}`](obj, buffer);
encode = (obj, copy = true) => { encode = (obj, copy = true) => {
const tailBuffer = this.#encode(obj, Buffer.from(this.outputBuffer, 1)); const tailBuffer = this.#encode(obj, this.outputBuffer.subarray(1));
process.stderr.write(`tailbuffer length: ${tailBuffer.length}\n`);
if (tailBuffer.length === 0) { if (tailBuffer.length === 0) {
throw new Error("Bert encode a too big term, encoding buffer overflow"); throw new Error("Bert encode a too big term, encoding buffer overflow");
} }
else if (copy) { else if (copy) {
const ret = Buffer.alloc(tailBuffer.length); const ret = Buffer.alloc(tailBuffer.length + 1);
this.outputBuffer.copy(ret, 0, 0, ret.length); this.outputBuffer.copy(ret, 0, 0, ret.length + 1);
return ret; return ret;
} }
else { else {
return Buffer.from(this.outputBuffer, 0, tailBuffer.length); return this.outputBuffer.subarray(0, tailBuffer.length + 1);
} }
}; };
#decode = (buffer) => { #decode = (buffer) => {
const t = buffer[0]; const t = buffer[0];
buffer = Buffer.from(buffer, 1); buffer = buffer.subarray(1);
switch (t) { switch (t) {
case Types.SMALL_ATOM: case Types.SMALL_ATOM:
return this.decode_atom(buffer, 1); return this.decode_atom(buffer, 1);
@ -102,13 +103,14 @@ export class Bert {
}; };
encode_string = (obj, buffer) => { encode_string = (obj, buffer) => {
if (this.convention === Lang.ELIXIR) { if (this.convention === Lang.ELIXIR) {
process.stderr.write(`encode string as elixir\n`);
return this.encode_binary(Buffer.from(obj), buffer); return this.encode_binary(Buffer.from(obj), buffer);
} }
else { else {
buffer[0] = Types.STRING; buffer[0] = Types.STRING;
buffer.writeUInt16BE(Buffer.byteLength(obj, "utf-8"), 1); buffer.writeUInt16BE(Buffer.byteLength(obj, "utf-8"), 1);
const len = buffer.write(obj, 3); const len = buffer.write(obj, 3);
return Buffer.from(buffer, 0, 3 + len); return buffer.subarray(0, 3 + len);
} }
}; };
encode_boolean = (obj, buffer) => { encode_boolean = (obj, buffer) => {
@ -129,13 +131,13 @@ export class Bert {
if (isInteger && obj >= 0 && obj < 256) { if (isInteger && obj >= 0 && obj < 256) {
buffer[0] = Types.SMALL_INTEGER; buffer[0] = Types.SMALL_INTEGER;
buffer.writeUInt8(obj, 1); buffer.writeUInt8(obj, 1);
return Buffer.from(buffer, 0, 2); return buffer.subarray(0, 2);
} }
// 4 byte int... // 4 byte int...
if (isInteger && obj >= -134217728 && obj <= 134217727) { if (isInteger && obj >= -134217728 && obj <= 134217727) {
buffer[0] = Types.INTEGER; buffer[0] = Types.INTEGER;
buffer.writeInt32BE(obj, 1); buffer.writeInt32BE(obj, 1);
return Buffer.from(buffer, 0, 5); return buffer.subarray(0, 5);
} }
// Bignum... // Bignum...
const numBuffer = Buffer.alloc(buffer.length); const numBuffer = Buffer.alloc(buffer.length);
@ -156,20 +158,20 @@ export class Bert {
buffer[0] = Types.SMALL_BIG; buffer[0] = Types.SMALL_BIG;
buffer.writeUInt8(offset - 1, 1); buffer.writeUInt8(offset - 1, 1);
numBuffer.copy(buffer, 2, 0, offset); numBuffer.copy(buffer, 2, 0, offset);
return Buffer.from(buffer, 0, 2 + offset); return buffer.subarray(0, 2 + offset);
} }
else { else {
buffer[0] = Types.LARGE_BIG; buffer[0] = Types.LARGE_BIG;
buffer.writeUInt32BE(offset - 1, 1); buffer.writeUInt32BE(offset - 1, 1);
numBuffer.copy(buffer, 5, 0, offset); numBuffer.copy(buffer, 5, 0, offset);
return Buffer.from(buffer, 0, 5 + offset); return buffer.subarray(0, 5 + offset);
} }
}; };
encode_float = (obj, buffer) => { encode_float = (obj, buffer) => {
// float... // float...
buffer[0] = Types.NEW_FLOAT; buffer[0] = Types.NEW_FLOAT;
buffer.writeDoubleBE(obj, 1); buffer.writeDoubleBE(obj, 1);
return Buffer.from(buffer, 0, 9); return buffer.subarray(0, 9);
}; };
encode_object = (obj, buffer) => { encode_object = (obj, buffer) => {
// Check if it's an atom, binary, or tuple... // Check if it's an atom, binary, or tuple...
@ -196,13 +198,14 @@ export class Bert {
buffer[0] = Types.ATOM; buffer[0] = Types.ATOM;
buffer.writeUInt16BE(obj.value.length, 1); buffer.writeUInt16BE(obj.value.length, 1);
const len = buffer.write(obj.value, 3); const len = buffer.write(obj.value, 3);
return Buffer.from(buffer, 0, 3 + len); return buffer.subarray(0, 3 + len);
}; };
encode_binary = (obj, buffer) => { encode_binary = (obj, buffer) => {
process.stderr.write(`encode binary\n`);
buffer[0] = Types.BINARY; buffer[0] = Types.BINARY;
buffer.writeUInt32BE(obj.length, 1); buffer.writeUInt32BE(obj.length, 1);
const len = obj.copy(buffer, 5); const len = obj.copy(buffer, 5);
return Buffer.from(buffer, 0, 5 + len); return buffer.subarray(0, 5 + len);
}; };
encode_undefined = (_obj, buffer) => { encode_undefined = (_obj, buffer) => {
return this.#encode(null, buffer); return this.#encode(null, buffer);
@ -211,12 +214,12 @@ export class Bert {
if (obj.length < 256) { if (obj.length < 256) {
buffer[0] = Types.SMALL_TUPLE; buffer[0] = Types.SMALL_TUPLE;
buffer.writeUInt8(obj.length, 1); buffer.writeUInt8(obj.length, 1);
buffer = Buffer.from(buffer, 0, 2); buffer = buffer.subarray(0, 2);
} }
else { else {
buffer[0] = Types.LARGE_TUPLE; buffer[0] = Types.LARGE_TUPLE;
buffer.writeUInt32BE(obj.length, 1); buffer.writeUInt32BE(obj.length, 1);
buffer = Buffer.from(buffer, 0, 5); buffer = buffer.subarray(0, 5);
} }
for (let i = 0; i < obj.length; ++i) { for (let i = 0; i < obj.length; ++i) {
buffer = this.#encode(obj[i], buffer); buffer = this.#encode(obj[i], buffer);
@ -226,22 +229,22 @@ export class Bert {
encode_array = (obj, buffer) => { encode_array = (obj, buffer) => {
if (obj.length === 0) { if (obj.length === 0) {
buffer[0] = Types.NIL; buffer[0] = Types.NIL;
return Buffer.from(buffer, 0, 1); return buffer.subarray(0, 1);
} }
buffer[0] = Types.LIST; buffer[0] = Types.LIST;
buffer.writeUInt32BE(obj.length, 1); buffer.writeUInt32BE(obj.length, 1);
buffer = Buffer.from(buffer, 0, 5); buffer = buffer.subarray(0, 5);
for (let i = 0; i < obj.length; ++i) { for (let i = 0; i < obj.length; ++i) {
buffer = this.#encode(obj[i], buffer); buffer = this.#encode(obj[i], buffer);
} }
buffer[0] = Types.NIL; buffer[0] = Types.NIL;
return Buffer.from(buffer, 0, 1); return buffer.subarray(0, 1);
}; };
encode_map = (obj, buffer) => { encode_map = (obj, buffer) => {
const keys = Object.keys(obj); const keys = Object.keys(obj);
buffer[0] = Types.MAP; buffer[0] = Types.MAP;
buffer.writeUInt32BE(keys.length, 1); buffer.writeUInt32BE(keys.length, 1);
buffer = Buffer.from(buffer, 0, 5); buffer = buffer.subarray(0, 5);
for (let i = 0; i < keys.length; ++i) { for (let i = 0; i < keys.length; ++i) {
const key = this.mapKeyAsAtom ? this.toAtom(keys[i]) : keys[i]; const key = this.mapKeyAsAtom ? this.toAtom(keys[i]) : keys[i];
buffer = this.#encode(key, buffer); buffer = this.#encode(key, buffer);
@ -274,7 +277,7 @@ export class Bert {
} }
return { return {
value, value,
rest: Buffer.from(buffer, size), rest: buffer.subarray(size),
}; };
}; };
decode_binary = (buffer) => { decode_binary = (buffer) => {
@ -286,21 +289,21 @@ export class Bert {
value: this.convention === Lang.ELIXIR && this.allBinariesAsString value: this.convention === Lang.ELIXIR && this.allBinariesAsString
? bin.toString() ? bin.toString()
: bin, : bin,
rest: Buffer.from(buffer, size), rest: buffer.subarray(size),
}; };
}; };
decode_integer = (buffer, count, unsigned = false) => { decode_integer = (buffer, count, unsigned = false) => {
return { return {
value: this.bytesToInt(buffer, count, unsigned), value: this.bytesToInt(buffer, count, unsigned),
rest: Buffer.from(buffer, count), rest: buffer.subarray(count),
}; };
}; };
decode_big = (buffer, count) => { decode_big = (buffer, count) => {
const size = this.bytesToInt(buffer, count, false); const size = this.bytesToInt(buffer, count, false);
buffer = Buffer.from(buffer, count); buffer = buffer.subarray(count);
let num = 0; let num = 0;
const isNegative = buffer[0] === 1; const isNegative = buffer[0] === 1;
buffer = Buffer.from(buffer, 1); buffer = buffer.subarray(1);
for (let i = size - 1; i >= 0; --i) { for (let i = size - 1; i >= 0; --i) {
const n = buffer[i]; const n = buffer[i];
if (num === 0) { if (num === 0) {
@ -315,28 +318,28 @@ export class Bert {
} }
return { return {
value: num, value: num,
rest: Buffer.from(buffer, size), rest: buffer.subarray(size),
}; };
}; };
decode_float = (buffer) => { decode_float = (buffer) => {
const size = 31; const size = 31;
return { return {
value: parseFloat(buffer.toString("utf8", 0, size)), value: parseFloat(buffer.toString("utf8", 0, size)),
rest: Buffer.from(buffer, size), rest: buffer.subarray(size),
}; };
}; };
decode_new_float = (buffer) => { decode_new_float = (buffer) => {
return { return {
value: buffer.readDoubleBE(0), value: buffer.readDoubleBE(0),
rest: Buffer.from(buffer, 8), rest: buffer.subarray(8),
}; };
}; };
decode_string = (buffer) => { decode_string = (buffer) => {
const size = this.bytesToInt(buffer, 2, true); const size = this.bytesToInt(buffer, 2, true);
buffer = Buffer.from(buffer, 2); buffer = buffer.subarray(2);
return { return {
value: buffer.toString("utf8", 0, size), value: buffer.toString("utf8", 0, size),
rest: Buffer.from(buffer, size), rest: buffer.subarray(size),
}; };
}; };
decode_list = (buffer) => { decode_list = (buffer) => {
@ -352,7 +355,7 @@ export class Bert {
if (lastChar !== Types.NIL) { if (lastChar !== Types.NIL) {
throw new Error("List does not end with NIL"); throw new Error("List does not end with NIL");
} }
buffer = Buffer.from(buffer, 1); buffer = buffer.subarray(1);
return { return {
value: arr, value: arr,
rest: buffer, rest: buffer,
@ -361,7 +364,7 @@ export class Bert {
decode_map = (buffer) => { decode_map = (buffer) => {
const map = {}; const map = {};
const size = this.bytesToInt(buffer, 4, true); const size = this.bytesToInt(buffer, 4, true);
buffer = Buffer.from(buffer, 4); buffer = buffer.subarray(4);
for (let i = 0; i < size; ++i) { for (let i = 0; i < size; ++i) {
let el = this.#decode(buffer); let el = this.#decode(buffer);
const key = el.value; const key = el.value;
@ -378,7 +381,7 @@ export class Bert {
decode_tuple = (buffer, count) => { decode_tuple = (buffer, count) => {
const arr = []; const arr = [];
const size = this.bytesToInt(buffer, count, true); const size = this.bytesToInt(buffer, count, true);
buffer = Buffer.from(buffer, count); buffer = buffer.subarray(count);
for (let i = 0; i < size; ++i) { for (let i = 0; i < size; ++i) {
const el = this.#decode(buffer); const el = this.#decode(buffer);
arr.push(el.value); arr.push(el.value);

View File

@ -47,32 +47,32 @@ export class Bert {
toAtom = toAtom; toAtom = toAtom;
toTuple = toTuple; toTuple = toTuple;
#encode = (obj: any, buffer: Buffer) => #encode = (obj: any, buffer: Buffer): Buffer =>
(this as any)[`encode_${typeof obj}`](obj, buffer); (this as any)[`encode_${typeof obj}`](obj, buffer);
encode = (obj: any, copy = true) => { encode = (obj: any, copy = true) => {
const tailBuffer = this.#encode(obj, Buffer.from(this.outputBuffer, 1)); const tailBuffer = this.#encode(obj, this.outputBuffer.subarray(1));
process.stderr.write(`tailbuffer length: ${tailBuffer.length}\n`);
if (tailBuffer.length === 0) { if (tailBuffer.length === 0) {
throw new Error("Bert encode a too big term, encoding buffer overflow"); throw new Error("Bert encode a too big term, encoding buffer overflow");
} }
else if (copy) { else if (copy) {
const ret = Buffer.alloc(tailBuffer.length); const ret = Buffer.alloc(tailBuffer.length + 1);
this.outputBuffer.copy(ret, 0, 0, ret.length); this.outputBuffer.copy(ret, 0, 0, ret.length + 1);
return ret; return ret;
} }
else { else {
return Buffer.from( return this.outputBuffer.subarray(
this.outputBuffer,
0, 0,
tailBuffer.length, tailBuffer.length + 1,
); );
} }
}; };
#decode = (buffer: Buffer): any => { #decode = (buffer: Buffer): any => {
const t = buffer[0]; const t = buffer[0];
buffer = Buffer.from(buffer, 1); buffer = buffer.subarray(1);
switch (t) { switch (t) {
case Types.SMALL_ATOM: case Types.SMALL_ATOM:
@ -126,20 +126,22 @@ export class Bert {
encode_string = (obj: string, buffer: Buffer) => { encode_string = (obj: string, buffer: Buffer) => {
if (this.convention === Lang.ELIXIR) { if (this.convention === Lang.ELIXIR) {
process.stderr.write(`encode string as elixir\n`);
return this.encode_binary(Buffer.from(obj), buffer); return this.encode_binary(Buffer.from(obj), buffer);
} }
else { else {
buffer[0] = Types.STRING; buffer[0] = Types.STRING;
buffer.writeUInt16BE(Buffer.byteLength(obj, "utf-8"), 1); buffer.writeUInt16BE(Buffer.byteLength(obj, "utf-8"), 1);
const len = buffer.write(obj, 3); const len = buffer.write(obj, 3);
return Buffer.from(buffer, 0, 3 + len); return buffer.subarray(0, 3 + len);
} }
}; };
encode_boolean = (obj: boolean, buffer: Buffer) => { encode_boolean = (obj: boolean, buffer: Buffer) => {
if (obj) { if (obj) {
return this.#encode(this.toAtom("true"), buffer); return this.#encode(this.toAtom("true"), buffer);
} else { }
else {
return this.#encode(this.toAtom("false"), buffer); return this.#encode(this.toAtom("false"), buffer);
} }
}; };
@ -156,14 +158,14 @@ export class Bert {
if (isInteger && obj >= 0 && obj < 256) { if (isInteger && obj >= 0 && obj < 256) {
buffer[0] = Types.SMALL_INTEGER; buffer[0] = Types.SMALL_INTEGER;
buffer.writeUInt8(obj, 1); buffer.writeUInt8(obj, 1);
return Buffer.from(buffer, 0, 2); return buffer.subarray(0, 2);
} }
// 4 byte int... // 4 byte int...
if (isInteger && obj >= -134217728 && obj <= 134217727) { if (isInteger && obj >= -134217728 && obj <= 134217727) {
buffer[0] = Types.INTEGER; buffer[0] = Types.INTEGER;
buffer.writeInt32BE(obj, 1); buffer.writeInt32BE(obj, 1);
return Buffer.from(buffer, 0, 5); return buffer.subarray(0, 5);
} }
// Bignum... // Bignum...
@ -171,7 +173,8 @@ export class Bert {
if (obj < 0) { if (obj < 0) {
obj *= -1; obj *= -1;
numBuffer[0] = 1; numBuffer[0] = 1;
} else { }
else {
numBuffer[0] = 0; numBuffer[0] = 0;
} }
@ -186,12 +189,12 @@ export class Bert {
buffer[0] = Types.SMALL_BIG; buffer[0] = Types.SMALL_BIG;
buffer.writeUInt8(offset - 1, 1); buffer.writeUInt8(offset - 1, 1);
numBuffer.copy(buffer, 2, 0, offset); numBuffer.copy(buffer, 2, 0, offset);
return Buffer.from(buffer, 0, 2 + offset); return buffer.subarray(0, 2 + offset);
} else { } else {
buffer[0] = Types.LARGE_BIG; buffer[0] = Types.LARGE_BIG;
buffer.writeUInt32BE(offset - 1, 1); buffer.writeUInt32BE(offset - 1, 1);
numBuffer.copy(buffer, 5, 0, offset); numBuffer.copy(buffer, 5, 0, offset);
return Buffer.from(buffer, 0, 5 + offset); return buffer.subarray(0, 5 + offset);
} }
}; };
@ -199,7 +202,7 @@ export class Bert {
// float... // float...
buffer[0] = Types.NEW_FLOAT; buffer[0] = Types.NEW_FLOAT;
buffer.writeDoubleBE(obj, 1); buffer.writeDoubleBE(obj, 1);
return Buffer.from(buffer, 0, 9); return buffer.subarray(0, 9);
}; };
encode_object = (obj: any, buffer: Buffer) => { encode_object = (obj: any, buffer: Buffer) => {
@ -230,14 +233,15 @@ export class Bert {
buffer[0] = Types.ATOM; buffer[0] = Types.ATOM;
buffer.writeUInt16BE(obj.value.length, 1); buffer.writeUInt16BE(obj.value.length, 1);
const len = buffer.write(obj.value, 3); const len = buffer.write(obj.value, 3);
return Buffer.from(buffer, 0, 3 + len); return buffer.subarray(0, 3 + len);
}; };
encode_binary = (obj: Buffer, buffer: Buffer) => { encode_binary = (obj: Buffer, buffer: Buffer) => {
process.stderr.write(`encode binary\n`);
buffer[0] = Types.BINARY; buffer[0] = Types.BINARY;
buffer.writeUInt32BE(obj.length, 1); buffer.writeUInt32BE(obj.length, 1);
const len = obj.copy(buffer, 5); const len = obj.copy(buffer, 5);
return Buffer.from(buffer, 0, 5 + len); return buffer.subarray(0, 5 + len);
}; };
encode_undefined = (_obj: Buffer, buffer: Buffer) => { encode_undefined = (_obj: Buffer, buffer: Buffer) => {
@ -248,11 +252,11 @@ export class Bert {
if (obj.length < 256) { if (obj.length < 256) {
buffer[0] = Types.SMALL_TUPLE; buffer[0] = Types.SMALL_TUPLE;
buffer.writeUInt8(obj.length, 1); buffer.writeUInt8(obj.length, 1);
buffer = Buffer.from(buffer, 0, 2); buffer = buffer.subarray(0, 2);
} else { } else {
buffer[0] = Types.LARGE_TUPLE; buffer[0] = Types.LARGE_TUPLE;
buffer.writeUInt32BE(obj.length, 1); buffer.writeUInt32BE(obj.length, 1);
buffer = Buffer.from(buffer, 0, 5); buffer = buffer.subarray(0, 5);
} }
for (let i = 0; i < obj.length; ++i) { for (let i = 0; i < obj.length; ++i) {
@ -265,25 +269,25 @@ export class Bert {
encode_array = (obj: any[], buffer: Buffer) => { encode_array = (obj: any[], buffer: Buffer) => {
if (obj.length === 0) { if (obj.length === 0) {
buffer[0] = Types.NIL; buffer[0] = Types.NIL;
return Buffer.from(buffer, 0, 1); return buffer.subarray(0, 1);
} }
buffer[0] = Types.LIST; buffer[0] = Types.LIST;
buffer.writeUInt32BE(obj.length, 1); buffer.writeUInt32BE(obj.length, 1);
buffer = Buffer.from(buffer, 0, 5); buffer = buffer.subarray(0, 5);
for (let i = 0; i < obj.length; ++i) { for (let i = 0; i < obj.length; ++i) {
buffer = this.#encode(obj[i], buffer); buffer = this.#encode(obj[i], buffer);
} }
buffer[0] = Types.NIL; buffer[0] = Types.NIL;
return Buffer.from(buffer, 0, 1); return buffer.subarray(0, 1);
}; };
encode_map = (obj: Record<string, any>, buffer: Buffer) => { encode_map = (obj: Record<string, any>, buffer: Buffer) => {
const keys = Object.keys(obj); const keys = Object.keys(obj);
buffer[0] = Types.MAP; buffer[0] = Types.MAP;
buffer.writeUInt32BE(keys.length, 1); buffer.writeUInt32BE(keys.length, 1);
buffer = Buffer.from(buffer, 0, 5); buffer = buffer.subarray(0, 5);
for (let i = 0; i < keys.length; ++i) { for (let i = 0; i < keys.length; ++i) {
const key = this.mapKeyAsAtom ? this.toAtom(keys[i]) : keys[i]; const key = this.mapKeyAsAtom ? this.toAtom(keys[i]) : keys[i];
@ -318,7 +322,7 @@ export class Bert {
} }
return { return {
value, value,
rest: Buffer.from(buffer, size), rest: buffer.subarray(size),
}; };
}; };
@ -332,25 +336,25 @@ export class Bert {
this.convention === Lang.ELIXIR && this.allBinariesAsString this.convention === Lang.ELIXIR && this.allBinariesAsString
? bin.toString() ? bin.toString()
: bin, : bin,
rest: Buffer.from(buffer, size), rest: buffer.subarray(size),
}; };
}; };
decode_integer = (buffer: Buffer, count: 1 | 2 | 4, unsigned = false) => { decode_integer = (buffer: Buffer, count: 1 | 2 | 4, unsigned = false) => {
return { return {
value: this.bytesToInt(buffer, count, unsigned), value: this.bytesToInt(buffer, count, unsigned),
rest: Buffer.from(buffer, count), rest: buffer.subarray(count),
}; };
}; };
decode_big = (buffer: Buffer, count: 1 | 2 | 4) => { decode_big = (buffer: Buffer, count: 1 | 2 | 4) => {
const size = this.bytesToInt(buffer, count, false); const size = this.bytesToInt(buffer, count, false);
buffer = Buffer.from(buffer, count); buffer = buffer.subarray(count);
let num = 0; let num = 0;
const isNegative = buffer[0] === 1; const isNegative = buffer[0] === 1;
buffer = Buffer.from(buffer, 1); buffer = buffer.subarray(1);
for (let i = size - 1; i >= 0; --i) { for (let i = size - 1; i >= 0; --i) {
const n = buffer[i]; const n = buffer[i];
@ -366,7 +370,7 @@ export class Bert {
return { return {
value: num, value: num,
rest: Buffer.from(buffer, size), rest: buffer.subarray(size),
}; };
}; };
@ -375,25 +379,25 @@ export class Bert {
return { return {
value: parseFloat(buffer.toString("utf8", 0, size)), value: parseFloat(buffer.toString("utf8", 0, size)),
rest: Buffer.from(buffer, size), rest: buffer.subarray(size),
}; };
}; };
decode_new_float = (buffer: Buffer) => { decode_new_float = (buffer: Buffer) => {
return { return {
value: buffer.readDoubleBE(0), value: buffer.readDoubleBE(0),
rest: Buffer.from(buffer, 8), rest: buffer.subarray(8),
}; };
}; };
decode_string = (buffer: Buffer) => { decode_string = (buffer: Buffer) => {
const size = this.bytesToInt(buffer, 2, true); const size = this.bytesToInt(buffer, 2, true);
buffer = Buffer.from(buffer, 2); buffer = buffer.subarray(2);
return { return {
value: buffer.toString("utf8", 0, size), value: buffer.toString("utf8", 0, size),
rest: Buffer.from(buffer, size), rest: buffer.subarray(size),
}; };
}; };
@ -414,7 +418,7 @@ export class Bert {
throw new Error("List does not end with NIL"); throw new Error("List does not end with NIL");
} }
buffer = Buffer.from(buffer, 1); buffer = buffer.subarray(1);
return { return {
value: arr, value: arr,
@ -426,7 +430,7 @@ export class Bert {
const map: Record<string, any> = {}; const map: Record<string, any> = {};
const size = this.bytesToInt(buffer, 4, true); const size = this.bytesToInt(buffer, 4, true);
buffer = Buffer.from(buffer, 4); buffer = buffer.subarray(4);
for (let i = 0; i < size; ++i) { for (let i = 0; i < size; ++i) {
let el = this.#decode(buffer); let el = this.#decode(buffer);
@ -445,7 +449,7 @@ export class Bert {
decode_tuple = (buffer: Buffer, count: 1 | 2 | 4) => { decode_tuple = (buffer: Buffer, count: 1 | 2 | 4) => {
const arr = []; const arr = [];
const size = this.bytesToInt(buffer, count, true); const size = this.bytesToInt(buffer, count, true);
buffer = Buffer.from(buffer, count); buffer = buffer.subarray(count);
for (let i = 0; i < size; ++i) { for (let i = 0; i < size; ++i) {
const el = this.#decode(buffer); const el = this.#decode(buffer);
arr.push(el.value); arr.push(el.value);