From 335501994caa977eecec72e8068580c393baf078 Mon Sep 17 00:00:00 2001 From: RedDwarfian Date: Sun, 11 Aug 2019 17:47:40 -0400 Subject: [PATCH 1/2] [Implement] Buffer.swap16/32/64 --- assembly/buffer/index.ts | 41 ++++++++++++++++++++++++++++++++++++++++ assembly/node.d.ts | 6 ++++++ tests/buffer.spec.ts | 39 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 0159575..f2d378b 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -2,6 +2,8 @@ import { BLOCK_MAXSIZE, BLOCK, BLOCK_OVERHEAD } from "rt/common"; import { E_INVALIDLENGTH, E_INDEXOUTOFRANGE } from "util/error"; import { Uint8Array } from "typedarray"; +const E_INVALIDBUFFERSIZE = "Buffer size is invalid."; // Temp String + export class Buffer extends Uint8Array { constructor(size: i32) { super(size); @@ -237,6 +239,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_INVALIDBUFFERSIZE); + 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_INVALIDBUFFERSIZE); + 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_INVALIDBUFFERSIZE); + 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 9989d246fc9645c28e153b1e7001fce1cdd36dc8 Mon Sep 17 00:00:00 2001 From: RedDwarfian Date: Sun, 11 Aug 2019 19:41:46 -0400 Subject: [PATCH 2/2] [Cleanup] Using proper error message --- assembly/buffer/index.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index f2d378b..91be52d 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -2,8 +2,6 @@ import { BLOCK_MAXSIZE, BLOCK, BLOCK_OVERHEAD } from "rt/common"; import { E_INVALIDLENGTH, E_INDEXOUTOFRANGE } from "util/error"; import { Uint8Array } from "typedarray"; -const E_INVALIDBUFFERSIZE = "Buffer size is invalid."; // Temp String - export class Buffer extends Uint8Array { constructor(size: i32) { super(size); @@ -243,7 +241,7 @@ export class Buffer extends Uint8Array { swap16(): Buffer { let dataLength = this.dataLength; // Make sure dataLength is even - if (dataLength & 1) throw new RangeError(E_INVALIDBUFFERSIZE); + if (dataLength & 1) throw new RangeError(E_INVALIDLENGTH); let dataStart = this.dataStart; dataLength += dataStart; while (dataStart < dataLength) { @@ -256,7 +254,7 @@ 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_INVALIDBUFFERSIZE); + if (dataLength & 3) throw new RangeError(E_INVALIDLENGTH); let dataStart = this.dataStart; dataLength += dataStart; while (dataStart < dataLength) { @@ -269,7 +267,7 @@ 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_INVALIDBUFFERSIZE); + if (dataLength & 7) throw new RangeError(E_INVALIDLENGTH); let dataStart = this.dataStart; dataLength += dataStart; while (dataStart < dataLength) {