Skip to content

Commit

Permalink
Using DataView for reading from a buffer.
Browse files Browse the repository at this point in the history
  • Loading branch information
iwoplaza committed Dec 17, 2024
1 parent adb99b7 commit c3c6674
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 32 deletions.
4 changes: 4 additions & 0 deletions packages/typed-binary/src/io/bufferIOBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ export type BufferIOOptions = {
};

export class BufferIOBase {
protected readonly dataView: DataView;
protected readonly uint8View: Uint8Array;
protected readonly helperInt32View: Int32Array;
protected readonly helperUint32View: Uint32Array;
protected readonly helperUint16View: Uint16Array;
protected readonly helperFloat32View: Float32Array;
protected readonly helperByteView: Uint8Array;
protected readonly switchEndianness: boolean;
protected readonly littleEndian: boolean;

protected byteOffset = 0;

Expand All @@ -34,11 +36,13 @@ export class BufferIOBase {
const systemEndianness = getSystemEndianness();
this.endianness = endianness === 'system' ? systemEndianness : endianness;
this.switchEndianness = this.endianness !== systemEndianness;
this.littleEndian = this.endianness === 'little';

// Getting rid of the outer shell, which causes the Uint8Array line to create a copy, instead of a view.
const unwrapped = unwrapBuffer(buffer);
this.byteOffset += unwrapped.byteOffset;

this.dataView = new DataView(unwrapped.buffer);
this.uint8View = new Uint8Array(unwrapped.buffer, 0);

const helperBuffer = new ArrayBuffer(4);
Expand Down
47 changes: 20 additions & 27 deletions packages/typed-binary/src/io/bufferReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,52 @@ export class BufferReader extends BufferIOBase implements ISerialInput {
return this._cachedTextDecoder;
}

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;
return this.dataView.getUint8(this.byteOffset++) !== 0;
}

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

readFloat16() {
this.copyInputToHelper(2);

return float16ToNumber(this.helperUint16View);
const value = this.dataView.getUint16(this.byteOffset, this.littleEndian);
this.byteOffset += 2;
return float16ToNumber(value);
}

readFloat32() {
this.copyInputToHelper(4);

return this.helperFloat32View[0];
const value = this.dataView.getFloat32(this.byteOffset, this.littleEndian);
this.byteOffset += 4;
return value;
}

readInt32() {
this.copyInputToHelper(4);

return this.helperInt32View[0];
const value = this.dataView.getInt32(this.byteOffset, this.littleEndian);
this.byteOffset += 4;
return value;
}

readUint32() {
this.copyInputToHelper(4);

return this.helperUint32View[0];
const value = this.dataView.getUint32(this.byteOffset, this.littleEndian);
this.byteOffset += 4;
return value;
}

readString() {
// Looking for the 'NULL' byte.
let end = this.byteOffset;
while (end < this.uint8View.byteLength) {
if (this.uint8View[end++] === 0) {
let strLength = 0;
while (this.byteOffset + strLength < this.dataView.byteLength) {
if (this.dataView.getUint8(this.byteOffset + strLength++) === 0) {
break;
}
}

const result = this._textDecoder.decode(
this.uint8View.subarray(this.byteOffset, end - 1),
new Uint8Array(this.dataView.buffer, this.byteOffset, strLength - 1),
);

this.byteOffset = end;
this.byteOffset += strLength;

return result;
}
Expand All @@ -82,7 +75,7 @@ export class BufferReader extends BufferIOBase implements ISerialInput {
);

for (let i = 0; i < byteLength; ++i) {
destU8[i] = this.uint8View[this.byteOffset++];
destU8[i] = this.dataView.getUint8(this.byteOffset++);
}
}
}
9 changes: 4 additions & 5 deletions packages/typed-binary/src/io/float16converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ export function numberToFloat16(value: number): Uint16Array {
return uint16Array;
}

export function float16ToNumber(uint16Array: Uint16Array): number {
const float16 = uint16Array[0];
const sign = (float16 & 0x8000) >> 15;
const exponent = (float16 & 0x7c00) >> 10;
const mantissa = float16 & 0x3ff;
export function float16ToNumber(uint16Encoding: number): number {
const sign = (uint16Encoding & 0x8000) >> 15;
const exponent = (uint16Encoding & 0x7c00) >> 10;
const mantissa = uint16Encoding & 0x3ff;
if (exponent === 0) {
return sign === 0 ? mantissa / 1024 : -mantissa / 1024;
}
Expand Down

0 comments on commit c3c6674

Please sign in to comment.