bl 0.6.0 → 0.8.2
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/README.md +4 -1
- package/bl.js +15 -7
- package/package.json +8 -5
- package/{test.js → test/basic-test.js} +114 -32
- package/test/sauce.js +38 -0
- package/test/test.js +9 -0
package/README.md
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
**A Node.js Buffer list collector, reader and streamer thingy.**
|
|
6
6
|
|
|
7
|
+
[](https://nodei.co/npm/bl/)
|
|
8
|
+
[](https://nodei.co/npm/bl/)
|
|
9
|
+
|
|
7
10
|
**bl** is a storage object for collections of Node Buffers, exposing them with the main Buffer readable API. Also works as a duplex stream so you can collect buffers from a stream that emits them and emit buffers to a stream that consumes them!
|
|
8
11
|
|
|
9
12
|
The original buffers are kept intact and copies are only done as necessary. Any reads that require the use of a single original buffer will return a slice of that buffer only (which references the same memory as the original buffer). Reads that span buffers perform concatenation as required and return the results transparently.
|
|
@@ -46,7 +49,7 @@ fs.createReadStream('README.md')
|
|
|
46
49
|
.pipe(bl(function (err, data) { // note 'new' isn't strictly required
|
|
47
50
|
// `data` is a complete Buffer object containing the full data
|
|
48
51
|
console.log(data.toString())
|
|
49
|
-
})
|
|
52
|
+
}))
|
|
50
53
|
```
|
|
51
54
|
|
|
52
55
|
Note that when you use the *callback* method like this, the resulting `data` parameter is a concatenation of all `Buffer` objects in the list. If you want to avoid the overhead of this concatenation (in cases of extreme performance consciousness), then avoid the *callback* method and just listen to `'end'` instead, like a standard Stream.
|
package/bl.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
var DuplexStream = require('readable-stream').Duplex
|
|
2
|
+
, util = require('util')
|
|
3
3
|
|
|
4
4
|
function BufferList (callback) {
|
|
5
5
|
if (!(this instanceof BufferList))
|
|
@@ -177,6 +177,12 @@ BufferList.prototype.duplicate = function () {
|
|
|
177
177
|
return copy
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
BufferList.prototype.destroy = function () {
|
|
181
|
+
this._bufs.length = 0;
|
|
182
|
+
this.length = 0;
|
|
183
|
+
this.push(null);
|
|
184
|
+
}
|
|
185
|
+
|
|
180
186
|
;(function () {
|
|
181
187
|
var methods = {
|
|
182
188
|
'readDoubleBE' : 8
|
|
@@ -195,11 +201,13 @@ BufferList.prototype.duplicate = function () {
|
|
|
195
201
|
, 'readUInt8' : 1
|
|
196
202
|
}
|
|
197
203
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
204
|
+
for (var m in methods) {
|
|
205
|
+
(function (m) {
|
|
206
|
+
BufferList.prototype[m] = function (offset) {
|
|
207
|
+
return this.slice(offset, offset + methods[m])[m](0)
|
|
208
|
+
}
|
|
209
|
+
}(m))
|
|
210
|
+
}
|
|
203
211
|
}())
|
|
204
212
|
|
|
205
213
|
module.exports = BufferList
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.2",
|
|
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": {
|
|
7
|
-
"test": "
|
|
7
|
+
"test": "node test/test.js | faucet",
|
|
8
|
+
"test-local": "brtapsauce-local test/basic-test.js"
|
|
8
9
|
},
|
|
9
10
|
"repository": {
|
|
10
11
|
"type": "git",
|
|
@@ -23,10 +24,12 @@
|
|
|
23
24
|
],
|
|
24
25
|
"license": "MIT",
|
|
25
26
|
"dependencies": {
|
|
26
|
-
"readable-stream": "~1.0.
|
|
27
|
+
"readable-stream": "~1.0.26"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
|
-
"tape": "
|
|
30
|
-
"hash_file": "
|
|
30
|
+
"tape": "~2.12.3",
|
|
31
|
+
"hash_file": "~0.1.1",
|
|
32
|
+
"faucet": "~0.0.1",
|
|
33
|
+
"brtapsauce": "~0.3.0"
|
|
31
34
|
}
|
|
32
35
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
var tape = require('tape')
|
|
2
|
+
, crypto = require('crypto')
|
|
3
|
+
, fs = require('fs')
|
|
4
|
+
, hash = require('hash_file')
|
|
5
|
+
, BufferList = require('../')
|
|
6
|
+
|
|
7
|
+
, encodings =
|
|
8
|
+
('hex utf8 utf-8 ascii binary base64'
|
|
9
|
+
+ (process.browser ? '' : ' ucs2 ucs-2 utf16le utf-16le')).split(' ')
|
|
6
10
|
|
|
7
11
|
tape('single bytes from single buffer', function (t) {
|
|
8
12
|
var bl = new BufferList()
|
|
@@ -254,17 +258,15 @@ tape('test toString encoding', function (t) {
|
|
|
254
258
|
bl.append(new Buffer('j'))
|
|
255
259
|
bl.append(new Buffer('\xff\x00'))
|
|
256
260
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
.forEach(function (enc) {
|
|
260
|
-
t.equal(bl.toString(enc), b.toString(enc))
|
|
261
|
+
encodings.forEach(function (enc) {
|
|
262
|
+
t.equal(bl.toString(enc), b.toString(enc), enc)
|
|
261
263
|
})
|
|
262
264
|
|
|
263
265
|
t.end()
|
|
264
266
|
})
|
|
265
267
|
|
|
266
|
-
tape('test stream', function (t) {
|
|
267
|
-
var random = crypto.randomBytes(
|
|
268
|
+
!process.browser && tape('test stream', function (t) {
|
|
269
|
+
var random = crypto.randomBytes(65534)
|
|
268
270
|
, rndhash = hash(random, 'md5')
|
|
269
271
|
, md5sum = crypto.createHash('md5')
|
|
270
272
|
, bl = new BufferList(function (err, buf) {
|
|
@@ -294,9 +296,9 @@ tape('instantiation with Buffer', function (t) {
|
|
|
294
296
|
, buf2 = crypto.randomBytes(1024)
|
|
295
297
|
, b = BufferList(buf)
|
|
296
298
|
|
|
297
|
-
t.equal(
|
|
299
|
+
t.equal(buf.toString('hex'), b.slice().toString('hex'), 'same buffer')
|
|
298
300
|
b = BufferList([ buf, buf2 ])
|
|
299
|
-
t.equal(
|
|
301
|
+
t.equal(b.slice().toString('hex'), Buffer.concat([ buf, buf2 ]).toString('hex'), 'same buffer')
|
|
300
302
|
t.end()
|
|
301
303
|
})
|
|
302
304
|
|
|
@@ -310,9 +312,7 @@ tape('test String appendage', function (t) {
|
|
|
310
312
|
bl.append('j')
|
|
311
313
|
bl.append('\xff\x00')
|
|
312
314
|
|
|
313
|
-
|
|
314
|
-
.split(' ')
|
|
315
|
-
.forEach(function (enc) {
|
|
315
|
+
encodings.forEach(function (enc) {
|
|
316
316
|
t.equal(bl.toString(enc), b.toString(enc))
|
|
317
317
|
})
|
|
318
318
|
|
|
@@ -345,7 +345,7 @@ tape('unicode string', function (t) {
|
|
|
345
345
|
tape('should emit finish', function (t) {
|
|
346
346
|
var source = BufferList()
|
|
347
347
|
, dest = BufferList()
|
|
348
|
-
|
|
348
|
+
|
|
349
349
|
source.write('hello')
|
|
350
350
|
source.pipe(dest)
|
|
351
351
|
|
|
@@ -361,7 +361,7 @@ tape('basic copy', function (t) {
|
|
|
361
361
|
, b = BufferList(buf)
|
|
362
362
|
|
|
363
363
|
b.copy(buf2)
|
|
364
|
-
t.equal(
|
|
364
|
+
t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')
|
|
365
365
|
t.end()
|
|
366
366
|
})
|
|
367
367
|
|
|
@@ -372,7 +372,7 @@ tape('copy after many appends', function (t) {
|
|
|
372
372
|
|
|
373
373
|
b.append(buf)
|
|
374
374
|
b.copy(buf2)
|
|
375
|
-
t.equal(
|
|
375
|
+
t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')
|
|
376
376
|
t.end()
|
|
377
377
|
})
|
|
378
378
|
|
|
@@ -382,7 +382,7 @@ tape('copy at a precise position', function (t) {
|
|
|
382
382
|
, b = BufferList(buf)
|
|
383
383
|
|
|
384
384
|
b.copy(buf2, 20)
|
|
385
|
-
t.equal(
|
|
385
|
+
t.equal(b.slice().toString('hex'), buf2.slice(20).toString('hex'), 'same buffer')
|
|
386
386
|
t.end()
|
|
387
387
|
})
|
|
388
388
|
|
|
@@ -392,22 +392,20 @@ tape('copy starting from a precise location', function (t) {
|
|
|
392
392
|
, b = BufferList(buf)
|
|
393
393
|
|
|
394
394
|
b.copy(buf2, 0, 5)
|
|
395
|
-
t.equal(
|
|
395
|
+
t.equal(b.slice(5).toString('hex'), buf2.toString('hex'), 'same buffer')
|
|
396
396
|
t.end()
|
|
397
397
|
})
|
|
398
398
|
|
|
399
399
|
tape('copy in an interval', function (t) {
|
|
400
|
-
var
|
|
401
|
-
,
|
|
402
|
-
,
|
|
400
|
+
var rnd = crypto.randomBytes(10)
|
|
401
|
+
, b = BufferList(rnd) // put the random bytes there
|
|
402
|
+
, actual = new Buffer(3)
|
|
403
403
|
, expected = new Buffer(3)
|
|
404
404
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
buf.copy(expected, 0, 5, 7)
|
|
405
|
+
rnd.copy(expected, 0, 5, 8)
|
|
406
|
+
b.copy(actual, 0, 5, 8)
|
|
408
407
|
|
|
409
|
-
|
|
410
|
-
t.equal(hash(expected, 'md5'), hash(buf2, 'md5'), 'same hash!')
|
|
408
|
+
t.equal(actual.toString('hex'), expected.toString('hex'), 'same buffer')
|
|
411
409
|
t.end()
|
|
412
410
|
})
|
|
413
411
|
|
|
@@ -419,7 +417,7 @@ tape('copy an interval between two buffers', function (t) {
|
|
|
419
417
|
b.append(buf)
|
|
420
418
|
b.copy(buf2, 0, 5, 15)
|
|
421
419
|
|
|
422
|
-
t.equal(
|
|
420
|
+
t.equal(b.slice(5, 15).toString('hex'), buf2.toString('hex'), 'same buffer')
|
|
423
421
|
t.end()
|
|
424
422
|
})
|
|
425
423
|
|
|
@@ -433,10 +431,94 @@ tape('duplicate', function (t) {
|
|
|
433
431
|
t.equal(bl.toString('hex'), dup.toString('hex'))
|
|
434
432
|
})
|
|
435
433
|
|
|
436
|
-
tape('
|
|
434
|
+
tape('destroy no pipe', function (t) {
|
|
435
|
+
t.plan(2)
|
|
436
|
+
|
|
437
|
+
var bl = new BufferList('alsdkfja;lsdkfja;lsdk')
|
|
438
|
+
bl.destroy()
|
|
439
|
+
|
|
440
|
+
t.equal(bl._bufs.length, 0)
|
|
441
|
+
t.equal(bl.length, 0)
|
|
442
|
+
})
|
|
443
|
+
|
|
444
|
+
!process.browser && tape('destroy with pipe before read end', function (t) {
|
|
445
|
+
t.plan(2)
|
|
446
|
+
|
|
447
|
+
var bl = new BufferList()
|
|
448
|
+
fs.createReadStream(__dirname + '/sauce.js')
|
|
449
|
+
.pipe(bl)
|
|
450
|
+
|
|
451
|
+
bl.destroy()
|
|
452
|
+
|
|
453
|
+
t.equal(bl._bufs.length, 0)
|
|
454
|
+
t.equal(bl.length, 0)
|
|
455
|
+
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
!process.browser && tape('destroy with pipe before read end with race', function (t) {
|
|
459
|
+
t.plan(2)
|
|
460
|
+
|
|
461
|
+
var bl = new BufferList()
|
|
462
|
+
fs.createReadStream(__dirname + '/sauce.js')
|
|
463
|
+
.pipe(bl)
|
|
464
|
+
|
|
465
|
+
setTimeout(function () {
|
|
466
|
+
bl.destroy()
|
|
467
|
+
setTimeout(function () {
|
|
468
|
+
t.equal(bl._bufs.length, 0)
|
|
469
|
+
t.equal(bl.length, 0)
|
|
470
|
+
}, 500)
|
|
471
|
+
}, 500)
|
|
472
|
+
})
|
|
473
|
+
|
|
474
|
+
!process.browser && tape('destroy with pipe after read end', function (t) {
|
|
475
|
+
t.plan(2)
|
|
476
|
+
|
|
477
|
+
var bl = new BufferList()
|
|
478
|
+
fs.createReadStream(__dirname + '/sauce.js')
|
|
479
|
+
.on('end', onEnd)
|
|
480
|
+
.pipe(bl)
|
|
481
|
+
|
|
482
|
+
function onEnd () {
|
|
483
|
+
bl.destroy()
|
|
484
|
+
|
|
485
|
+
t.equal(bl._bufs.length, 0)
|
|
486
|
+
t.equal(bl.length, 0)
|
|
487
|
+
}
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
!process.browser && tape('destroy with pipe while writing to a destination', function (t) {
|
|
491
|
+
t.plan(4)
|
|
492
|
+
|
|
493
|
+
var bl = new BufferList()
|
|
494
|
+
, ds = new BufferList()
|
|
495
|
+
|
|
496
|
+
fs.createReadStream(__dirname + '/sauce.js')
|
|
497
|
+
.on('end', onEnd)
|
|
498
|
+
.pipe(bl)
|
|
499
|
+
|
|
500
|
+
function onEnd () {
|
|
501
|
+
bl.pipe(ds)
|
|
502
|
+
|
|
503
|
+
setTimeout(function () {
|
|
504
|
+
bl.destroy()
|
|
505
|
+
|
|
506
|
+
t.equals(bl._bufs.length, 0)
|
|
507
|
+
t.equals(bl.length, 0)
|
|
508
|
+
|
|
509
|
+
ds.destroy()
|
|
510
|
+
|
|
511
|
+
t.equals(bl._bufs.length, 0)
|
|
512
|
+
t.equals(bl.length, 0)
|
|
513
|
+
|
|
514
|
+
}, 100)
|
|
515
|
+
}
|
|
516
|
+
})
|
|
517
|
+
|
|
518
|
+
!process.browser && tape('handle error', function (t) {
|
|
437
519
|
t.plan(2)
|
|
438
520
|
fs.createReadStream('/does/not/exist').pipe(BufferList(function (err, data) {
|
|
439
521
|
t.ok(err instanceof Error, 'has error')
|
|
440
522
|
t.notOk(data, 'no data')
|
|
441
523
|
}))
|
|
442
|
-
})
|
|
524
|
+
})
|
package/test/sauce.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const user = process.env.SAUCE_USER
|
|
4
|
+
, key = process.env.SAUCE_KEY
|
|
5
|
+
, path = require('path')
|
|
6
|
+
, brtapsauce = require('brtapsauce')
|
|
7
|
+
, testFile = path.join(__dirname, 'basic-test.js')
|
|
8
|
+
|
|
9
|
+
, capabilities = [
|
|
10
|
+
{ browserName: 'chrome' , platform: 'Windows XP', version: '' }
|
|
11
|
+
, { browserName: 'firefox' , platform: 'Windows 8' , version: '' }
|
|
12
|
+
, { browserName: 'firefox' , platform: 'Windows XP', version: '4' }
|
|
13
|
+
, { browserName: 'internet explorer' , platform: 'Windows 8' , version: '10' }
|
|
14
|
+
, { browserName: 'internet explorer' , platform: 'Windows 7' , version: '9' }
|
|
15
|
+
, { browserName: 'internet explorer' , platform: 'Windows 7' , version: '8' }
|
|
16
|
+
, { browserName: 'internet explorer' , platform: 'Windows XP', version: '7' }
|
|
17
|
+
, { browserName: 'internet explorer' , platform: 'Windows XP', version: '6' }
|
|
18
|
+
, { browserName: 'safari' , platform: 'Windows 7' , version: '5' }
|
|
19
|
+
, { browserName: 'safari' , platform: 'OS X 10.8' , version: '6' }
|
|
20
|
+
, { browserName: 'opera' , platform: 'Windows 7' , version: '' }
|
|
21
|
+
, { browserName: 'opera' , platform: 'Windows 7' , version: '11' }
|
|
22
|
+
, { browserName: 'ipad' , platform: 'OS X 10.8' , version: '6' }
|
|
23
|
+
, { browserName: 'android' , platform: 'Linux' , version: '4.0', 'device-type': 'tablet' }
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
if (!user)
|
|
27
|
+
throw new Error('Must set a SAUCE_USER env var')
|
|
28
|
+
if (!key)
|
|
29
|
+
throw new Error('Must set a SAUCE_KEY env var')
|
|
30
|
+
|
|
31
|
+
brtapsauce({
|
|
32
|
+
name : 'Traversty'
|
|
33
|
+
, user : user
|
|
34
|
+
, key : key
|
|
35
|
+
, brsrc : testFile
|
|
36
|
+
, capabilities : capabilities
|
|
37
|
+
, options : { timeout: 60 * 6 }
|
|
38
|
+
})
|
package/test/test.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require('./basic-test')
|
|
2
|
+
|
|
3
|
+
if (!process.env.SAUCE_KEY || !process.env.SAUCE_USER)
|
|
4
|
+
return console.log('SAUCE_KEY and/or SAUCE_USER not set, not running sauce tests')
|
|
5
|
+
|
|
6
|
+
if (!/v0\.10/.test(process.version))
|
|
7
|
+
return console.log('Not Node v0.10.x, not running sauce tests')
|
|
8
|
+
|
|
9
|
+
require('./sauce.js')
|