UNPKG

nxkit

Version:

This is a collection of tools, independent of any other libraries

268 lines (267 loc) 9.52 kB
"use strict"; /* ***** BEGIN LICENSE BLOCK ***** * Distributed under the BSD license: * * Copyright (c) 2015, xuewen.chu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of xuewen.chu nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL xuewen.chu BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ Object.defineProperty(exports, "__esModule", { value: true }); const stream_1 = require("stream"); class BufferList extends stream_1.Duplex { constructor(callback) { super(); this._bufs = []; this._callback = null; this.length = 0; if (typeof callback == 'function') { this._callback = callback; var piper = (err) => { if (this._callback) { this._callback(err); this._callback = null; } }; this.on('pipe', function onPipe(src) { src.on('error', piper); }); this.on('unpipe', function onUnpipe(src) { src.removeListener('error', piper); }); } else if (callback) { this.append(callback); } } _offset(offset) { var tot = 0, i = 0, _t; if (offset === 0) return [0, 0]; for (; i < this._bufs.length; i++) { _t = tot + this._bufs[i].length; if (offset < _t || i == this._bufs.length - 1) return [i, offset - tot]; tot = _t; } return [0, 0]; } append(buf) { var i = 0; if (Buffer.isBuffer(buf)) { this._appendBuffer(buf); } else if (Array.isArray(buf)) { for (; i < buf.length; i++) this.append(buf[i]); } else if (buf instanceof BufferList) { // unwrap argument into individual BufferLists for (; i < buf._bufs.length; i++) this.append(buf._bufs[i]); } else if (buf != null) { // coerce number arguments to strings, since Buffer(number) does // uninitialized memory allocation if (typeof buf == 'number') buf = buf.toString(); this._appendBuffer(Buffer.from(buf)); } return this; } _appendBuffer(buf) { this._bufs.push(buf); this.length += buf.length; } _write(buf, encoding, callback) { this._appendBuffer(buf); if (typeof callback == 'function') callback(); } _read(size) { if (!this.length) return this.push(null); size = Math.min(size, this.length); this.push(this.slice(0, size)); this.consume(size); } end(chunk) { super.end(chunk); if (this._callback) { this._callback(null, this.slice()); this._callback = null; } } get(index) { return this.slice(index, index + 1)[0]; } slice(start, end) { if (typeof start == 'number' && start < 0) start += this.length; if (typeof end == 'number' && end < 0) end += this.length; return this.copy(null, 0, start, end); } copy(dst, dstStart, srcStart, srcEnd) { if (typeof srcStart != 'number' || srcStart < 0) srcStart = 0; if (typeof srcEnd != 'number' || srcEnd > this.length) srcEnd = this.length; if (srcStart >= this.length) return dst || Buffer.alloc(0); if (srcEnd <= 0) return dst || Buffer.alloc(0); var copy = !!dst, off = this._offset(srcStart), len = srcEnd - srcStart, bytes = len, bufoff = (copy && dstStart) || 0, start = off[1], l, i; // copy/slice everything if (srcStart === 0 && srcEnd == this.length) { if (!dst) { // slice, but full concat if multiple buffers return this._bufs.length === 1 ? this._bufs[0] : Buffer.concat(this._bufs, this.length); } // copy, need to copy individual buffers for (i = 0; i < this._bufs.length; i++) { this._bufs[i].copy(dst, bufoff); bufoff += this._bufs[i].length; } return dst; } // easy, cheap case where it's a subset of one of the buffers if (bytes <= this._bufs[off[0]].length - start) { if (dst) { this._bufs[off[0]].copy(dst, dstStart, start, start + bytes); return dst; } else { return this._bufs[off[0]].slice(start, start + bytes); } } if (!dst) // a slice, we need something to copy in to dst = Buffer.allocUnsafe(len); for (i = off[0]; i < this._bufs.length; i++) { l = this._bufs[i].length - start; if (bytes > l) { this._bufs[i].copy(dst, bufoff, start); } else { this._bufs[i].copy(dst, bufoff, start, start + bytes); break; } bufoff += l; bytes -= l; if (start) start = 0; } return dst; } shallowSlice(start, end) { start = start || 0; end = end || this.length; if (start < 0) start += this.length; if (end < 0) end += this.length; var startOffset = this._offset(start), endOffset = this._offset(end), buffers = this._bufs.slice(startOffset[0], endOffset[0] + 1); if (endOffset[1] == 0) buffers.pop(); else buffers[buffers.length - 1] = buffers[buffers.length - 1].slice(0, endOffset[1]); if (startOffset[1] != 0) buffers[0] = buffers[0].slice(startOffset[1]); return new BufferList(buffers); } toString(encoding, start, end) { return this.slice(start, end).toString(encoding); } consume(bytes) { while (this._bufs.length) { if (bytes >= this._bufs[0].length) { bytes -= this._bufs[0].length; this.length -= this._bufs[0].length; this._bufs.shift(); } else { this._bufs[0] = this._bufs[0].slice(bytes); this.length -= bytes; break; } } return this; } duplicate() { var i = 0; var copy = new BufferList(); for (; i < this._bufs.length; i++) copy.append(this._bufs[i]); return copy; } destroy() { this._bufs.length = 0; this.length = 0; this.push(null); } readDoubleBE(offset = 0) { return this.slice(offset, offset + 8).readDoubleBE(0); } readDoubleLE(offset = 0) { return this.slice(offset, offset + 8).readDoubleLE(0); } readFloatBE(offset = 0) { return this.slice(offset, offset + 4).readFloatBE(0); } readFloatLE(offset = 0) { return this.slice(offset, offset + 4).readFloatLE(0); } readInt32BE(offset = 0) { return this.slice(offset, offset + 4).readInt32BE(0); } readInt32LE(offset = 0) { return this.slice(offset, offset + 4).readInt32LE(0); } readUInt32BE(offset = 0) { return this.slice(offset, offset + 4).readUInt32BE(0); } readUInt32LE(offset = 0) { return this.slice(offset, offset + 4).readUInt32LE(0); } readInt16BE(offset = 0) { return this.slice(offset, offset + 2).readInt16BE(0); } readInt16LE(offset = 0) { return this.slice(offset, offset + 2).readInt16LE(0); } readUInt16BE(offset = 0) { return this.slice(offset, offset + 2).readUInt16BE(0); } readUInt16LE(offset = 0) { return this.slice(offset, offset + 2).readUInt16LE(0); } readInt8(offset = 0) { return this.slice(offset, offset + 1).readInt8(0); } readUInt8(offset = 0) { return this.slice(offset, offset + 1).readUInt8(0); } } exports.default = BufferList;