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.
|
|
var Buffer = require('buffer').Buffer;
function OffsetBuffer() { this.offset = 0; this.size = 0; this.buffers = []; } module.exports = OffsetBuffer;
OffsetBuffer.prototype.isEmpty = function isEmpty() { return this.size === 0; };
OffsetBuffer.prototype.clone = function clone(size) { var r = new OffsetBuffer(); r.offset = this.offset; r.size = size; r.buffers = this.buffers.slice(); return r; };
OffsetBuffer.prototype.toChunks = function toChunks() { if (this.size === 0) return [];
// We are going to slice it anyway
if (this.offset !== 0) { this.buffers[0] = this.buffers[0].slice(this.offset); this.offset = 0; }
var chunks = [ ]; var off = 0; for (var i = 0; off <= this.size && i < this.buffers.length; i++) { var buf = this.buffers[i]; off += buf.length;
// Slice off last buffer
if (off > this.size) { buf = buf.slice(0, buf.length - (off - this.size)); this.buffers[i] = buf; }
chunks.push(buf); }
// If some buffers were skipped - trim length
if (i < this.buffers.length) this.buffers.length = i;
return chunks; };
OffsetBuffer.prototype.toString = function toString(enc) { return this.toChunks().map(function(c) { return c.toString(enc); }).join(''); };
OffsetBuffer.prototype.use = function use(buf, off, n) { this.buffers = [ buf ]; this.offset = off; this.size = n; };
OffsetBuffer.prototype.push = function push(data) { // Ignore empty writes
if (data.length === 0) return;
this.size += data.length; this.buffers.push(data); };
OffsetBuffer.prototype.has = function has(n) { return this.size >= n; };
OffsetBuffer.prototype.skip = function skip(n) { if (this.size === 0) return;
this.size -= n;
// Fast case, skip bytes in a first buffer
if (this.offset + n < this.buffers[0].length) { this.offset += n; return; }
var left = n - (this.buffers[0].length - this.offset); this.offset = 0;
for (var shift = 1; left > 0 && shift < this.buffers.length; shift++) { var buf = this.buffers[shift]; if (buf.length > left) { this.offset = left; break; } left -= buf.length; } this.buffers = this.buffers.slice(shift); };
OffsetBuffer.prototype.copy = function copy(target, targetOff, off, n) { if (this.size === 0) return; if (off !== 0) throw new Error('Unsupported offset in .copy()');
var toff = targetOff; var first = this.buffers[0]; var toCopy = Math.min(n, first.length - this.offset); first.copy(target, toff, this.offset, this.offset + toCopy);
toff += toCopy; var left = n - toCopy; for (var i = 1; left > 0 && i < this.buffers.length; i++) { var buf = this.buffers[i]; var toCopy = Math.min(left, buf.length);
buf.copy(target, toff, 0, toCopy);
toff += toCopy; left -= toCopy; } };
OffsetBuffer.prototype.take = function take(n) { if (n === 0) return new Buffer(0);
this.size -= n;
// Fast cases
var first = this.buffers[0].length - this.offset; if (first === n) { var r = this.buffers.shift(); if (this.offset !== 0) { r = r.slice(this.offset); this.offset = 0; } return r; } else if (first > n) { var r = this.buffers[0].slice(this.offset, this.offset + n); this.offset += n; return r; }
// Allocate and fill buffer
var out = new Buffer(n); var toOff = 0; var startOff = this.offset; for (var i = 0; toOff !== n && i < this.buffers.length; i++) { var buf = this.buffers[i]; var toCopy = Math.min(buf.length - startOff, n - toOff);
buf.copy(out, toOff, startOff, startOff + toCopy); if (startOff + toCopy < buf.length) { this.offset = startOff + toCopy; break; } else { toOff += toCopy; startOff = 0; } }
this.buffers = this.buffers.slice(i); if (this.buffers.length === 0) this.offset = 0;
return out; };
OffsetBuffer.prototype.peekUInt8 = function peekUInt8() { return this.buffers[0][this.offset]; };
OffsetBuffer.prototype.readUInt8 = function readUInt8() { this.size -= 1; var first = this.buffers[0]; var r = first[this.offset]; if (++this.offset === first.length) { this.offset = 0; this.buffers.shift(); }
return r; };
OffsetBuffer.prototype.readUInt16LE = function readUInt16LE() { var first = this.buffers[0]; this.size -= 2;
var r; var shift;
// Fast case - first buffer has all bytes
if (first.length - this.offset >= 2) { r = first.readUInt16LE(this.offset); shift = 0; this.offset += 2;
// One byte here - one byte there
} else { r = first[this.offset] | (this.buffers[1][0] << 8); shift = 1; this.offset = 1; }
if (this.offset === this.buffers[shift].length) { this.offset = 0; shift++; } if (shift !== 0) this.buffers = this.buffers.slice(shift);
return r; };
OffsetBuffer.prototype.readUInt24LE = function readUInt24LE() { var first = this.buffers[0];
var r; var shift; var firstHas = first.length - this.offset;
// Fast case - first buffer has all bytes
if (firstHas >= 3) { r = first.readUInt16LE(this.offset) | (first[this.offset + 2] << 16); shift = 0; this.offset += 3;
// First buffer has 2 of 3 bytes
} else if (firstHas >= 2) { r = first.readUInt16LE(this.offset) | (this.buffers[1][0] << 16); shift = 1; this.offset = 1;
// Slow case: First buffer has 1 of 3 bytes
} else { r = first[this.offset]; this.offset = 0; this.buffers.shift(); this.size -= 1;
r |= this.readUInt16LE() << 8; return r; }
this.size -= 3; if (this.offset === this.buffers[shift].length) { this.offset = 0; shift++; } if (shift !== 0) this.buffers = this.buffers.slice(shift);
return r; };
OffsetBuffer.prototype.readUInt32LE = function readUInt32LE() { var first = this.buffers[0];
var r; var shift; var firstHas = first.length - this.offset;
// Fast case - first buffer has all bytes
if (firstHas >= 4) { r = first.readUInt32LE(this.offset); shift = 0; this.offset += 4;
// First buffer has 3 of 4 bytes
} else if (firstHas >= 3) { r = (first.readUInt16LE(this.offset) | (first[this.offset + 2] << 16)) + (this.buffers[1][0] * 0x1000000); shift = 1; this.offset = 1;
// Slow case: First buffer has 2 of 4 bytes
} else if (firstHas >= 2) { r = first.readUInt16LE(this.offset); this.offset = 0; this.buffers.shift(); this.size -= 2;
r += this.readUInt16LE() * 0x10000; return r;
// Slow case: First buffer has 1 of 4 bytes
} else { r = first[this.offset]; this.offset = 0; this.buffers.shift(); this.size -= 1;
r += this.readUInt24LE() * 0x100; return r; }
this.size -= 4; if (this.offset === this.buffers[shift].length) { this.offset = 0; shift++; } if (shift !== 0) this.buffers = this.buffers.slice(shift);
return r; };
OffsetBuffer.prototype.readUInt16BE = function readUInt16BE() { var r = this.readUInt16LE();
return ((r & 0xff) << 8) | (r >> 8); };
OffsetBuffer.prototype.readUInt24BE = function readUInt24BE() { var r = this.readUInt24LE();
return ((r & 0xff) << 16) | (((r >> 8) & 0xff) << 8) | (r >> 16); };
OffsetBuffer.prototype.readUInt32BE = function readUInt32BE() { var r = this.readUInt32LE();
return (((r & 0xff) << 24) | (((r >>> 8) & 0xff) << 16) | (((r >>> 16) & 0xff) << 8) | (r >>> 24)) >>> 0; };
// Signed number APIs
function signedInt8(num) { if (num >= 0x80) return -(0xff ^ num) - 1; else return num; }
OffsetBuffer.prototype.peekInt8 = function peekInt8() { return signedInt8(this.peekUInt8()); };
OffsetBuffer.prototype.readInt8 = function readInt8() { return signedInt8(this.readUInt8()); };
function signedInt16(num) { if (num >= 0x8000) return -(0xffff ^ num) - 1; else return num; }
OffsetBuffer.prototype.readInt16BE = function readInt16BE() { return signedInt16(this.readUInt16BE()); };
OffsetBuffer.prototype.readInt16LE = function readInt16LE() { return signedInt16(this.readUInt16LE()); };
function signedInt24(num) { if (num >= 0x800000) return -(0xffffff ^ num) - 1; else return num; }
OffsetBuffer.prototype.readInt24BE = function readInt24BE() { return signedInt24(this.readUInt24BE()); };
OffsetBuffer.prototype.readInt24LE = function readInt24LE() { return signedInt24(this.readUInt24LE()); };
function signedInt32(num) { if (num >= 0x80000000) return -(0xffffffff ^ num) - 1; else return num; }
OffsetBuffer.prototype.readInt32BE = function readInt32BE() { return signedInt32(this.readUInt32BE()); };
OffsetBuffer.prototype.readInt32LE = function readInt32LE() { return signedInt32(this.readUInt32LE()); };
|