Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
[Merge] master, use Hex encoding method
  • Loading branch information
jtenner committed Aug 1, 2019
commit cea74736ccccd3d781f5d58197136c7af1b63756
98 changes: 47 additions & 51 deletions assembly/buffer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,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 Expand Up @@ -208,55 +255,4 @@ export namespace Buffer {
return changetype<string>(result);
}
}

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 = load<u8>(dataStart + <usize>i);
let top = (byte >>> 4) & 0xF;
byte &= 0xF;

store<u16>(writeOffset, top < 10 ? <u16>top + 48 : <u16>top + 87);
store<u16>(writeOffset, byte < 10 ? <u16>byte + 48 : <u16>byte + 87, 2);

if (i == (maxBytes - 1)) {
if (elipsisEnd) {
// make this a single 64 bit store
store<u64>(writeOffset, <u64>17451646127570990, 4); // "...>"
} else {
store<u16>(writeOffset, <u16>62, 4); // ">"
}
} else {
store<u16>(writeOffset, <u16>32, 4); // " "
}
}

return changetype<string>(result);
}
}
35 changes: 35 additions & 0 deletions assembly/node.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ declare class Buffer extends Uint8Array {
static isBuffer<T>(value: T): bool;
/** Reads a signed integer at the designated offset. */
readInt8(offset?: i32): i8;
/** Reads an unsigned integer at the designated offset. */
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;
}
Expand All @@ -25,4 +31,33 @@ declare module "buffer" {
// 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. */
readInt16LE(offset?: i32): i16;
/** Reads a signed 16-bit integer, stored in Big Endian format at the designated offset. */
readInt16BE(offset?: i32): i16;
/** Reads an unsigned 16-bit integer, stored in Little Endian format at the designated offset. */
readUInt16LE(offset?: i32): u16;
/** Reads an unsigned 16-bit integer, stored in Big Endian format at the designated offset. */
readUInt16BE(offset?: i32): u16;
/** Writes an inputted 16-bit integer at the designated offset, stored in Little Endian format */
writeInt16LE(value: i16, offset?: i32): i32;
/** Writes an inputted 16-bit integer at the designated offset, stored in Big Endian format */
writeInt16BE(value: i16, offset?: i32): i32;
/** Writes an inputted unsigned 16-bit integer at the designated offset, stored in Little Endian format */
writeUInt16LE(value: u16, offset?: i32): i32;
/** Writes an inputted unsigned 16-bit integer at the designated offset, stored in Big Endian format */
writeUInt16BE(value: u16, offset?: i32): i32;
}

declare namespace Buffer {
export namespace HEX {
/** Creates an ArrayBuffer from a given string that is encoded in the hex format. */
export function encode(str: string): ArrayBuffer;
/** Creates a string from a given ArrayBuffer that is decoded into hex format. */
export function decode(buffer: ArrayBuffer): string;
/** Decodes a chunk of memory to a utf16le encoded string in hex format. */
export function decodeUnsafe(ptr: usize, byteLength: i32): string;
}
}
154 changes: 154 additions & 0 deletions tests/buffer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,42 @@ describe("buffer", () => {
// }).toThrow();
});

test("#writeUInt8", () => {
let buff = new Buffer(5);
expect<i32>(buff.writeUInt8(4)).toBe(1);
expect<i32>(buff.writeUInt8(252,4)).toBe(5);
let result = create<Buffer>([0x04, 0x0, 0x0, 0x0, 0xFC]);
expect<Buffer>(buff).toStrictEqual(result);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.writeUInt8(5,10);
// }).toThrow();
});

test("#readInt16LE", () => {
let buff = create<Buffer>([0x0,0x05,0x0]);
expect<i16>(buff.readInt16LE()).toBe(1280);
expect<i16>(buff.readInt16LE(1)).toBe(5);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.readInt16LE(0);
// }).toThrow();
});

test("#readInt16BE", () => {
let buff = create<Buffer>([0x0,0x05,0x0]);
expect<i16>(buff.readInt16BE()).toBe(5);
expect<i16>(buff.readInt16BE(1)).toBe(1280);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.readInt16BE(0);
// }).toThrow();
});


test("#inspect", () => {
let buff = new Buffer(16);
for (let i = 0; i < 16; i++) buff[i] = i;
Expand All @@ -119,4 +155,122 @@ describe("buffer", () => {
result = buff.inspect()
expect<string>(result).toBe("<Buffer >");
});

test("#readUInt16LE", () => {
let buff = create<Buffer>([0x0,0x05,0x0]);
expect<u16>(buff.readUInt16LE()).toBe(1280);
expect<u16>(buff.readUInt16LE(1)).toBe(5);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.readUInt16LE(0);
// }).toThrow();
});

test("#readUInt16BE", () => {
let buff = create<Buffer>([0x0,0x05,0x0]);
expect<i16>(buff.readUInt16BE()).toBe(5);
expect<i16>(buff.readUInt16BE(1)).toBe(1280);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.readUInt16BE(0);
// }).toThrow();
});

test("#writeInt16LE", () => {
let buff = new Buffer(4);
expect<i32>(buff.writeInt16LE(5)).toBe(2);
expect<i32>(buff.writeInt16LE(1280,2)).toBe(4);
let result = create<Buffer>([0x05, 0x0, 0x0, 0x5]);
expect<Buffer>(buff).toStrictEqual(result);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.writeInt16LE(0);
// }).toThrow();
});

test("#writeInt16BE", () => {
let buff = new Buffer(4);
expect<i32>(buff.writeInt16BE(1280)).toBe(2);
expect<i32>(buff.writeInt16BE(5,2)).toBe(4);
let result = create<Buffer>([0x05, 0x0, 0x0, 0x5]);
expect<Buffer>(buff).toStrictEqual(result);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.writeInt16BE(0);
// }).toThrow();
});

test("#writeUInt16LE", () => {
let buff = new Buffer(4);
expect<i32>(buff.writeUInt16LE(5)).toBe(2);
expect<i32>(buff.writeUInt16LE(1280,2)).toBe(4);
let result = create<Buffer>([0x05, 0x0, 0x0, 0x5]);
expect<Buffer>(buff).toStrictEqual(result);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.writeUInt16LE(0);
// }).toThrow();
});

test("#writeUInt16BE", () => {
let buff = new Buffer(4);
expect<i32>(buff.writeUInt16BE(1280)).toBe(2);
expect<i32>(buff.writeUInt16BE(5,2)).toBe(4);
let result = create<Buffer>([0x05, 0x0, 0x0, 0x5]);
expect<Buffer>(buff).toStrictEqual(result);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.writeUInt16BE(0);
// }).toThrow();
});

test("#subarray", () => {
let example = create<Buffer>([1, 2, 3, 4, 5, 6, 7, 8]);

// no parameters means copy the Buffer
let actual = example.subarray();
expect<Buffer>(actual).toStrictEqual(example);
expect<ArrayBuffer>(actual.buffer).toBe(example.buffer); // should use the same buffer

// start at offset 5
actual = example.subarray(5);
let expected = create<Buffer>([6, 7, 8]);
// trace("length", 1, expected.length);
expect<Buffer>(actual).toStrictEqual(expected);

// negative start indicies, start at (8 - 5)
actual = example.subarray(-5);
expected = create<Buffer>([4, 5, 6, 7, 8]);
expect<Buffer>(actual).toStrictEqual(expected);

// two parameters
actual = example.subarray(2, 6);
expected = create<Buffer>([3, 4, 5, 6]);
expect<Buffer>(actual).toStrictEqual(expected);

// negative end index
actual = example.subarray(4, -1);
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]);
let encoded = Buffer.HEX.encode(actual);
expect<ArrayBuffer>(encoded).toStrictEqual(exampleBuffer.buffer);
});

test("#Hex.decode", () => {
let expected = "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]);
let decoded = Buffer.HEX.decode(exampleBuffer.buffer);
expect<string>(decoded).toStrictEqual(expected);
});
});
You are viewing a condensed version of this merge commit. You can view the full changes here.