Version 1
[yaffs-website] / node_modules / bl / bl.js
1 var DuplexStream = require('readable-stream/duplex')
2   , util         = require('util')
3
4 function BufferList (callback) {
5   if (!(this instanceof BufferList))
6     return new BufferList(callback)
7
8   this._bufs  = []
9   this.length = 0
10
11   if (typeof callback == 'function') {
12     this._callback = callback
13
14     var piper = function (err) {
15       if (this._callback) {
16         this._callback(err)
17         this._callback = null
18       }
19     }.bind(this)
20
21     this.on('pipe', function (src) {
22       src.on('error', piper)
23     })
24     this.on('unpipe', function (src) {
25       src.removeListener('error', piper)
26     })
27   }
28   else if (Buffer.isBuffer(callback))
29     this.append(callback)
30   else if (Array.isArray(callback)) {
31     callback.forEach(function (b) {
32       Buffer.isBuffer(b) && this.append(b)
33     }.bind(this))
34   }
35
36   DuplexStream.call(this)
37 }
38
39 util.inherits(BufferList, DuplexStream)
40
41 BufferList.prototype._offset = function (offset) {
42   var tot = 0, i = 0, _t
43   for (; i < this._bufs.length; i++) {
44     _t = tot + this._bufs[i].length
45     if (offset < _t)
46       return [ i, offset - tot ]
47     tot = _t
48   }
49 }
50
51 BufferList.prototype.append = function (buf) {
52   var isBuffer = Buffer.isBuffer(buf) ||
53                  buf instanceof BufferList
54
55   // coerce number arguments to strings, since Buffer(number) does
56   // uninitialized memory allocation
57   if (typeof buf == 'number')
58     buf = buf.toString()
59
60   if (buf instanceof BufferList) {
61     this._bufs.push.apply(this._bufs, buf._bufs)
62     this.length += buf.length
63   } else {
64     this._bufs.push(isBuffer ? buf : new Buffer(buf))
65     this.length += buf.length
66   }
67
68   return this
69 }
70
71 BufferList.prototype._write = function (buf, encoding, callback) {
72   this.append(buf)
73   if (callback)
74     callback()
75 }
76
77 BufferList.prototype._read = function (size) {
78   if (!this.length)
79     return this.push(null)
80   size = Math.min(size, this.length)
81   this.push(this.slice(0, size))
82   this.consume(size)
83 }
84
85 BufferList.prototype.end = function (chunk) {
86   DuplexStream.prototype.end.call(this, chunk)
87
88   if (this._callback) {
89     this._callback(null, this.slice())
90     this._callback = null
91   }
92 }
93
94 BufferList.prototype.get = function (index) {
95   return this.slice(index, index + 1)[0]
96 }
97
98 BufferList.prototype.slice = function (start, end) {
99   return this.copy(null, 0, start, end)
100 }
101
102 BufferList.prototype.copy = function (dst, dstStart, srcStart, srcEnd) {
103   if (typeof srcStart != 'number' || srcStart < 0)
104     srcStart = 0
105   if (typeof srcEnd != 'number' || srcEnd > this.length)
106     srcEnd = this.length
107   if (srcStart >= this.length)
108     return dst || new Buffer(0)
109   if (srcEnd <= 0)
110     return dst || new Buffer(0)
111
112   var copy   = !!dst
113     , off    = this._offset(srcStart)
114     , len    = srcEnd - srcStart
115     , bytes  = len
116     , bufoff = (copy && dstStart) || 0
117     , start  = off[1]
118     , l
119     , i
120
121   // copy/slice everything
122   if (srcStart === 0 && srcEnd == this.length) {
123     if (!copy) // slice, just return a full concat
124       return Buffer.concat(this._bufs)
125
126     // copy, need to copy individual buffers
127     for (i = 0; i < this._bufs.length; i++) {
128       this._bufs[i].copy(dst, bufoff)
129       bufoff += this._bufs[i].length
130     }
131
132     return dst
133   }
134
135   // easy, cheap case where it's a subset of one of the buffers
136   if (bytes <= this._bufs[off[0]].length - start) {
137     return copy
138       ? this._bufs[off[0]].copy(dst, dstStart, start, start + bytes)
139       : this._bufs[off[0]].slice(start, start + bytes)
140   }
141
142   if (!copy) // a slice, we need something to copy in to
143     dst = new Buffer(len)
144
145   for (i = off[0]; i < this._bufs.length; i++) {
146     l = this._bufs[i].length - start
147
148     if (bytes > l) {
149       this._bufs[i].copy(dst, bufoff, start)
150     } else {
151       this._bufs[i].copy(dst, bufoff, start, start + bytes)
152       break
153     }
154
155     bufoff += l
156     bytes -= l
157
158     if (start)
159       start = 0
160   }
161
162   return dst
163 }
164
165 BufferList.prototype.toString = function (encoding, start, end) {
166   return this.slice(start, end).toString(encoding)
167 }
168
169 BufferList.prototype.consume = function (bytes) {
170   while (this._bufs.length) {
171     if (bytes >= this._bufs[0].length) {
172       bytes -= this._bufs[0].length
173       this.length -= this._bufs[0].length
174       this._bufs.shift()
175     } else {
176       this._bufs[0] = this._bufs[0].slice(bytes)
177       this.length -= bytes
178       break
179     }
180   }
181   return this
182 }
183
184 BufferList.prototype.duplicate = function () {
185   var i = 0
186     , copy = new BufferList()
187
188   for (; i < this._bufs.length; i++)
189     copy.append(this._bufs[i])
190
191   return copy
192 }
193
194 BufferList.prototype.destroy = function () {
195   this._bufs.length = 0;
196   this.length = 0;
197   this.push(null);
198 }
199
200 ;(function () {
201   var methods = {
202       'readDoubleBE' : 8
203     , 'readDoubleLE' : 8
204     , 'readFloatBE'  : 4
205     , 'readFloatLE'  : 4
206     , 'readInt32BE'  : 4
207     , 'readInt32LE'  : 4
208     , 'readUInt32BE' : 4
209     , 'readUInt32LE' : 4
210     , 'readInt16BE'  : 2
211     , 'readInt16LE'  : 2
212     , 'readUInt16BE' : 2
213     , 'readUInt16LE' : 2
214     , 'readInt8'     : 1
215     , 'readUInt8'    : 1
216   }
217
218   for (var m in methods) {
219     (function (m) {
220       BufferList.prototype[m] = function (offset) {
221         return this.slice(offset, offset + methods[m])[m](0)
222       }
223     }(m))
224   }
225 }())
226
227 module.exports = BufferList