From 62b4dc92ccd67675bedabeb23bc93de65436d1dc Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Fri, 19 Jul 2019 15:01:33 -0400 Subject: [PATCH 1/9] [Implement] Naive Buffer.from --- assembly/buffer/index.ts | 54 ++++++++++++++++++++++++++++++++++++++++ assembly/node.d.ts | 2 ++ tests/buffer.spec.ts | 50 +++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 66866bf..6dc73eb 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -1,6 +1,7 @@ import { BLOCK_MAXSIZE } from "rt/common"; import { E_INVALIDLENGTH, E_INDEXOUTOFRANGE } from "util/error"; import { Uint8Array } from "typedarray"; +import { ArrayBufferView } from "arraybuffer"; export class Buffer extends Uint8Array { constructor(size: i32) { @@ -22,4 +23,57 @@ export class Buffer extends Uint8Array { result.dataLength = size; return result; } + + // @ts-ignore: Buffer returns on all valid branches + public static from(value: T): Buffer { + // @ts-ignore: AssemblyScript treats this statement correctly + if (value instanceof String[]) { + let length = value.length; + log(length); + let buffer = __alloc(length, idof()); + let sourceStart = value.dataStart; + for (let i = 0; i < length; i++) { + let str = changetype(load(sourceStart + (usize(i) << alignof()))); + let value = parseFloat(str); // parseFloat is still naive + store(buffer + usize(i), isFinite(value) ? u8(value) : u8(0)); + } + let result = changetype(__alloc(offsetof(), idof())); + result.data = changetype(buffer); + result.dataStart = changetype(value); + result.dataLength = length; + return result; + } else if (value instanceof ArrayBuffer) { + let result = changetype(__alloc(offsetof(), idof())); + result.data = value; + result.dataStart = changetype(value); + result.dataLength = value.byteLength; + return result; + } else if (value instanceof String) { + // @ts-ignore value not instance of `string` does changetype(value) work here? + let buffer = String.UTF8.encode(value); + let result = changetype(__alloc(offsetof(), idof())); + result.data = buffer; + result.dataStart = changetype(buffer); + result.dataLength = buffer.byteLength; + return result; + } else if (value instanceof Buffer) { + let result = changetype(__alloc(offsetof(), idof())); + result.data = value.buffer; + result.dataStart = value.dataStart; + result.dataLength = value.dataLength; + return result; + } else if (value instanceof ArrayBufferView) { + let length = value.length; + let buffer = __alloc(length, idof()); + let result = changetype(__alloc(offsetof(), idof())); + // @ts-ignore: value[i] is implied to work + for (let i = 0; i < length; i++) store(buffer + usize(i), u8(unchecked(value[i]))); + result.data = changetype(buffer); + result.dataStart = buffer; + result.dataLength = u32(length); + return result; + + } + ERROR("Cannot call Buffer.from() where T is not a string, Buffer, ArrayBuffer, Array, or Array-like Object."); + } } diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 80075a8..97bfaf0 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -3,4 +3,6 @@ declare class Buffer extends Uint8Array { static alloc(size: i32): Buffer; /** This method allocates a new Buffer of indicated size. This is unsafe because the data is not zeroed. */ static allocUnsafe(size: i32): Buffer; + /** This method creates a Buffer from the given reference. This method is naive and defaults to utf8 encoding for strings. */ + static from(value: T): Buffer; } diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 1596845..817b9d5 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -1,3 +1,10 @@ +function bufferFrom(values: valueof[]): T { + let buffer = instantiate(values.length); + // @ts-ignore + for (let i = 0; i < values.length; i++) buffer[i] = values[i]; + return buffer; +} + /** * This is the buffer test suite. For each prototype function, put a single test * function call here. @@ -42,4 +49,47 @@ describe("buffer", () => { // TODO: expectFn(() => { Buffer.allocUnsafe(-1); }).toThrow(); // TODO: expectFn(() => { Buffer.allocUnsafe(BLOCK_MAXSIZE + 1); }).toThrow(); }); + + + /** + * This specification is a tradeoff, because Buffer.from() takes _many_ parameters. + * Instead, the only common parameter is the first one, which results in Buffer.from + * acting in a very naive fashion. Perhaps an optional encoding parameter might be + * possible for strings, at least. However, this makes things more complicated. + * There are no good solutions. Only tradeoffs. Function overloading is the only + * way to fix this problem. + */ + test("#from", () => { + // TODO: Switch to expect() when 2.2.1 releases + + // Buffer.from uses the array buffer reference + let buff = new ArrayBuffer(100); + for (let i = 0; i < 100; i++) store(changetype(buff), u8(i)); + let abBuffer = Buffer.from(buff); + expect(abBuffer.buffer).toStrictEqual(buff); + expect(abBuffer.buffer).toBe(buff); + + // strings are utf8 encoded by default + let strBuffer = Buffer.from("Hello world!"); + let strBufferExpected = bufferFrom([0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21]); + expect(strBuffer.buffer).toStrictEqual(strBufferExpected.buffer); + + // buffer returns a new reference view to the same ArrayBuffer + let buff2 = Buffer.from(abBuffer); + expect(buff2).not.toBe(abBuffer); + expect(buff2.buffer).toBe(abBuffer.buffer); + expect(buff2.dataStart).toBe(abBuffer.dataStart); + expect(buff2.dataLength).toBe(abBuffer.dataLength); + + // else if it extends ArrayBufferView simply converts all the values + let floats = bufferFrom([1.1, 2.2, 3.3]); + let floatBuff = Buffer.from(floats); + let floatBuffExpected = bufferFrom([1, 2, 3]); + expect(floatBuff.buffer).toStrictEqual(floatBuffExpected.buffer); + + let strArrayExpected = bufferFrom([1, 2, 3, 4, 5, 6, 7, 0, 0, 0]); + let stringValues: string[] = ["1.1", "2.2", "3.3", "4.4", "5.5", "6.6", "7.7", "Infinity", "NaN", "-Infinity"]; + let strArrayActual = Buffer.from>(stringValues); + expect(strArrayActual.buffer).toStrictEqual(strArrayExpected.buffer); + }); }); From 3b677540651ede21eacebab5e33077ce0d8e7e3f Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Sat, 20 Jul 2019 14:30:50 -0400 Subject: [PATCH 2/9] [Cleanup] remove log function --- assembly/buffer/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 6dc73eb..ef90ac0 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -29,7 +29,6 @@ export class Buffer extends Uint8Array { // @ts-ignore: AssemblyScript treats this statement correctly if (value instanceof String[]) { let length = value.length; - log(length); let buffer = __alloc(length, idof()); let sourceStart = value.dataStart; for (let i = 0; i < length; i++) { @@ -72,7 +71,6 @@ export class Buffer extends Uint8Array { result.dataStart = buffer; result.dataLength = u32(length); return result; - } ERROR("Cannot call Buffer.from() where T is not a string, Buffer, ArrayBuffer, Array, or Array-like Object."); } From c2a64325e5d7564c9c69765505d25e69fa483b26 Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Sat, 20 Jul 2019 14:33:01 -0400 Subject: [PATCH 3/9] [Cleanup] add T extends ArrayBufferView to squelch intellisense --- assembly/buffer/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index ef90ac0..7543c50 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -25,7 +25,7 @@ export class Buffer extends Uint8Array { } // @ts-ignore: Buffer returns on all valid branches - public static from(value: T): Buffer { + public static from(value: T): Buffer { // @ts-ignore: AssemblyScript treats this statement correctly if (value instanceof String[]) { let length = value.length; From cc536a0fbba888414fca3bb589edac4267d8e907 Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Tue, 6 Aug 2019 12:29:18 -0400 Subject: [PATCH 4/9] [merge] from master --- assembly/buffer/index.ts | 1 + tests/buffer.spec.ts | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index cc68e5a..49fdc83 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -74,6 +74,7 @@ export class Buffer extends Uint8Array { } ERROR("Cannot call Buffer.from() where T is not a string, Buffer, ArrayBuffer, Array, or Array-like Object."); } + public static isBuffer(value: T): bool { return value instanceof Buffer; } diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 87c46f7..7844e2e 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -1,10 +1,3 @@ -function bufferFrom(values: valueof[]): T { - let buffer = instantiate(values.length); - // @ts-ignore - for (let i = 0; i < values.length; i++) buffer[i] = values[i]; - return buffer; -} - /** * This is the buffer test suite. For each prototype function, put a single test * function call here. From c6997e1f719065c03787d97b524d5a41658205be Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Tue, 6 Aug 2019 12:39:42 -0400 Subject: [PATCH 5/9] [Fix] array of strings implementation --- assembly/buffer/index.ts | 9 +++++---- tests/buffer.spec.ts | 22 ++++++++++------------ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 49fdc83..c1d4341 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -28,17 +28,18 @@ export class Buffer extends Uint8Array { public static from(value: T): Buffer { // @ts-ignore: AssemblyScript treats this statement correctly if (value instanceof String[]) { - let length = value.length; + let length = value.length; let buffer = __alloc(length, idof()); let sourceStart = value.dataStart; - for (let i = 0; i < length; i++) { + for (let i: usize = 0; i < length; i++) { let str = changetype(load(sourceStart + (i << alignof()))); let value = parseFloat(str); // parseFloat is still naive - store(buffer + usize(i), isFinite(value) ? u8(value) : u8(0)); + trace("float values", 2, value, u8(value)); + store(buffer + i, isFinite(value) ? u8(value) : u8(0)); } let result = changetype(__alloc(offsetof(), idof())); result.data = changetype(buffer); - result.dataStart = changetype(value); + result.dataStart = changetype(buffer); result.dataLength = length; return result; } else if (value instanceof ArrayBuffer) { diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 7844e2e..e10597f 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -60,9 +60,7 @@ describe("buffer", () => { * There are no good solutions. Only tradeoffs. Function overloading is the only * way to fix this problem. */ - test("#from", () => { - // TODO: Switch to expect() when 2.2.1 releases - + test(".from", () => { // Buffer.from uses the array buffer reference let buff = new ArrayBuffer(100); for (let i = 0; i < 100; i++) store(changetype(buff), u8(i)); @@ -72,26 +70,26 @@ describe("buffer", () => { // strings are utf8 encoded by default let strBuffer = Buffer.from("Hello world!"); - let strBufferExpected = bufferFrom([0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21]); - expect(strBuffer.buffer).toStrictEqual(strBufferExpected.buffer); + let strBufferExpected = create([0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21]); + expect(strBuffer).toStrictEqual(strBufferExpected); // buffer returns a new reference view to the same ArrayBuffer let buff2 = Buffer.from(abBuffer); expect(buff2).not.toBe(abBuffer); + expect(buff2).toStrictEqual(abBuffer); expect(buff2.buffer).toBe(abBuffer.buffer); - expect(buff2.dataStart).toBe(abBuffer.dataStart); - expect(buff2.dataLength).toBe(abBuffer.dataLength); + expect(buff2.byteOffset).toBe(abBuffer.byteOffset); // else if it extends ArrayBufferView simply converts all the values - let floats = bufferFrom([1.1, 2.2, 3.3]); + let floats = create([1.1, 2.2, 3.3]); let floatBuff = Buffer.from(floats); - let floatBuffExpected = bufferFrom([1, 2, 3]); - expect(floatBuff.buffer).toStrictEqual(floatBuffExpected.buffer); + let floatBuffExpected = create([1, 2, 3]); + expect(floatBuff).toStrictEqual(floatBuffExpected); - let strArrayExpected = bufferFrom([1, 2, 3, 4, 5, 6, 7, 0, 0, 0]); + let strArrayExpected = create([1, 2, 3, 4, 5, 6, 7, 0, 0, 0]); let stringValues: string[] = ["1.1", "2.2", "3.3", "4.4", "5.5", "6.6", "7.7", "Infinity", "NaN", "-Infinity"]; let strArrayActual = Buffer.from>(stringValues); - expect(strArrayActual.buffer).toStrictEqual(strArrayExpected.buffer); + expect(strArrayActual).toStrictEqual(strArrayExpected, "Array Of Strings"); }); test("#isBuffer", () => { From 45a61c5599ebd5a80743f51501f4e111e389c51c Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Thu, 22 Aug 2019 09:29:13 -0400 Subject: [PATCH 6/9] [Implement] rest of buffer.from functions per dcode --- assembly/buffer/index.ts | 90 +++++++++++++++++++++++++++++++++++----- assembly/node.d.ts | 8 ++++ tests/buffer.spec.ts | 70 +++++++++++++++++++++++++++++-- 3 files changed, 155 insertions(+), 13 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index e57fbc3..66ea9c8 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -2,6 +2,9 @@ import { BLOCK_MAXSIZE, BLOCK, BLOCK_OVERHEAD } from "rt/common"; import { E_INVALIDLENGTH, E_INDEXOUTOFRANGE } from "util/error"; import { Uint8Array } from "typedarray"; import { ArrayBufferView } from "arraybuffer"; +import { Array } from "array"; + + export class Buffer extends Uint8Array { constructor(size: i32) { @@ -24,18 +27,85 @@ export class Buffer extends Uint8Array { return result; } + public static fromArrayBuffer(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Buffer { + length = select(buffer.byteLength, length, length < 0); + if (i32(byteOffset < 0) | i32(byteOffset > buffer.byteLength - length)) throw new RangeError(E_INDEXOUTOFRANGE); + if (length == 0) return new Buffer(0); + let result = changetype(__alloc(offsetof(), idof())); + result.data = buffer; // retains + result.dataStart = changetype(buffer) + byteOffset; + result.dataLength = length; + return result; + } + + public static fromString(value: string, encoding: string = "utf8"): Buffer { + let result = changetype(__alloc(offsetof(), idof())); // retains + let buffer: ArrayBuffer; + if (encoding == "utf8" || encoding == "utf-8") { + buffer = String.UTF8.encode(value); + } else if (encoding == "utf16le") { + buffer = String.UTF16.encode(value); + } else if (encoding == "hex") { + buffer = Buffer.HEX.encode(value); + // TODO: add ascii encoding + } else { + throw new TypeError("Invalid string encoding."); + } + + result.data = buffer; // retains + result.dataStart = changetype(buffer); + result.dataLength = buffer.byteLength; + return result; + } + + public static fromArray(value: T, offset: i32 = 0, length: i32 = -1): Buffer { + length = select(value.length, length, length < 0); + if (i32(offset < 0) | i32(offset > value.length)) throw new RangeError(E_INDEXOUTOFRANGE); + if (length > value.length - offset) throw new RangeError(E_INVALIDLENGTH); + if (length == 0) return new Buffer(0); + let abv = __alloc(offsetof(), idof()); + let buffer = __alloc(length, idof()); + if (value instanceof Array) { + for (let i = 0; i < length; i++) { + let index = i + offset; + let byteValue = parseFloat(unchecked(value[index])); + store(buffer + i, select(0, byteValue, isNaN(byteValue))); + } + } else { + for (let i = 0; i < length; i++) { + let index = i + offset; + store(buffer + i, unchecked(value[index])); + } + } + let result = changetype(abv); // retains + result.data = changetype(buffer); // retains + result.dataStart = buffer; + result.dataLength = length; + return result; + } + + public static fromBuffer(source: Buffer): Buffer { + let length = source.dataLength; + let data = changetype(__alloc(length, idof())); // retains + memory.copy(changetype(data), source.dataStart, length); + let result = changetype(__alloc(offsetof(), idof())); // retains + result.data = data; + result.dataStart = changetype(data); + result.dataLength = length; + return result; + } + // @ts-ignore: Buffer returns on all valid branches - public static from(value: T): Buffer { + public static from(value: T): Buffer { // @ts-ignore: AssemblyScript treats this statement correctly - if (value instanceof String[]) { + if (value instanceof Array) { let length = value.length; let buffer = __alloc(length, idof()); let sourceStart = value.dataStart; for (let i: usize = 0; i < length; i++) { let str = changetype(load(sourceStart + (i << alignof()))); let value = parseFloat(str); // parseFloat is still naive - trace("float values", 2, value, u8(value)); - store(buffer + i, isFinite(value) ? u8(value) : u8(0)); + store(buffer + i, select(value, 0.0, isFinite(value))); } let result = changetype(__alloc(offsetof(), idof())); result.data = changetype(buffer); @@ -57,20 +127,20 @@ export class Buffer extends Uint8Array { result.dataLength = buffer.byteLength; return result; } else if (value instanceof Buffer) { - let result = changetype(__alloc(offsetof(), idof())); + let result = changetype(__alloc(offsetof(), idof())); // retains result.data = value.buffer; result.dataStart = value.dataStart; result.dataLength = value.dataLength; return result; } else if (value instanceof ArrayBufferView) { - let length = value.length; + let length = value.length; let buffer = __alloc(length, idof()); - let result = changetype(__alloc(offsetof(), idof())); + let result = changetype(__alloc(offsetof(), idof())); // retains // @ts-ignore: value[i] is implied to work - for (let i = 0; i < length; i++) store(buffer + usize(i), u8(unchecked(value[i]))); - result.data = changetype(buffer); + for (let i = 0; i < length; i++) store(buffer + i, unchecked(value[i])); + result.data = changetype(buffer); // retains result.dataStart = buffer; - result.dataLength = u32(length); + result.dataLength = length; return result; } ERROR("Cannot call Buffer.from() where T is not a string, Buffer, ArrayBuffer, Array, or Array-like Object."); diff --git a/assembly/node.d.ts b/assembly/node.d.ts index e73ccab..6fd6ab7 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -5,6 +5,14 @@ declare class Buffer extends Uint8Array { static allocUnsafe(size: i32): Buffer; /** This method creates a Buffer from the given reference. This method is naive and defaults to utf8 encoding for strings. */ static from(value: T): Buffer; + /** This method creates a buffer from a given string. This method defaults to utf8 encoding. */ + public static fromString(value: string, encoding?: string): Buffer; + /** This method creates a buffer that uses the given ArrayBuffer as an underlying value. */ + public static fromArrayBuffer(buffer: ArrayBuffer, byteOffset?: i32 , length?: i32): Buffer; + /** This method creates a copy of the buffer using memory.copy(). */ + public static fromBuffer(source: Buffer): Buffer; + /** This method creates a new Buffer by copying the underlying values to a new ArrayBuffer and coercing each one to an 8 bit integer value. */ + public static fromArray>(value: T, offset?: i32, length?: i32): Buffer; /** This method asserts a value is a Buffer object via `value instanceof Buffer`. */ static isBuffer(value: T): bool; /** Reads a signed integer at the designated offset. */ diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index a4875dd..6e53d2c 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -21,7 +21,7 @@ function create(values: valueof[]): T { } describe("buffer", () => { - test("#constructor", () => { + test(".constructor", () => { expect(new Buffer(0)).toBeTruthy(); expect(new Buffer(10)).toHaveLength(10); let myBuffer = new Buffer(10); @@ -31,7 +31,7 @@ describe("buffer", () => { // TODO: expectFn(() => { new Buffer(BLOCK_MAXSIZE + 1); }).toThrow(); }); - test("#alloc", () => { + test(".alloc", () => { expect(Buffer.alloc(10)).toBeTruthy(); expect(Buffer.alloc(10)).toHaveLength(10); let buff = Buffer.alloc(100); @@ -42,7 +42,7 @@ describe("buffer", () => { // TODO: expectFn(() => { Buffer.alloc(BLOCK_MAXSIZE + 1); }).toThrow(); }); - test("#allocUnsafe", () => { + test(".allocUnsafe", () => { expect(Buffer.allocUnsafe(10)).toBeTruthy(); expect(Buffer.allocUnsafe(10)).toHaveLength(10); let buff = Buffer.allocUnsafe(100); @@ -92,6 +92,70 @@ describe("buffer", () => { expect(strArrayActual).toStrictEqual(strArrayExpected, "Array Of Strings"); }); + test(".fromString", () => { + // public static fromString(value: string, encoding: string = "utf8"): Buffer { + // default encoding is utf8 + let expected = create([0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0xc3, 0xa9, 0x73, 0x74]) + expect(Buffer.from('this is a tést')) + .toStrictEqual(expected); + + expect(Buffer.fromString('7468697320697320612074c3a97374', 'hex')) + .toStrictEqual(expected); + }); + + test(".fromArrayBuffer", () => { + const arr = new Uint16Array(2); + + arr[0] = 5000; + arr[1] = 4000; + + // Shares memory with `arr`. + const buf = Buffer.fromArrayBuffer(arr.buffer); + + + expect(buf).toStrictEqual(create([0x88, 0x13, 0xa0, 0x0f])); + + // Changing the original Uint16Array changes the Buffer also. + arr[1] = 6000; + expect(buf).toStrictEqual(create([0x88, 0x13, 0x70, 0x17])); + + // test optional parameters + expect(Buffer.fromArrayBuffer(arr.buffer, 1, 2)).toStrictEqual(create([0x13, 0x70])); + + // TODO: + // expectFn(() => { + // let value = create([5000, 4000]); // 4 bytes + // Buffer.fromArrayBuffer(value.buffer, 5); + // }).toThrow("offset out of bounds should throw"); + // expectFn(() => { + // let value = create([5000, 4000]); // 4 bytes + // Buffer.fromArrayBuffer(value.buffer, 2, 3); + // }).toThrow("length out of bounds should throw"); + }); + + test(".fromBuffer", () => { + let buff1 = create([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + let buff2 = Buffer.fromBuffer(buff1); + + expect(buff1).not.toBe(buff2); + expect(buff1.buffer).not.toBe(buff2.buffer); + expect(buff1).toStrictEqual(buff2); + }); + + test(".fromArray", () => { + let buff1 = create([3, 6, 9, 12, 15, 18, 21]); + let buff2 = Buffer.fromArray(buff1, 2, 4); + let expected = create([9, 12, 15, 18]); + expect(buff2).toStrictEqual(expected); + + // test string values + buff2 = Buffer.fromArray(["9.2", "12.1", "15.3", "18.8"]); + expect(buff2).toStrictEqual(expected); + }); + + // todo: fromArray + // todo: fromBuffer + test("#isBuffer", () => { let a = ""; let b = new Uint8Array(0); From 7f69832a3a5fb55c8f555f273a35e6821318a02a Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Thu, 12 Mar 2020 23:53:37 -0400 Subject: [PATCH 7/9] remove type info --- tests/buffer.spec.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index f3b179a..b04fe91 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -36,7 +36,7 @@ describe("buffer", () => { expect(Buffer.alloc(10)).toBeTruthy(); expect(Buffer.alloc(10)).toHaveLength(10); let buff = Buffer.alloc(100); - for (let i = 0; i < buff.length; i++) expect(buff[i]).toBe(0); + for (let i = 0; i < buff.length; i++) expect(buff[i]).toBe(0); expect(buff.buffer).not.toBeNull(); expect(buff.byteLength).toBe(100); expect(() => { Buffer.alloc(-1); }).toThrow(); @@ -89,7 +89,7 @@ describe("buffer", () => { expect(floatBuff).toStrictEqual(floatBuffExpected, "float values"); let strArrayExpected = create([1, 2, 3, 4, 5, 6, 7, 0, 0, 0]); - let stringValues: string[] = ["1.1", "2.2", "3.3", "4.4", "5.5", "6.6", "7.7", "Infinity", "NaN", "-Infinity"]; + let stringValues = ["1.1", "2.2", "3.3", "4.4", "5.5", "6.6", "7.7", "Infinity", "NaN", "-Infinity"]; let strArrayActual = Buffer.from(stringValues); expect(strArrayActual).toStrictEqual(strArrayExpected, "Array Of Strings"); }); @@ -118,10 +118,10 @@ describe("buffer", () => { // Changing the original Uint16Array changes the Buffer also. arr[1] = 6000; - expect(buf).toStrictEqual(create([0x88, 0x13, 0x70, 0x17])); + expect(buf).toStrictEqual(create([0x88, 0x13, 0x70, 0x17])); // test optional parameters - expect(Buffer.fromArrayBuffer(arr.buffer, 1, 2)).toStrictEqual(create([0x13, 0x70])); + expect(Buffer.fromArrayBuffer(arr.buffer, 1, 2)).toStrictEqual(create([0x13, 0x70])); // TODO: // expectFn(() => { @@ -138,20 +138,20 @@ describe("buffer", () => { let buff1 = create([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); let buff2 = Buffer.fromBuffer(buff1); - expect(buff1).not.toBe(buff2); - expect(buff1.buffer).not.toBe(buff2.buffer); - expect(buff1).toStrictEqual(buff2); + expect(buff1).not.toBe(buff2); + expect(buff1.buffer).not.toBe(buff2.buffer); + expect(buff1).toStrictEqual(buff2); }); test(".fromArray", () => { let buff1 = create([3, 6, 9, 12, 15, 18, 21]); let buff2 = Buffer.fromArray(buff1, 2, 4); let expected = create([9, 12, 15, 18]); - expect(buff2).toStrictEqual(expected); + expect(buff2).toStrictEqual(expected); // test string values buff2 = Buffer.fromArray(["9.2", "12.1", "15.3", "18.8"]); - expect(buff2).toStrictEqual(expected); + expect(buff2).toStrictEqual(expected); }); // todo: fromArray @@ -354,7 +354,7 @@ describe("buffer", () => { expect(buff.writeInt32LE(-559038737)).toBe(4); expect(buff.writeInt32LE(283033613,4)).toBe(8); let result = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]); - expect(buff).toStrictEqual(result); + expect(buff).toStrictEqual(result); expect(() => { let newBuff = new Buffer(1); newBuff.writeInt32LE(0); From 11be548adfc246189130692b93c8d0c79d8dc7dc Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Fri, 13 Mar 2020 00:15:44 -0400 Subject: [PATCH 8/9] add ascii encoding --- assembly/buffer/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index e4df314..069de02 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -45,7 +45,8 @@ export class Buffer extends Uint8Array { buffer = String.UTF16.encode(value); } else if (encoding == "hex") { buffer = Buffer.HEX.encode(value); - // TODO: add ascii encoding + } else if (encoding == "ascii") { + buffer = Buffer.ASCII.encode(value); } else { throw new TypeError("Invalid string encoding."); } From 7f3e8c2089ac2e903ac574c415c71d0f78b950c0 Mon Sep 17 00:00:00 2001 From: Joshua Tenner Date: Fri, 13 Mar 2020 00:42:14 -0400 Subject: [PATCH 9/9] rename to allocBuffer --- assembly/buffer/index.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 069de02..62e1987 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -6,7 +6,7 @@ import { Array } from "array"; // @ts-ignore: Decorator @inline -function assembleBuffer(arrayBuffer: usize, offset: usize, length: u32): Buffer { +function allocBuffer(arrayBuffer: usize, offset: usize, length: u32): Buffer { let pointer = __alloc(offsetof(), idof()); store(pointer, __retain(arrayBuffer), offsetof("buffer")); store(pointer, arrayBuffer + offset, offsetof("dataStart")); @@ -26,7 +26,7 @@ export class Buffer extends Uint8Array { @unsafe static allocUnsafe(size: i32): Buffer { // range must be valid if (size > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); - return assembleBuffer(__alloc(size, idof()), 0, size); + return allocBuffer(__alloc(size, idof()), 0, size); } public static fromArrayBuffer(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Buffer { @@ -34,7 +34,7 @@ export class Buffer extends Uint8Array { if (i32(byteOffset < 0) | i32(byteOffset > buffer.byteLength - length)) throw new RangeError(E_INDEXOUTOFRANGE); if (length == 0) return new Buffer(0); - return assembleBuffer(changetype(buffer), byteOffset, length); + return allocBuffer(changetype(buffer), byteOffset, length); } public static fromString(value: string, encoding: string = "utf8"): Buffer { @@ -52,7 +52,7 @@ export class Buffer extends Uint8Array { } // assemble the buffer - return assembleBuffer(changetype(buffer), 0, buffer.byteLength); + return allocBuffer(changetype(buffer), 0, buffer.byteLength); } public static fromArray(value: T, offset: i32 = 0, length: i32 = -1): Buffer { @@ -82,24 +82,24 @@ export class Buffer extends Uint8Array { } } - return assembleBuffer(arrayBuffer, 0, length); + return allocBuffer(arrayBuffer, 0, length); } public static fromBuffer(source: Buffer): Buffer { let length = source.byteLength; let data = __alloc(length, idof()); // retains memory.copy(data, source.dataStart, length); - return assembleBuffer(data, 0, length); + return allocBuffer(data, 0, length); } // @ts-ignore: Buffer returns on all valid branches public static from(value: T): Buffer { if (value instanceof ArrayBuffer) { - return assembleBuffer(changetype(value), 0, value.byteLength); + return allocBuffer(changetype(value), 0, value.byteLength); } else if (value instanceof String) { // @ts-ignore value not instance of `string` does changetype(value) work here? let buffer = String.UTF8.encode(value); - return assembleBuffer(changetype(buffer), 0, buffer.byteLength); + return allocBuffer(changetype(buffer), 0, buffer.byteLength); } else if (value instanceof Buffer) { return Buffer.fromBuffer(value); } else if (value instanceof ArrayBufferView) { @@ -119,7 +119,7 @@ export class Buffer extends Uint8Array { end = end < 0 ? max(len + end, 0) : min(end, len); end = max(end, begin); - return assembleBuffer(changetype(this.buffer), this.byteOffset + begin, end - begin); + return allocBuffer(changetype(this.buffer), this.byteOffset + begin, end - begin); } readInt8(offset: i32 = 0): i8 {