From 364fe6341619bd3475d3b2ab75d169601fed1952 Mon Sep 17 00:00:00 2001 From: RedDwarfian Date: Sun, 21 Jul 2019 13:08:39 -0400 Subject: [PATCH 01/17] [Implement] Buffer.readInt8 (#9) * [Cleanup] readInt8's offset defaults to 0 --- assembly/buffer/index.ts | 5 +++++ assembly/node.d.ts | 2 ++ tests/buffer.spec.ts | 15 +++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 66866bf..b42edf7 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -22,4 +22,9 @@ export class Buffer extends Uint8Array { result.dataLength = size; return result; } + + readInt8(offset: i32 = 0): i8 { + if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + usize(offset)); + } } diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 80075a8..52f1eba 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; + /** Reads a signed integer at the designated offset. */ + readInt8(offset?: i32): i8; } diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 1596845..d202073 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -42,4 +42,19 @@ describe("buffer", () => { // TODO: expectFn(() => { Buffer.allocUnsafe(-1); }).toThrow(); // TODO: expectFn(() => { Buffer.allocUnsafe(BLOCK_MAXSIZE + 1); }).toThrow(); }); + + test("#readInt8", () => { + let buff = new Buffer(10); + buff[0] = 5; + buff[9] = 255; + expect(buff.readInt8(0)).toBe(5); + expect(buff.readInt8()).toBe(5); + // Testing offset, and casting between u8 and i8. + expect(buff.readInt8(9)).toBe(-1); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readInt8(5); + // }).toThrow(); + }) }); From 8613b1474580c88489d2a3d1800050dc54cf5035 Mon Sep 17 00:00:00 2001 From: RedDwarfian Date: Sun, 21 Jul 2019 17:53:02 -0400 Subject: [PATCH 02/17] [Implement] Buffer.writeInt8 (#13) --- assembly/buffer/index.ts | 6 ++++++ assembly/node.d.ts | 2 ++ tests/buffer.spec.ts | 9 +++++++++ 3 files changed, 17 insertions(+) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index b42edf7..11ee8c5 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -23,6 +23,12 @@ export class Buffer extends Uint8Array { return result; } + writeInt8(value: i8, offset: i32 = 0): i32 { + if(offset > this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 1; + } + readInt8(offset: i32 = 0): i8 { if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + usize(offset)); diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 52f1eba..1e4f387 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -3,6 +3,8 @@ 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; + /** 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; } diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index d202073..eb0d0b1 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -43,6 +43,14 @@ describe("buffer", () => { // TODO: expectFn(() => { Buffer.allocUnsafe(BLOCK_MAXSIZE + 1); }).toThrow(); }); + test("#writeInt8", () => { + let buff = new Buffer(5); + expect(buff.writeInt8(9)).toBe(1); + expect(buff.writeInt8(-3,4)).toBe(5); + expect(buff[0]).toBe(9); + expect(buff[4]).toBe(-3); + }); + test("#readInt8", () => { let buff = new Buffer(10); buff[0] = 5; @@ -57,4 +65,5 @@ describe("buffer", () => { // newBuff.readInt8(5); // }).toThrow(); }) + }); From 00e1d25a2517a781eb227aa921604e862517636c Mon Sep 17 00:00:00 2001 From: RedDwarfian Date: Sun, 21 Jul 2019 17:55:47 -0400 Subject: [PATCH 03/17] [Implement] Buffer.writeUInt8 (#12) --- assembly/buffer/index.ts | 6 ++++++ assembly/node.d.ts | 2 ++ tests/buffer.spec.ts | 9 ++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 11ee8c5..19a28b2 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -23,6 +23,12 @@ export class Buffer extends Uint8Array { return result; } + writeUInt8(value: u8, offset: i32 = 0): i32 { + if(offset > this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 1; + } + writeInt8(value: i8, offset: i32 = 0): i32 { if(offset > this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 1e4f387..1fc97e4 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -3,6 +3,8 @@ 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; + /** Writes an inputted u8 value to the buffer, at the desired offset. */ + writeUInt8(value:u8, offset?:i32): i32; /** 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. */ diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index eb0d0b1..89dfbba 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -43,6 +43,14 @@ describe("buffer", () => { // TODO: expectFn(() => { Buffer.allocUnsafe(BLOCK_MAXSIZE + 1); }).toThrow(); }); + test("#writeUInt8", () => { + let buff = new Buffer(5); + expect(buff.writeUInt8(4)).toBe(1); + expect(buff.writeUInt8(252,4)).toBe(5); + expect(buff[0]).toBe(4); + expect(buff[4]).toBe(252); + }); + test("#writeInt8", () => { let buff = new Buffer(5); expect(buff.writeInt8(9)).toBe(1); @@ -65,5 +73,4 @@ describe("buffer", () => { // newBuff.readInt8(5); // }).toThrow(); }) - }); From 1b2fe13ff86ab88fef5175727419c4ee947bcf1d Mon Sep 17 00:00:00 2001 From: RedDwarfian Date: Sun, 21 Jul 2019 18:00:08 -0400 Subject: [PATCH 04/17] Buffer readuint8 (#11) * [Implement] Buffer.readUInt8 * [Cleanup] Removing readInt8 Clearing out a stray piece of code left over from a different branch. --- assembly/buffer/index.ts | 5 +++++ assembly/node.d.ts | 2 ++ tests/buffer.spec.ts | 18 +++++++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 19a28b2..c73f012 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -23,6 +23,11 @@ export class Buffer extends Uint8Array { return result; } + readUInt8(offset: i32 = 0): u8 { + if(offset > this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + usize(offset)); + } + writeUInt8(value: u8, offset: i32 = 0): i32 { if(offset > this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 1fc97e4..895ea93 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -3,6 +3,8 @@ 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; + /** Reads an unsigned integer at the designated offset. */ + readUInt8(offset?: i32): u8; /** Writes an inputted u8 value to the buffer, at the desired offset. */ writeUInt8(value:u8, offset?:i32): i32; /** Writes an inputted value to the buffer, at the desired offset. */ diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 89dfbba..9ba33fe 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -43,6 +43,22 @@ describe("buffer", () => { // TODO: expectFn(() => { Buffer.allocUnsafe(BLOCK_MAXSIZE + 1); }).toThrow(); }); + test("#readUInt8", () => { + let buff = new Buffer(10); + buff[0] = -2; + buff[9] = 47; + // Testing casting between u8 and i8. + expect(buff.readUInt8(0)).toBe(254); + expect(buff.readUInt8()).toBe(254); + // Testing offset + expect(buff.readUInt8(9)).toBe(47); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readUInt8(5); + // }).toThrow(); + }); + test("#writeUInt8", () => { let buff = new Buffer(5); expect(buff.writeUInt8(4)).toBe(1); @@ -72,5 +88,5 @@ describe("buffer", () => { // let newBuff = new Buffer(1); // newBuff.readInt8(5); // }).toThrow(); - }) + }); }); From ada4ce4bd1a6dae56d72ed4485b9e9425a4b2b7d Mon Sep 17 00:00:00 2001 From: jtenner Date: Sun, 21 Jul 2019 18:03:57 -0400 Subject: [PATCH 05/17] [Tests] Add wat output and .gitignore (#2) --- tests/node.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/node.js b/tests/node.js index 5117ef9..5cb4a58 100644 --- a/tests/node.js +++ b/tests/node.js @@ -139,6 +139,14 @@ for (const file of files) { } function runTest(file, type, binary, wat) { + const watPath = path.join(path.dirname(file), path.basename(file, ".ts")) + + "." + type + ".wat"; + + // should not block testing + fs.writeFile(watPath, wat, (err) => { + if (err) console.warn(err); + }); + const context = new TestContext({ fileName: file, reporter, From 05f31eeeaf4a11fd0d38a5e1915630990402eede Mon Sep 17 00:00:00 2001 From: jtenner Date: Mon, 22 Jul 2019 10:19:15 -0400 Subject: [PATCH 06/17] [Cleanup] Update index.ts and fix mistake (#14) --- assembly/buffer/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index c73f012..769dd8a 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -24,18 +24,18 @@ export class Buffer extends Uint8Array { } readUInt8(offset: i32 = 0): u8 { - if(offset > this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); + if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + usize(offset)); } writeUInt8(value: u8, offset: i32 = 0): i32 { - if(offset > this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); + if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 1; } writeInt8(value: i8, offset: i32 = 0): i32 { - if(offset > this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); + if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 1; } From 22e7456cd117aeb4f962449f0ebd65f654ef9e78 Mon Sep 17 00:00:00 2001 From: jtenner Date: Tue, 23 Jul 2019 13:49:44 -0400 Subject: [PATCH 07/17] [Implement] isBuffer(value: T) (#8) * [Implement] isBuffer(value: T) * [Fix] Null expectation, remove diff * [Cleanup] remove null check * [Cleanup] Update assemblyscript, fix null assertions, wait for as-pect bug fix in 2.2.0 * [Chore] update package versions * [Fix] update pass check --- assembly/buffer/index.ts | 6 +++++- assembly/node.d.ts | 2 ++ package-lock.json | 24 ++++++++-------------- package.json | 5 ++--- tests/buffer.spec.ts | 27 ++++++++++++++++++------ tests/node.js | 44 +++++++--------------------------------- 6 files changed, 46 insertions(+), 62 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 769dd8a..2d43385 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -23,6 +23,10 @@ export class Buffer extends Uint8Array { return result; } + public static isBuffer(value: T): bool { + return value instanceof Buffer; + } + readUInt8(offset: i32 = 0): u8 { if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + usize(offset)); @@ -39,7 +43,7 @@ export class Buffer extends Uint8Array { store(this.dataStart + offset, value); return offset + 1; } - + readInt8(offset: i32 = 0): i8 { if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + usize(offset)); diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 895ea93..d6da2cb 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -3,6 +3,8 @@ 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 asserts a value is a Buffer object via `value instanceof Buffer`. */ + static isBuffer(value: T): bool; /** Reads an unsigned integer at the designated offset. */ readUInt8(offset?: i32): u8; /** Writes an inputted u8 value to the buffer, at the desired offset. */ diff --git a/package-lock.json b/package-lock.json index 039989d..1d4efe9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,18 +5,18 @@ "requires": true, "dependencies": { "@as-pect/assembly": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@as-pect/assembly/-/assembly-2.2.0.tgz", - "integrity": "sha512-Md50OTJRH6uTCqNJpcJu8/W9qNGZixzIHLktTeK5Ot5UEiWqd/JoQlTAM5V5+Bp1cI5fCqmUld6Dpq+ixDraPA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@as-pect/assembly/-/assembly-2.3.1.tgz", + "integrity": "sha512-KYBhyTEnaVcJjN/1EpzLhpbUHKT3pJjCPxm+Mdc7obnZ9EdVz6vN/lw+BQjeL4cUi1YLsnvgl8ftXcup5jVbQA==", "dev": true }, "@as-pect/core": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@as-pect/core/-/core-2.2.0.tgz", - "integrity": "sha512-a1I142/J1JOa4mLeRI0tKT9KrGlHgLNHn7ZkLlkp9v/n9pE4Zuh9rGYzGuUZg285ze+0yGQfYVmRqBLJkS+IlQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@as-pect/core/-/core-2.3.1.tgz", + "integrity": "sha512-iwd4MkGuO1wZqo9/sPlT567XYK0PkMLzBvwfkXOM2zq1wwuc5GZQrKoofgYorA40KI0edJW39djtOmPwIhx2vA==", "dev": true, "requires": { - "@as-pect/assembly": "^2.2.0", + "@as-pect/assembly": "^2.3.1", "chalk": "^2.4.2", "csv-stringify": "^5.3.0", "long": "^4.0.0" @@ -38,8 +38,8 @@ } }, "assemblyscript": { - "version": "github:assemblyscript/assemblyscript#7c775d1bccbe08fec5d820b9d53ae44ff6bd1e49", - "from": "github:assemblyscript/assemblyscript#7c775d1bccbe08fec5d820b9d53ae44ff6bd1e49", + "version": "github:assemblyscript/assemblyscript#4c938f7689c39e3a1ad813356781e2689fd4ec70", + "from": "github:assemblyscript/assemblyscript", "dev": true, "requires": { "@protobufjs/utf8": "^1.1.0", @@ -129,12 +129,6 @@ "lodash.get": "~4.4.2" } }, - "diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", - "dev": true - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", diff --git a/package.json b/package.json index 831c9c0..ff4bc6b 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,8 @@ "url": "https://github.com/AssemblyScript/node/issues" }, "devDependencies": { - "@as-pect/core": "^2.2.0", - "assemblyscript": "github:assemblyscript/assemblyscript#7c775d1bccbe08fec5d820b9d53ae44ff6bd1e49", - "diff": "^4.0.1", + "@as-pect/core": "^2.3.1", + "assemblyscript": "github:assemblyscript/assemblyscript", "glob": "^7.1.4", "wasi": "github:devsnek/node-wasi" }, diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 9ba33fe..8645074 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -27,7 +27,7 @@ describe("buffer", () => { expect(Buffer.alloc(10)).toHaveLength(10); let buff = Buffer.alloc(100); for (let i = 0; i < buff.length; i++) expect(buff[i]).toBe(0); - expect(buff.buffer).not.toBeNull(); + expect(buff.buffer).not.toBeNull(); expect(buff.byteLength).toBe(100); // TODO: expectFn(() => { Buffer.alloc(-1); }).toThrow(); // TODO: expectFn(() => { Buffer.alloc(BLOCK_MAXSIZE + 1); }).toThrow(); @@ -37,12 +37,27 @@ describe("buffer", () => { expect(Buffer.allocUnsafe(10)).toBeTruthy(); expect(Buffer.allocUnsafe(10)).toHaveLength(10); let buff = Buffer.allocUnsafe(100); - expect(buff.buffer).not.toBeNull(); + expect(buff.buffer).not.toBeNull(); expect(buff.byteLength).toBe(100); // TODO: expectFn(() => { Buffer.allocUnsafe(-1); }).toThrow(); // TODO: expectFn(() => { Buffer.allocUnsafe(BLOCK_MAXSIZE + 1); }).toThrow(); }); + test("#isBuffer", () => { + let a = ""; + let b = new Uint8Array(0); + let c = 0; + let d = 1.1; + let e = new Buffer(0); + expect(Buffer.isBuffer(a)).toBeFalsy(); + expect(Buffer.isBuffer(b)).toBeFalsy(); + expect(Buffer.isBuffer(c)).toBeFalsy(); + expect(Buffer.isBuffer(d)).toBeFalsy(); + expect(Buffer.isBuffer(e)).toBeTruthy(); + // null checks are done by the compiler explicitly at runtime + expect(Buffer.isBuffer(null)).toBeFalsy(); + }); + test("#readUInt8", () => { let buff = new Buffer(10); buff[0] = -2; @@ -53,10 +68,10 @@ describe("buffer", () => { // Testing offset expect(buff.readUInt8(9)).toBe(47); // TODO: - // expectFn(() => { + // expectFn(() => { // let newBuff = new Buffer(1); // newBuff.readUInt8(5); - // }).toThrow(); + // }).toThrow(); }); test("#writeUInt8", () => { @@ -65,7 +80,7 @@ describe("buffer", () => { expect(buff.writeUInt8(252,4)).toBe(5); expect(buff[0]).toBe(4); expect(buff[4]).toBe(252); - }); + }); test("#writeInt8", () => { let buff = new Buffer(5); @@ -84,7 +99,7 @@ describe("buffer", () => { // Testing offset, and casting between u8 and i8. expect(buff.readInt8(9)).toBe(-1); // TODO: - // expectFn(() => { + // expectFn(() => { // let newBuff = new Buffer(1); // newBuff.readInt8(5); // }).toThrow(); diff --git a/tests/node.js b/tests/node.js index 5cb4a58..c652c1e 100644 --- a/tests/node.js +++ b/tests/node.js @@ -1,4 +1,4 @@ -const { TestContext, EmptyReporter } = require("@as-pect/core"); +const { TestContext, VerboseReporter } = require("@as-pect/core"); const { instantiateBuffer } = require("assemblyscript/lib/loader"); const glob = require("glob"); const { main } = require("assemblyscript/cli/asc"); @@ -7,7 +7,7 @@ const path = require("path"); const fs = require("fs"); const Wasi = require("wasi"); const wasi = new Wasi({}); -const diff = require("diff"); +let pass = true; const options = parse(process.argv.slice(2), { "help": { @@ -27,41 +27,7 @@ if (options.unknown.length > 1) { process.exit(1); } -class Reporter extends EmptyReporter { - onGroupFinish(group) { - if (group.name) { - if (group.pass) process.stdout.write("Group : " + group.name + " -> ✔ PASS"); - else process.stdout.write("Group : " + group.name + " -> ❌ FAIL"); - process.stdout.write("\n"); - } - } - - onTestFinish(group, test) { - if (test.pass) process.stdout.write("Test : " + group.name + " -> " + test.name + " ✔ PASS\n"); - else process.stdout.write("Test : " + group.name + " -> " + test.name + " ❌ FAIL\n"); - - if (!test.pass) { - process.stdout.write("Actual : " + test.actual.message + "\n"); - process.stdout.write("Expected : " + test.expected.message + "\n"); - } - - if (test.logs.length > 0) { - test.logs.forEach((e, i) => { - if (i > 0) process.stdout.write("\n"); - process.stdout.write("Log : " + e.value); - }); - process.stdout.write("\n"); - } - } - onFinish(context) { - const passed = context.testGroups.filter(e => !e.pass).length === 0; - if (passed) process.stdout.write("Suite : ✔ PASS"); - else process.stdout.write("Suite : ❌ FAIL"); - process.stdout.write("\n"); - } -} - -const reporter = new Reporter(); +const reporter = new VerboseReporter(); function relativeFromCwd(location) { return path.relative(process.cwd(), location); @@ -160,4 +126,8 @@ function runTest(file, type, binary, wat) { wasi.setMemory(wasm.memory); wasi.view = new DataView(wasm.memory.buffer); context.run(wasm); + + if (!context.pass) pass = false; } + +process.exit(pass ? 0 : 1); From 5ced001d3cc156c4d6e955bb111bb7c9a54305aa Mon Sep 17 00:00:00 2001 From: RedDwarfian Date: Fri, 26 Jul 2019 10:47:46 -0400 Subject: [PATCH 08/17] [Implement] Read/Write Int16/UInt16, LE and BE (#16) * [Implement] ReadInt16BE and ReadInt16LE * [Cleanup] Consistent with std lib, Missing TODOs * [Implement] ReadUInt16BE and ReadUInt16LE * [Implement] write(U)Int(L/B)E * [Cleanup] [Optimize] Using recommended changes * [Cleanup] Directly comparing written buffers * [Cleanup] Increases tests readability and malleability * [Cleanup] Formatting * [Cleanup] commented toThrow() function formatting --- assembly/buffer/index.ts | 64 +++++++++++++--- assembly/node.d.ts | 24 +++++- tests/buffer.spec.ts | 153 +++++++++++++++++++++++++++++++++------ 3 files changed, 205 insertions(+), 36 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 2d43385..fb5d4ca 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -27,25 +27,69 @@ export class Buffer extends Uint8Array { return value instanceof Buffer; } + readInt8(offset: i32 = 0): i8 { + if(i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + readUInt8(offset: i32 = 0): u8 { - if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); - return load(this.dataStart + usize(offset)); + if(i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + writeInt8(value: i8, offset: i32 = 0): i32 { + if(i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 1; } writeUInt8(value: u8, offset: i32 = 0): i32 { - if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); + if(i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 1; } - writeInt8(value: i8, offset: i32 = 0): i32 { - if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); - store(this.dataStart + offset, value); - return offset + 1; + readInt16LE(offset: i32 = 0): i16 { + if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); } - readInt8(offset: i32 = 0): i8 { - if(offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE); - return load(this.dataStart + usize(offset)); + readInt16BE(offset: i32 = 0): i16 { + if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + readUInt16LE(offset: i32 = 0): u16 { + if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readUInt16BE(offset: i32 = 0): u16 { + if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + writeInt16LE(value: i16, offset: i32 = 0): i32 { + if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 2; + } + + writeInt16BE(value: i16, offset: i32 = 0): i32 { + if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 2; + } + + writeUInt16LE(value: u16, offset: i32 = 0): i32 { + if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 2; + } + + writeUInt16BE(value: u16, offset: i32 = 0): i32 { + if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 2; } } diff --git a/assembly/node.d.ts b/assembly/node.d.ts index d6da2cb..5beb381 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -5,12 +5,28 @@ declare class Buffer extends Uint8Array { static allocUnsafe(size: 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. */ + readInt8(offset?: i32): i8; /** Reads an unsigned integer at the designated offset. */ readUInt8(offset?: i32): u8; - /** Writes an inputted u8 value to the buffer, at the desired offset. */ - writeUInt8(value:u8, offset?:i32): i32; /** 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; + /** 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; } diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 8645074..ba4ff36 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -11,6 +11,15 @@ */ import { BLOCK_MAXSIZE } from "rt/common"; +// Helper function to quickly create a Buffer from an array. +//@ts-ignore +function create(values: valueof[]): T { + let result = instantiate(values.length); + //@ts-ignore + for (let i = 0; i < values.length; i++) result[i] = values[i]; + return result; +} + describe("buffer", () => { test("#constructor", () => { expect(new Buffer(0)).toBeTruthy(); @@ -58,15 +67,24 @@ describe("buffer", () => { expect(Buffer.isBuffer(null)).toBeFalsy(); }); + test("#readInt8", () => { + let buff = create([0x5,0x0,0x0,0x0,0xFF]); + expect(buff.readInt8()).toBe(5); + // Testing offset, and casting between u8 and i8. + expect(buff.readInt8(4)).toBe(-1); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readInt8(5); + // }).toThrow(); + }); + test("#readUInt8", () => { - let buff = new Buffer(10); - buff[0] = -2; - buff[9] = 47; + let buff = create([0xFE,0x0,0x0,0x0,0x2F]); // Testing casting between u8 and i8. - expect(buff.readUInt8(0)).toBe(254); expect(buff.readUInt8()).toBe(254); // Testing offset - expect(buff.readUInt8(9)).toBe(47); + expect(buff.readUInt8(4)).toBe(47); // TODO: // expectFn(() => { // let newBuff = new Buffer(1); @@ -74,34 +92,125 @@ describe("buffer", () => { // }).toThrow(); }); + test("#writeInt8", () => { + let buff = new Buffer(5); + expect(buff.writeInt8(9)).toBe(1); + expect(buff.writeInt8(-3,4)).toBe(5); + let result = create([0x09, 0x0, 0x0, 0x0, 0xFD]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeInt8(5,10); + // }).toThrow(); + }); + test("#writeUInt8", () => { let buff = new Buffer(5); expect(buff.writeUInt8(4)).toBe(1); expect(buff.writeUInt8(252,4)).toBe(5); - expect(buff[0]).toBe(4); - expect(buff[4]).toBe(252); + let result = create([0x04, 0x0, 0x0, 0x0, 0xFC]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeUInt8(5,10); + // }).toThrow(); + }); + + test("#readInt16LE", () => { + let buff = create([0x0,0x05,0x0]); + expect(buff.readInt16LE()).toBe(1280); + expect(buff.readInt16LE(1)).toBe(5); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readInt16LE(0); + // }).toThrow(); }); - test("#writeInt8", () => { - let buff = new Buffer(5); - expect(buff.writeInt8(9)).toBe(1); - expect(buff.writeInt8(-3,4)).toBe(5); - expect(buff[0]).toBe(9); - expect(buff[4]).toBe(-3); + test("#readInt16BE", () => { + let buff = create([0x0,0x05,0x0]); + expect(buff.readInt16BE()).toBe(5); + expect(buff.readInt16BE(1)).toBe(1280); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readInt16BE(0); + // }).toThrow(); }); - test("#readInt8", () => { - let buff = new Buffer(10); - buff[0] = 5; - buff[9] = 255; - expect(buff.readInt8(0)).toBe(5); - expect(buff.readInt8()).toBe(5); - // Testing offset, and casting between u8 and i8. - expect(buff.readInt8(9)).toBe(-1); + test("#readUInt16LE", () => { + let buff = create([0x0,0x05,0x0]); + expect(buff.readUInt16LE()).toBe(1280); + expect(buff.readUInt16LE(1)).toBe(5); // TODO: // expectFn(() => { // let newBuff = new Buffer(1); - // newBuff.readInt8(5); + // newBuff.readUInt16LE(0); + // }).toThrow(); + }); + + test("#readUInt16BE", () => { + let buff = create([0x0,0x05,0x0]); + expect(buff.readUInt16BE()).toBe(5); + expect(buff.readUInt16BE(1)).toBe(1280); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readUInt16BE(0); + // }).toThrow(); + }); + + test("#writeInt16LE", () => { + let buff = new Buffer(4); + expect(buff.writeInt16LE(5)).toBe(2); + expect(buff.writeInt16LE(1280,2)).toBe(4); + let result = create([0x05, 0x0, 0x0, 0x5]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeInt16LE(0); + // }).toThrow(); + }); + + test("#writeInt16BE", () => { + let buff = new Buffer(4); + expect(buff.writeInt16BE(1280)).toBe(2); + expect(buff.writeInt16BE(5,2)).toBe(4); + let result = create([0x05, 0x0, 0x0, 0x5]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeInt16BE(0); + // }).toThrow(); + }); + + test("#writeUInt16LE", () => { + let buff = new Buffer(4); + expect(buff.writeUInt16LE(5)).toBe(2); + expect(buff.writeUInt16LE(1280,2)).toBe(4); + let result = create([0x05, 0x0, 0x0, 0x5]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeUInt16LE(0); + // }).toThrow(); + }); + + test("#writeUInt16BE", () => { + let buff = new Buffer(4); + expect(buff.writeUInt16BE(1280)).toBe(2); + expect(buff.writeUInt16BE(5,2)).toBe(4); + let result = create([0x05, 0x0, 0x0, 0x5]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeUInt16BE(0); // }).toThrow(); }); }); From 9027d732f7c3150e34b9163f716da58abe5f9bdf Mon Sep 17 00:00:00 2001 From: jtenner Date: Thu, 1 Aug 2019 10:46:33 -0400 Subject: [PATCH 09/17] [Implement] HEX Encoding: decode, decodeUnsafe, encode (#17) * [Implement] HEX encoding * [Optimize] Hex encode * [Optimize] hex#encode * [Fix] docs, switch to single if * Update node.d.ts --- assembly/buffer/index.ts | 102 ++++++++++++++++++++++++++++++++++++++- assembly/node.d.ts | 11 +++++ tests/buffer.spec.ts | 14 ++++++ tests/node.js | 4 +- 4 files changed, 127 insertions(+), 4 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index fb5d4ca..87cf104 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -1,4 +1,4 @@ -import { BLOCK_MAXSIZE } from "rt/common"; +import { BLOCK_MAXSIZE, BLOCK, BLOCK_OVERHEAD } from "rt/common"; import { E_INVALIDLENGTH, E_INDEXOUTOFRANGE } from "util/error"; import { Uint8Array } from "typedarray"; @@ -93,3 +93,103 @@ export class Buffer extends Uint8Array { return offset + 2; } } + +export namespace Buffer { + export namespace HEX { + /** Calculates the two char combination from the byte. */ + @inline export function charsFromByte(byte: u32): u32 { + let top = (byte >>> 4) & 0xF; + let bottom = (0xF & byte); + top += select(0x57, 0x30, top > 9); + bottom += select(0x57, 0x30, bottom > 9); + return (bottom << 16) | top; + } + + /** Calculates the byte length of the specified string when encoded as HEX. */ + export function byteLength(str: string): i32 { + let ptr = changetype(str); + let byteCount = changetype(changetype(str) - BLOCK_OVERHEAD).rtSize; + let length = byteCount >> 2; + // The string length must be even because the bytes come in pairs of characters two wide + if (byteCount & 0x3) return 0; // encoding fails and returns an empty ArrayBuffer + + byteCount += ptr; + while (ptr < byteCount) { + var char = load(ptr); + if ( ((char - 0x30) <= 0x9) + || ((char - 0x61) <= 0x5) + || ((char - 0x41) <= 0x5)) { + ptr += 2; + continue; + } else { + return 0; + } + } + return length; + } + + /** Creates an ArrayBuffer from a given string that is encoded in the HEX format. */ + export function encode(str: string): ArrayBuffer { + let bufferLength = byteLength(str); + // short path: string is not a valid hex string, return a new empty ArrayBuffer + if (bufferLength == 0) return changetype(__alloc(0, idof())); + + // long path: loop over each enociding pair and perform the conversion + let ptr = changetype(str); + let byteEnd = changetype(changetype(str) - BLOCK_OVERHEAD).rtSize + ptr; + let result = __alloc(bufferLength, idof()); + let b: u32 = 0; + let outChar = 0; + for (let i: usize = 0; ptr < byteEnd; i++) { + let odd = i & 1; + if (odd) { + outChar <<= 4; + b >>>= 16; + if ((b - 0x30) <= 9) { + outChar |= b - 0x30; + } else if ((b - 0x61) <= 0x5) { + outChar |= b - 0x57; + } else if (b - 0x41 <= 0x5) { + outChar |= b - 0x37; + } + store(result + (i >> 1), (outChar & 0xFF)); + ptr += 4; + } else { + b = load(ptr); + outChar <<= 4; + let c = b & 0xFF; + if ((c - 0x30) <= 9) { + outChar |= c - 0x30; + } else if ((c - 0x61) <= 0x5) { + outChar |= c - 0x57; + } else if (c - 0x41 <= 0x5) { + outChar |= c - 0x37; + } + } + } + return changetype(result); + } + + /** Creates a string from a given ArrayBuffer that is decoded into hex format. */ + export function decode(buff: ArrayBuffer): string { + return decodeUnsafe(changetype(buff), buff.byteLength); + } + + /** Decodes a chunk of memory to a utf16le encoded string in hex format. */ + @unsafe export function decodeUnsafe(ptr: usize, length: i32): string { + let stringByteLength = length << 2; // length * (2 bytes per char) * (2 chars per input byte) + let result = __alloc(stringByteLength, idof()); + let i = 0; + let inputByteLength = length + ptr; + + // loop over each byte and store a `u32` for each one + while (ptr < inputByteLength) { + store(result + i, charsFromByte(load(ptr))); + i += 4; + ptr++; + } + + return changetype(result); + } + } +} diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 5beb381..16f3e81 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -30,3 +30,14 @@ declare class Buffer extends Uint8Array { /** 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; + } +} diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index ba4ff36..5e15eaa 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -213,4 +213,18 @@ describe("buffer", () => { // newBuff.writeUInt16BE(0); // }).toThrow(); }); + + test("#Hex.encode", () => { + let actual = "000102030405060708090a0b0c0d0e0f102030405060708090a0b0c0d0e0f0"; + let exampleBuffer = create([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(encoded).toStrictEqual(exampleBuffer.buffer); + }); + + test("#Hex.decode", () => { + let expected = "000102030405060708090a0b0c0d0e0f102030405060708090a0b0c0d0e0f0"; + let exampleBuffer = create([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(decoded).toStrictEqual(expected); + }); }); diff --git a/tests/node.js b/tests/node.js index c652c1e..0b5a3d4 100644 --- a/tests/node.js +++ b/tests/node.js @@ -109,9 +109,7 @@ function runTest(file, type, binary, wat) { + "." + type + ".wat"; // should not block testing - fs.writeFile(watPath, wat, (err) => { - if (err) console.warn(err); - }); + fs.writeFileSync(watPath, wat); const context = new TestContext({ fileName: file, From 04668b8f6867a38da89b66a71165d88cba7a056d Mon Sep 17 00:00:00 2001 From: jtenner Date: Thu, 1 Aug 2019 11:34:47 -0400 Subject: [PATCH 10/17] [Implement] subarray (#20) --- assembly/buffer/index.ts | 13 +++++++++++++ package-lock.json | 2 +- tests/buffer.spec.ts | 36 +++++++++++++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 87cf104..7a76822 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -27,6 +27,19 @@ export class Buffer extends Uint8Array { return value instanceof Buffer; } + // Adapted from https://github.com/AssemblyScript/assemblyscript/blob/master/std/assembly/typedarray.ts + public subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Buffer { + var len = this.dataLength; + begin = begin < 0 ? max(len + begin, 0) : min(begin, len); + end = end < 0 ? max(len + end, 0) : min(end, len); + end = max(end, begin); + var out = changetype(__alloc(offsetof(), idof())); // retains + out.data = this.data; // retains + out.dataStart = this.dataStart + begin; + out.dataLength = end - begin; + return out; + } + readInt8(offset: i32 = 0): i8 { if(i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); diff --git a/package-lock.json b/package-lock.json index 1d4efe9..05a35d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ } }, "assemblyscript": { - "version": "github:assemblyscript/assemblyscript#4c938f7689c39e3a1ad813356781e2689fd4ec70", + "version": "github:assemblyscript/assemblyscript#227c626921175ab19701752397fa513171750d38", "from": "github:assemblyscript/assemblyscript", "dev": true, "requires": { diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 5e15eaa..8193282 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -102,7 +102,7 @@ describe("buffer", () => { // expectFn(() => { // let newBuff = new Buffer(1); // newBuff.writeInt8(5,10); - // }).toThrow(); + // }).toThrow(); }); test("#writeUInt8", () => { @@ -115,8 +115,8 @@ describe("buffer", () => { // expectFn(() => { // let newBuff = new Buffer(1); // newBuff.writeUInt8(5,10); - // }).toThrow(); - }); + // }).toThrow(); + }); test("#readInt16LE", () => { let buff = create([0x0,0x05,0x0]); @@ -214,6 +214,36 @@ describe("buffer", () => { // }).toThrow(); }); + test("#subarray", () => { + let example = create([1, 2, 3, 4, 5, 6, 7, 8]); + + // no parameters means copy the Buffer + let actual = example.subarray(); + expect(actual).toStrictEqual(example); + expect(actual.buffer).toBe(example.buffer); // should use the same buffer + + // start at offset 5 + actual = example.subarray(5); + let expected = create([6, 7, 8]); + // trace("length", 1, expected.length); + expect(actual).toStrictEqual(expected); + + // negative start indicies, start at (8 - 5) + actual = example.subarray(-5); + expected = create([4, 5, 6, 7, 8]); + expect(actual).toStrictEqual(expected); + + // two parameters + actual = example.subarray(2, 6); + expected = create([3, 4, 5, 6]); + expect(actual).toStrictEqual(expected); + + // negative end index + actual = example.subarray(4, -1); + expected = create([5, 6, 7]); + expect(actual).toStrictEqual(expected); + }); + test("#Hex.encode", () => { let actual = "000102030405060708090a0b0c0d0e0f102030405060708090a0b0c0d0e0f0"; let exampleBuffer = create([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]); From f1056aad723ed6c77bfe79351a99d93811f3613a Mon Sep 17 00:00:00 2001 From: RedDwarfian Date: Tue, 6 Aug 2019 10:05:35 -0400 Subject: [PATCH 11/17] [Implement] Buffer Read/Write 32 Bit Int/Float (#19) * [Implement] Buffer Handling (U)Int32 * [Cleanup] Actually using signed int 32, now. * [Implement] Buffer Handling Float * [Bug] Copy-Paste Issue * [Cleanup] Simplified load and store for LE Floats * [Chore] fix space between if keywords --- assembly/buffer/index.ts | 90 ++++++++++++++++++++---- assembly/node.d.ts | 24 +++++++ tests/buffer.spec.ts | 144 +++++++++++++++++++++++++++++++++++++++ tests/node.js | 4 +- 4 files changed, 249 insertions(+), 13 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 7a76822..ce4b27f 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -41,70 +41,136 @@ export class Buffer extends Uint8Array { } readInt8(offset: i32 = 0): i8 { - if(i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readUInt8(offset: i32 = 0): u8 { - if(i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } writeInt8(value: i8, offset: i32 = 0): i32 { - if(i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 1; } writeUInt8(value: u8, offset: i32 = 0): i32 { - if(i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 1; } readInt16LE(offset: i32 = 0): i16 { - if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readInt16BE(offset: i32 = 0): i16 { - if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); return bswap(load(this.dataStart + offset)); } readUInt16LE(offset: i32 = 0): u16 { - if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readUInt16BE(offset: i32 = 0): u16 { - if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); return bswap(load(this.dataStart + offset)); } writeInt16LE(value: i16, offset: i32 = 0): i32 { - if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 2; } writeInt16BE(value: i16, offset: i32 = 0): i32 { - if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, bswap(value)); return offset + 2; } writeUInt16LE(value: u16, offset: i32 = 0): i32 { - if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 2; } writeUInt16BE(value: u16, offset: i32 = 0): i32 { - if(i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, bswap(value)); return offset + 2; } + + readInt32LE(offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readInt32BE(offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + readUInt32LE(offset: i32 = 0): u32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readUInt32BE(offset: i32 = 0): u32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + writeInt32LE(value: i32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 4; + } + + writeInt32BE(value: i32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 4; + } + + writeUInt32LE(value: u32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 4; + } + + writeUInt32BE(value: u32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 4; + } + + readFloatLE(offset: i32 = 0): f32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readFloatBE(offset: i32 = 0): f32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return reinterpret(bswap(load(this.dataStart + offset))); + } + + writeFloatLE(value: f32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 4; + } + + writeFloatBE(value: f32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(reinterpret(value))); + return offset + 4; + } } export namespace Buffer { diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 16f3e81..fc8f579 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -29,6 +29,30 @@ declare class Buffer extends Uint8Array { 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; + /** Reads a signed 32-bit integer, stored in Little Endian format at the designated offset. */ + readInt32LE(offset?: i32): i32; + /** Reads a signed 32-bit integer, stored in Big Endian format at the designated offset. */ + readInt32BE(offset?: i32): i32; + /** Reads an unsigned 32-bit integer, stored in Little Endian format at the designated offset. */ + readUInt32LE(offset?: i32): u32; + /** Reads an unsigned 32-bit integer, stored in Big Endian format at the designated offset. */ + readUInt32BE(offset?: i32): u32; + /** Writes an inputted 32-bit integer at the designated offset, stored in Little Endian format */ + writeInt32LE(value: i32, offset?: i32): i32; + /** Writes an inputted 32-bit integer at the designated offset, stored in Big Endian format */ + writeInt32BE(value: i32, offset?: i32): i32; + /** Writes an inputted unsigned 32-bit integer at the designated offset, stored in Little Endian format */ + writeUInt32LE(value: u32, offset?: i32): i32; + /** Writes an inputted unsigned 32-bit integer at the designated offset, stored in Big Endian format */ + writeUInt32BE(value: u32, offset?: i32): i32; + /** Reads a signed 32-bit float, stored in Little Endian format at the designated offset. */ + readFloatLE(offset?: i32): f32; + /** Reads a signed 32-bit float, stored in Big Endian format at the designated offset. */ + readFloatBE(offset?: i32): f32; + /** Writes an inputted 32-bit float at the designated offset, stored in Little Endian format */ + writeFloatLE(value: f32, offset?: i32): i32; + /** Writes an inputted 32-bit float at the designated offset, stored in Big Endian format */ + writeFloatBE(value: f32, offset?: i32): i32; } declare namespace Buffer { diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 8193282..a3eb1e1 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -214,6 +214,150 @@ describe("buffer", () => { // }).toThrow(); }); + test("#readInt32LE", () => { + let buff = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]); + expect(buff.readInt32LE()).toBe(-559038737); + expect(buff.readInt32LE(4)).toBe(283033613); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readInt32LE(0); + // }).toThrow(); + }); + + test("#readInt32BE", () => { + let buff = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); + expect(buff.readInt32BE()).toBe(-559038737); + expect(buff.readInt32BE(4)).toBe(283033613); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readInt32BE(0); + // }).toThrow(); + }); + + test("#readUInt32LE", () => { + let buff = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]); + expect(buff.readUInt32LE()).toBe(3735928559); + expect(buff.readUInt32LE(4)).toBe(283033613); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readUInt32LE(0); + // }).toThrow(); + }); + + test("#readUInt32BE", () => { + let buff = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); + expect(buff.readUInt32BE()).toBe(3735928559); + expect(buff.readUInt32BE(4)).toBe(283033613); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readUInt32BE(0); + // }).toThrow(); + }); + + test("#writeInt32LE", () => { + let buff = new Buffer(8); + 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); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeInt32LE(0); + // }).toThrow(); + }); + + test("#writeInt32BE", () => { + let buff = new Buffer(8); + expect(buff.writeInt32BE(-559038737)).toBe(4); + expect(buff.writeInt32BE(283033613,4)).toBe(8); + let result = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeInt32BE(0); + // }).toThrow(); + }); + + test("#writeUInt32LE", () => { + let buff = new Buffer(8); + expect(buff.writeUInt32LE(3735928559)).toBe(4); + expect(buff.writeUInt32LE(283033613,4)).toBe(8); + let result = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]);; + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeUInt32LE(0); + // }).toThrow(); + }); + + test("#writeUInt32BE", () => { + let buff = new Buffer(8); + expect(buff.writeUInt32BE(3735928559)).toBe(4); + expect(buff.writeUInt32BE(283033613,4)).toBe(8); + let result = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeUInt32BE(0); + // }).toThrow(); + }); + + test("#readFloatLE", () => { + let buff = create([0xbb,0xfe,0x4a,0x4f,0x01,0x02,0x03,0x04]); + expect(buff.readFloatLE()).toBe(0xcafebabe); + expect(buff.readFloatLE(4)).toBe(1.539989614439558e-36); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readFloatLE(0); + // }).toThrow(); + }); + + test("#readFloatBE", () => { + let buff = create([0x4f,0x4a,0xfe,0xbb,0x01,0x02,0x03,0x04]); + expect(buff.readFloatBE()).toBe(0xcafebabe); + expect(buff.readFloatBE(4)).toBe(2.387939260590663e-38); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readFloatBE(0); + // }).toThrow(); + }); + + test("#writeFloatLE", () => { + let buff = new Buffer(8); + expect(buff.writeFloatLE(0xcafebabe)).toBe(4); + expect(buff.writeFloatLE(1.539989614439558e-36,4)).toBe(8); + let result = create([0xbb,0xfe,0x4a,0x4f,0x01,0x02,0x03,0x04]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeFloatLE(0); + // }).toThrow(); + }); + + test("#writeFloatBE", () => { + let buff = new Buffer(8); + expect(buff.writeFloatBE(0xcafebabe)).toBe(4); + expect(buff.writeFloatBE(2.387939260590663e-38,4)).toBe(8); + let result = create([0x4f,0x4a,0xfe,0xbb,0x01,0x02,0x03,0x04]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeFloatBE(0); + // }).toThrow(); + }); + test("#subarray", () => { let example = create([1, 2, 3, 4, 5, 6, 7, 8]); diff --git a/tests/node.js b/tests/node.js index 0b5a3d4..c652c1e 100644 --- a/tests/node.js +++ b/tests/node.js @@ -109,7 +109,9 @@ function runTest(file, type, binary, wat) { + "." + type + ".wat"; // should not block testing - fs.writeFileSync(watPath, wat); + fs.writeFile(watPath, wat, (err) => { + if (err) console.warn(err); + }); const context = new TestContext({ fileName: file, From 5f0b0dc30bd9198444c982e144177760339d6a41 Mon Sep 17 00:00:00 2001 From: RedDwarfian Date: Tue, 6 Aug 2019 10:30:24 -0400 Subject: [PATCH 12/17] [Implement] Read/Write BigInt and Double (#21) * [Implement] Read/Write BigInt and Double * [Fix] Small changes --- assembly/buffer/index.ts | 66 ++++++++++++++++++ assembly/node.d.ts | 24 +++++++ tests/buffer.spec.ts | 144 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index ce4b27f..0159575 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -171,6 +171,72 @@ export class Buffer extends Uint8Array { store(this.dataStart + offset, bswap(reinterpret(value))); return offset + 4; } + + readBigInt64LE(offset: i32 = 0): i64 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readBigInt64BE(offset: i32 = 0): i64 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + readBigUInt64LE(offset: i32 = 0): u64 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readBigUInt64BE(offset: i32 = 0): u64 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + writeBigInt64LE(value: i64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 8; + } + + writeBigInt64BE(value: i64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 8; + } + + writeBigUInt64LE(value: u64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 8; + } + + writeBigUInt64BE(value: u64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 8; + } + + readDoubleLE(offset: i32 = 0): f64 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readDoubleBE(offset: i32 = 0): f64 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return reinterpret(bswap(load(this.dataStart + offset))); + } + + writeDoubleLE(value: f64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 8; + } + + writeDoubleBE(value: f64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(reinterpret(value))); + return offset + 8; + } } export namespace Buffer { diff --git a/assembly/node.d.ts b/assembly/node.d.ts index fc8f579..9e3f070 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -53,6 +53,30 @@ declare class Buffer extends Uint8Array { writeFloatLE(value: f32, offset?: i32): i32; /** Writes an inputted 32-bit float at the designated offset, stored in Big Endian format */ writeFloatBE(value: f32, offset?: i32): i32; + /** Reads a signed 64-bit integer, stored in Little Endian format at the designated offset. */ + readBigInt64LE(offset?: i32): i64; + /** Reads a signed 64-bit integer, stored in Big Endian format at the designated offset. */ + readBigInt64BE(offset?: i32): i64; + /** Reads an unsigned 64-bit integer, stored in Little Endian format at the designated offset. */ + readBigUInt64LE(offset?: i32): u64; + /** Reads an unsigned 64-bit integer, stored in Big Endian format at the designated offset. */ + readBigUInt64BE(offset?: i32): u64; + /** Writes an inputted 64-bit integer at the designated offset, stored in Little Endian format */ + writeBigInt64LE(value: i64, offset?: i32): i32; + /** Writes an inputted 64-bit integer at the designated offset, stored in Big Endian format */ + writeBigInt64BE(value: i64, offset?: i32): i32; + /** Writes an inputted unsigned 64-bit integer at the designated offset, stored in Little Endian format */ + writeBigUInt64LE(value: u64, offset?: i32): i32; + /** Writes an inputted unsigned 64-bit integer at the designated offset, stored in Big Endian format */ + writeBigUInt64BE(value: u64, offset?: i32): i32; + /** Reads a signed 64-bit double, stored in Little Endian format at the designated offset. */ + readDoubleLE(offset?: i32): f64; + /** Reads a signed 64-bit double, stored in Big Endian format at the designated offset. */ + readDoubleBE(offset?: i32): f64; + /** Writes an inputted 64-bit double at the designated offset, stored in Little Endian format */ + writeDoubleLE(value: f64, offset?: i32): i32; + /** Writes an inputted 64-bit double at the designated offset, stored in Big Endian format */ + writeDoubleBE(value: f64, offset?: i32): i32; } declare namespace Buffer { diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index a3eb1e1..38a7a20 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -358,6 +358,150 @@ describe("buffer", () => { // }).toThrow(); }); + test("#readBigInt64LE", () => { + let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); + expect(buff.readBigInt64LE()).toBe(-4294967296); + expect(buff.readBigInt64LE(8)).toBe(4294967295); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readBigInt64LE(0); + // }).toThrow(); + }); + + test("#readBigInt64BE", () => { + let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); + expect(buff.readBigInt64BE()).toBe(4294967295); + expect(buff.readBigInt64BE(8)).toBe(-4294967296); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readBigInt64BE(0); + // }).toThrow(); + }); + + test("#readBigUInt64LE", () => { + let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); + expect(buff.readBigUInt64LE()).toBe(18446744069414584320); + expect(buff.readBigUInt64LE(8)).toBe(4294967295); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readBigUInt64LE(0); + // }).toThrow(); + }); + + test("#readBigUInt64BE", () => { + let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); + expect(buff.readBigUInt64BE()).toBe(4294967295); + expect(buff.readBigUInt64BE(8)).toBe(18446744069414584320); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readBigUInt64BE(0); + // }).toThrow(); + }); + + test("#writeBigInt64LE", () => { + let buff = new Buffer(16); + expect(buff.writeBigInt64LE(-559038737)).toBe(8); + expect(buff.writeBigInt64LE(283033613,8)).toBe(16); + let result = create([0xEF,0xBE,0xAD,0xDE,0xFF,0xFF,0xFF,0xFF,0x0d,0xc0,0xde,0x10,0x00,0x00,0x00,0x00]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeBigInt64LE(0); + // }).toThrow(); + }); + + test("#writeBigInt64BE", () => { + let buff = new Buffer(16); + expect(buff.writeBigInt64BE(-559038737)).toBe(8); + expect(buff.writeBigInt64BE(283033613,8)).toBe(16); + let result = create([0xFF,0xFF,0xFF,0xFF,0xDE,0xAD,0xBE,0xEF,0x00,0x00,0x00,0x00,0x10,0xde,0xc0,0x0d]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeBigInt64BE(0); + // }).toThrow(); + }); + + test("#writeBigUInt64LE", () => { + let buff = new Buffer(16); + expect(buff.writeBigUInt64LE(3735928559)).toBe(8); + expect(buff.writeBigUInt64LE(283033613,8)).toBe(16); + let result = create([0xEF,0xBE,0xAD,0xDE,0x00,0x00,0x00,0x00,0x0d,0xc0,0xde,0x10,0x00,0x00,0x00,0x00]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeBigUInt64LE(0); + // }).toThrow(); + }); + + test("#writeBigUInt64BE", () => { + let buff = new Buffer(16); + expect(buff.writeBigUInt64BE(3735928559)).toBe(8); + expect(buff.writeBigUInt64BE(283033613,8)).toBe(16); + let result = create([0x00,0x00,0x00,0x00,0xDE,0xAD,0xBE,0xEF,0x00,0x00,0x00,0x00,0x10,0xde,0xc0,0x0d]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeBigUInt64BE(0); + // }).toThrow(); + }); + + test("#readDoubleLE", () => { + let buff = create([0x77, 0xbe, 0x9f, 0x1a, 0x2f, 0xdd, 0x5e, 0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + expect(buff.readDoubleLE()).toBe(123.456); + expect(buff.readDoubleLE(8)).toBe(5.447603722011605e-270); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readDoubleLE(0); + // }).toThrow(); + }); + + test("#readDoubleBE", () => { + let buff = create([0x40, 0x5e, 0xdd, 0x2f, 0x1a, 0x9f, 0xbe, 0x77, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + expect(buff.readDoubleBE()).toBe(123.456); + expect(buff.readDoubleBE(8)).toBe(8.20788039913184e-304); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.readDoubleBE(0); + // }).toThrow(); + }); + + test("#writeDoubleLE", () => { + let buff = new Buffer(16); + expect(buff.writeDoubleLE(123.456)).toBe(8); + expect(buff.writeDoubleLE(5.447603722011605e-270,8)).toBe(16); + let result = create([0x77, 0xbe, 0x9f, 0x1a, 0x2f, 0xdd, 0x5e, 0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeDoubleLE(0); + // }).toThrow(); + }); + + test("#writeDoubleBE", () => { + let buff = new Buffer(16); + expect(buff.writeDoubleBE(123.456)).toBe(8); + expect(buff.writeDoubleBE(8.20788039913184e-304,8)).toBe(16); + let result = create([0x40, 0x5e, 0xdd, 0x2f, 0x1a, 0x9f, 0xbe, 0x77, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + expect(buff).toStrictEqual(result); + // TODO: + // expectFn(() => { + // let newBuff = new Buffer(1); + // newBuff.writeDoubleBE(0); + // }).toThrow(); + }); + test("#subarray", () => { let example = create([1, 2, 3, 4, 5, 6, 7, 8]); From e3e6b3ab704297f4d4c38340b02a5a9831025444 Mon Sep 17 00:00:00 2001 From: RedDwarfian Date: Wed, 21 Aug 2019 09:23:41 -0400 Subject: [PATCH 13/17] [Implement] Buffer.swap16/32/64 (#22) * [Implement] Buffer.swap16/32/64 * [Cleanup] Using proper error message --- assembly/buffer/index.ts | 39 +++++++++++++++++++++++++++++++++++++++ assembly/node.d.ts | 6 ++++++ tests/buffer.spec.ts | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 0159575..91be52d 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -237,6 +237,45 @@ export class Buffer extends Uint8Array { store(this.dataStart + offset, bswap(reinterpret(value))); return offset + 8; } + + swap16(): Buffer { + let dataLength = this.dataLength; + // Make sure dataLength is even + if (dataLength & 1) throw new RangeError(E_INVALIDLENGTH); + let dataStart = this.dataStart; + dataLength += dataStart; + while (dataStart < dataLength) { + store(dataStart, bswap(load(dataStart))); + dataStart += 2; + } + return this; + } + + swap32(): Buffer { + let dataLength = this.dataLength; + // Make sure dataLength is divisible by 4 + if (dataLength & 3) throw new RangeError(E_INVALIDLENGTH); + let dataStart = this.dataStart; + dataLength += dataStart; + while (dataStart < dataLength) { + store(dataStart, bswap(load(dataStart))); + dataStart += 4; + } + return this; + } + + swap64(): Buffer { + let dataLength = this.dataLength; + // Make sure dataLength is divisible by 8 + if (dataLength & 7) throw new RangeError(E_INVALIDLENGTH); + let dataStart = this.dataStart; + dataLength += dataStart; + while (dataStart < dataLength) { + store(dataStart, bswap(load(dataStart))); + dataStart += 8; + } + return this; + } } export namespace Buffer { diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 9e3f070..419384a 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -77,6 +77,12 @@ declare class Buffer extends Uint8Array { writeDoubleLE(value: f64, offset?: i32): i32; /** Writes an inputted 64-bit double at the designated offset, stored in Big Endian format */ writeDoubleBE(value: f64, offset?: i32): i32; + /** Swaps every group of two bytes in a Buffer in-place */ + swap16(): Buffer; + /** Swaps every group of four bytes in a Buffer in-place */ + swap32(): Buffer; + /** Swaps every group of eight bytes in a Buffer in-place */ + swap64(): Buffer; } declare namespace Buffer { diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 38a7a20..c508a08 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -531,6 +531,45 @@ describe("buffer", () => { expected = create([5, 6, 7]); expect(actual).toStrictEqual(expected); }); + + test("#swap16", () => { + let actual = create([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); + let expected = create([0x2, 0x1, 0x4, 0x3, 0x6, 0x5, 0x8, 0x7]); + let swapped = actual.swap16(); + expect(actual).toStrictEqual(expected); + expect(swapped).toBe(actual); + // TODO: + // expectFn(() => { + // let newBuff = create([0x1, 0x2, 0x3]); + // newBuff.swap16(); + // }).toThrow(); + }); + + test("#swap32", () => { + let actual = create([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); + let expected = create([0x4, 0x3, 0x2, 0x1, 0x8, 0x7, 0x6, 0x5]); + let swapped = actual.swap32(); + expect(actual).toStrictEqual(expected); + expect(swapped).toBe(actual); + // TODO: + // expectFn(() => { + // let newBuff = create([0x1, 0x2, 0x3]); + // newBuff.swap64(); + // }).toThrow(); + }); + + test("#swap64", () => { + let actual = create([0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf]); + let expected = create([0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0, 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8]); + let swapped = actual.swap64(); + expect(actual).toStrictEqual(expected); + expect(swapped).toBe(actual); + // TODO: + // expectFn(() => { + // let newBuff = create([0x1, 0x2, 0x3]); + // newBuff.swap64(); + // }).toThrow(); + }); test("#Hex.encode", () => { let actual = "000102030405060708090a0b0c0d0e0f102030405060708090a0b0c0d0e0f0"; From b6ef8c71a5af51c1be817855fc50d42168c76032 Mon Sep 17 00:00:00 2001 From: Max Graey Date: Mon, 2 Sep 2019 03:06:49 +0300 Subject: [PATCH 14/17] Buffer refactoring (#24) * refactor Buffer * remove inline for exported methods --- assembly/buffer/index.ts | 94 ++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 91be52d..363ab5e 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -7,28 +7,28 @@ export class Buffer extends Uint8Array { super(size); } - public static alloc(size: i32): Buffer { + static alloc(size: i32): Buffer { return new Buffer(size); } - @unsafe public static allocUnsafe(size: i32): Buffer { + @unsafe static allocUnsafe(size: i32): Buffer { // Node throws an error if size is less than 0 - if (u32(size) > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); + if (size > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); let buffer = __alloc(size, idof()); // This retains the pointer to the result Buffer. let result = changetype(__alloc(offsetof(), idof())); result.data = changetype(buffer); - result.dataStart = changetype(buffer); + result.dataStart = buffer; result.dataLength = size; return result; } - public static isBuffer(value: T): bool { + static isBuffer(value: T): bool { return value instanceof Buffer; } // Adapted from https://github.com/AssemblyScript/assemblyscript/blob/master/std/assembly/typedarray.ts - public subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Buffer { + subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Buffer { var len = this.dataLength; begin = begin < 0 ? max(len + begin, 0) : min(begin, len); end = end < 0 ? max(len + end, 0) : min(end, len); @@ -69,7 +69,7 @@ export class Buffer extends Uint8Array { readInt16BE(offset: i32 = 0): i16 { if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - return bswap(load(this.dataStart + offset)); + return bswap(load(this.dataStart + offset)); } readUInt16LE(offset: i32 = 0): u16 { @@ -79,7 +79,7 @@ export class Buffer extends Uint8Array { readUInt16BE(offset: i32 = 0): u16 { if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - return bswap(load(this.dataStart + offset)); + return bswap(load(this.dataStart + offset)); } writeInt16LE(value: i16, offset: i32 = 0): i32 { @@ -90,7 +90,7 @@ export class Buffer extends Uint8Array { writeInt16BE(value: i16, offset: i32 = 0): i32 { if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - store(this.dataStart + offset, bswap(value)); + store(this.dataStart + offset, bswap(value)); return offset + 2; } @@ -102,7 +102,7 @@ export class Buffer extends Uint8Array { writeUInt16BE(value: u16, offset: i32 = 0): i32 { if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - store(this.dataStart + offset, bswap(value)); + store(this.dataStart + offset, bswap(value)); return offset + 2; } @@ -113,7 +113,7 @@ export class Buffer extends Uint8Array { readInt32BE(offset: i32 = 0): i32 { if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - return bswap(load(this.dataStart + offset)); + return bswap(load(this.dataStart + offset)); } readUInt32LE(offset: i32 = 0): u32 { @@ -123,7 +123,7 @@ export class Buffer extends Uint8Array { readUInt32BE(offset: i32 = 0): u32 { if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - return bswap(load(this.dataStart + offset)); + return bswap(load(this.dataStart + offset)); } writeInt32LE(value: i32, offset: i32 = 0): i32 { @@ -134,7 +134,7 @@ export class Buffer extends Uint8Array { writeInt32BE(value: i32, offset: i32 = 0): i32 { if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - store(this.dataStart + offset, bswap(value)); + store(this.dataStart + offset, bswap(value)); return offset + 4; } @@ -146,7 +146,7 @@ export class Buffer extends Uint8Array { writeUInt32BE(value: u32, offset: i32 = 0): i32 { if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - store(this.dataStart + offset, bswap(value)); + store(this.dataStart + offset, bswap(value)); return offset + 4; } @@ -157,7 +157,7 @@ export class Buffer extends Uint8Array { readFloatBE(offset: i32 = 0): f32 { if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - return reinterpret(bswap(load(this.dataStart + offset))); + return reinterpret(bswap(load(this.dataStart + offset))); } writeFloatLE(value: f32, offset: i32 = 0): i32 { @@ -168,7 +168,7 @@ export class Buffer extends Uint8Array { writeFloatBE(value: f32, offset: i32 = 0): i32 { if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - store(this.dataStart + offset, bswap(reinterpret(value))); + store(this.dataStart + offset, bswap(reinterpret(value))); return offset + 4; } @@ -179,7 +179,7 @@ export class Buffer extends Uint8Array { readBigInt64BE(offset: i32 = 0): i64 { if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - return bswap(load(this.dataStart + offset)); + return bswap(load(this.dataStart + offset)); } readBigUInt64LE(offset: i32 = 0): u64 { @@ -189,7 +189,7 @@ export class Buffer extends Uint8Array { readBigUInt64BE(offset: i32 = 0): u64 { if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - return bswap(load(this.dataStart + offset)); + return bswap(load(this.dataStart + offset)); } writeBigInt64LE(value: i64, offset: i32 = 0): i32 { @@ -200,7 +200,7 @@ export class Buffer extends Uint8Array { writeBigInt64BE(value: i64, offset: i32 = 0): i32 { if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - store(this.dataStart + offset, bswap(value)); + store(this.dataStart + offset, bswap(value)); return offset + 8; } @@ -212,7 +212,7 @@ export class Buffer extends Uint8Array { writeBigUInt64BE(value: u64, offset: i32 = 0): i32 { if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - store(this.dataStart + offset, bswap(value)); + store(this.dataStart + offset, bswap(value)); return offset + 8; } @@ -223,7 +223,7 @@ export class Buffer extends Uint8Array { readDoubleBE(offset: i32 = 0): f64 { if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - return reinterpret(bswap(load(this.dataStart + offset))); + return reinterpret(bswap(load(this.dataStart + offset))); } writeDoubleLE(value: f64, offset: i32 = 0): i32 { @@ -234,7 +234,7 @@ export class Buffer extends Uint8Array { writeDoubleBE(value: f64, offset: i32 = 0): i32 { if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); - store(this.dataStart + offset, bswap(reinterpret(value))); + store(this.dataStart + offset, bswap(reinterpret(value))); return offset + 8; } @@ -245,12 +245,12 @@ export class Buffer extends Uint8Array { let dataStart = this.dataStart; dataLength += dataStart; while (dataStart < dataLength) { - store(dataStart, bswap(load(dataStart))); + store(dataStart, bswap(load(dataStart))); dataStart += 2; } return this; } - + swap32(): Buffer { let dataLength = this.dataLength; // Make sure dataLength is divisible by 4 @@ -258,12 +258,12 @@ export class Buffer extends Uint8Array { let dataStart = this.dataStart; dataLength += dataStart; while (dataStart < dataLength) { - store(dataStart, bswap(load(dataStart))); + store(dataStart, bswap(load(dataStart))); dataStart += 4; } return this; } - + swap64(): Buffer { let dataLength = this.dataLength; // Make sure dataLength is divisible by 8 @@ -271,7 +271,7 @@ export class Buffer extends Uint8Array { let dataStart = this.dataStart; dataLength += dataStart; while (dataStart < dataLength) { - store(dataStart, bswap(load(dataStart))); + store(dataStart, bswap(load(dataStart))); dataStart += 8; } return this; @@ -280,29 +280,20 @@ export class Buffer extends Uint8Array { export namespace Buffer { export namespace HEX { - /** Calculates the two char combination from the byte. */ - @inline export function charsFromByte(byte: u32): u32 { - let top = (byte >>> 4) & 0xF; - let bottom = (0xF & byte); - top += select(0x57, 0x30, top > 9); - bottom += select(0x57, 0x30, bottom > 9); - return (bottom << 16) | top; - } - /** Calculates the byte length of the specified string when encoded as HEX. */ export function byteLength(str: string): i32 { let ptr = changetype(str); let byteCount = changetype(changetype(str) - BLOCK_OVERHEAD).rtSize; let length = byteCount >> 2; // The string length must be even because the bytes come in pairs of characters two wide - if (byteCount & 0x3) return 0; // encoding fails and returns an empty ArrayBuffer + if (byteCount & 3) return 0; // encoding fails and returns an empty ArrayBuffer byteCount += ptr; while (ptr < byteCount) { var char = load(ptr); - if ( ((char - 0x30) <= 0x9) - || ((char - 0x61) <= 0x5) - || ((char - 0x41) <= 0x5)) { + if ( ((char - 0x30) <= 9) + || ((char - 0x61) <= 5) + || ((char - 0x41) <= 5)) { ptr += 2; continue; } else { @@ -325,15 +316,14 @@ export namespace Buffer { let b: u32 = 0; let outChar = 0; for (let i: usize = 0; ptr < byteEnd; i++) { - let odd = i & 1; - if (odd) { + if (i & 1) { outChar <<= 4; b >>>= 16; if ((b - 0x30) <= 9) { outChar |= b - 0x30; - } else if ((b - 0x61) <= 0x5) { + } else if ((b - 0x61) <= 5) { outChar |= b - 0x57; - } else if (b - 0x41 <= 0x5) { + } else if (b - 0x41 <= 5) { outChar |= b - 0x37; } store(result + (i >> 1), (outChar & 0xFF)); @@ -344,9 +334,9 @@ export namespace Buffer { let c = b & 0xFF; if ((c - 0x30) <= 9) { outChar |= c - 0x30; - } else if ((c - 0x61) <= 0x5) { + } else if ((c - 0x61) <= 5) { outChar |= c - 0x57; - } else if (c - 0x41 <= 0x5) { + } else if (c - 0x41 <= 5) { outChar |= c - 0x37; } } @@ -368,12 +358,20 @@ export namespace Buffer { // loop over each byte and store a `u32` for each one while (ptr < inputByteLength) { - store(result + i, charsFromByte(load(ptr))); + store(result + i, charsFromByte(load(ptr++))); i += 4; - ptr++; } return changetype(result); } + + /** Calculates the two char combination from the byte. */ + @inline function charsFromByte(byte: u32): u32 { + let hi = (byte >>> 4) & 0xF; + let lo = byte & 0xF; + hi += select(0x57, 0x30, hi > 9); + lo += select(0x57, 0x30, lo > 9); + return (lo << 16) | hi; + } } } From d3ac890cc43accd5eedbc7223962ddb26f64c3bd Mon Sep 17 00:00:00 2001 From: jtenner Date: Thu, 12 Mar 2020 14:43:40 -0400 Subject: [PATCH 15/17] Update to latest as-pect, fix compiler errors (#26) * update to latest as-pect, fix ArrayBufferView errors * add compiler errors detection for code exit * remove excess type info * fix up wasi * general cleanups * update to latest aspect and assemblyscript, remove index signatures, add in some unreachable tests * use promises to write files, optimize allocUnsafe --- assembly/buffer/index.ts | 146 +++++----- package-lock.json | 226 +++++++-------- package.json | 9 +- tests/buffer.spec.ts | 612 ++++++++++++++++++--------------------- tests/node.js | 73 +++-- 5 files changed, 532 insertions(+), 534 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 363ab5e..1c5a832 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -3,6 +3,8 @@ import { E_INVALIDLENGTH, E_INDEXOUTOFRANGE } from "util/error"; import { Uint8Array } from "typedarray"; export class Buffer extends Uint8Array { + [key: number]: u8; + constructor(size: i32) { super(size); } @@ -12,15 +14,18 @@ export class Buffer extends Uint8Array { } @unsafe static allocUnsafe(size: i32): Buffer { - // Node throws an error if size is less than 0 - if (size > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); + // range must be valid + if (size > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); let buffer = __alloc(size, idof()); - // This retains the pointer to the result Buffer. - let result = changetype(__alloc(offsetof(), idof())); - result.data = changetype(buffer); - result.dataStart = buffer; - result.dataLength = size; - return result; + let result = __alloc(offsetof(), idof()); + + // set the properties + store(result, __retain(buffer), offsetof("buffer")); + store(result, buffer, offsetof("dataStart")); + store(result, size, offsetof("byteLength")); + + // return and retain + return changetype(result); } static isBuffer(value: T): bool { @@ -29,222 +34,225 @@ export class Buffer extends Uint8Array { // Adapted from https://github.com/AssemblyScript/assemblyscript/blob/master/std/assembly/typedarray.ts subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Buffer { - var len = this.dataLength; + var len = this.byteLength; begin = begin < 0 ? max(len + begin, 0) : min(begin, len); end = end < 0 ? max(len + end, 0) : min(end, len); end = max(end, begin); - var out = changetype(__alloc(offsetof(), idof())); // retains - out.data = this.data; // retains - out.dataStart = this.dataStart + begin; - out.dataLength = end - begin; - return out; + + var out = __alloc(offsetof(), idof()); // retains + store(out, __retain(changetype(this.buffer)), offsetof("buffer")); + store(out, this.dataStart + begin, offsetof("dataStart")); + store(out, end - begin, offsetof("byteLength")); + + // retains + return changetype(out); } readInt8(offset: i32 = 0): i8 { - if (i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset >= this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readUInt8(offset: i32 = 0): u8 { - if (i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset >= this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } writeInt8(value: i8, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset >= this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 1; } writeUInt8(value: u8, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset >= this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 1; } readInt16LE(offset: i32 = 0): i16 { - if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readInt16BE(offset: i32 = 0): i16 { - if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return bswap(load(this.dataStart + offset)); } readUInt16LE(offset: i32 = 0): u16 { - if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readUInt16BE(offset: i32 = 0): u16 { - if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return bswap(load(this.dataStart + offset)); } writeInt16LE(value: i16, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 2; } writeInt16BE(value: i16, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, bswap(value)); return offset + 2; } writeUInt16LE(value: u16, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 2; } writeUInt16BE(value: u16, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, bswap(value)); return offset + 2; } readInt32LE(offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readInt32BE(offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return bswap(load(this.dataStart + offset)); } readUInt32LE(offset: i32 = 0): u32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readUInt32BE(offset: i32 = 0): u32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return bswap(load(this.dataStart + offset)); } writeInt32LE(value: i32, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 4; } writeInt32BE(value: i32, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, bswap(value)); return offset + 4; } writeUInt32LE(value: u32, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 4; } writeUInt32BE(value: u32, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, bswap(value)); return offset + 4; } readFloatLE(offset: i32 = 0): f32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readFloatBE(offset: i32 = 0): f32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return reinterpret(bswap(load(this.dataStart + offset))); } writeFloatLE(value: f32, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 4; } writeFloatBE(value: f32, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 4 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, bswap(reinterpret(value))); return offset + 4; } readBigInt64LE(offset: i32 = 0): i64 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readBigInt64BE(offset: i32 = 0): i64 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return bswap(load(this.dataStart + offset)); } readBigUInt64LE(offset: i32 = 0): u64 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readBigUInt64BE(offset: i32 = 0): u64 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return bswap(load(this.dataStart + offset)); } writeBigInt64LE(value: i64, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 8; } writeBigInt64BE(value: i64, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, bswap(value)); return offset + 8; } writeBigUInt64LE(value: u64, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 8; } writeBigUInt64BE(value: u64, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, bswap(value)); return offset + 8; } readDoubleLE(offset: i32 = 0): f64 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + offset); } readDoubleBE(offset: i32 = 0): f64 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); return reinterpret(bswap(load(this.dataStart + offset))); } writeDoubleLE(value: f64, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, value); return offset + 8; } writeDoubleBE(value: f64, offset: i32 = 0): i32 { - if (i32(offset < 0) | i32(offset + 8 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE); + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + offset, bswap(reinterpret(value))); return offset + 8; } swap16(): Buffer { - let dataLength = this.dataLength; - // Make sure dataLength is even - if (dataLength & 1) throw new RangeError(E_INVALIDLENGTH); + let byteLength = this.byteLength; + // Make sure byteLength is even + if (byteLength & 1) throw new RangeError(E_INVALIDLENGTH); let dataStart = this.dataStart; - dataLength += dataStart; - while (dataStart < dataLength) { + byteLength += dataStart; + while (dataStart < byteLength) { store(dataStart, bswap(load(dataStart))); dataStart += 2; } @@ -252,12 +260,12 @@ export class Buffer extends Uint8Array { } swap32(): Buffer { - let dataLength = this.dataLength; - // Make sure dataLength is divisible by 4 - if (dataLength & 3) throw new RangeError(E_INVALIDLENGTH); + let byteLength = this.byteLength; + // Make sure byteLength is divisible by 4 + if (byteLength & 3) throw new RangeError(E_INVALIDLENGTH); let dataStart = this.dataStart; - dataLength += dataStart; - while (dataStart < dataLength) { + byteLength += dataStart; + while (dataStart < byteLength) { store(dataStart, bswap(load(dataStart))); dataStart += 4; } @@ -265,12 +273,12 @@ export class Buffer extends Uint8Array { } swap64(): Buffer { - let dataLength = this.dataLength; - // Make sure dataLength is divisible by 8 - if (dataLength & 7) throw new RangeError(E_INVALIDLENGTH); + let byteLength = this.byteLength; + // Make sure byteLength is divisible by 8 + if (byteLength & 7) throw new RangeError(E_INVALIDLENGTH); let dataStart = this.dataStart; - dataLength += dataStart; - while (dataStart < dataLength) { + byteLength += dataStart; + while (dataStart < byteLength) { store(dataStart, bswap(load(dataStart))); dataStart += 8; } @@ -283,8 +291,8 @@ export namespace Buffer { /** Calculates the byte length of the specified string when encoded as HEX. */ export function byteLength(str: string): i32 { let ptr = changetype(str); - let byteCount = changetype(changetype(str) - BLOCK_OVERHEAD).rtSize; - let length = byteCount >> 2; + let byteCount = changetype(changetype(str) - BLOCK_OVERHEAD).rtSize; + let length = byteCount >>> 2; // The string length must be even because the bytes come in pairs of characters two wide if (byteCount & 3) return 0; // encoding fails and returns an empty ArrayBuffer @@ -300,7 +308,7 @@ export namespace Buffer { return 0; } } - return length; + return length; } /** Creates an ArrayBuffer from a given string that is encoded in the HEX format. */ @@ -311,7 +319,7 @@ export namespace Buffer { // long path: loop over each enociding pair and perform the conversion let ptr = changetype(str); - let byteEnd = changetype(changetype(str) - BLOCK_OVERHEAD).rtSize + ptr; + let byteEnd = ptr + changetype(changetype(str) - BLOCK_OVERHEAD).rtSize; let result = __alloc(bufferLength, idof()); let b: u32 = 0; let outChar = 0; diff --git a/package-lock.json b/package-lock.json index 05a35d2..411d808 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,49 +5,57 @@ "requires": true, "dependencies": { "@as-pect/assembly": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@as-pect/assembly/-/assembly-2.3.1.tgz", - "integrity": "sha512-KYBhyTEnaVcJjN/1EpzLhpbUHKT3pJjCPxm+Mdc7obnZ9EdVz6vN/lw+BQjeL4cUi1YLsnvgl8ftXcup5jVbQA==", + "version": "3.1.0-beta.3", + "resolved": "https://registry.npmjs.org/@as-pect/assembly/-/assembly-3.1.0-beta.3.tgz", + "integrity": "sha512-NYMzh8c4mloGJHQEyEz7Gw4DFKDjepyuSkojca0agSOVsjJcaTy6DtM42Lq7DTLwNoM4xt+YI7nQNTWcrhhHGw==", "dev": true }, "@as-pect/core": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@as-pect/core/-/core-2.3.1.tgz", - "integrity": "sha512-iwd4MkGuO1wZqo9/sPlT567XYK0PkMLzBvwfkXOM2zq1wwuc5GZQrKoofgYorA40KI0edJW39djtOmPwIhx2vA==", + "version": "3.1.0-beta.3", + "resolved": "https://registry.npmjs.org/@as-pect/core/-/core-3.1.0-beta.3.tgz", + "integrity": "sha512-/i3wzOYEvvzECRKLPWm7FGKnPgtD6RdaPFWAT6nA4OHtsHdHz2BvvGdCecheLRG3GoRk00LfCSRB8/L3IJnS/A==", "dev": true, "requires": { - "@as-pect/assembly": "^2.3.1", - "chalk": "^2.4.2", - "csv-stringify": "^5.3.0", + "@as-pect/assembly": "^3.1.0-beta.3", + "@as-pect/snapshots": "^3.1.0-beta.3", + "chalk": "^3.0.0", "long": "^4.0.0" } }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", + "@as-pect/snapshots": { + "version": "3.1.0-beta.3", + "resolved": "https://registry.npmjs.org/@as-pect/snapshots/-/snapshots-3.1.0-beta.3.tgz", + "integrity": "sha512-hL+a3/ByQQAhLLVsY9Qtd0eAb9UTZbMeJyh4mKQQS4X9KXhpVHADjoK31PbOlM+E3TUbR/KbZFFPu2Z79T3How==", + "dev": true, + "requires": { + "diff": "^4.0.2", + "nearley": "^2.19.1" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, "assemblyscript": { - "version": "github:assemblyscript/assemblyscript#227c626921175ab19701752397fa513171750d38", - "from": "github:assemblyscript/assemblyscript", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.9.3.tgz", + "integrity": "sha512-5Mm15oLOi4Uj/N9h2uGuy4U2zFpaOQuP3kcRuFYiTchuvKIpyqqihMm+e7P6VaTLzPnN+oIRwn1KjTyo4aSw1A==", "dev": true, "requires": { - "@protobufjs/utf8": "^1.1.0", - "binaryen": "87.0.0-nightly.20190716", - "glob": "^7.1.4", - "long": "^4.0.0", - "opencollective-postinstall": "^2.0.0", - "source-map-support": "^0.5.12" + "binaryen": "91.0.0-nightly.20200310", + "long": "^4.0.0" } }, "balanced-match": { @@ -57,20 +65,11 @@ "dev": true }, "binaryen": { - "version": "87.0.0-nightly.20190716", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-87.0.0-nightly.20190716.tgz", - "integrity": "sha512-qRGfV8cLV4HVVo1oUCtTaDmOhbwctaW7vyW0G6HKftywWOJI9t9IsCrUEFKya50RqyEnanuS2w3nfOg4bxTGqg==", + "version": "91.0.0-nightly.20200310", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-91.0.0-nightly.20200310.tgz", + "integrity": "sha512-MmDzq267aa61HdEQeYiz+7guJlsYk2/6NxWC8I4w1jijqDwoqyZZxi7UYnTH7QvfLrNdMjweEgfT7FHjkvkPmQ==", "dev": true }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -81,36 +80,35 @@ "concat-map": "0.0.1" } }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, "concat-map": { @@ -119,26 +117,16 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "csv-stringify": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.3.0.tgz", - "integrity": "sha512-VMYPbE8zWz475smwqb9VbX9cj0y4J0PBl59UdcqzLkzXHZZ8dh4Rmbb0ZywsWEtUml4A96Hn7Q5MW9ppVghYzg==", - "dev": true, - "optional": true, - "requires": { - "lodash.get": "~4.4.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, - "file-uri-to-path": { + "discontinuous-range": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=", "dev": true }, "fs.realpath": { @@ -148,9 +136,9 @@ "dev": true }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -162,9 +150,9 @@ } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "inflight": { @@ -183,13 +171,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true, - "optional": true - }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -205,6 +186,25 @@ "brace-expansion": "^1.1.7" } }, + "moo": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", + "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==", + "dev": true + }, + "nearley": { + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.1.tgz", + "integrity": "sha512-xq47GIUGXxU9vQg7g/y1o1xuKnkO7ev4nRWqftmQrLkfnE/FjRqDaGOUakM8XHPn/6pW3bGjU2wgoJyId90rqg==", + "dev": true, + "requires": { + "commander": "^2.19.0", + "moo": "^0.5.0", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6", + "semver": "^5.4.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -214,49 +214,47 @@ "wrappy": "1" } }, - "opencollective-postinstall": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", - "dev": true - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", + "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=", "dev": true }, - "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "randexp": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true }, - "wasi": { - "version": "github:devsnek/node-wasi#12a0985a46589587facd8d8e161911650ef15f3b", - "from": "github:devsnek/node-wasi", + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, "requires": { - "bindings": "^1.5.0" + "has-flag": "^4.0.0" } }, "wrappy": { diff --git a/package.json b/package.json index ff4bc6b..0b5ba7b 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,12 @@ "url": "https://github.com/AssemblyScript/node/issues" }, "devDependencies": { - "@as-pect/core": "^2.3.1", - "assemblyscript": "github:assemblyscript/assemblyscript", - "glob": "^7.1.4", - "wasi": "github:devsnek/node-wasi" + "@as-pect/core": "^3.1.0-beta.3", + "assemblyscript": "0.9.3", + "glob": "^7.1.6" }, "scripts": { - "test": "node tests/node" + "test": "node --experimental-wasi-unstable-preview1 tests/node" }, "dependencies": {} } diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index c508a08..b7681a4 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -22,34 +22,37 @@ function create(values: valueof[]): T { describe("buffer", () => { test("#constructor", () => { - expect(new Buffer(0)).toBeTruthy(); - expect(new Buffer(10)).toHaveLength(10); + expect(new Buffer(0)).toBeTruthy(); + expect(new Buffer(10)).toHaveLength(10); let myBuffer = new Buffer(10); - expect(myBuffer.buffer).toBeTruthy(); - expect(myBuffer.buffer).toHaveLength(10); - // TODO: expectFn(() => { new Buffer(-1); }).toThrow(); - // TODO: expectFn(() => { new Buffer(BLOCK_MAXSIZE + 1); }).toThrow(); + expect(myBuffer.buffer).toBeTruthy(); + expect(myBuffer.buffer).toHaveLength(10); + expect(() => { new Buffer(-1); }).toThrow(); + // TODO: figure out how to test block maxsize + // expect(() => { new Buffer(1 + BLOCK_MAXSIZE); }).toThrow(); }); test("#alloc", () => { - expect(Buffer.alloc(10)).toBeTruthy(); - expect(Buffer.alloc(10)).toHaveLength(10); + 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); - expect(buff.buffer).not.toBeNull(); - expect(buff.byteLength).toBe(100); - // TODO: expectFn(() => { Buffer.alloc(-1); }).toThrow(); - // TODO: expectFn(() => { Buffer.alloc(BLOCK_MAXSIZE + 1); }).toThrow(); + expect(buff.buffer).not.toBeNull(); + expect(buff.byteLength).toBe(100); + expect(() => { Buffer.alloc(-1); }).toThrow(); + // TODO: figure out how to test block maxsize + // expect(() => { Buffer.alloc(1 + BLOCK_MAXSIZE); }).toThrow(); }); test("#allocUnsafe", () => { - expect(Buffer.allocUnsafe(10)).toBeTruthy(); - expect(Buffer.allocUnsafe(10)).toHaveLength(10); + expect(Buffer.allocUnsafe(10)).toBeTruthy(); + expect(Buffer.allocUnsafe(10)).toHaveLength(10); let buff = Buffer.allocUnsafe(100); - expect(buff.buffer).not.toBeNull(); - expect(buff.byteLength).toBe(100); - // TODO: expectFn(() => { Buffer.allocUnsafe(-1); }).toThrow(); - // TODO: expectFn(() => { Buffer.allocUnsafe(BLOCK_MAXSIZE + 1); }).toThrow(); + expect(buff.buffer).not.toBeNull(); + expect(buff.byteLength).toBe(100); + expect(() => { Buffer.allocUnsafe(-1); }).toThrow(); + // TODO: figure out how to test block maxsize + // expect(() => { Buffer.allocUnsafe(BLOCK_MAXSIZE + 1); }).toThrow(); }); test("#isBuffer", () => { @@ -58,448 +61,414 @@ describe("buffer", () => { let c = 0; let d = 1.1; let e = new Buffer(0); - expect(Buffer.isBuffer(a)).toBeFalsy(); - expect(Buffer.isBuffer(b)).toBeFalsy(); - expect(Buffer.isBuffer(c)).toBeFalsy(); - expect(Buffer.isBuffer(d)).toBeFalsy(); - expect(Buffer.isBuffer(e)).toBeTruthy(); - // null checks are done by the compiler explicitly at runtime - expect(Buffer.isBuffer(null)).toBeFalsy(); + let f: Buffer | null = null; + + expect(Buffer.isBuffer(a)).toBeFalsy(); + expect(Buffer.isBuffer(b)).toBeFalsy(); + expect(Buffer.isBuffer(c)).toBeFalsy(); + expect(Buffer.isBuffer(d)).toBeFalsy(); + expect(Buffer.isBuffer(e)).toBeTruthy(); + expect(Buffer.isBuffer(f)).toBeFalsy(); }); test("#readInt8", () => { let buff = create([0x5,0x0,0x0,0x0,0xFF]); - expect(buff.readInt8()).toBe(5); + expect(buff.readInt8()).toBe(5); // Testing offset, and casting between u8 and i8. - expect(buff.readInt8(4)).toBe(-1); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readInt8(5); - // }).toThrow(); + expect(buff.readInt8(4)).toBe(-1); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readInt8(5); + }).toThrow(); }); test("#readUInt8", () => { let buff = create([0xFE,0x0,0x0,0x0,0x2F]); // Testing casting between u8 and i8. - expect(buff.readUInt8()).toBe(254); + expect(buff.readUInt8()).toBe(254); // Testing offset - expect(buff.readUInt8(4)).toBe(47); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readUInt8(5); - // }).toThrow(); + expect(buff.readUInt8(4)).toBe(47); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readUInt8(5); + }).toThrow(); }); test("#writeInt8", () => { let buff = new Buffer(5); - expect(buff.writeInt8(9)).toBe(1); - expect(buff.writeInt8(-3,4)).toBe(5); + expect(buff.writeInt8(9)).toBe(1); + expect(buff.writeInt8(-3,4)).toBe(5); let result = create([0x09, 0x0, 0x0, 0x0, 0xFD]); - expect(buff).toStrictEqual(result); + expect(buff).toStrictEqual(result); // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeInt8(5,10); - // }).toThrow(); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeInt8(5,10); + }).toThrow(); }); test("#writeUInt8", () => { let buff = new Buffer(5); - expect(buff.writeUInt8(4)).toBe(1); - expect(buff.writeUInt8(252,4)).toBe(5); + expect(buff.writeUInt8(4)).toBe(1); + expect(buff.writeUInt8(252,4)).toBe(5); let result = create([0x04, 0x0, 0x0, 0x0, 0xFC]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeUInt8(5,10); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeUInt8(5,10); + }).toThrow(); }); test("#readInt16LE", () => { let buff = create([0x0,0x05,0x0]); - expect(buff.readInt16LE()).toBe(1280); - expect(buff.readInt16LE(1)).toBe(5); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readInt16LE(0); - // }).toThrow(); + expect(buff.readInt16LE()).toBe(1280); + expect(buff.readInt16LE(1)).toBe(5); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readInt16LE(0); + }).toThrow(); }); test("#readInt16BE", () => { let buff = create([0x0,0x05,0x0]); - expect(buff.readInt16BE()).toBe(5); - expect(buff.readInt16BE(1)).toBe(1280); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readInt16BE(0); - // }).toThrow(); + expect(buff.readInt16BE()).toBe(5); + expect(buff.readInt16BE(1)).toBe(1280); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readInt16BE(0); + }).toThrow(); }); test("#readUInt16LE", () => { let buff = create([0x0,0x05,0x0]); - expect(buff.readUInt16LE()).toBe(1280); - expect(buff.readUInt16LE(1)).toBe(5); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readUInt16LE(0); - // }).toThrow(); + expect(buff.readUInt16LE()).toBe(1280); + expect(buff.readUInt16LE(1)).toBe(5); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readUInt16LE(0); + }).toThrow(); }); test("#readUInt16BE", () => { let buff = create([0x0,0x05,0x0]); - expect(buff.readUInt16BE()).toBe(5); - expect(buff.readUInt16BE(1)).toBe(1280); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readUInt16BE(0); - // }).toThrow(); + expect(buff.readUInt16BE()).toBe(5); + expect(buff.readUInt16BE(1)).toBe(1280); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readUInt16BE(0); + }).toThrow(); }); test("#writeInt16LE", () => { let buff = new Buffer(4); - expect(buff.writeInt16LE(5)).toBe(2); - expect(buff.writeInt16LE(1280,2)).toBe(4); + expect(buff.writeInt16LE(5)).toBe(2); + expect(buff.writeInt16LE(1280,2)).toBe(4); let result = create([0x05, 0x0, 0x0, 0x5]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeInt16LE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeInt16LE(0); + }).toThrow(); }); test("#writeInt16BE", () => { let buff = new Buffer(4); - expect(buff.writeInt16BE(1280)).toBe(2); - expect(buff.writeInt16BE(5,2)).toBe(4); + expect(buff.writeInt16BE(1280)).toBe(2); + expect(buff.writeInt16BE(5,2)).toBe(4); let result = create([0x05, 0x0, 0x0, 0x5]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeInt16BE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeInt16BE(0); + }).toThrow(); }); test("#writeUInt16LE", () => { let buff = new Buffer(4); - expect(buff.writeUInt16LE(5)).toBe(2); - expect(buff.writeUInt16LE(1280,2)).toBe(4); + expect(buff.writeUInt16LE(5)).toBe(2); + expect(buff.writeUInt16LE(1280,2)).toBe(4); let result = create([0x05, 0x0, 0x0, 0x5]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeUInt16LE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeUInt16LE(0); + }).toThrow(); }); test("#writeUInt16BE", () => { let buff = new Buffer(4); - expect(buff.writeUInt16BE(1280)).toBe(2); - expect(buff.writeUInt16BE(5,2)).toBe(4); + expect(buff.writeUInt16BE(1280)).toBe(2); + expect(buff.writeUInt16BE(5,2)).toBe(4); let result = create([0x05, 0x0, 0x0, 0x5]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeUInt16BE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeUInt16BE(0); + }).toThrow(); }); test("#readInt32LE", () => { let buff = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]); - expect(buff.readInt32LE()).toBe(-559038737); - expect(buff.readInt32LE(4)).toBe(283033613); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readInt32LE(0); - // }).toThrow(); + expect(buff.readInt32LE()).toBe(-559038737); + expect(buff.readInt32LE(4)).toBe(283033613); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readInt32LE(0); + }).toThrow(); }); test("#readInt32BE", () => { let buff = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); - expect(buff.readInt32BE()).toBe(-559038737); - expect(buff.readInt32BE(4)).toBe(283033613); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readInt32BE(0); - // }).toThrow(); + expect(buff.readInt32BE()).toBe(-559038737); + expect(buff.readInt32BE(4)).toBe(283033613); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readInt32BE(0); + }).toThrow(); }); test("#readUInt32LE", () => { let buff = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]); - expect(buff.readUInt32LE()).toBe(3735928559); - expect(buff.readUInt32LE(4)).toBe(283033613); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readUInt32LE(0); - // }).toThrow(); + expect(buff.readUInt32LE()).toBe(3735928559); + expect(buff.readUInt32LE(4)).toBe(283033613); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readUInt32LE(0); + }).toThrow(); }); test("#readUInt32BE", () => { let buff = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); - expect(buff.readUInt32BE()).toBe(3735928559); - expect(buff.readUInt32BE(4)).toBe(283033613); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readUInt32BE(0); - // }).toThrow(); + expect(buff.readUInt32BE()).toBe(3735928559); + expect(buff.readUInt32BE(4)).toBe(283033613); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readUInt32BE(0); + }).toThrow(); }); test("#writeInt32LE", () => { let buff = new Buffer(8); - expect(buff.writeInt32LE(-559038737)).toBe(4); - expect(buff.writeInt32LE(283033613,4)).toBe(8); + 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); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeInt32LE(0); - // }).toThrow(); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeInt32LE(0); + }).toThrow(); }); test("#writeInt32BE", () => { let buff = new Buffer(8); - expect(buff.writeInt32BE(-559038737)).toBe(4); - expect(buff.writeInt32BE(283033613,4)).toBe(8); + expect(buff.writeInt32BE(-559038737)).toBe(4); + expect(buff.writeInt32BE(283033613,4)).toBe(8); let result = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeInt32BE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeInt32BE(0); + }).toThrow(); }); test("#writeUInt32LE", () => { let buff = new Buffer(8); - expect(buff.writeUInt32LE(3735928559)).toBe(4); - expect(buff.writeUInt32LE(283033613,4)).toBe(8); + expect(buff.writeUInt32LE(3735928559)).toBe(4); + expect(buff.writeUInt32LE(283033613,4)).toBe(8); let result = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]);; - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeUInt32LE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeUInt32LE(0); + }).toThrow(); }); test("#writeUInt32BE", () => { let buff = new Buffer(8); - expect(buff.writeUInt32BE(3735928559)).toBe(4); - expect(buff.writeUInt32BE(283033613,4)).toBe(8); + expect(buff.writeUInt32BE(3735928559)).toBe(4); + expect(buff.writeUInt32BE(283033613,4)).toBe(8); let result = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeUInt32BE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeUInt32BE(0); + }).toThrow(); }); test("#readFloatLE", () => { let buff = create([0xbb,0xfe,0x4a,0x4f,0x01,0x02,0x03,0x04]); - expect(buff.readFloatLE()).toBe(0xcafebabe); - expect(buff.readFloatLE(4)).toBe(1.539989614439558e-36); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readFloatLE(0); - // }).toThrow(); + expect(buff.readFloatLE()).toBe(0xcafebabe); + expect(buff.readFloatLE(4)).toBe(1.539989614439558e-36); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readFloatLE(0); + }).toThrow(); }); test("#readFloatBE", () => { let buff = create([0x4f,0x4a,0xfe,0xbb,0x01,0x02,0x03,0x04]); - expect(buff.readFloatBE()).toBe(0xcafebabe); - expect(buff.readFloatBE(4)).toBe(2.387939260590663e-38); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readFloatBE(0); - // }).toThrow(); + expect(buff.readFloatBE()).toBe(0xcafebabe); + expect(buff.readFloatBE(4)).toBe(2.387939260590663e-38); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readFloatBE(0); + }).toThrow(); }); test("#writeFloatLE", () => { let buff = new Buffer(8); - expect(buff.writeFloatLE(0xcafebabe)).toBe(4); - expect(buff.writeFloatLE(1.539989614439558e-36,4)).toBe(8); + expect(buff.writeFloatLE(0xcafebabe)).toBe(4); + expect(buff.writeFloatLE(1.539989614439558e-36,4)).toBe(8); let result = create([0xbb,0xfe,0x4a,0x4f,0x01,0x02,0x03,0x04]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeFloatLE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeFloatLE(0); + }).toThrow(); }); test("#writeFloatBE", () => { let buff = new Buffer(8); - expect(buff.writeFloatBE(0xcafebabe)).toBe(4); - expect(buff.writeFloatBE(2.387939260590663e-38,4)).toBe(8); + expect(buff.writeFloatBE(0xcafebabe)).toBe(4); + expect(buff.writeFloatBE(2.387939260590663e-38,4)).toBe(8); let result = create([0x4f,0x4a,0xfe,0xbb,0x01,0x02,0x03,0x04]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeFloatBE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeFloatBE(0); + }).toThrow(); }); test("#readBigInt64LE", () => { let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); - expect(buff.readBigInt64LE()).toBe(-4294967296); - expect(buff.readBigInt64LE(8)).toBe(4294967295); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readBigInt64LE(0); - // }).toThrow(); + expect(buff.readBigInt64LE()).toBe(-4294967296); + expect(buff.readBigInt64LE(8)).toBe(4294967295); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readBigInt64LE(0); + }).toThrow(); }); test("#readBigInt64BE", () => { let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); - expect(buff.readBigInt64BE()).toBe(4294967295); - expect(buff.readBigInt64BE(8)).toBe(-4294967296); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readBigInt64BE(0); - // }).toThrow(); + expect(buff.readBigInt64BE()).toBe(4294967295); + expect(buff.readBigInt64BE(8)).toBe(-4294967296); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readBigInt64BE(0); + }).toThrow(); }); test("#readBigUInt64LE", () => { let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); - expect(buff.readBigUInt64LE()).toBe(18446744069414584320); - expect(buff.readBigUInt64LE(8)).toBe(4294967295); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readBigUInt64LE(0); - // }).toThrow(); + expect(buff.readBigUInt64LE()).toBe(18446744069414584320); + expect(buff.readBigUInt64LE(8)).toBe(4294967295); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readBigUInt64LE(0); + }).toThrow(); }); test("#readBigUInt64BE", () => { let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); - expect(buff.readBigUInt64BE()).toBe(4294967295); - expect(buff.readBigUInt64BE(8)).toBe(18446744069414584320); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readBigUInt64BE(0); - // }).toThrow(); + expect(buff.readBigUInt64BE()).toBe(4294967295); + expect(buff.readBigUInt64BE(8)).toBe(18446744069414584320); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readBigUInt64BE(0); + }).toThrow(); }); test("#writeBigInt64LE", () => { let buff = new Buffer(16); - expect(buff.writeBigInt64LE(-559038737)).toBe(8); - expect(buff.writeBigInt64LE(283033613,8)).toBe(16); + expect(buff.writeBigInt64LE(-559038737)).toBe(8); + expect(buff.writeBigInt64LE(283033613,8)).toBe(16); let result = create([0xEF,0xBE,0xAD,0xDE,0xFF,0xFF,0xFF,0xFF,0x0d,0xc0,0xde,0x10,0x00,0x00,0x00,0x00]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeBigInt64LE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeBigInt64LE(0); + }).toThrow(); }); test("#writeBigInt64BE", () => { let buff = new Buffer(16); - expect(buff.writeBigInt64BE(-559038737)).toBe(8); - expect(buff.writeBigInt64BE(283033613,8)).toBe(16); + expect(buff.writeBigInt64BE(-559038737)).toBe(8); + expect(buff.writeBigInt64BE(283033613,8)).toBe(16); let result = create([0xFF,0xFF,0xFF,0xFF,0xDE,0xAD,0xBE,0xEF,0x00,0x00,0x00,0x00,0x10,0xde,0xc0,0x0d]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeBigInt64BE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeBigInt64BE(0); + }).toThrow(); }); test("#writeBigUInt64LE", () => { let buff = new Buffer(16); - expect(buff.writeBigUInt64LE(3735928559)).toBe(8); - expect(buff.writeBigUInt64LE(283033613,8)).toBe(16); + expect(buff.writeBigUInt64LE(3735928559)).toBe(8); + expect(buff.writeBigUInt64LE(283033613,8)).toBe(16); let result = create([0xEF,0xBE,0xAD,0xDE,0x00,0x00,0x00,0x00,0x0d,0xc0,0xde,0x10,0x00,0x00,0x00,0x00]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeBigUInt64LE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeBigUInt64LE(0); + }).toThrow(); }); test("#writeBigUInt64BE", () => { let buff = new Buffer(16); - expect(buff.writeBigUInt64BE(3735928559)).toBe(8); - expect(buff.writeBigUInt64BE(283033613,8)).toBe(16); + expect(buff.writeBigUInt64BE(3735928559)).toBe(8); + expect(buff.writeBigUInt64BE(283033613,8)).toBe(16); let result = create([0x00,0x00,0x00,0x00,0xDE,0xAD,0xBE,0xEF,0x00,0x00,0x00,0x00,0x10,0xde,0xc0,0x0d]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeBigUInt64BE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeBigUInt64BE(0); + }).toThrow(); }); test("#readDoubleLE", () => { let buff = create([0x77, 0xbe, 0x9f, 0x1a, 0x2f, 0xdd, 0x5e, 0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); - expect(buff.readDoubleLE()).toBe(123.456); - expect(buff.readDoubleLE(8)).toBe(5.447603722011605e-270); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readDoubleLE(0); - // }).toThrow(); + expect(buff.readDoubleLE()).toBe(123.456); + expect(buff.readDoubleLE(8)).toBe(5.447603722011605e-270); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readDoubleLE(0); + }).toThrow(); }); test("#readDoubleBE", () => { let buff = create([0x40, 0x5e, 0xdd, 0x2f, 0x1a, 0x9f, 0xbe, 0x77, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); - expect(buff.readDoubleBE()).toBe(123.456); - expect(buff.readDoubleBE(8)).toBe(8.20788039913184e-304); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.readDoubleBE(0); - // }).toThrow(); + expect(buff.readDoubleBE()).toBe(123.456); + expect(buff.readDoubleBE(8)).toBe(8.20788039913184e-304); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readDoubleBE(0); + }).toThrow(); }); test("#writeDoubleLE", () => { let buff = new Buffer(16); - expect(buff.writeDoubleLE(123.456)).toBe(8); - expect(buff.writeDoubleLE(5.447603722011605e-270,8)).toBe(16); + expect(buff.writeDoubleLE(123.456)).toBe(8); + expect(buff.writeDoubleLE(5.447603722011605e-270,8)).toBe(16); let result = create([0x77, 0xbe, 0x9f, 0x1a, 0x2f, 0xdd, 0x5e, 0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeDoubleLE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeDoubleLE(0); + }).toThrow(); }); test("#writeDoubleBE", () => { let buff = new Buffer(16); - expect(buff.writeDoubleBE(123.456)).toBe(8); - expect(buff.writeDoubleBE(8.20788039913184e-304,8)).toBe(16); + expect(buff.writeDoubleBE(123.456)).toBe(8); + expect(buff.writeDoubleBE(8.20788039913184e-304,8)).toBe(16); let result = create([0x40, 0x5e, 0xdd, 0x2f, 0x1a, 0x9f, 0xbe, 0x77, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); - expect(buff).toStrictEqual(result); - // TODO: - // expectFn(() => { - // let newBuff = new Buffer(1); - // newBuff.writeDoubleBE(0); - // }).toThrow(); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeDoubleBE(0); + }).toThrow(); }); test("#subarray", () => { @@ -507,81 +476,78 @@ describe("buffer", () => { // no parameters means copy the Buffer let actual = example.subarray(); - expect(actual).toStrictEqual(example); - expect(actual.buffer).toBe(example.buffer); // should use the same buffer + expect(actual).toStrictEqual(example); + expect(actual.buffer).toBe(example.buffer); // should use the same buffer // start at offset 5 actual = example.subarray(5); let expected = create([6, 7, 8]); // trace("length", 1, expected.length); - expect(actual).toStrictEqual(expected); + expect(actual).toStrictEqual(expected); // negative start indicies, start at (8 - 5) actual = example.subarray(-5); expected = create([4, 5, 6, 7, 8]); - expect(actual).toStrictEqual(expected); + expect(actual).toStrictEqual(expected); // two parameters actual = example.subarray(2, 6); expected = create([3, 4, 5, 6]); - expect(actual).toStrictEqual(expected); + expect(actual).toStrictEqual(expected); // negative end index actual = example.subarray(4, -1); expected = create([5, 6, 7]); - expect(actual).toStrictEqual(expected); + expect(actual).toStrictEqual(expected); }); test("#swap16", () => { let actual = create([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); let expected = create([0x2, 0x1, 0x4, 0x3, 0x6, 0x5, 0x8, 0x7]); let swapped = actual.swap16(); - expect(actual).toStrictEqual(expected); - expect(swapped).toBe(actual); - // TODO: - // expectFn(() => { - // let newBuff = create([0x1, 0x2, 0x3]); - // newBuff.swap16(); - // }).toThrow(); + expect(actual).toStrictEqual(expected); + expect(swapped).toBe(actual); + expect(() => { + let newBuff = create([0x1, 0x2, 0x3]); + newBuff.swap16(); + }).toThrow(); }); test("#swap32", () => { let actual = create([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); let expected = create([0x4, 0x3, 0x2, 0x1, 0x8, 0x7, 0x6, 0x5]); let swapped = actual.swap32(); - expect(actual).toStrictEqual(expected); - expect(swapped).toBe(actual); - // TODO: - // expectFn(() => { - // let newBuff = create([0x1, 0x2, 0x3]); - // newBuff.swap64(); - // }).toThrow(); + expect(actual).toStrictEqual(expected); + expect(swapped).toBe(actual); + expect(() => { + let newBuff = create([0x1, 0x2, 0x3]); + newBuff.swap64(); + }).toThrow(); }); test("#swap64", () => { let actual = create([0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf]); let expected = create([0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0, 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8]); let swapped = actual.swap64(); - expect(actual).toStrictEqual(expected); - expect(swapped).toBe(actual); - // TODO: - // expectFn(() => { - // let newBuff = create([0x1, 0x2, 0x3]); - // newBuff.swap64(); - // }).toThrow(); + expect(actual).toStrictEqual(expected); + expect(swapped).toBe(actual); + expect(() => { + let newBuff = create([0x1, 0x2, 0x3]); + newBuff.swap64(); + }).toThrow(); }); - + test("#Hex.encode", () => { let actual = "000102030405060708090a0b0c0d0e0f102030405060708090a0b0c0d0e0f0"; let exampleBuffer = create([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(encoded).toStrictEqual(exampleBuffer.buffer); + expect(encoded).toStrictEqual(exampleBuffer.buffer); }); test("#Hex.decode", () => { let expected = "000102030405060708090a0b0c0d0e0f102030405060708090a0b0c0d0e0f0"; let exampleBuffer = create([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(decoded).toStrictEqual(expected); + expect(decoded).toStrictEqual(expected); }); }); diff --git a/tests/node.js b/tests/node.js index c652c1e..6c9e25f 100644 --- a/tests/node.js +++ b/tests/node.js @@ -1,12 +1,13 @@ const { TestContext, VerboseReporter } = require("@as-pect/core"); -const { instantiateBuffer } = require("assemblyscript/lib/loader"); const glob = require("glob"); +const { instantiateSync } = require("assemblyscript/lib/loader"); const { main } = require("assemblyscript/cli/asc"); const { parse } = require("assemblyscript/cli/util/options"); const path = require("path"); -const fs = require("fs"); -const Wasi = require("wasi"); -const wasi = new Wasi({}); +const fs = require("fs").promises; +const { WASI } = require("wasi"); + +const promises = []; let pass = true; const options = parse(process.argv.slice(2), { @@ -28,6 +29,8 @@ if (options.unknown.length > 1) { } const reporter = new VerboseReporter(); +reporter.stderr = process.stderr; +reporter.stdout = process.stdout; function relativeFromCwd(location) { return path.relative(process.cwd(), location); @@ -38,9 +41,9 @@ const ascOptions = [ "--use", "ASC_RTRACE=1", "--explicitStart", "--validate", - "--debug", "--measure", "--lib", "assembly", + "--transform", require.resolve("@as-pect/core/lib/transform/index.js"), ]; const files = glob.sync("tests/**/*.spec.ts") @@ -74,10 +77,15 @@ for (const file of files) { const ext = path.extname(file); const wasmFileName = path.join(path.dirname(file), path.basename(file, ext)) + ".wasm"; const watFileName = path.join(path.dirname(file), path.basename(file, ext)) + ".wat"; - const cliOptions = ascOptions.concat([file, "--binaryFile", wasmFileName, "--textFile", watFileName]); + + const cliOptions = ascOptions.concat([ + file, + "--binaryFile", wasmFileName, + "--textFile", watFileName, + ]); process.stdout.write("Test File : " + file + " (untouched)\n"); - main(cliOptions, untouchedAscOptions, (err) => { + main(cliOptions.concat(["--debug"]), untouchedAscOptions, (err) => { if (err) { console.error(err); errors.push(err); @@ -104,30 +112,49 @@ for (const file of files) { process.stdout.write("\n"); } -function runTest(file, type, binary, wat) { - const watPath = path.join(path.dirname(file), path.basename(file, ".ts")) - + "." + type + ".wat"; +function runTest(fileName, type, binary, wat) { + const dirname = path.dirname(fileName); + const basename = path.basename(fileName, ".ts"); + const fullName = path.join(dirname, basename) + const watPath = `${fullName}.${type}.wat`; + const fileNamePath = `${fullName}.${type}.ts`; // should not block testing - fs.writeFile(watPath, wat, (err) => { - if (err) console.warn(err); - }); + promises.push(fs.writeFile(watPath, wat)); const context = new TestContext({ - fileName: file, - reporter, - stderr: process.stderr, - stdout: process.stdout, + fileName: fileNamePath, // set the fileName + reporter, // use verbose reporter + binary, // pass the binary to get function names + }); + const wasi = new WASI({ + args: [], + env: {}, + preopens: { + // '/sandbox': '/some/real/path/that/wasm/can/access' + } }); const imports = context.createImports({ - wasi_unstable: wasi.exports, + wasi_snapshot_preview1: wasi.wasiImport, }); - const wasm = instantiateBuffer(binary, imports); - wasi.setMemory(wasm.memory); - wasi.view = new DataView(wasm.memory.buffer); - context.run(wasm); + + const instance = instantiateSync(binary, imports); + // TODO: wasi.start(instance); + process.stdout.write("\n"); + context.run(instance); if (!context.pass) pass = false; } -process.exit(pass ? 0 : 1); +// await for all the file writes to occur for the wat files +Promise.all(promises) + .then(() => { + // if the file writes were successful, inspect errors and pass + process.exit(pass && errors.length === 0 ? 0 : 1); + }) + .catch((error) => { + // report the file write error and exit 1 + console.error(error); + process.exit(1); + }); + From 6e0743c4958a6656cf6a3e9db12fad43753c1a63 Mon Sep 17 00:00:00 2001 From: jtenner Date: Fri, 13 Mar 2020 00:13:31 -0400 Subject: [PATCH 16/17] Feature ASCII encoding and decoding (#27) * start implementation * fix operator grouping, now to optimize * remove lookup table, switch to simple bitwise * mask with shorter literal, remove explicit cast * add decorator --- assembly/buffer/index.ts | 30 ++++++++++++++++++++++++++++++ assembly/node.d.ts | 10 ++++++++++ tests/buffer.spec.ts | 14 ++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 1c5a832..627a273 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -287,6 +287,34 @@ export class Buffer extends Uint8Array { } export namespace Buffer { + export namespace ASCII { + export function encode(str: string): ArrayBuffer { + let length = str.length; + let output = __alloc(length, idof()); + for (let i = 0; i < length; i++) { + let char = load(changetype(str) + (i << 1)); + store(output + i, char & 0x7F); + } + return changetype(output); + } + + export function decode(buffer: ArrayBuffer): String { + return decodeUnsafe(changetype(buffer), buffer.byteLength); + } + + // @ts-ignore: decorator + @unsafe export function decodeUnsafe(pointer: usize, length: i32): String { + let result = __alloc(length << 1, idof()); + + for (let i = 0; i < length; i++) { + let byte = load(pointer + i); + store(result + (i << 1), byte & 0x7F); + } + + return changetype(result); + } + } + export namespace HEX { /** Calculates the byte length of the specified string when encoded as HEX. */ export function byteLength(str: string): i32 { @@ -358,6 +386,7 @@ export namespace Buffer { } /** Decodes a chunk of memory to a utf16le encoded string in hex format. */ + // @ts-ignore: decorator @unsafe export function decodeUnsafe(ptr: usize, length: i32): string { let stringByteLength = length << 2; // length * (2 bytes per char) * (2 chars per input byte) let result = __alloc(stringByteLength, idof()); @@ -374,6 +403,7 @@ export namespace Buffer { } /** Calculates the two char combination from the byte. */ + // @ts-ignore: decorator @inline function charsFromByte(byte: u32): u32 { let hi = (byte >>> 4) & 0xF; let lo = byte & 0xF; diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 419384a..a276e60 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -86,6 +86,7 @@ declare class Buffer extends Uint8Array { } declare namespace Buffer { + /** The HEX encoding and decoding namespace. */ export namespace HEX { /** Creates an ArrayBuffer from a given string that is encoded in the hex format. */ export function encode(str: string): ArrayBuffer; @@ -94,4 +95,13 @@ declare namespace Buffer { /** Decodes a chunk of memory to a utf16le encoded string in hex format. */ export function decodeUnsafe(ptr: usize, byteLength: i32): string; } + /** The ASCII encoding and decoding namespace. */ + export namespace ASCII { + /** Creates an ArrayBuffer from a given string that is encoded in the ASCII format. */ + export function encode(str: string): ArrayBuffer; + /** Creates a string from a given ArrayBuffer that is decoded into ASCII format. */ + export function decode(buffer: ArrayBuffer): string; + /** Decodes a chunk of memory to a utf16le encoded string in ASCII format. */ + export function decodeUnsafe(ptr: usize, byteLength: i32): string; + } } diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index b7681a4..dcd4177 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -550,4 +550,18 @@ describe("buffer", () => { let decoded = Buffer.HEX.decode(exampleBuffer.buffer); expect(decoded).toStrictEqual(expected); }); + + test("#ASCII.encode", () => { + let actual = "D34dB3eF"; + let exampleBuffer = create([0x44, 0x33, 0x34, 0x64, 0x42, 0x33, 0x65, 0x46]); + let encoded = Buffer.ASCII.encode(actual); + expect(encoded).toStrictEqual(exampleBuffer.buffer); + }); + + test("#ASCII.decode", () => { + let expected = create([0x44, 0x33, 0x34, 0x64, 0x42, 0x33, 0x65, 0x46]); + let example = "D34dB3eF"; + let encoded = Buffer.ASCII.decode(expected.buffer); + expect(encoded).toStrictEqual(example); + }); }); From bbd353ffbf2a7180ad6979a5f9a5bd91e677acb6 Mon Sep 17 00:00:00 2001 From: jtenner Date: Fri, 22 May 2020 14:15:40 -0400 Subject: [PATCH 17/17] update as to 10, add wasi, add sandbox (#29) * update as to 10, add wasi, add sandbox * add cli flag preopens, override at {testname}.spec.wasi.js --- package-lock.json | 52 +++++++++++++++++++++--------------------- package.json | 6 ++--- tests/fs.spec.ts | 3 +++ tests/fs.spec.wasi.js | 7 ++++++ tests/node.js | 43 ++++++++++++++++++++++++++-------- tests/sandbox/test.txt | 0 6 files changed, 72 insertions(+), 39 deletions(-) create mode 100644 tests/fs.spec.ts create mode 100644 tests/fs.spec.wasi.js create mode 100644 tests/sandbox/test.txt diff --git a/package-lock.json b/package-lock.json index 411d808..836d43b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,31 +5,31 @@ "requires": true, "dependencies": { "@as-pect/assembly": { - "version": "3.1.0-beta.3", - "resolved": "https://registry.npmjs.org/@as-pect/assembly/-/assembly-3.1.0-beta.3.tgz", - "integrity": "sha512-NYMzh8c4mloGJHQEyEz7Gw4DFKDjepyuSkojca0agSOVsjJcaTy6DtM42Lq7DTLwNoM4xt+YI7nQNTWcrhhHGw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@as-pect/assembly/-/assembly-3.2.1.tgz", + "integrity": "sha512-qok+WPvKV1BLQ+nnpn+hc0PLSZ69Pim4eT72PruA1C+hvMu6HCbNKDFcj4lrL7XNMKuibPf0633SW14asC0//w==", "dev": true }, "@as-pect/core": { - "version": "3.1.0-beta.3", - "resolved": "https://registry.npmjs.org/@as-pect/core/-/core-3.1.0-beta.3.tgz", - "integrity": "sha512-/i3wzOYEvvzECRKLPWm7FGKnPgtD6RdaPFWAT6nA4OHtsHdHz2BvvGdCecheLRG3GoRk00LfCSRB8/L3IJnS/A==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@as-pect/core/-/core-3.2.2.tgz", + "integrity": "sha512-Gr6ha3WGS/omSLvquDC6WPqZt1vP/hxvWovxgUuqNJ1APymMTjbvP2W86pjKLqvSaZj1gETAr5703PxhnnoL4g==", "dev": true, "requires": { - "@as-pect/assembly": "^3.1.0-beta.3", - "@as-pect/snapshots": "^3.1.0-beta.3", - "chalk": "^3.0.0", + "@as-pect/assembly": "^3.2.1", + "@as-pect/snapshots": "^3.2.2", + "chalk": "^4.0.0", "long": "^4.0.0" } }, "@as-pect/snapshots": { - "version": "3.1.0-beta.3", - "resolved": "https://registry.npmjs.org/@as-pect/snapshots/-/snapshots-3.1.0-beta.3.tgz", - "integrity": "sha512-hL+a3/ByQQAhLLVsY9Qtd0eAb9UTZbMeJyh4mKQQS4X9KXhpVHADjoK31PbOlM+E3TUbR/KbZFFPu2Z79T3How==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@as-pect/snapshots/-/snapshots-3.2.2.tgz", + "integrity": "sha512-uJQwwbgX0gGRVD4Au8r3g9TbPCseBuChSDVjfaNAZifaQ0JKrrzB4tga2PVDrWrZHIgYvajTph5tsN3x9pJ5nA==", "dev": true, "requires": { "diff": "^4.0.2", - "nearley": "^2.19.1" + "nearley": "^2.19.3" } }, "@types/color-name": { @@ -49,12 +49,12 @@ } }, "assemblyscript": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.9.3.tgz", - "integrity": "sha512-5Mm15oLOi4Uj/N9h2uGuy4U2zFpaOQuP3kcRuFYiTchuvKIpyqqihMm+e7P6VaTLzPnN+oIRwn1KjTyo4aSw1A==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.10.0.tgz", + "integrity": "sha512-ErUNhHboD+zsB4oG6X1YICDAIo27Gq7LeNX6jVe+Q0W5cI51/fHwC8yJ68IukqvupmZgYPdp1JqqRXlS+BrUfA==", "dev": true, "requires": { - "binaryen": "91.0.0-nightly.20200310", + "binaryen": "93.0.0-nightly.20200514", "long": "^4.0.0" } }, @@ -65,9 +65,9 @@ "dev": true }, "binaryen": { - "version": "91.0.0-nightly.20200310", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-91.0.0-nightly.20200310.tgz", - "integrity": "sha512-MmDzq267aa61HdEQeYiz+7guJlsYk2/6NxWC8I4w1jijqDwoqyZZxi7UYnTH7QvfLrNdMjweEgfT7FHjkvkPmQ==", + "version": "93.0.0-nightly.20200514", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-93.0.0-nightly.20200514.tgz", + "integrity": "sha512-SRRItmNvhRVfoWWbRloO4i8IqkKH8rZ7/0QWRgLpM3umupK8gBpo9MY7Zp3pDysRSp+rVoqxvM5x4tFyCSa9zw==", "dev": true }, "brace-expansion": { @@ -81,9 +81,9 @@ } }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -193,9 +193,9 @@ "dev": true }, "nearley": { - "version": "2.19.1", - "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.1.tgz", - "integrity": "sha512-xq47GIUGXxU9vQg7g/y1o1xuKnkO7ev4nRWqftmQrLkfnE/FjRqDaGOUakM8XHPn/6pW3bGjU2wgoJyId90rqg==", + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.3.tgz", + "integrity": "sha512-FpAy1PmTsUpOtgxr23g4jRNvJHYzZEW2PixXeSzksLR/ykPfwKhAodc2+9wQhY+JneWLcvkDw6q7FJIsIdF/aQ==", "dev": true, "requires": { "commander": "^2.19.0", diff --git a/package.json b/package.json index 0b5ba7b..3265e45 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,12 @@ "url": "https://github.com/AssemblyScript/node/issues" }, "devDependencies": { - "@as-pect/core": "^3.1.0-beta.3", - "assemblyscript": "0.9.3", + "@as-pect/core": "^3.2.2", + "assemblyscript": "0.10.0", "glob": "^7.1.6" }, "scripts": { - "test": "node --experimental-wasi-unstable-preview1 tests/node" + "test": "node --experimental-wasi-unstable-preview1 --experimental-wasm-bigint tests/node" }, "dependencies": {} } diff --git a/tests/fs.spec.ts b/tests/fs.spec.ts new file mode 100644 index 0000000..84315f6 --- /dev/null +++ b/tests/fs.spec.ts @@ -0,0 +1,3 @@ +test("an empty test", () => { + +}); diff --git a/tests/fs.spec.wasi.js b/tests/fs.spec.wasi.js new file mode 100644 index 0000000..afa6f72 --- /dev/null +++ b/tests/fs.spec.wasi.js @@ -0,0 +1,7 @@ +module.exports = { + env: process.env, + argv: process.argv, + preopens: { + "./tests/sandbox": "./tests/sandbox" + } +}; diff --git a/tests/node.js b/tests/node.js index 6c9e25f..f6b7e5e 100644 --- a/tests/node.js +++ b/tests/node.js @@ -4,7 +4,8 @@ const { instantiateSync } = require("assemblyscript/lib/loader"); const { main } = require("assemblyscript/cli/asc"); const { parse } = require("assemblyscript/cli/util/options"); const path = require("path"); -const fs = require("fs").promises; +const fssync = require("fs"); +const fs = fssync.promises; const { WASI } = require("wasi"); const promises = []; @@ -21,6 +22,12 @@ const options = parse(process.argv.slice(2), { "type": "b", "alias": "u" }, + "preopens": { + "description": "A set of preopened directories for wasi. Ex. ./dir=./dir", + "type": "S", + "alias": "p", + "default": [], + }, }); if (options.unknown.length > 1) { @@ -28,6 +35,16 @@ if (options.unknown.length > 1) { process.exit(1); } +// calculate default preopens from cli +const preopens = options.options.preopens.reduce( + (obj, value) => { + const [_, dir1, dir2] = /([^=])*=(.*)/.exec(value); + obj[dir1] = dir2; + return obj; + }, + {} +); + const reporter = new VerboseReporter(); reporter.stderr = process.stderr; reporter.stdout = process.stdout; @@ -40,7 +57,6 @@ const ascOptions = [ relativeFromCwd(require.resolve("@as-pect/assembly/assembly/index.ts")), "--use", "ASC_RTRACE=1", "--explicitStart", - "--validate", "--measure", "--lib", "assembly", "--transform", require.resolve("@as-pect/core/lib/transform/index.js"), @@ -117,29 +133,36 @@ function runTest(fileName, type, binary, wat) { const basename = path.basename(fileName, ".ts"); const fullName = path.join(dirname, basename) const watPath = `${fullName}.${type}.wat`; + const wasiPath = `${fullName}.wasi.js`; const fileNamePath = `${fullName}.${type}.ts`; + // use either a custom wasi configuration, or the default one + const wasiOptions = fssync.existsSync(wasiPath) + ? require(path.resolve(wasiPath)) + : { + args: process.argv, + env: process.env, + preopens, + }; + // should not block testing promises.push(fs.writeFile(watPath, wat)); + const wasi = new WASI(wasiOptions); + const context = new TestContext({ fileName: fileNamePath, // set the fileName reporter, // use verbose reporter binary, // pass the binary to get function names + wasi, }); - const wasi = new WASI({ - args: [], - env: {}, - preopens: { - // '/sandbox': '/some/real/path/that/wasm/can/access' - } - }); + const imports = context.createImports({ wasi_snapshot_preview1: wasi.wasiImport, }); const instance = instantiateSync(binary, imports); - // TODO: wasi.start(instance); + process.stdout.write("\n"); context.run(instance); diff --git a/tests/sandbox/test.txt b/tests/sandbox/test.txt new file mode 100644 index 0000000..e69de29