Skip to content

Commit

Permalink
Implemented u32.
Browse files Browse the repository at this point in the history
  • Loading branch information
iwoplaza committed Sep 10, 2023
1 parent 93f078f commit 3866e31
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 118 deletions.
78 changes: 40 additions & 38 deletions src/io/bufferIOBase.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,49 @@
import { isBigEndian } from '../util';

export type BufferIOOptions = {
/**
* @default 0
*/
byteOffset: number;
/**
* @default 'system'
*/
endianness: 'big' | 'little' | 'system';
/**
* @default 0
*/
byteOffset: number;
/**
* @default 'system'
*/
endianness: 'big' | 'little' | 'system';
};

export class BufferIOBase {
protected readonly uint8View: Uint8Array;
protected readonly helperIntView: Int32Array;
protected readonly helperFloatView: Float32Array;
protected readonly helperByteView: Uint8Array;
protected readonly switchEndianness: boolean;

protected byteOffset = 0;

constructor(buffer: ArrayBufferLike, options?: BufferIOOptions) {
if (typeof Buffer !== 'undefined' && buffer instanceof Buffer) {
// Getting rid of the outer shell, which causes the Uint8Array line to create a copy, instead of a view.
buffer = buffer.buffer;
}

this.uint8View = new Uint8Array(buffer, 0);
this.byteOffset = options?.byteOffset ?? 0;

const helperBuffer = new ArrayBuffer(4);
this.helperIntView = new Int32Array(helperBuffer);
this.helperFloatView = new Float32Array(helperBuffer);
this.helperByteView = new Uint8Array(helperBuffer);

const isSystemBigEndian = isBigEndian();
const endianness = options?.endianness ?? 'system';
this.switchEndianness =
(endianness === 'big' && !isSystemBigEndian) ||
(endianness === 'little' && isSystemBigEndian);
}
protected readonly uint8View: Uint8Array;
protected readonly helperInt32View: Int32Array;
protected readonly helperUint32View: Uint32Array;
protected readonly helperFloatView: Float32Array;
protected readonly helperByteView: Uint8Array;
protected readonly switchEndianness: boolean;

protected byteOffset = 0;

get currentByteOffset() {
return this.byteOffset;
constructor(buffer: ArrayBufferLike, options?: BufferIOOptions) {
if (typeof Buffer !== 'undefined' && buffer instanceof Buffer) {
// Getting rid of the outer shell, which causes the Uint8Array line to create a copy, instead of a view.
buffer = buffer.buffer;
}

this.uint8View = new Uint8Array(buffer, 0);
this.byteOffset = options?.byteOffset ?? 0;

const helperBuffer = new ArrayBuffer(4);
this.helperInt32View = new Int32Array(helperBuffer);
this.helperUint32View = new Uint32Array(helperBuffer);
this.helperFloatView = new Float32Array(helperBuffer);
this.helperByteView = new Uint8Array(helperBuffer);

const isSystemBigEndian = isBigEndian();
const endianness = options?.endianness ?? 'system';
this.switchEndianness =
(endianness === 'big' && !isSystemBigEndian) ||
(endianness === 'little' && isSystemBigEndian);
}

get currentByteOffset() {
return this.byteOffset;
}
}
67 changes: 38 additions & 29 deletions src/io/bufferReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,52 @@ import { BufferIOBase, BufferIOOptions } from './bufferIOBase';
import { ISerialInput } from './types';

export class BufferReader extends BufferIOBase implements ISerialInput {
constructor(buffer: ArrayBufferLike, options?: BufferIOOptions) {
super(buffer, options);
constructor(buffer: ArrayBufferLike, options?: BufferIOOptions) {
super(buffer, options);
}

private copyInputToHelper(bytes: number) {
for (let i = 0; i < bytes; ++i) {
this.helperByteView[this.switchEndianness ? bytes - 1 - i : i] =
this.uint8View[this.byteOffset++];
}
}

readBool() {
return this.uint8View[this.byteOffset++] !== 0;
}
readBool() {
return this.uint8View[this.byteOffset++] !== 0;
}

readByte() {
return this.uint8View[this.byteOffset++];
}
readByte() {
return this.uint8View[this.byteOffset++];
}

readFloat() {
for (let i = 0; i < 4; ++i) {
this.helperByteView[this.switchEndianness ? (3-i) : i] = this.uint8View[this.byteOffset++];
}
readFloat32() {
this.copyInputToHelper(4);

return this.helperFloatView[0];
}
return this.helperFloatView[0];
}

readInt() {
for (let i = 0; i < 4; ++i) {
this.helperByteView[this.switchEndianness ? (3-i) : i] = this.uint8View[this.byteOffset++];
}
readInt32() {
this.copyInputToHelper(4);

return this.helperIntView[0];
}
return this.helperInt32View[0];
}

readUint32() {
this.copyInputToHelper(4);

readString() {
let contents = '';
return this.helperUint32View[0];
}

let char = String.fromCharCode(this.uint8View[this.byteOffset++]);
while (char !== '\0') {
contents += char;
char = String.fromCharCode(this.uint8View[this.byteOffset++]);
}
readString() {
let contents = '';

return contents;
let char = String.fromCharCode(this.uint8View[this.byteOffset++]);
while (char !== '\0') {
contents += char;
char = String.fromCharCode(this.uint8View[this.byteOffset++]);
}
}

return contents;
}
}
10 changes: 5 additions & 5 deletions src/io/bufferReaderWriter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('BufferWriter/BufferReader', () => {

// Writing the ints
for (const int of intList) {
writer.writeInt(int);
writer.writeInt32(int);
}

// Expecting specific buffer offset
Expand All @@ -29,7 +29,7 @@ describe('BufferWriter/BufferReader', () => {
// Reading the ints
const reader = new BufferReader(buffer);
for (let i = 0; i < intList.length; ++i) {
expect(reader.readInt()).to.equal(intList[i]);
expect(reader.readInt32()).to.equal(intList[i]);
}
});

Expand All @@ -48,16 +48,16 @@ describe('BufferWriter/BufferReader', () => {

// Writing the ints
for (const float of floatList) {
writer.writeFloat(float);
writer.writeFloat32(float);
}

// Expecting specific buffer offset
expect(writer.currentByteOffset).to.equal(floatList.length * 4);

// Reading the ints
// Reading the floats
const reader = new BufferReader(buffer);
for (let i = 0; i < floatList.length; ++i) {
expect(reader.readFloat()).to.be.closeTo(floatList[i], 0.001);
expect(reader.readFloat32()).to.be.closeTo(floatList[i], 0.001);
}
});
});
60 changes: 35 additions & 25 deletions src/io/bufferWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,48 @@ import { BufferIOBase, BufferIOOptions } from './bufferIOBase';
import { ISerialOutput } from './types';

export class BufferWriter extends BufferIOBase implements ISerialOutput {
constructor(buffer: ArrayBufferLike, options?: BufferIOOptions) {
super(buffer, options);
}
constructor(buffer: ArrayBufferLike, options?: BufferIOOptions) {
super(buffer, options);
}

writeBool(value: boolean) {
this.uint8View[this.byteOffset++] = value ? 1 : 0;
}
private copyHelperToOutput(bytes: number) {
for (let i = 0; i < bytes; ++i)
this.uint8View[this.byteOffset++] =
this.helperByteView[this.switchEndianness ? bytes - 1 - i : i];
}

writeByte(value: number) {
this.uint8View[this.byteOffset++] = Math.floor(value) % 256;
}
writeBool(value: boolean) {
this.uint8View[this.byteOffset++] = value ? 1 : 0;
}

writeInt(value: number) {
this.helperIntView[0] = Math.floor(value);
writeByte(value: number) {
this.uint8View[this.byteOffset++] = Math.floor(value) % 256;
}

for (let i = 0; i < 4; ++i)
this.uint8View[this.byteOffset++] = this.helperByteView[this.switchEndianness ? (3-i) : i];
}
writeInt32(value: number) {
this.helperInt32View[0] = Math.floor(value);

writeFloat(value: number) {
this.helperFloatView[0] = value;
this.copyHelperToOutput(4);
}

for (let i = 0; i < 4; ++i)
this.uint8View[this.byteOffset++] = this.helperByteView[this.switchEndianness ? (3-i) : i];
}
writeUint32(value: number) {
this.helperUint32View[0] = Math.floor(value);

this.copyHelperToOutput(4);
}

writeString(value: string) {
for (let i = 0; i < value.length; ++i) {
this.uint8View[this.byteOffset++] = value.charCodeAt(i);
}
writeFloat32(value: number) {
this.helperFloatView[0] = value;

// Extra null character
this.uint8View[this.byteOffset++] = 0;
this.copyHelperToOutput(4);
}

writeString(value: string) {
for (let i = 0; i < value.length; ++i) {
this.uint8View[this.byteOffset++] = value.charCodeAt(i);
}

// Extra null character
this.uint8View[this.byteOffset++] = 0;
}
}
10 changes: 6 additions & 4 deletions src/io/types.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
export interface ISerialInput {
readBool(): boolean;
readByte(): number;
readInt(): number;
readFloat(): number;
readInt32(): number;
readUint32(): number;
readFloat32(): number;
readString(): string;
readonly currentByteOffset: number;
}

export interface ISerialOutput {
writeBool(value: boolean): void;
writeByte(value: number): void;
writeInt(value: number): void;
writeFloat(value: number): void;
writeInt32(value: number): void;
writeUint32(value: number): void;
writeFloat32(value: number): void;
writeString(value: string): void;
readonly currentByteOffset: number;
}
4 changes: 2 additions & 2 deletions src/structure/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class ArraySchema<T> extends Schema<T[]> {
}

write(output: ISerialOutput, values: T[]): void {
output.writeInt(values.length);
output.writeUint32(values.length);

for (const value of values) {
this.elementType.write(output, value);
Expand All @@ -28,7 +28,7 @@ export class ArraySchema<T> extends Schema<T[]> {
read(input: ISerialInput): T[] {
const array = [];

const len = input.readInt();
const len = input.readUint32();

for (let i = 0; i < len; ++i) {
array.push(this.elementType.read(input));
Expand Down
Loading

0 comments on commit 3866e31

Please sign in to comment.