You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
5.6 KiB
173 lines
5.6 KiB
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.createCursor = createCursor;
|
|
const cursor_js_1 = require("../errors/cursor.js");
|
|
const staticCursor = {
|
|
bytes: new Uint8Array(),
|
|
dataView: new DataView(new ArrayBuffer(0)),
|
|
position: 0,
|
|
positionReadCount: new Map(),
|
|
recursiveReadCount: 0,
|
|
recursiveReadLimit: Number.POSITIVE_INFINITY,
|
|
assertReadLimit() {
|
|
if (this.recursiveReadCount >= this.recursiveReadLimit)
|
|
throw new cursor_js_1.RecursiveReadLimitExceededError({
|
|
count: this.recursiveReadCount + 1,
|
|
limit: this.recursiveReadLimit,
|
|
});
|
|
},
|
|
assertPosition(position) {
|
|
if (position < 0 || position > this.bytes.length - 1)
|
|
throw new cursor_js_1.PositionOutOfBoundsError({
|
|
length: this.bytes.length,
|
|
position,
|
|
});
|
|
},
|
|
decrementPosition(offset) {
|
|
if (offset < 0)
|
|
throw new cursor_js_1.NegativeOffsetError({ offset });
|
|
const position = this.position - offset;
|
|
this.assertPosition(position);
|
|
this.position = position;
|
|
},
|
|
getReadCount(position) {
|
|
return this.positionReadCount.get(position || this.position) || 0;
|
|
},
|
|
incrementPosition(offset) {
|
|
if (offset < 0)
|
|
throw new cursor_js_1.NegativeOffsetError({ offset });
|
|
const position = this.position + offset;
|
|
this.assertPosition(position);
|
|
this.position = position;
|
|
},
|
|
inspectByte(position_) {
|
|
const position = position_ ?? this.position;
|
|
this.assertPosition(position);
|
|
return this.bytes[position];
|
|
},
|
|
inspectBytes(length, position_) {
|
|
const position = position_ ?? this.position;
|
|
this.assertPosition(position + length - 1);
|
|
return this.bytes.subarray(position, position + length);
|
|
},
|
|
inspectUint8(position_) {
|
|
const position = position_ ?? this.position;
|
|
this.assertPosition(position);
|
|
return this.bytes[position];
|
|
},
|
|
inspectUint16(position_) {
|
|
const position = position_ ?? this.position;
|
|
this.assertPosition(position + 1);
|
|
return this.dataView.getUint16(position);
|
|
},
|
|
inspectUint24(position_) {
|
|
const position = position_ ?? this.position;
|
|
this.assertPosition(position + 2);
|
|
return ((this.dataView.getUint16(position) << 8) +
|
|
this.dataView.getUint8(position + 2));
|
|
},
|
|
inspectUint32(position_) {
|
|
const position = position_ ?? this.position;
|
|
this.assertPosition(position + 3);
|
|
return this.dataView.getUint32(position);
|
|
},
|
|
pushByte(byte) {
|
|
this.assertPosition(this.position);
|
|
this.bytes[this.position] = byte;
|
|
this.position++;
|
|
},
|
|
pushBytes(bytes) {
|
|
this.assertPosition(this.position + bytes.length - 1);
|
|
this.bytes.set(bytes, this.position);
|
|
this.position += bytes.length;
|
|
},
|
|
pushUint8(value) {
|
|
this.assertPosition(this.position);
|
|
this.bytes[this.position] = value;
|
|
this.position++;
|
|
},
|
|
pushUint16(value) {
|
|
this.assertPosition(this.position + 1);
|
|
this.dataView.setUint16(this.position, value);
|
|
this.position += 2;
|
|
},
|
|
pushUint24(value) {
|
|
this.assertPosition(this.position + 2);
|
|
this.dataView.setUint16(this.position, value >> 8);
|
|
this.dataView.setUint8(this.position + 2, value & ~4294967040);
|
|
this.position += 3;
|
|
},
|
|
pushUint32(value) {
|
|
this.assertPosition(this.position + 3);
|
|
this.dataView.setUint32(this.position, value);
|
|
this.position += 4;
|
|
},
|
|
readByte() {
|
|
this.assertReadLimit();
|
|
this._touch();
|
|
const value = this.inspectByte();
|
|
this.position++;
|
|
return value;
|
|
},
|
|
readBytes(length, size) {
|
|
this.assertReadLimit();
|
|
this._touch();
|
|
const value = this.inspectBytes(length);
|
|
this.position += size ?? length;
|
|
return value;
|
|
},
|
|
readUint8() {
|
|
this.assertReadLimit();
|
|
this._touch();
|
|
const value = this.inspectUint8();
|
|
this.position += 1;
|
|
return value;
|
|
},
|
|
readUint16() {
|
|
this.assertReadLimit();
|
|
this._touch();
|
|
const value = this.inspectUint16();
|
|
this.position += 2;
|
|
return value;
|
|
},
|
|
readUint24() {
|
|
this.assertReadLimit();
|
|
this._touch();
|
|
const value = this.inspectUint24();
|
|
this.position += 3;
|
|
return value;
|
|
},
|
|
readUint32() {
|
|
this.assertReadLimit();
|
|
this._touch();
|
|
const value = this.inspectUint32();
|
|
this.position += 4;
|
|
return value;
|
|
},
|
|
get remaining() {
|
|
return this.bytes.length - this.position;
|
|
},
|
|
setPosition(position) {
|
|
const oldPosition = this.position;
|
|
this.assertPosition(position);
|
|
this.position = position;
|
|
return () => (this.position = oldPosition);
|
|
},
|
|
_touch() {
|
|
if (this.recursiveReadLimit === Number.POSITIVE_INFINITY)
|
|
return;
|
|
const count = this.getReadCount();
|
|
this.positionReadCount.set(this.position, count + 1);
|
|
if (count > 0)
|
|
this.recursiveReadCount++;
|
|
},
|
|
};
|
|
function createCursor(bytes, { recursiveReadLimit = 8_192 } = {}) {
|
|
const cursor = Object.create(staticCursor);
|
|
cursor.bytes = bytes;
|
|
cursor.dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
cursor.positionReadCount = new Map();
|
|
cursor.recursiveReadLimit = recursiveReadLimit;
|
|
return cursor;
|
|
}
|
|
//# sourceMappingURL=cursor.js.map
|