Lutz Roeder пре 4 година
родитељ
комит
565d0b5cd6
1 измењених фајлова са 62 додато и 5 уклоњено
  1. 62 5
      source/base.js

+ 62 - 5
source/base.js

@@ -556,11 +556,12 @@ DataView.prototype.getBits = DataView.prototype.getBits || function(offset, bits
 
 base.BinaryReader = class {
 
-    constructor(buffer) {
-        this._buffer = buffer;
+    constructor(data) {
+        this._buffer = data instanceof Uint8Array ? data : data.peek();
         this._position = 0;
-        this._length = buffer.length;
-        this._view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
+        this._length = this._buffer.length;
+        this._view = new DataView(this._buffer.buffer, this._buffer.byteOffset, this._buffer.byteLength);
+        this._utf8 = new TextDecoder('utf-8');
     }
 
     get length() {
@@ -573,10 +574,16 @@ base.BinaryReader = class {
 
     seek(position) {
         this._position = position >= 0 ? position : this._length + position;
+        if (this._position > this._length || this._position < 0) {
+            throw new Error('Expected ' + (this._position - this._length) + ' more bytes. The file might be corrupted. Unexpected end of file.');
+        }
     }
 
     skip(offset) {
         this._position += offset;
+        if (this._position > this._length) {
+            throw new Error('Expected ' + (this._position - this._length) + ' more bytes. The file might be corrupted. Unexpected end of file.');
+        }
     }
 
     read(length) {
@@ -586,7 +593,7 @@ base.BinaryReader = class {
         }
         const position = this._position;
         this.skip(length !== undefined ? length : this._length - this._position);
-        return this._buffer.subarray(position, this._position);
+        return this._buffer.slice(position, this._position);
     }
 
     byte() {
@@ -595,11 +602,61 @@ base.BinaryReader = class {
         return this._buffer[position];
     }
 
+    int16() {
+        const position = this._position;
+        this.skip(2);
+        return this._view.getInt16(position, true);
+    }
+
+    int32() {
+        const position = this._position;
+        this.skip(4);
+        return this._view.getInt32(position, true);
+    }
+
+    int64() {
+        const position = this._position;
+        this.skip(8);
+        return this._view.getInt64(position, true).toNumber();
+    }
+
+    uint16() {
+        const position = this._position;
+        this.skip(2);
+        return this._view.getUint16(position, true);
+    }
+
     uint32() {
         const position = this._position;
         this.skip(4);
         return this._view.getUint32(position, true);
     }
+
+    uint64() {
+        const position = this._position;
+        this.skip(8);
+        return this._view.getUint64(position, true).toNumber();
+    }
+
+    float32() {
+        const position = this._position;
+        this.skip(4);
+        return this._view.getFloat32(position, true);
+    }
+
+    float64() {
+        const position = this._position;
+        this.skip(8);
+        return this._view.getFloat64(position, true);
+    }
+
+    string() {
+        const length = this.uint32();
+        const position = this._position;
+        this.skip(length);
+        const data = this._buffer.subarray(position, this._position);
+        return this._utf8.decode(data);
+    }
 };
 
 if (typeof window !== 'undefined' && typeof window.Long != 'undefined') {