Skip to content

Commit

Permalink
unwrap bl children when passed to append() & support bl in constructor
Browse files Browse the repository at this point in the history
fixes: #26
  • Loading branch information
rvagg committed Feb 12, 2016
1 parent c72ba4e commit cbb1429
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 25 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ bl.pipe(fs.createWriteStream('gibberish.txt'))

--------------------------------------------------------
<a name="ctor"></a>
### new BufferList([ callback | buffer | buffer array ])
### new BufferList([ callback | Buffer | Buffer array | BufferList | BufferList array | String ])
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.

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.
Expand All @@ -120,8 +120,8 @@ Get the length of the list in bytes. This is the sum of the lengths of all of th

--------------------------------------------------------
<a name="append"></a>
### bl.append(buffer)
`append(buffer)` adds an additional buffer or BufferList to the internal list.
### bl.append(Buffer | Buffer array | BufferList | BufferList array | String)
`append(buffer)` adds an additional buffer or BufferList to the internal list. `this` is returned so it can be chained.

--------------------------------------------------------
<a name="get"></a>
Expand Down
40 changes: 20 additions & 20 deletions bl.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,8 @@ function BufferList (callback) {
this.on('unpipe', function (src) {
src.removeListener('error', piper)
})
}
else if (Buffer.isBuffer(callback))
} else {
this.append(callback)
else if (Array.isArray(callback)) {
callback.forEach(function (b) {
Buffer.isBuffer(b) && this.append(b)
}.bind(this))
}

DuplexStream.call(this)
Expand All @@ -49,20 +44,25 @@ BufferList.prototype._offset = function (offset) {
}

BufferList.prototype.append = function (buf) {
var isBuffer = Buffer.isBuffer(buf) ||
buf instanceof BufferList

// coerce number arguments to strings, since Buffer(number) does
// uninitialized memory allocation
if (typeof buf == 'number')
buf = buf.toString()

if (buf instanceof BufferList) {
this._bufs.push.apply(this._bufs, buf._bufs)
this.length += buf.length
} else {
this._bufs.push(isBuffer ? buf : new Buffer(buf))
this.length += buf.length
var i = 0
, newBuf

if (Array.isArray(buf)) {
for (; i < buf.length; i++)
this.append(buf[i])
} else if (buf instanceof BufferList) {
// unwrap argument into individual BufferLists
for (; i < buf._bufs.length; i++)
this.append(buf._bufs[i])
} else if (buf != null) {
// coerce number arguments to strings, since Buffer(number) does
// uninitialized memory allocation
if (typeof buf == 'number')
buf = buf.toString()

newBuf = Buffer.isBuffer(buf) ? buf : new Buffer(buf)
this._bufs.push(newBuf)
this.length += newBuf.length
}

return this
Expand Down
73 changes: 71 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,39 @@ tape('multiple bytes from multiple buffers', function (t) {
tape('multiple bytes from multiple buffer lists', function (t) {
var bl = new BufferList()

bl.append(new BufferList([new Buffer('abcd'), new Buffer('efg')]))
bl.append(new BufferList([new Buffer('hi'), new Buffer('j')]))
bl.append(new BufferList([ new Buffer('abcd'), new Buffer('efg') ]))
bl.append(new BufferList([ new Buffer('hi'), new Buffer('j') ]))

t.equal(bl.length, 10)

t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')

t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
t.equal(bl.slice(3, 6).toString('ascii'), 'def')
t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')

t.end()
})

// same data as previous test, just using nested constructors
tape('multiple bytes from crazy nested buffer lists', function (t) {
var bl = new BufferList()

bl.append(new BufferList([
new BufferList([
new BufferList(new Buffer('abc'))
, new Buffer('d')
, new BufferList(new Buffer('efg'))
])
, new BufferList([ new Buffer('hi') ])
, new BufferList(new Buffer('j'))
]))

t.equal(bl.length, 10)

t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')

t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
t.equal(bl.slice(3, 6).toString('ascii'), 'def')
t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
Expand All @@ -93,6 +120,48 @@ tape('multiple bytes from multiple buffer lists', function (t) {
t.end()
})

tape('append accepts arrays of Buffers', function (t) {
var bl = new BufferList()
bl.append(new Buffer('abc'))
bl.append([ new Buffer('def') ])
bl.append([ new Buffer('ghi'), new Buffer('jkl') ])
bl.append([ new Buffer('mnop'), new Buffer('qrstu'), new Buffer('vwxyz') ])
t.equal(bl.length, 26)
t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
t.end()
})

tape('append accepts arrays of BufferLists', function (t) {
var bl = new BufferList()
bl.append(new Buffer('abc'))
bl.append([ new BufferList('def') ])
bl.append(new BufferList([ new Buffer('ghi'), new BufferList('jkl') ]))
bl.append([ new Buffer('mnop'), new BufferList([ new Buffer('qrstu'), new Buffer('vwxyz') ]) ])
t.equal(bl.length, 26)
t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
t.end()
})

tape('append chainable', function (t) {
var bl = new BufferList()
t.ok(bl.append(new Buffer('abcd')) === bl)
t.ok(bl.append([ new Buffer('abcd') ]) === bl)
t.ok(bl.append(new BufferList(new Buffer('abcd'))) === bl)
t.ok(bl.append([ new BufferList(new Buffer('abcd')) ]) === bl)
t.end()
})

tape('append chainable (test results)', function (t) {
var bl = new BufferList('abc')
.append([ new BufferList('def') ])
.append(new BufferList([ new Buffer('ghi'), new BufferList('jkl') ]))
.append([ new Buffer('mnop'), new BufferList([ new Buffer('qrstu'), new Buffer('vwxyz') ]) ])

t.equal(bl.length, 26)
t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
t.end()
})

tape('consuming from multiple buffers', function (t) {
var bl = new BufferList()

Expand Down

0 comments on commit cbb1429

Please sign in to comment.