| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 | 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 APIsfunction 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());};
 |