123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- module.exports = Buffers;
- function Buffers (bufs) {
- if (!(this instanceof Buffers)) return new Buffers(bufs);
- this.buffers = bufs || [];
- this.length = this.buffers.reduce(function (size, buf) {
- return size + buf.length
- }, 0);
- }
- Buffers.prototype.push = function () {
- for (var i = 0; i < arguments.length; i++) {
- if (!Buffer.isBuffer(arguments[i])) {
- throw new TypeError('Tried to push a non-buffer');
- }
- }
-
- for (var i = 0; i < arguments.length; i++) {
- var buf = arguments[i];
- this.buffers.push(buf);
- this.length += buf.length;
- }
- return this.length;
- };
- Buffers.prototype.unshift = function () {
- for (var i = 0; i < arguments.length; i++) {
- if (!Buffer.isBuffer(arguments[i])) {
- throw new TypeError('Tried to unshift a non-buffer');
- }
- }
-
- for (var i = 0; i < arguments.length; i++) {
- var buf = arguments[i];
- this.buffers.unshift(buf);
- this.length += buf.length;
- }
- return this.length;
- };
- Buffers.prototype.copy = function (dst, dStart, start, end) {
- return this.slice(start, end).copy(dst, dStart, 0, end - start);
- };
- Buffers.prototype.splice = function (i, howMany) {
- var buffers = this.buffers;
- var index = i >= 0 ? i : this.length - i;
- var reps = [].slice.call(arguments, 2);
-
- if (howMany === undefined) {
- howMany = this.length - index;
- }
- else if (howMany > this.length - index) {
- howMany = this.length - index;
- }
-
- for (var i = 0; i < reps.length; i++) {
- this.length += reps[i].length;
- }
-
- var removed = new Buffers();
- var bytes = 0;
-
- var startBytes = 0;
- for (
- var ii = 0;
- ii < buffers.length && startBytes + buffers[ii].length < index;
- ii ++
- ) { startBytes += buffers[ii].length }
-
- if (index - startBytes > 0) {
- var start = index - startBytes;
-
- if (start + howMany < buffers[ii].length) {
- removed.push(buffers[ii].slice(start, start + howMany));
-
- var orig = buffers[ii];
- //var buf = new Buffer(orig.length - howMany);
- var buf0 = new Buffer(start);
- for (var i = 0; i < start; i++) {
- buf0[i] = orig[i];
- }
-
- var buf1 = new Buffer(orig.length - start - howMany);
- for (var i = start + howMany; i < orig.length; i++) {
- buf1[ i - howMany - start ] = orig[i]
- }
-
- if (reps.length > 0) {
- var reps_ = reps.slice();
- reps_.unshift(buf0);
- reps_.push(buf1);
- buffers.splice.apply(buffers, [ ii, 1 ].concat(reps_));
- ii += reps_.length;
- reps = [];
- }
- else {
- buffers.splice(ii, 1, buf0, buf1);
- //buffers[ii] = buf;
- ii += 2;
- }
- }
- else {
- removed.push(buffers[ii].slice(start));
- buffers[ii] = buffers[ii].slice(0, start);
- ii ++;
- }
- }
-
- if (reps.length > 0) {
- buffers.splice.apply(buffers, [ ii, 0 ].concat(reps));
- ii += reps.length;
- }
-
- while (removed.length < howMany) {
- var buf = buffers[ii];
- var len = buf.length;
- var take = Math.min(len, howMany - removed.length);
-
- if (take === len) {
- removed.push(buf);
- buffers.splice(ii, 1);
- }
- else {
- removed.push(buf.slice(0, take));
- buffers[ii] = buffers[ii].slice(take);
- }
- }
-
- this.length -= removed.length;
-
- return removed;
- };
-
- Buffers.prototype.slice = function (i, j) {
- var buffers = this.buffers;
- if (j === undefined) j = this.length;
- if (i === undefined) i = 0;
-
- if (j > this.length) j = this.length;
-
- var startBytes = 0;
- for (
- var si = 0;
- si < buffers.length && startBytes + buffers[si].length <= i;
- si ++
- ) { startBytes += buffers[si].length }
-
- var target = new Buffer(j - i);
-
- var ti = 0;
- for (var ii = si; ti < j - i && ii < buffers.length; ii++) {
- var len = buffers[ii].length;
-
- var start = ti === 0 ? i - startBytes : 0;
- var end = ti + len >= j - i
- ? Math.min(start + (j - i) - ti, len)
- : len
- ;
-
- buffers[ii].copy(target, ti, start, end);
- ti += end - start;
- }
-
- return target;
- };
- Buffers.prototype.pos = function (i) {
- if (i < 0 || i >= this.length) throw new Error('oob');
- var l = i, bi = 0, bu = null;
- for (;;) {
- bu = this.buffers[bi];
- if (l < bu.length) {
- return {buf: bi, offset: l};
- } else {
- l -= bu.length;
- }
- bi++;
- }
- };
- Buffers.prototype.get = function get (i) {
- var pos = this.pos(i);
- return this.buffers[pos.buf].get(pos.offset);
- };
- Buffers.prototype.set = function set (i, b) {
- var pos = this.pos(i);
- return this.buffers[pos.buf].set(pos.offset, b);
- };
- Buffers.prototype.indexOf = function (needle, offset) {
- if ("string" === typeof needle) {
- needle = new Buffer(needle);
- } else if (needle instanceof Buffer) {
- // already a buffer
- } else {
- throw new Error('Invalid type for a search string');
- }
- if (!needle.length) {
- return 0;
- }
- if (!this.length) {
- return -1;
- }
- var i = 0, j = 0, match = 0, mstart, pos = 0;
- // start search from a particular point in the virtual buffer
- if (offset) {
- var p = this.pos(offset);
- i = p.buf;
- j = p.offset;
- pos = offset;
- }
- // for each character in virtual buffer
- for (;;) {
- while (j >= this.buffers[i].length) {
- j = 0;
- i++;
- if (i >= this.buffers.length) {
- // search string not found
- return -1;
- }
- }
- var char = this.buffers[i][j];
- if (char == needle[match]) {
- // keep track where match started
- if (match == 0) {
- mstart = {
- i: i,
- j: j,
- pos: pos
- };
- }
- match++;
- if (match == needle.length) {
- // full match
- return mstart.pos;
- }
- } else if (match != 0) {
- // a partial match ended, go back to match starting position
- // this will continue the search at the next character
- i = mstart.i;
- j = mstart.j;
- pos = mstart.pos;
- match = 0;
- }
- j++;
- pos++;
- }
- };
- Buffers.prototype.toBuffer = function() {
- return this.slice();
- }
- Buffers.prototype.toString = function(encoding, start, end) {
- return this.slice(start, end).toString(encoding);
- }
|