Skip to content
64 changes: 54 additions & 10 deletions assembly/buffer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,69 @@ export class Buffer extends Uint8Array {
return value instanceof Buffer;
}

readInt8(offset: i32 = 0): i8 {
if(i32(offset < 0) | i32(<u32>offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
return load<i8>(this.dataStart + <usize>offset);
}

readUInt8(offset: i32 = 0): u8 {
if(<u32>offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE);
return load<u8>(this.dataStart + usize(offset));
if(i32(offset < 0) | i32(<u32>offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
return load<u8>(this.dataStart + <usize>offset);
}

writeInt8(value: i8, offset: i32 = 0): i32 {
if(i32(offset < 0) | i32(<u32>offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
store<i8>(this.dataStart + offset, value);
return offset + 1;
}

writeUInt8(value: u8, offset: i32 = 0): i32 {
if(<u32>offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE);
if(i32(offset < 0) | i32(<u32>offset >= this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
store<u8>(this.dataStart + offset, value);
return offset + 1;
}

writeInt8(value: i8, offset: i32 = 0): i32 {
if(<u32>offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE);
store<i8>(this.dataStart + offset, value);
return offset + 1;
readInt16LE(offset: i32 = 0): i16 {
if(i32(offset < 0) | i32(<u32>offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
return load<i16>(this.dataStart + <usize>offset);
}

readInt8(offset: i32 = 0): i8 {
if(<u32>offset >= this.dataLength) throw new RangeError(E_INDEXOUTOFRANGE);
return load<i8>(this.dataStart + usize(offset));
readInt16BE(offset: i32 = 0): i16 {
if(i32(offset < 0) | i32(<u32>offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
return bswap<i16>(load<i16>(this.dataStart + <usize>offset));
}

readUInt16LE(offset: i32 = 0): u16 {
if(i32(offset < 0) | i32(<u32>offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
return load<u16>(this.dataStart + <usize>offset);
}

readUInt16BE(offset: i32 = 0): u16 {
if(i32(offset < 0) | i32(<u32>offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
return bswap<u16>(load<u16>(this.dataStart + <usize>offset));
}

writeInt16LE(value: i16, offset: i32 = 0): i32 {
if(i32(offset < 0) | i32(<u32>offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
store<i16>(this.dataStart + offset, value);
return offset + 2;
}

writeInt16BE(value: i16, offset: i32 = 0): i32 {
if(i32(offset < 0) | i32(<u32>offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
store<i16>(this.dataStart + offset, bswap<i16>(value));
return offset + 2;
}

writeUInt16LE(value: u16, offset: i32 = 0): i32 {
if(i32(offset < 0) | i32(<u32>offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
store<u16>(this.dataStart + offset, value);
return offset + 2;
}

writeUInt16BE(value: u16, offset: i32 = 0): i32 {
if(i32(offset < 0) | i32(<u32>offset + 2 > this.dataLength)) throw new RangeError(E_INDEXOUTOFRANGE);
store<u16>(this.dataStart + offset, bswap<u16>(value));
return offset + 2;
}
}
24 changes: 20 additions & 4 deletions assembly/node.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(value: T): bool;
/** Reads a signed integer at the designated offset. */
readInt8(offset?: i32): i8;
/** Reads an unsigned integer at the designated offset. */
readUInt8(offset?: i32): u8;
/** Writes an inputted 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;
}
153 changes: 131 additions & 22 deletions tests/buffer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
*/
import { BLOCK_MAXSIZE } from "rt/common";

// Helper function to quickly create a Buffer from an array.
//@ts-ignore
function create<T>(values: valueof<T>[]): T {
let result = instantiate<T>(values.length);
//@ts-ignore
for (let i = 0; i < values.length; i++) result[i] = values[i];
return result;
}

describe("buffer", () => {
test("#constructor", () => {
expect<Buffer>(new Buffer(0)).toBeTruthy();
Expand Down Expand Up @@ -58,50 +67,150 @@ describe("buffer", () => {
expect<bool>(Buffer.isBuffer<Buffer | null>(null)).toBeFalsy();
});

test("#readInt8", () => {
let buff = create<Buffer>([0x5,0x0,0x0,0x0,0xFF]);
expect<i8>(buff.readInt8()).toBe(5);
// Testing offset, and casting between u8 and i8.
expect<i8>(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<Buffer>([0xFE,0x0,0x0,0x0,0x2F]);
// Testing casting between u8 and i8.
expect<u8>(buff.readUInt8(0)).toBe(254);
expect<u8>(buff.readUInt8()).toBe(254);
// Testing offset
expect<u8>(buff.readUInt8(9)).toBe(47);
expect<u8>(buff.readUInt8(4)).toBe(47);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.readUInt8(5);
// }).toThrow();
});

test("#writeInt8", () => {
let buff = new Buffer(5);
expect<i32>(buff.writeInt8(9)).toBe(1);
expect<i32>(buff.writeInt8(-3,4)).toBe(5);
let result = create<Buffer>([0x09, 0x0, 0x0, 0x0, 0xFD]);
expect<Buffer>(buff).toStrictEqual(result);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.writeInt8(5,10);
// }).toThrow();
});

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

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

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

test("#readInt8", () => {
let buff = new Buffer(10);
buff[0] = 5;
buff[9] = 255;
expect<i8>(buff.readInt8(0)).toBe(5);
expect<i8>(buff.readInt8()).toBe(5);
// Testing offset, and casting between u8 and i8.
expect<i8>(buff.readInt8(9)).toBe(-1);
test("#readUInt16LE", () => {
let buff = create<Buffer>([0x0,0x05,0x0]);
expect<u16>(buff.readUInt16LE()).toBe(1280);
expect<u16>(buff.readUInt16LE(1)).toBe(5);
// TODO:
// expectFn(() => {
// let newBuff = new Buffer(1);
// newBuff.readInt8(5);
// newBuff.readUInt16LE(0);
// }).toThrow();
});

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

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

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

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

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