Files: 4f27567900a7b5b821bccc74e95bfc96c8233159 / node_modules / bl / bl.js
9308 bytesRaw
1 | |
2 | var DuplexStream = require('readable-stream').Duplex |
3 | , util = require('util') |
4 | |
5 | function BufferList (callback) { |
6 | if (!(this instanceof BufferList)) |
7 | return new BufferList(callback) |
8 | |
9 | this._bufs = [] |
10 | this.length = 0 |
11 | |
12 | if (typeof callback == 'function') { |
13 | this._callback = callback |
14 | |
15 | var piper = function piper (err) { |
16 | if (this._callback) { |
17 | this._callback(err) |
18 | this._callback = null |
19 | } |
20 | }.bind(this) |
21 | |
22 | this.on('pipe', function onPipe (src) { |
23 | src.on('error', piper) |
24 | }) |
25 | this.on('unpipe', function onUnpipe (src) { |
26 | src.removeListener('error', piper) |
27 | }) |
28 | } else { |
29 | this.append(callback) |
30 | } |
31 | |
32 | DuplexStream.call(this) |
33 | } |
34 | |
35 | |
36 | util.inherits(BufferList, DuplexStream) |
37 | |
38 | |
39 | BufferList.prototype._offset = function _offset (offset) { |
40 | var tot = 0, i = 0, _t |
41 | if (offset === 0) return [ 0, 0 ] |
42 | for (; i < this._bufs.length; i++) { |
43 | _t = tot + this._bufs[i].length |
44 | if (offset < _t || i == this._bufs.length - 1) { |
45 | return [ i, offset - tot ] |
46 | } |
47 | tot = _t |
48 | } |
49 | } |
50 | |
51 | BufferList.prototype._reverseOffset = function (blOffset) { |
52 | var bufferId = blOffset[0] |
53 | var offset = blOffset[1] |
54 | for (var i = 0; i < bufferId; i++) { |
55 | offset += this._bufs[i].length |
56 | } |
57 | return offset |
58 | } |
59 | |
60 | BufferList.prototype.append = function append (buf) { |
61 | var i = 0 |
62 | |
63 | if (Buffer.isBuffer(buf)) { |
64 | this._appendBuffer(buf) |
65 | } else if (Array.isArray(buf)) { |
66 | for (; i < buf.length; i++) |
67 | this.append(buf[i]) |
68 | } else if (buf instanceof BufferList) { |
69 | // unwrap argument into individual BufferLists |
70 | for (; i < buf._bufs.length; i++) |
71 | this.append(buf._bufs[i]) |
72 | } else if (buf != null) { |
73 | // coerce number arguments to strings, since Buffer(number) does |
74 | // uninitialized memory allocation |
75 | if (typeof buf == 'number') |
76 | buf = buf.toString() |
77 | |
78 | this._appendBuffer(Buffer.from(buf)) |
79 | } |
80 | |
81 | return this |
82 | } |
83 | |
84 | |
85 | BufferList.prototype._appendBuffer = function appendBuffer (buf) { |
86 | this._bufs.push(buf) |
87 | this.length += buf.length |
88 | } |
89 | |
90 | |
91 | BufferList.prototype._write = function _write (buf, encoding, callback) { |
92 | this._appendBuffer(buf) |
93 | |
94 | if (typeof callback == 'function') |
95 | callback() |
96 | } |
97 | |
98 | |
99 | BufferList.prototype._read = function _read (size) { |
100 | if (!this.length) |
101 | return this.push(null) |
102 | |
103 | size = Math.min(size, this.length) |
104 | this.push(this.slice(0, size)) |
105 | this.consume(size) |
106 | } |
107 | |
108 | |
109 | BufferList.prototype.end = function end (chunk) { |
110 | DuplexStream.prototype.end.call(this, chunk) |
111 | |
112 | if (this._callback) { |
113 | this._callback(null, this.slice()) |
114 | this._callback = null |
115 | } |
116 | } |
117 | |
118 | |
119 | BufferList.prototype.get = function get (index) { |
120 | if (index > this.length || index < 0) { |
121 | return undefined |
122 | } |
123 | var offset = this._offset(index) |
124 | return this._bufs[offset[0]][offset[1]] |
125 | } |
126 | |
127 | |
128 | BufferList.prototype.slice = function slice (start, end) { |
129 | if (typeof start == 'number' && start < 0) |
130 | start += this.length |
131 | if (typeof end == 'number' && end < 0) |
132 | end += this.length |
133 | return this.copy(null, 0, start, end) |
134 | } |
135 | |
136 | |
137 | BufferList.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) { |
138 | if (typeof srcStart != 'number' || srcStart < 0) |
139 | srcStart = 0 |
140 | if (typeof srcEnd != 'number' || srcEnd > this.length) |
141 | srcEnd = this.length |
142 | if (srcStart >= this.length) |
143 | return dst || Buffer.alloc(0) |
144 | if (srcEnd <= 0) |
145 | return dst || Buffer.alloc(0) |
146 | |
147 | var copy = !!dst |
148 | , off = this._offset(srcStart) |
149 | , len = srcEnd - srcStart |
150 | , bytes = len |
151 | , bufoff = (copy && dstStart) || 0 |
152 | , start = off[1] |
153 | , l |
154 | , i |
155 | |
156 | // copy/slice everything |
157 | if (srcStart === 0 && srcEnd == this.length) { |
158 | if (!copy) { // slice, but full concat if multiple buffers |
159 | return this._bufs.length === 1 |
160 | ? this._bufs[0] |
161 | : Buffer.concat(this._bufs, this.length) |
162 | } |
163 | |
164 | // copy, need to copy individual buffers |
165 | for (i = 0; i < this._bufs.length; i++) { |
166 | this._bufs[i].copy(dst, bufoff) |
167 | bufoff += this._bufs[i].length |
168 | } |
169 | |
170 | return dst |
171 | } |
172 | |
173 | // easy, cheap case where it's a subset of one of the buffers |
174 | if (bytes <= this._bufs[off[0]].length - start) { |
175 | return copy |
176 | ? this._bufs[off[0]].copy(dst, dstStart, start, start + bytes) |
177 | : this._bufs[off[0]].slice(start, start + bytes) |
178 | } |
179 | |
180 | if (!copy) // a slice, we need something to copy in to |
181 | dst = Buffer.allocUnsafe(len) |
182 | |
183 | for (i = off[0]; i < this._bufs.length; i++) { |
184 | l = this._bufs[i].length - start |
185 | |
186 | if (bytes > l) { |
187 | this._bufs[i].copy(dst, bufoff, start) |
188 | } else { |
189 | this._bufs[i].copy(dst, bufoff, start, start + bytes) |
190 | break |
191 | } |
192 | |
193 | bufoff += l |
194 | bytes -= l |
195 | |
196 | if (start) |
197 | start = 0 |
198 | } |
199 | |
200 | return dst |
201 | } |
202 | |
203 | BufferList.prototype.shallowSlice = function shallowSlice (start, end) { |
204 | start = start || 0 |
205 | end = typeof end !== 'number' ? this.length : end |
206 | |
207 | if (start < 0) |
208 | start += this.length |
209 | if (end < 0) |
210 | end += this.length |
211 | |
212 | if (start === end) { |
213 | return new BufferList() |
214 | } |
215 | var startOffset = this._offset(start) |
216 | , endOffset = this._offset(end) |
217 | , buffers = this._bufs.slice(startOffset[0], endOffset[0] + 1) |
218 | |
219 | if (endOffset[1] == 0) |
220 | buffers.pop() |
221 | else |
222 | buffers[buffers.length-1] = buffers[buffers.length-1].slice(0, endOffset[1]) |
223 | |
224 | if (startOffset[1] != 0) |
225 | buffers[0] = buffers[0].slice(startOffset[1]) |
226 | |
227 | return new BufferList(buffers) |
228 | } |
229 | |
230 | BufferList.prototype.toString = function toString (encoding, start, end) { |
231 | return this.slice(start, end).toString(encoding) |
232 | } |
233 | |
234 | BufferList.prototype.consume = function consume (bytes) { |
235 | while (this._bufs.length) { |
236 | if (bytes >= this._bufs[0].length) { |
237 | bytes -= this._bufs[0].length |
238 | this.length -= this._bufs[0].length |
239 | this._bufs.shift() |
240 | } else { |
241 | this._bufs[0] = this._bufs[0].slice(bytes) |
242 | this.length -= bytes |
243 | break |
244 | } |
245 | } |
246 | return this |
247 | } |
248 | |
249 | |
250 | BufferList.prototype.duplicate = function duplicate () { |
251 | var i = 0 |
252 | , copy = new BufferList() |
253 | |
254 | for (; i < this._bufs.length; i++) |
255 | copy.append(this._bufs[i]) |
256 | |
257 | return copy |
258 | } |
259 | |
260 | |
261 | BufferList.prototype._destroy = function _destroy (err, cb) { |
262 | this._bufs.length = 0 |
263 | this.length = 0 |
264 | cb(err) |
265 | } |
266 | |
267 | |
268 | BufferList.prototype.indexOf = function (search, offset, encoding) { |
269 | if (encoding === undefined && typeof offset === 'string') { |
270 | encoding = offset |
271 | offset = undefined |
272 | } |
273 | if (typeof search === 'function' || Array.isArray(search)) { |
274 | throw new TypeError('The "value" argument must be one of type string, Buffer, BufferList, or Uint8Array.') |
275 | } else if (typeof search === 'number') { |
276 | search = Buffer.from([search]) |
277 | } else if (typeof search === 'string') { |
278 | search = Buffer.from(search, encoding) |
279 | } else if (search instanceof BufferList) { |
280 | search = search.slice() |
281 | } else if (!Buffer.isBuffer(search)) { |
282 | search = Buffer.from(search) |
283 | } |
284 | |
285 | offset = Number(offset || 0) |
286 | if (isNaN(offset)) { |
287 | offset = 0 |
288 | } |
289 | |
290 | if (offset < 0) { |
291 | offset = this.length + offset |
292 | } |
293 | |
294 | if (offset < 0) { |
295 | offset = 0 |
296 | } |
297 | |
298 | if (search.length === 0) { |
299 | return offset > this.length ? this.length : offset |
300 | } |
301 | |
302 | var blOffset = this._offset(offset) |
303 | var blIndex = blOffset[0] // index of which internal buffer we're working on |
304 | var buffOffset = blOffset[1] // offset of the internal buffer we're working on |
305 | |
306 | // scan over each buffer |
307 | for (blIndex; blIndex < this._bufs.length; blIndex++) { |
308 | var buff = this._bufs[blIndex] |
309 | while(buffOffset < buff.length) { |
310 | var availableWindow = buff.length - buffOffset |
311 | if (availableWindow >= search.length) { |
312 | var nativeSearchResult = buff.indexOf(search, buffOffset) |
313 | if (nativeSearchResult !== -1) { |
314 | return this._reverseOffset([blIndex, nativeSearchResult]) |
315 | } |
316 | buffOffset = buff.length - search.length + 1 // end of native search window |
317 | } else { |
318 | var revOffset = this._reverseOffset([blIndex, buffOffset]) |
319 | if (this._match(revOffset, search)) { |
320 | return revOffset |
321 | } |
322 | buffOffset++ |
323 | } |
324 | } |
325 | buffOffset = 0 |
326 | } |
327 | return -1 |
328 | } |
329 | |
330 | BufferList.prototype._match = function(offset, search) { |
331 | if (this.length - offset < search.length) { |
332 | return false |
333 | } |
334 | for (var searchOffset = 0; searchOffset < search.length ; searchOffset++) { |
335 | if(this.get(offset + searchOffset) !== search[searchOffset]){ |
336 | return false |
337 | } |
338 | } |
339 | return true |
340 | } |
341 | |
342 | |
343 | ;(function () { |
344 | var methods = { |
345 | 'readDoubleBE' : 8 |
346 | , 'readDoubleLE' : 8 |
347 | , 'readFloatBE' : 4 |
348 | , 'readFloatLE' : 4 |
349 | , 'readInt32BE' : 4 |
350 | , 'readInt32LE' : 4 |
351 | , 'readUInt32BE' : 4 |
352 | , 'readUInt32LE' : 4 |
353 | , 'readInt16BE' : 2 |
354 | , 'readInt16LE' : 2 |
355 | , 'readUInt16BE' : 2 |
356 | , 'readUInt16LE' : 2 |
357 | , 'readInt8' : 1 |
358 | , 'readUInt8' : 1 |
359 | , 'readIntBE' : null |
360 | , 'readIntLE' : null |
361 | , 'readUIntBE' : null |
362 | , 'readUIntLE' : null |
363 | } |
364 | |
365 | for (var m in methods) { |
366 | (function (m) { |
367 | if (methods[m] === null) { |
368 | BufferList.prototype[m] = function (offset, byteLength) { |
369 | return this.slice(offset, offset + byteLength)[m](0, byteLength) |
370 | } |
371 | } |
372 | else { |
373 | BufferList.prototype[m] = function (offset) { |
374 | return this.slice(offset, offset + methods[m])[m](0) |
375 | } |
376 | } |
377 | }(m)) |
378 | } |
379 | }()) |
380 | |
381 | |
382 | module.exports = BufferList |
383 |
Built with git-ssb-web