Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions assembly/buffer/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { BLOCK_MAXSIZE, BLOCK, BLOCK_OVERHEAD } from "rt/common";
import { E_INVALIDLENGTH, E_INDEXOUTOFRANGE } from "util/error";
import { Uint8Array } from "typedarray";
const BUFFER_INSPECT_HEADER_START: string = "<Buffer ";

export let INSPECT_MAX_BYTES: i32 = 50;

export class Buffer extends Uint8Array {
constructor(size: i32) {
Expand Down Expand Up @@ -105,6 +108,53 @@ export class Buffer extends Uint8Array {
store<u16>(this.dataStart + offset, bswap<u16>(value));
return offset + 2;
}

inspect(): string {
let byteLength = this.byteLength;
if (INSPECT_MAX_BYTES == 0 || byteLength == 0) return "<Buffer >";

// Calculate if an elipsis will be in the string
let elipsisEnd = byteLength > INSPECT_MAX_BYTES;
let maxBytes = elipsisEnd ? INSPECT_MAX_BYTES : byteLength;

// find the start of the buffer
let dataStart = this.dataStart;

// formula for calculating end string length (3 * bytes) + 8
// Example: Buffer.from([1, 2, 3, 4, 5]).inspect() == '<Buffer 01 02 03 04 05>'
let stringLength = 3 * maxBytes + 8;
if (elipsisEnd) stringLength += 3; // add 3 characters for elipsis

// create the result
let result = __alloc(stringLength << 1, idof<String>());

// copy the 16 "<Buffer " bytes
memory.copy(
result,
changetype<usize>(BUFFER_INSPECT_HEADER_START),
changetype<BLOCK>(changetype<usize>(BUFFER_INSPECT_HEADER_START) - BLOCK_OVERHEAD).rtSize,
);

// Start writing at index 8
let writeOffset: usize = result + 16;
for (let i = 0; i < maxBytes; i++, writeOffset += 6) {
let byte = <u32>load<u8>(dataStart + <usize>i);

store<u32>(writeOffset, Buffer.HEX.charsFromByte(byte));
if (i == (maxBytes - 1)) {
Comment thread
jtenner marked this conversation as resolved.
Outdated
if (elipsisEnd) {
// make this a single 64 bit store
store<u64>(writeOffset, <u64>17451646127570990, 4); // "...>"
Comment thread
jtenner marked this conversation as resolved.
Outdated
} else {
store<u16>(writeOffset, <u16>62, 4); // ">"
}
} else {
store<u16>(writeOffset, <u16>32, 4); // " "
}
}

return changetype<string>(result);
}
}

export namespace Buffer {
Expand Down
20 changes: 20 additions & 0 deletions assembly/node.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ declare class Buffer extends Uint8Array {
readUInt8(offset?: i32): u8;
/** Writes an inputted value to the buffer, at the desired offset. */
writeInt8(value:i8, offset?:i32): i32;
/** Reads a signed integer at the designated offset. */
readInt8(offset?: i32): i8;
/** Inspect a buffer. */
inspect(): string;
}

declare module "buffer" {
/**
* The maximum number of bytes to inspect on a buffer.
*
* @example
* import { INSPECT_MAX_BYTES } from "buffer";
* // @ts-ignore: This is treated like a global
* INSPECT_MAX_BYTES = <i32>10;
*/
export var INSPECT_MAX_BYTES: i32;

// To export the buffer, we must obtain the `typeof Buffer`
const BuffType: typeof Buffer;
export { BuffType as Buffer };
/** Writes an inputted u8 value to the buffer, at the desired offset. */
writeUInt8(value:u8, offset?:i32): i32;
/** Reads a signed 16-bit integer, stored in Little Endian format at the designated offset. */
Expand Down
18 changes: 17 additions & 1 deletion tests/buffer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* });
*/
import { BLOCK_MAXSIZE } from "rt/common";
import { INSPECT_MAX_BYTES } from "buffer";

// Helper function to quickly create a Buffer from an array.
//@ts-ignore
Expand Down Expand Up @@ -140,6 +141,21 @@ describe("buffer", () => {
// }).toThrow();
});


test("#inspect", () => {
let buff = new Buffer(16);
for (let i = 0; i < 16; i++) buff[i] = i;
let result = buff.inspect();
expect<string>(result).toBe("<Buffer 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f>");
INSPECT_MAX_BYTES = 5;
result = buff.inspect();
expect<string>(result).toBe("<Buffer 00 01 02 03 04...>");

buff = new Buffer(0);
result = buff.inspect()
expect<string>(result).toBe("<Buffer >");
});

test("#readUInt16LE", () => {
let buff = create<Buffer>([0x0,0x05,0x0]);
expect<u16>(buff.readUInt16LE()).toBe(1280);
Expand Down Expand Up @@ -243,7 +259,7 @@ describe("buffer", () => {
expected = create<Buffer>([5, 6, 7]);
expect<Buffer>(actual).toStrictEqual(expected);
});

test("#Hex.encode", () => {
let actual = "000102030405060708090a0b0c0d0e0f102030405060708090a0b0c0d0e0f0";
let exampleBuffer = create<Buffer>([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0]);
Expand Down