bl 1.0.3 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.travis.yml CHANGED
@@ -4,10 +4,12 @@ node_js:
4
4
  - '0.10'
5
5
  - '0.12'
6
6
  - '4'
7
- - '5'
7
+ - '6'
8
+ - '7'
8
9
  branches:
9
10
  only:
10
11
  - master
11
12
  notifications:
12
13
  email:
13
14
  - rod@vagg.org
15
+ - matteo.collina@gmail.com
package/LICENSE.md CHANGED
@@ -1,7 +1,7 @@
1
1
  The MIT License (MIT)
2
2
  =====================
3
3
 
4
- Copyright (c) 2014 bl contributors
4
+ Copyright (c) 2013-2016 bl contributors
5
5
  ----------------------------------
6
6
 
7
7
  *bl contributors listed at <https://github.com/rvagg/bl#contributors>*
package/README.md CHANGED
@@ -87,6 +87,7 @@ bl.pipe(fs.createWriteStream('gibberish.txt'))
87
87
  * <a href="#append"><code>bl.<b>append(buffer)</b></code></a>
88
88
  * <a href="#get"><code>bl.<b>get(index)</b></code></a>
89
89
  * <a href="#slice"><code>bl.<b>slice([ start[, end ] ])</b></code></a>
90
+ * <a href="#shallowSlice"><code>bl.<b>shallowSlice([ start[, end ] ])</b></code></a>
90
91
  * <a href="#copy"><code>bl.<b>copy(dest, [ destStart, [ srcStart [, srcEnd ] ] ])</b></code></a>
91
92
  * <a href="#duplicate"><code>bl.<b>duplicate()</b></code></a>
92
93
  * <a href="#consume"><code>bl.<b>consume(bytes)</b></code></a>
@@ -96,7 +97,7 @@ bl.pipe(fs.createWriteStream('gibberish.txt'))
96
97
 
97
98
  --------------------------------------------------------
98
99
  <a name="ctor"></a>
99
- ### new BufferList([ callback | buffer | buffer array ])
100
+ ### new BufferList([ callback | Buffer | Buffer array | BufferList | BufferList array | String ])
100
101
  The constructor takes an optional callback, if supplied, the callback will be called with an error argument followed by a reference to the **bl** instance, when `bl.end()` is called (i.e. from a piped stream). This is a convenient method of collecting the entire contents of a stream, particularly when the stream is *chunky*, such as a network stream.
101
102
 
102
103
  Normally, no arguments are required for the constructor, but you can initialise the list by passing in a single `Buffer` object or an array of `Buffer` object.
@@ -120,8 +121,8 @@ Get the length of the list in bytes. This is the sum of the lengths of all of th
120
121
 
121
122
  --------------------------------------------------------
122
123
  <a name="append"></a>
123
- ### bl.append(buffer)
124
- `append(buffer)` adds an additional buffer or BufferList to the internal list.
124
+ ### bl.append(Buffer | Buffer array | BufferList | BufferList array | String)
125
+ `append(buffer)` adds an additional buffer or BufferList to the internal list. `this` is returned so it can be chained.
125
126
 
126
127
  --------------------------------------------------------
127
128
  <a name="get"></a>
@@ -135,6 +136,13 @@ Get the length of the list in bytes. This is the sum of the lengths of all of th
135
136
 
136
137
  If the requested range spans a single internal buffer then a slice of that buffer will be returned which shares the original memory range of that Buffer. If the range spans multiple buffers then copy operations will likely occur to give you a uniform Buffer.
137
138
 
139
+ --------------------------------------------------------
140
+ <a name="shallowSlice"></a>
141
+ ### bl.shallowSlice([ start, [ end ] ])
142
+ `shallowSlice()` returns a new `BufferList` object containing the bytes within the range specified. Both `start` and `end` are optional and will default to the beginning and end of the list respectively.
143
+
144
+ No copies will be performed. All buffers in the result share memory with the original list.
145
+
138
146
  --------------------------------------------------------
139
147
  <a name="copy"></a>
140
148
  ### bl.copy(dest, [ destStart, [ srcStart [, srcEnd ] ] ])
@@ -195,6 +203,6 @@ See the <b><code>[Buffer](http://nodejs.org/docs/latest/api/buffer.html)</code><
195
203
  <a name="license"></a>
196
204
  ## License &amp; copyright
197
205
 
198
- Copyright (c) 2013-2014 bl contributors (listed above).
206
+ Copyright (c) 2013-2016 bl contributors (listed above).
199
207
 
200
208
  bl is licensed under the MIT license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details.
package/bl.js CHANGED
@@ -1,6 +1,7 @@
1
1
  var DuplexStream = require('readable-stream/duplex')
2
2
  , util = require('util')
3
3
 
4
+
4
5
  function BufferList (callback) {
5
6
  if (!(this instanceof BufferList))
6
7
  return new BufferList(callback)
@@ -11,78 +12,92 @@ function BufferList (callback) {
11
12
  if (typeof callback == 'function') {
12
13
  this._callback = callback
13
14
 
14
- var piper = function (err) {
15
+ var piper = function piper (err) {
15
16
  if (this._callback) {
16
17
  this._callback(err)
17
18
  this._callback = null
18
19
  }
19
20
  }.bind(this)
20
21
 
21
- this.on('pipe', function (src) {
22
+ this.on('pipe', function onPipe (src) {
22
23
  src.on('error', piper)
23
24
  })
24
- this.on('unpipe', function (src) {
25
+ this.on('unpipe', function onUnpipe (src) {
25
26
  src.removeListener('error', piper)
26
27
  })
27
- }
28
- else if (Buffer.isBuffer(callback))
28
+ } else {
29
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
30
  }
35
31
 
36
32
  DuplexStream.call(this)
37
33
  }
38
34
 
35
+
39
36
  util.inherits(BufferList, DuplexStream)
40
37
 
41
- BufferList.prototype._offset = function (offset) {
38
+
39
+ BufferList.prototype._offset = function _offset (offset) {
42
40
  var tot = 0, i = 0, _t
41
+ if (offset === 0) return [ 0, 0 ]
43
42
  for (; i < this._bufs.length; i++) {
44
43
  _t = tot + this._bufs[i].length
45
- if (offset < _t)
44
+ if (offset < _t || i == this._bufs.length - 1)
46
45
  return [ i, offset - tot ]
47
46
  tot = _t
48
47
  }
49
48
  }
50
49
 
51
- BufferList.prototype.append = function (buf) {
52
- var isBuffer = Buffer.isBuffer(buf) ||
53
- buf instanceof BufferList
54
50
 
55
- // coerce number arguments to strings, since Buffer(number) does
56
- // uninitialized memory allocation
57
- if (typeof buf == 'number')
58
- buf = buf.toString()
51
+ BufferList.prototype.append = function append (buf) {
52
+ var i = 0
59
53
 
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
54
+ if (Buffer.isBuffer(buf)) {
55
+ this._appendBuffer(buf);
56
+ } else if (Array.isArray(buf)) {
57
+ for (; i < buf.length; i++)
58
+ this.append(buf[i])
59
+ } else if (buf instanceof BufferList) {
60
+ // unwrap argument into individual BufferLists
61
+ for (; i < buf._bufs.length; i++)
62
+ this.append(buf._bufs[i])
63
+ } else if (buf != null) {
64
+ // coerce number arguments to strings, since Buffer(number) does
65
+ // uninitialized memory allocation
66
+ if (typeof buf == 'number')
67
+ buf = buf.toString()
68
+
69
+ this._appendBuffer(new Buffer(buf));
66
70
  }
67
71
 
68
72
  return this
69
73
  }
70
74
 
71
- BufferList.prototype._write = function (buf, encoding, callback) {
72
- this.append(buf)
73
- if (callback)
75
+
76
+ BufferList.prototype._appendBuffer = function appendBuffer (buf) {
77
+ this._bufs.push(buf)
78
+ this.length += buf.length
79
+ }
80
+
81
+
82
+ BufferList.prototype._write = function _write (buf, encoding, callback) {
83
+ this._appendBuffer(buf)
84
+
85
+ if (typeof callback == 'function')
74
86
  callback()
75
87
  }
76
88
 
77
- BufferList.prototype._read = function (size) {
89
+
90
+ BufferList.prototype._read = function _read (size) {
78
91
  if (!this.length)
79
92
  return this.push(null)
93
+
80
94
  size = Math.min(size, this.length)
81
95
  this.push(this.slice(0, size))
82
96
  this.consume(size)
83
97
  }
84
98
 
85
- BufferList.prototype.end = function (chunk) {
99
+
100
+ BufferList.prototype.end = function end (chunk) {
86
101
  DuplexStream.prototype.end.call(this, chunk)
87
102
 
88
103
  if (this._callback) {
@@ -91,15 +106,22 @@ BufferList.prototype.end = function (chunk) {
91
106
  }
92
107
  }
93
108
 
94
- BufferList.prototype.get = function (index) {
109
+
110
+ BufferList.prototype.get = function get (index) {
95
111
  return this.slice(index, index + 1)[0]
96
112
  }
97
113
 
98
- BufferList.prototype.slice = function (start, end) {
114
+
115
+ BufferList.prototype.slice = function slice (start, end) {
116
+ if (typeof start == 'number' && start < 0)
117
+ start += this.length
118
+ if (typeof end == 'number' && end < 0)
119
+ end += this.length
99
120
  return this.copy(null, 0, start, end)
100
121
  }
101
122
 
102
- BufferList.prototype.copy = function (dst, dstStart, srcStart, srcEnd) {
123
+
124
+ BufferList.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) {
103
125
  if (typeof srcStart != 'number' || srcStart < 0)
104
126
  srcStart = 0
105
127
  if (typeof srcEnd != 'number' || srcEnd > this.length)
@@ -120,8 +142,11 @@ BufferList.prototype.copy = function (dst, dstStart, srcStart, srcEnd) {
120
142
 
121
143
  // copy/slice everything
122
144
  if (srcStart === 0 && srcEnd == this.length) {
123
- if (!copy) // slice, just return a full concat
124
- return Buffer.concat(this._bufs)
145
+ if (!copy) { // slice, but full concat if multiple buffers
146
+ return this._bufs.length === 1
147
+ ? this._bufs[0]
148
+ : Buffer.concat(this._bufs, this.length)
149
+ }
125
150
 
126
151
  // copy, need to copy individual buffers
127
152
  for (i = 0; i < this._bufs.length; i++) {
@@ -162,11 +187,35 @@ BufferList.prototype.copy = function (dst, dstStart, srcStart, srcEnd) {
162
187
  return dst
163
188
  }
164
189
 
165
- BufferList.prototype.toString = function (encoding, start, end) {
190
+ BufferList.prototype.shallowSlice = function shallowSlice (start, end) {
191
+ start = start || 0
192
+ end = end || this.length
193
+
194
+ if (start < 0)
195
+ start += this.length
196
+ if (end < 0)
197
+ end += this.length
198
+
199
+ var startOffset = this._offset(start)
200
+ , endOffset = this._offset(end)
201
+ , buffers = this._bufs.slice(startOffset[0], endOffset[0] + 1)
202
+
203
+ if (endOffset[1] == 0)
204
+ buffers.pop()
205
+ else
206
+ buffers[buffers.length-1] = buffers[buffers.length-1].slice(0, endOffset[1])
207
+
208
+ if (startOffset[1] != 0)
209
+ buffers[0] = buffers[0].slice(startOffset[1])
210
+
211
+ return new BufferList(buffers)
212
+ }
213
+
214
+ BufferList.prototype.toString = function toString (encoding, start, end) {
166
215
  return this.slice(start, end).toString(encoding)
167
216
  }
168
217
 
169
- BufferList.prototype.consume = function (bytes) {
218
+ BufferList.prototype.consume = function consume (bytes) {
170
219
  while (this._bufs.length) {
171
220
  if (bytes >= this._bufs[0].length) {
172
221
  bytes -= this._bufs[0].length
@@ -181,7 +230,8 @@ BufferList.prototype.consume = function (bytes) {
181
230
  return this
182
231
  }
183
232
 
184
- BufferList.prototype.duplicate = function () {
233
+
234
+ BufferList.prototype.duplicate = function duplicate () {
185
235
  var i = 0
186
236
  , copy = new BufferList()
187
237
 
@@ -191,12 +241,14 @@ BufferList.prototype.duplicate = function () {
191
241
  return copy
192
242
  }
193
243
 
194
- BufferList.prototype.destroy = function () {
195
- this._bufs.length = 0;
196
- this.length = 0;
197
- this.push(null);
244
+
245
+ BufferList.prototype.destroy = function destroy () {
246
+ this._bufs.length = 0
247
+ this.length = 0
248
+ this.push(null)
198
249
  }
199
250
 
251
+
200
252
  ;(function () {
201
253
  var methods = {
202
254
  'readDoubleBE' : 8
@@ -224,4 +276,5 @@ BufferList.prototype.destroy = function () {
224
276
  }
225
277
  }())
226
278
 
279
+
227
280
  module.exports = BufferList
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bl",
3
- "version": "1.0.3",
3
+ "version": "1.2.1",
4
4
  "description": "Buffer List: collect buffers and access with a standard readable Buffer interface, streamable too!",
5
5
  "main": "bl.js",
6
6
  "scripts": {
@@ -24,11 +24,11 @@
24
24
  ],
25
25
  "license": "MIT",
26
26
  "dependencies": {
27
- "readable-stream": "~2.0.5"
27
+ "readable-stream": "^2.0.5"
28
28
  },
29
29
  "devDependencies": {
30
30
  "faucet": "0.0.1",
31
31
  "hash_file": "~0.1.1",
32
- "tape": "~4.4.0"
32
+ "tape": "~4.6.0"
33
33
  }
34
34
  }
package/test/test.js CHANGED
@@ -53,6 +53,20 @@ tape('multi bytes from single buffer', function (t) {
53
53
  t.equal(bl.slice(0, 4).toString('ascii'), 'abcd')
54
54
  t.equal(bl.slice(0, 3).toString('ascii'), 'abc')
55
55
  t.equal(bl.slice(1, 4).toString('ascii'), 'bcd')
56
+ t.equal(bl.slice(-4, -1).toString('ascii'), 'abc')
57
+
58
+ t.end()
59
+ })
60
+
61
+ tape('multi bytes from single buffer (negative indexes)', function (t) {
62
+ var bl = new BufferList()
63
+ bl.append(new Buffer('buffer'))
64
+
65
+ t.equal(bl.length, 6)
66
+
67
+ t.equal(bl.slice(-6, -1).toString('ascii'), 'buffe')
68
+ t.equal(bl.slice(-6, -2).toString('ascii'), 'buff')
69
+ t.equal(bl.slice(-5, -2).toString('ascii'), 'uff')
56
70
 
57
71
  t.end()
58
72
  })
@@ -72,6 +86,7 @@ tape('multiple bytes from multiple buffers', function (t) {
72
86
  t.equal(bl.slice(3, 6).toString('ascii'), 'def')
73
87
  t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
74
88
  t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
89
+ t.equal(bl.slice(-7, -4).toString('ascii'), 'def')
75
90
 
76
91
  t.end()
77
92
  })
@@ -79,12 +94,39 @@ tape('multiple bytes from multiple buffers', function (t) {
79
94
  tape('multiple bytes from multiple buffer lists', function (t) {
80
95
  var bl = new BufferList()
81
96
 
82
- bl.append(new BufferList([new Buffer('abcd'), new Buffer('efg')]))
83
- bl.append(new BufferList([new Buffer('hi'), new Buffer('j')]))
97
+ bl.append(new BufferList([ new Buffer('abcd'), new Buffer('efg') ]))
98
+ bl.append(new BufferList([ new Buffer('hi'), new Buffer('j') ]))
99
+
100
+ t.equal(bl.length, 10)
101
+
102
+ t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
103
+
104
+ t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
105
+ t.equal(bl.slice(3, 6).toString('ascii'), 'def')
106
+ t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
107
+ t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
108
+
109
+ t.end()
110
+ })
111
+
112
+ // same data as previous test, just using nested constructors
113
+ tape('multiple bytes from crazy nested buffer lists', function (t) {
114
+ var bl = new BufferList()
115
+
116
+ bl.append(new BufferList([
117
+ new BufferList([
118
+ new BufferList(new Buffer('abc'))
119
+ , new Buffer('d')
120
+ , new BufferList(new Buffer('efg'))
121
+ ])
122
+ , new BufferList([ new Buffer('hi') ])
123
+ , new BufferList(new Buffer('j'))
124
+ ]))
84
125
 
85
126
  t.equal(bl.length, 10)
86
127
 
87
128
  t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
129
+
88
130
  t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
89
131
  t.equal(bl.slice(3, 6).toString('ascii'), 'def')
90
132
  t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
@@ -93,6 +135,48 @@ tape('multiple bytes from multiple buffer lists', function (t) {
93
135
  t.end()
94
136
  })
95
137
 
138
+ tape('append accepts arrays of Buffers', function (t) {
139
+ var bl = new BufferList()
140
+ bl.append(new Buffer('abc'))
141
+ bl.append([ new Buffer('def') ])
142
+ bl.append([ new Buffer('ghi'), new Buffer('jkl') ])
143
+ bl.append([ new Buffer('mnop'), new Buffer('qrstu'), new Buffer('vwxyz') ])
144
+ t.equal(bl.length, 26)
145
+ t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
146
+ t.end()
147
+ })
148
+
149
+ tape('append accepts arrays of BufferLists', function (t) {
150
+ var bl = new BufferList()
151
+ bl.append(new Buffer('abc'))
152
+ bl.append([ new BufferList('def') ])
153
+ bl.append(new BufferList([ new Buffer('ghi'), new BufferList('jkl') ]))
154
+ bl.append([ new Buffer('mnop'), new BufferList([ new Buffer('qrstu'), new Buffer('vwxyz') ]) ])
155
+ t.equal(bl.length, 26)
156
+ t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
157
+ t.end()
158
+ })
159
+
160
+ tape('append chainable', function (t) {
161
+ var bl = new BufferList()
162
+ t.ok(bl.append(new Buffer('abcd')) === bl)
163
+ t.ok(bl.append([ new Buffer('abcd') ]) === bl)
164
+ t.ok(bl.append(new BufferList(new Buffer('abcd'))) === bl)
165
+ t.ok(bl.append([ new BufferList(new Buffer('abcd')) ]) === bl)
166
+ t.end()
167
+ })
168
+
169
+ tape('append chainable (test results)', function (t) {
170
+ var bl = new BufferList('abc')
171
+ .append([ new BufferList('def') ])
172
+ .append(new BufferList([ new Buffer('ghi'), new BufferList('jkl') ]))
173
+ .append([ new Buffer('mnop'), new BufferList([ new Buffer('qrstu'), new Buffer('vwxyz') ]) ])
174
+
175
+ t.equal(bl.length, 26)
176
+ t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
177
+ t.end()
178
+ })
179
+
96
180
  tape('consuming from multiple buffers', function (t) {
97
181
  var bl = new BufferList()
98
182
 
@@ -468,6 +552,52 @@ tape('copy an interval between two buffers', function (t) {
468
552
  t.end()
469
553
  })
470
554
 
555
+ tape('shallow slice across buffer boundaries', function (t) {
556
+ var bl = new BufferList(['First', 'Second', 'Third'])
557
+
558
+ t.equal(bl.shallowSlice(3, 13).toString(), 'stSecondTh')
559
+ t.end()
560
+ })
561
+
562
+ tape('shallow slice within single buffer', function (t) {
563
+ t.plan(2)
564
+ var bl = new BufferList(['First', 'Second', 'Third'])
565
+
566
+ t.equal(bl.shallowSlice(5, 10).toString(), 'Secon')
567
+ t.equal(bl.shallowSlice(7, 10).toString(), 'con')
568
+ t.end()
569
+ })
570
+
571
+ tape('shallow slice single buffer', function (t) {
572
+ t.plan(3)
573
+ var bl = new BufferList(['First', 'Second', 'Third'])
574
+
575
+ t.equal(bl.shallowSlice(0, 5).toString(), 'First')
576
+ t.equal(bl.shallowSlice(5, 11).toString(), 'Second')
577
+ t.equal(bl.shallowSlice(11, 16).toString(), 'Third')
578
+ })
579
+
580
+ tape('shallow slice with negative or omitted indices', function (t) {
581
+ t.plan(4)
582
+ var bl = new BufferList(['First', 'Second', 'Third'])
583
+
584
+ t.equal(bl.shallowSlice().toString(), 'FirstSecondThird')
585
+ t.equal(bl.shallowSlice(5).toString(), 'SecondThird')
586
+ t.equal(bl.shallowSlice(5, -3).toString(), 'SecondTh')
587
+ t.equal(bl.shallowSlice(-8).toString(), 'ondThird')
588
+ })
589
+
590
+ tape('shallow slice does not make a copy', function (t) {
591
+ t.plan(1)
592
+ var buffers = [new Buffer('First'), new Buffer('Second'), new Buffer('Third')]
593
+ var bl = (new BufferList(buffers)).shallowSlice(5, -3)
594
+
595
+ buffers[1].fill('h')
596
+ buffers[2].fill('h')
597
+
598
+ t.equal(bl.toString(), 'hhhhhhhh')
599
+ })
600
+
471
601
  tape('duplicate', function (t) {
472
602
  t.plan(2)
473
603