UNPKG

multi-buffer-data-view

Version:

A wrapper around the native DataView which can handle multiple ArrayBuffers.

165 lines (164 loc) 7.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MultiBufferDataView = void 0; class MultiBufferDataView { constructor(buffers, byteOffset = 0, byteLength) { if (byteOffset < 0 || byteLength !== undefined && byteLength < 0) { throw new RangeError(); } const availableBytes = buffers.reduce((length, buffer) => length + buffer.byteLength, 0); if (byteOffset > availableBytes || byteLength !== undefined && byteOffset + byteLength > availableBytes) { throw new RangeError(); } const dataViews = []; const effectiveByteLength = byteLength === undefined ? availableBytes - byteOffset : byteLength; const truncatedBuffers = []; let consumedByteLength = 0; let truncatedByteOffset = byteOffset; for (const buffer of buffers) { if (truncatedBuffers.length === 0) { if (buffer.byteLength > truncatedByteOffset) { consumedByteLength = buffer.byteLength - truncatedByteOffset; const byteLengthOfDataView = consumedByteLength > effectiveByteLength ? effectiveByteLength : consumedByteLength; dataViews.push(new DataView(buffer, truncatedByteOffset, byteLengthOfDataView)); truncatedBuffers.push(buffer); } else { truncatedByteOffset -= buffer.byteLength; } } else if (consumedByteLength < effectiveByteLength) { consumedByteLength += buffer.byteLength; const byteLengthOfDataView = consumedByteLength > effectiveByteLength ? buffer.byteLength - consumedByteLength + effectiveByteLength : buffer.byteLength; dataViews.push(new DataView(buffer, 0, byteLengthOfDataView)); truncatedBuffers.push(buffer); } } this._buffers = truncatedBuffers; this._byteLength = effectiveByteLength; this._byteOffset = truncatedByteOffset; this._dataViews = dataViews; this._internalBuffer = new DataView(new ArrayBuffer(8)); } get buffers() { return this._buffers; } get byteLength() { return this._byteLength; } get byteOffset() { return this._byteOffset; } getFloat32(byteOffset, littleEndian) { this._internalBuffer.setUint8(0, this.getUint8(byteOffset + 0)); this._internalBuffer.setUint8(1, this.getUint8(byteOffset + 1)); this._internalBuffer.setUint8(2, this.getUint8(byteOffset + 2)); this._internalBuffer.setUint8(3, this.getUint8(byteOffset + 3)); return this._internalBuffer.getFloat32(0, littleEndian); } getFloat64(byteOffset, littleEndian) { this._internalBuffer.setUint8(0, this.getUint8(byteOffset + 0)); this._internalBuffer.setUint8(1, this.getUint8(byteOffset + 1)); this._internalBuffer.setUint8(2, this.getUint8(byteOffset + 2)); this._internalBuffer.setUint8(3, this.getUint8(byteOffset + 3)); this._internalBuffer.setUint8(4, this.getUint8(byteOffset + 4)); this._internalBuffer.setUint8(5, this.getUint8(byteOffset + 5)); this._internalBuffer.setUint8(6, this.getUint8(byteOffset + 6)); this._internalBuffer.setUint8(7, this.getUint8(byteOffset + 7)); return this._internalBuffer.getFloat64(0, littleEndian); } getInt16(byteOffset, littleEndian) { this._internalBuffer.setUint8(0, this.getUint8(byteOffset + 0)); this._internalBuffer.setUint8(1, this.getUint8(byteOffset + 1)); return this._internalBuffer.getInt16(0, littleEndian); } getInt32(byteOffset, littleEndian) { this._internalBuffer.setUint8(0, this.getUint8(byteOffset + 0)); this._internalBuffer.setUint8(1, this.getUint8(byteOffset + 1)); this._internalBuffer.setUint8(2, this.getUint8(byteOffset + 2)); this._internalBuffer.setUint8(3, this.getUint8(byteOffset + 3)); return this._internalBuffer.getInt32(0, littleEndian); } getInt8(byteOffset) { const [dataView, byteOffsetOfDataView] = this._findDataViewWithOffset(byteOffset); return dataView.getInt8(byteOffset - byteOffsetOfDataView); } getUint16(byteOffset, littleEndian) { this._internalBuffer.setUint8(0, this.getUint8(byteOffset + 0)); this._internalBuffer.setUint8(1, this.getUint8(byteOffset + 1)); return this._internalBuffer.getUint16(0, littleEndian); } getUint32(byteOffset, littleEndian) { this._internalBuffer.setUint8(0, this.getUint8(byteOffset + 0)); this._internalBuffer.setUint8(1, this.getUint8(byteOffset + 1)); this._internalBuffer.setUint8(2, this.getUint8(byteOffset + 2)); this._internalBuffer.setUint8(3, this.getUint8(byteOffset + 3)); return this._internalBuffer.getUint32(0, littleEndian); } getUint8(byteOffset) { const [dataView, byteOffsetOfDataView] = this._findDataViewWithOffset(byteOffset); return dataView.getUint8(byteOffset - byteOffsetOfDataView); } setFloat32(byteOffset, value, littleEndian) { this._internalBuffer.setFloat32(0, value, littleEndian); this.setUint8(byteOffset, this._internalBuffer.getUint8(0)); this.setUint8(byteOffset + 1, this._internalBuffer.getUint8(1)); this.setUint8(byteOffset + 2, this._internalBuffer.getUint8(2)); this.setUint8(byteOffset + 3, this._internalBuffer.getUint8(3)); } setFloat64(byteOffset, value, littleEndian) { this._internalBuffer.setFloat64(0, value, littleEndian); this.setUint8(byteOffset, this._internalBuffer.getUint8(0)); this.setUint8(byteOffset + 1, this._internalBuffer.getUint8(1)); this.setUint8(byteOffset + 2, this._internalBuffer.getUint8(2)); this.setUint8(byteOffset + 3, this._internalBuffer.getUint8(3)); this.setUint8(byteOffset + 4, this._internalBuffer.getUint8(4)); this.setUint8(byteOffset + 5, this._internalBuffer.getUint8(5)); this.setUint8(byteOffset + 6, this._internalBuffer.getUint8(6)); this.setUint8(byteOffset + 7, this._internalBuffer.getUint8(7)); } setInt16(byteOffset, value, littleEndian) { this._internalBuffer.setInt16(0, value, littleEndian); this.setUint8(byteOffset, this._internalBuffer.getUint8(0)); this.setUint8(byteOffset + 1, this._internalBuffer.getUint8(1)); } setInt32(byteOffset, value, littleEndian) { this._internalBuffer.setInt32(0, value, littleEndian); this.setUint8(byteOffset, this._internalBuffer.getUint8(0)); this.setUint8(byteOffset + 1, this._internalBuffer.getUint8(1)); this.setUint8(byteOffset + 2, this._internalBuffer.getUint8(2)); this.setUint8(byteOffset + 3, this._internalBuffer.getUint8(3)); } setInt8(byteOffset, value) { const [dataView, byteOffsetOfDataView] = this._findDataViewWithOffset(byteOffset); dataView.setInt8(byteOffset - byteOffsetOfDataView, value); } setUint16(byteOffset, value, littleEndian) { this._internalBuffer.setUint16(0, value, littleEndian); this.setUint8(byteOffset, this._internalBuffer.getUint8(0)); this.setUint8(byteOffset + 1, this._internalBuffer.getUint8(1)); } setUint32(byteOffset, value, littleEndian) { this._internalBuffer.setUint32(0, value, littleEndian); this.setUint8(byteOffset, this._internalBuffer.getUint8(0)); this.setUint8(byteOffset + 1, this._internalBuffer.getUint8(1)); this.setUint8(byteOffset + 2, this._internalBuffer.getUint8(2)); this.setUint8(byteOffset + 3, this._internalBuffer.getUint8(3)); } setUint8(byteOffset, value) { const [dataView, byteOffsetOfDataView] = this._findDataViewWithOffset(byteOffset); dataView.setUint8(byteOffset - byteOffsetOfDataView, value); } _findDataViewWithOffset(byteOffset) { let byteOffsetOfDataView = 0; for (const dataView of this._dataViews) { const byteOffsetOfNextDataView = byteOffsetOfDataView + dataView.byteLength; if (byteOffset >= byteOffsetOfDataView && byteOffset < byteOffsetOfNextDataView) { return [dataView, byteOffsetOfDataView]; } byteOffsetOfDataView = byteOffsetOfNextDataView; } throw new RangeError(); } } exports.MultiBufferDataView = MultiBufferDataView;