UNPKG

viem

Version:

TypeScript Interface for Ethereum

170 lines 5.63 kB
import { NegativeOffsetError, PositionOutOfBoundsError, RecursiveReadLimitExceededError, } from '../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 RecursiveReadLimitExceededError({ count: this.recursiveReadCount + 1, limit: this.recursiveReadLimit, }); }, assertPosition(position) { if (position < 0 || position > this.bytes.length - 1) throw new PositionOutOfBoundsError({ length: this.bytes.length, position, }); }, decrementPosition(offset) { if (offset < 0) throw new 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 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++; }, }; export 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