Skip to content

Commit

Permalink
added BufferedDataReader
Browse files Browse the repository at this point in the history
  • Loading branch information
KurtThiemann committed Mar 10, 2023
1 parent d2e42c1 commit 789055f
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 94 deletions.
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export { default as ExtraField } from "./src/Archive/Structure/ExtraField/ExtraF
export { default as UnicodeExtraField } from "./src/Archive/Structure/ExtraField/UnicodeExtraField.js";

export { default as DataReader } from "./src/Reader/DataReader.js";
export { default as BufferedDataReader } from "./src/Reader/BufferedDataReader.js";
export { default as BrowserFileReader } from "./src/Reader/BrowserFileReader.js";
export { default as ArrayBufferReader } from "./src/Reader/ArrayBufferReader.js";

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "armarius",
"version": "1.9.2",
"version": "1.10.0",
"description": "A JavaScript library to read, write, and merge ZIP archives in web browsers.",
"repository": "github:aternosorg/armarius",
"type": "module",
Expand Down
95 changes: 2 additions & 93 deletions src/Reader/BrowserFileReader.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import DataReader from "./DataReader.js";
import BigIntUtils from "../Util/BigIntUtils.js";
import ArmariusError from '../Error/ArmariusError.js';
import BufferedDataReader from './BufferedDataReader.js';


export default class BrowserFileReader extends DataReader {
export default class BrowserFileReader extends BufferedDataReader {
/** @type {File} */ file;
/** @type {?Uint8Array} */ buffer;
/** @type {DataView} */ bufferView;
/** @type {Number} */ bufferStartOffset;
/** @type {FileReader} */ reader = new FileReader();
/** @type {boolean} */ blocked = false;

Expand All @@ -26,22 +22,6 @@ export default class BrowserFileReader extends DataReader {
}
}

/**
* @inheritDoc
*/
async readAt(offset, length, longLived = true) {
if (this.buffer && offset >= this.bufferStartOffset && length <= this.buffer.byteLength - (offset - this.bufferStartOffset)) {
return this.readFromBuffer(offset, length, longLived);
}

if (length < this.bufferSize) {
this.setBuffer(offset, await this.readRaw(offset, Math.max(length, Math.min(this.bufferSize, this.byteLength - offset))));
return this.readFromBuffer(offset, length, longLived);
}

return await this.readRaw(offset, length);
}

/**
* @param {number} offset
* @param {number} length
Expand Down Expand Up @@ -73,77 +53,6 @@ export default class BrowserFileReader extends DataReader {
});
}

/**
* @param {number} offset
* @param {number} length
* @param {boolean} longLived
* @protected
* @returns {Uint8Array}
*/
readFromBuffer(offset, length, longLived = false) {
let bufferOffset = offset - this.bufferStartOffset;
if (bufferOffset < 0 || bufferOffset + length > this.buffer.byteLength) {
throw new ArmariusError(`Cannot read ${length} bytes of buffer at ${bufferOffset}`);
}

if (longLived && this.buffer.byteLength - length > 512) {
return this.buffer.slice(bufferOffset, bufferOffset + length);
}

return new Uint8Array(this.buffer.buffer, this.buffer.byteOffset + bufferOffset, length);
}

/**
* @param {number} bufferOffset
* @param {Uint8Array} data
* @protected
*/
setBuffer(bufferOffset, data) {
this.buffer = data;
this.bufferView = new DataView(data.buffer, data.byteOffset, data.byteLength);
this.bufferStartOffset = bufferOffset;
}

/**
* @inheritDoc
*/
async getUint8At(offset) {
if (this.buffer && offset > this.bufferStartOffset && offset - this.bufferStartOffset + 1 < this.buffer.byteLength) {
return this.bufferView.getUint8(offset - this.bufferStartOffset);
}
return super.getUint8At(offset);
}

/**
* @inheritDoc
*/
async getUint16At(offset, littleEndian = true) {
if (this.buffer && offset > this.bufferStartOffset && offset - this.bufferStartOffset + 2 < this.buffer.byteLength) {
return this.bufferView.getUint16(offset - this.bufferStartOffset, littleEndian);
}
return super.getUint16At(offset, littleEndian);
}

/**
* @inheritDoc
*/
async getUint32At(offset, littleEndian = true) {
if (this.buffer && offset > this.bufferStartOffset && offset - this.bufferStartOffset + 4 < this.buffer.byteLength) {
return this.bufferView.getUint32(offset - this.bufferStartOffset, littleEndian);
}
return super.getUint32At(offset, littleEndian);
}

/**
* @inheritDoc
*/
async getBigUint64At(offset, littleEndian = true) {
if (this.buffer && offset > this.bufferStartOffset && offset - this.bufferStartOffset + 8 < this.buffer.byteLength) {
return BigIntUtils.getBigUint64FromView(this.bufferView, offset - this.bufferStartOffset, littleEndian);
}
return super.getBigUint64At(offset, littleEndian);
}

/**
* @inheritDoc
*/
Expand Down
110 changes: 110 additions & 0 deletions src/Reader/BufferedDataReader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import DataReader from './DataReader.js';
import ArmariusError from '../Error/ArmariusError.js';
import BigIntUtils from '../Util/BigIntUtils.js';

/**
* @abstract
*/
export default class BufferedDataReader extends DataReader {
/** @type {?Uint8Array} */ buffer;
/** @type {DataView} */ bufferView;
/** @type {Number} */ bufferStartOffset;

/**
* @inheritDoc
*/
async readAt(offset, length, longLived = true) {
if (this.buffer && offset >= this.bufferStartOffset && length <= this.buffer.byteLength - (offset - this.bufferStartOffset)) {
return this.readFromBuffer(offset, length, longLived);
}

if (length < this.bufferSize) {
this.setBuffer(offset, await this.readRaw(offset, Math.max(length, Math.min(this.bufferSize, this.byteLength - offset))));
return this.readFromBuffer(offset, length, longLived);
}

return await this.readRaw(offset, length);
}

/**
* @param {number} offset
* @param {number} length
* @protected
* @abstract
* @returns {Promise<Uint8Array>}
*/
async readRaw(offset, length) {

}

/**
* @param {number} offset
* @param {number} length
* @param {boolean} longLived
* @protected
* @returns {Uint8Array}
*/
readFromBuffer(offset, length, longLived = false) {
let bufferOffset = offset - this.bufferStartOffset;
if (bufferOffset < 0 || bufferOffset + length > this.buffer.byteLength) {
throw new ArmariusError(`Cannot read ${length} bytes of buffer at ${bufferOffset}`);
}

if (longLived && this.buffer.byteLength - length > 512) {
return this.buffer.slice(bufferOffset, bufferOffset + length);
}

return new Uint8Array(this.buffer.buffer, this.buffer.byteOffset + bufferOffset, length);
}

/**
* @param {number} bufferOffset
* @param {Uint8Array} data
* @protected
*/
setBuffer(bufferOffset, data) {
this.buffer = data;
this.bufferView = new DataView(data.buffer, data.byteOffset, data.byteLength);
this.bufferStartOffset = bufferOffset;
}

/**
* @inheritDoc
*/
async getUint8At(offset) {
if (this.buffer && offset > this.bufferStartOffset && offset - this.bufferStartOffset + 1 < this.buffer.byteLength) {
return this.bufferView.getUint8(offset - this.bufferStartOffset);
}
return super.getUint8At(offset);
}

/**
* @inheritDoc
*/
async getUint16At(offset, littleEndian = true) {
if (this.buffer && offset > this.bufferStartOffset && offset - this.bufferStartOffset + 2 < this.buffer.byteLength) {
return this.bufferView.getUint16(offset - this.bufferStartOffset, littleEndian);
}
return super.getUint16At(offset, littleEndian);
}

/**
* @inheritDoc
*/
async getUint32At(offset, littleEndian = true) {
if (this.buffer && offset > this.bufferStartOffset && offset - this.bufferStartOffset + 4 < this.buffer.byteLength) {
return this.bufferView.getUint32(offset - this.bufferStartOffset, littleEndian);
}
return super.getUint32At(offset, littleEndian);
}

/**
* @inheritDoc
*/
async getBigUint64At(offset, littleEndian = true) {
if (this.buffer && offset > this.bufferStartOffset && offset - this.bufferStartOffset + 8 < this.buffer.byteLength) {
return BigIntUtils.getBigUint64FromView(this.bufferView, offset - this.bufferStartOffset, littleEndian);
}
return super.getBigUint64At(offset, littleEndian);
}
}

0 comments on commit 789055f

Please sign in to comment.