Selaa lähdekoodia

Add additional read functions + ability to read from a given buffer

Popov72 5 vuotta sitten
vanhempi
commit
b710f8d773
1 muutettua tiedostoa jossa 111 lisäystä ja 12 poistoa
  1. 111 12
      src/Misc/dataReader.ts

+ 111 - 12
src/Misc/dataReader.ts

@@ -25,12 +25,19 @@ export class DataReader {
     /**
      * The data buffer associated with this data reader.
      */
-    public readonly buffer: IDataBuffer;
+    public readonly buffer: IDataBuffer | undefined;
 
     /**
      * The current byte offset from the beginning of the data buffer.
      */
-    public byteOffset = 0;
+    public get byteOffset() {
+        return this._dataByteOffset;
+    }
+
+    /**
+     * Indicates the endianness of the data in the buffer
+     */
+    public littleEndian = true;
 
     private _dataView: DataView;
     private _dataByteOffset: number;
@@ -39,7 +46,7 @@ export class DataReader {
      * Constructor
      * @param buffer The buffer to read
      */
-    constructor(buffer: IDataBuffer) {
+    constructor(buffer?: IDataBuffer) {
         this.buffer = buffer;
     }
 
@@ -52,10 +59,73 @@ export class DataReader {
         delete this._dataView;
         delete this._dataByteOffset;
 
-        return this.buffer.readAsync(this.byteOffset, byteLength).then((data) => {
-            this._dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);
-            this._dataByteOffset = 0;
-        });
+        if (!this.buffer) {
+            return Promise.resolve();
+        } else {
+            return this.buffer.readAsync(this.byteOffset, byteLength).then((data) => {
+                this._dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);
+                this._dataByteOffset = 0;
+            });
+        }
+    }
+
+    /**
+     * Sets the given buffer
+     * @param buffer The buffer to set
+     * @param byteOffset The starting offset in the buffer
+     * @param byteLength The byte length of the buffer
+     * @returns This instance
+     */
+    public setBuffer(buffer: ArrayBuffer | ArrayBufferView, byteOffset?: number, byteLength?: number) {
+        if ((buffer as  ArrayBufferView).buffer) {
+            this._dataView = new DataView((buffer as ArrayBufferView).buffer, byteOffset ?? (buffer as ArrayBufferView).byteOffset, byteLength ?? (buffer as ArrayBufferView).byteLength);
+        } else {
+            this._dataView = new DataView(buffer as ArrayBuffer, byteOffset ?? 0, byteLength ?? (buffer as ArrayBuffer).byteLength);
+        }
+
+        this._dataByteOffset = 0;
+
+        return this;
+    }
+
+    /**
+     * Read a unsigned 8-bit integer from the currently loaded data range.
+     * @returns The 8-bit integer read
+     */
+    public readUint8(): number {
+        const value = this._dataView.getUint8(this._dataByteOffset);
+        this._dataByteOffset += 1;
+        return value;
+    }
+
+    /**
+     * Read a signed 8-bit integer from the currently loaded data range.
+     * @returns The 8-bit integer read
+     */
+    public readInt8(): number {
+        const value = this._dataView.getInt8(this._dataByteOffset);
+        this._dataByteOffset += 1;
+        return value;
+    }
+
+    /**
+     * Read a unsigned 16-bit integer from the currently loaded data range.
+     * @returns The 16-bit integer read
+     */
+    public readUint16(): number {
+        const value = this._dataView.getUint16(this._dataByteOffset, this.littleEndian);
+        this._dataByteOffset += 2;
+        return value;
+    }
+
+    /**
+     * Read a signed 16-bit integer from the currently loaded data range.
+     * @returns The 16-bit integer read
+     */
+    public readInt16(): number {
+        const value = this._dataView.getInt16(this._dataByteOffset, this.littleEndian);
+        this._dataByteOffset += 2;
+        return value;
     }
 
     /**
@@ -63,13 +133,42 @@ export class DataReader {
      * @returns The 32-bit integer read
      */
     public readUint32(): number {
-        const value = this._dataView.getUint32(this._dataByteOffset, true);
+        const value = this._dataView.getUint32(this._dataByteOffset, this.littleEndian);
         this._dataByteOffset += 4;
-        this.byteOffset += 4;
         return value;
     }
 
     /**
+     * Read a signed 32-bit integer from the currently loaded data range.
+     * @returns The 32-bit integer read
+     */
+    public readInt32(): number {
+        const value = this._dataView.getInt32(this._dataByteOffset, this.littleEndian);
+        this._dataByteOffset += 4;
+        return value;
+    }
+
+    /**
+     * Read a unsigned 32-bit integer from the currently loaded data range.
+     * @returns The 32-bit integer read
+     */
+    public readUint64(): number {
+        // split 64-bit number into two 32-bit (4-byte) parts
+        const left = this._dataView.getUint32(this._dataByteOffset, this.littleEndian);
+        const right = this._dataView.getUint32(this._dataByteOffset + 4, this.littleEndian);
+
+        // combine the two 32-bit values
+        const combined = this.littleEndian ? left + (2 ** 32 * right) : (2 ** 32 * left) + right;
+
+        /*if (!Number.isSafeInteger(combined)) {
+            console.warn('DataReader: ' + combined + ' exceeds MAX_SAFE_INTEGER. Precision may be lost.');
+        }*/
+
+        this._dataByteOffset += 8;
+        return combined;
+    }
+
+    /**
      * Read a byte array from the currently loaded data range.
      * @param byteLength The byte length to read
      * @returns The byte array read
@@ -77,7 +176,6 @@ export class DataReader {
     public readUint8Array(byteLength: number): Uint8Array {
         const value = new Uint8Array(this._dataView.buffer, this._dataView.byteOffset + this._dataByteOffset, byteLength);
         this._dataByteOffset += byteLength;
-        this.byteOffset += byteLength;
         return value;
     }
 
@@ -93,9 +191,10 @@ export class DataReader {
     /**
      * Skips the given byte length the currently loaded data range.
      * @param byteLength The byte length to skip
+     * @returns This instance
      */
-    public skipBytes(byteLength: number): void {
+    public skipBytes(byteLength: number) {
         this._dataByteOffset += byteLength;
-        this.byteOffset += byteLength;
+        return this;
     }
 }