UNPKG

biner

Version:

Declarative binary data encoder / decoder.

295 lines 9.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const ll_1 = require("./ll"); class BufferList { constructor() { this.queue = new ll_1.LinkedList(); this.offset = 0; } get length() { return this.queue.length - this.offset; } append(buf) { if (Buffer.isBuffer(buf)) { if (this.offset > 0) { const head = this.queue.shift(); if (!head) throw new Error("queue is empty but offset is greater than 0"); this.queue.unshift(head.slice(this.offset)); this.offset = 0; } this.queue.push(buf); } else if (Array.isArray(buf)) { for (let i = 0; i < buf.length; i += 1) { this.append(buf[i]); } } else if (buf instanceof BufferList) { if (this.offset > 0) { const head = this.queue.shift(); if (!head) throw new Error("queue is empty but offset is greater than 0"); this.queue.unshift(head.slice(this.offset)); this.offset = 0; } if (buf.offset > 0) { const head = buf.queue.shift(); if (!head) throw new Error("queue is empty but offset is greater than 0"); buf.queue.unshift(head.slice(buf.offset)); buf.offset = 0; } let leaf = buf.queue.head; while (leaf) { this.queue.push(leaf.buffer); leaf = leaf.next; } } } get(index) { let i = index; while (i >= this.length) { i -= this.length; } while (i < 0) { i += this.length; } let leaf = this.queue.head; let { offset } = this; while (leaf) { if (leaf.buffer.length - offset > i) { return leaf.buffer[i + offset]; } i -= leaf.buffer.length - offset; offset = 0; leaf = leaf.next; } } slice(start, end) { if (typeof start !== 'number') { start = 0; } if (typeof end !== 'number') { end = this.length; } while (start < 0) { start += this.length; } while (end < 0) { end += this.length; } end = Math.min(end, this.length); if (start >= this.length || end === 0) { return Buffer.alloc(0); } const tmpStart = start; start = Math.min(tmpStart, end); end = Math.max(tmpStart, end); const subset = this.queue.slice(start + this.offset, end + this.offset); if (subset.count === 1) { return subset.first; } let leaf = subset.head; const target = Buffer.allocUnsafe(subset.length); let offset = 0; for (let i = 0; i < subset.count; i += 1) if (leaf) { target.set(leaf.buffer, offset); offset += leaf.buffer.length; leaf = leaf.next; } return target; } toString(encoding, start, end) { return this.slice(start, end).toString(encoding); } consume(bytes) { let remainder = bytes; while (this.length > 0 && this.queue.first) { const firstLength = this.queue.first.length - this.offset; if (remainder >= firstLength) { this.queue.shift(); remainder -= firstLength; this.offset = 0; } else { this.offset += remainder; break; } } } indexOf(byte, offset = 0) { if (!Number.isInteger(byte)) { throw new TypeError('Invalid argument 1'); } if (byte < 0 || byte > 0xff) { throw new Error('Invalid argument 1'); } if (!Number.isInteger(offset)) { offset = 0; } while (offset >= this.length) { offset -= this.length; } while (offset < 0) { offset += this.length; } let leaf = this.queue.head; let bias = 0; const next = () => { if (leaf) { bias += leaf.buffer.length; leaf = leaf.next; } }; while (leaf) { let byteOffset = 0; if (leaf === this.queue.head) { byteOffset += this.offset; } if (offset >= leaf.buffer.length - byteOffset) { offset -= leaf.buffer.length - byteOffset; next(); continue; } if (offset < leaf.buffer.length) { byteOffset += offset; } const index = leaf.buffer.indexOf(byte, byteOffset); if (index > -1) { return index + bias - this.offset; } next(); if (byteOffset > this.offset) { offset = 0; } } return -1; } doRead(method, size, offset = 0) { const start = offset + this.offset; const head = this.queue.first; if (!head) { throw new RangeError(); } return head.length - start >= size ? head[method](start, size) : this.slice(offset, offset + size)[method](0, size); } doWrite(method, value, size) { const buf = Buffer.allocUnsafe(size); const ret = buf[method](value, 0, size); this.append(buf); return ret; } readDoubleBE(offset) { return this.doRead('readDoubleBE', 8, offset); } readDoubleLE(offset) { return this.doRead('readDoubleLE', 8, offset); } readFloatBE(offset) { return this.doRead('readFloatBE', 4, offset); } readFloatLE(offset) { return this.doRead('readFloatLE', 4, offset); } readInt16BE(offset) { return this.doRead('readInt16BE', 2, offset); } readInt16LE(offset) { return this.doRead('readInt16LE', 2, offset); } readInt32BE(offset) { return this.doRead('readInt32BE', 4, offset); } readInt32LE(offset) { return this.doRead('readInt32LE', 4, offset); } readInt8(offset) { return this.doRead('readInt8', 1, offset); } readIntBE(offset, byteLength) { return this.doRead('readIntBE', byteLength, offset); } readIntLE(offset, byteLength) { return this.doRead('readIntLE', byteLength, offset); } readUInt16BE(offset) { return this.doRead('readUInt16BE', 2, offset); } readUInt16LE(offset) { return this.doRead('readUInt16LE', 2, offset); } readUInt32BE(offset) { return this.doRead('readUInt32BE', 4, offset); } readUInt32LE(offset) { return this.doRead('readUInt32LE', 4, offset); } readUInt8(offset) { return this.doRead('readUInt8', 1, offset); } readUIntBE(offset, byteLength) { return this.doRead('readUIntBE', byteLength, offset); } readUIntLE(offset, byteLength) { return this.doRead('readUIntLE', byteLength, offset); } writeDoubleBE(value) { return this.doWrite('writeDoubleBE', value, 8); } writeDoubleLE(value) { return this.doWrite('writeDoubleLE', value, 8); } writeFloatBE(value) { return this.doWrite('writeFloatBE', value, 4); } writeFloatLE(value) { return this.doWrite('writeFloatLE', value, 4); } writeInt16BE(value) { return this.doWrite('writeInt16BE', value, 2); } writeInt16LE(value) { return this.doWrite('writeInt16LE', value, 2); } writeInt32BE(value) { return this.doWrite('writeInt32BE', value, 4); } writeInt32LE(value) { return this.doWrite('writeInt32LE', value, 4); } writeInt8(value) { return this.doWrite('writeInt8', value, 1); } writeIntBE(value, byteLength) { return this.doWrite('writeIntBE', value, byteLength); } writeIntLE(value, byteLength) { return this.doWrite('writeIntLE', value, byteLength); } writeUInt16BE(value) { return this.doWrite('writeUInt16BE', value, 2); } writeUInt16LE(value) { return this.doWrite('writeUInt16LE', value, 2); } writeUInt32BE(value) { return this.doWrite('writeUInt32BE', value, 4); } writeUInt32LE(value) { return this.doWrite('writeUInt32LE', value, 4); } writeUInt8(value) { return this.doWrite('writeUInt8', value, 1); } writeUIntBE(value, byteLength) { return this.doWrite('writeUIntBE', value, byteLength); } writeUIntLE(value, byteLength) { return this.doWrite('writeUIntLE', value, byteLength); } } exports.BufferList = BufferList; //# sourceMappingURL=bl.js.map