Comparing version 0.4.0 to 1.0.0
@@ -0,1 +1,11 @@ | ||
### 1.0.0 | ||
* `new FdSlicer(fd, options)` must now be `fdSlicer.createFromFd(fd, options)` | ||
* fix behavior when `end` is 0. | ||
* fix `createWriteStream` when using `createFromBuffer` | ||
### 0.4.0 | ||
* add ability to create an FdSlicer instance from a Buffer | ||
### 0.3.2 | ||
@@ -2,0 +12,0 @@ |
18
index.js
@@ -10,5 +10,6 @@ var fs = require('fs'); | ||
module.exports = FdSlicer; | ||
FdSlicer.BufferSlicer = BufferSlicer; | ||
FdSlicer.createFromBuffer = createFromBuffer; | ||
exports.createFromBuffer = createFromBuffer; | ||
exports.createFromFd = createFromFd; | ||
exports.BufferSlicer = BufferSlicer; | ||
exports.FdSlicer = FdSlicer; | ||
@@ -143,3 +144,3 @@ util.inherits(FdSlicer, EventEmitter); | ||
this.start = options.start || 0; | ||
this.endOffset = options.end || Infinity; | ||
this.endOffset = (options.end == null) ? Infinity : +options.end; | ||
this.bytesWritten = 0; | ||
@@ -230,5 +231,5 @@ this.pos = this.start; | ||
options = options || {}; | ||
var writeStream = new WriteStream(options); | ||
var writeStream = new Writable(options); | ||
writeStream.start = options.start || 0; | ||
writeStream.endOffset = options.end || Infinity; | ||
writeStream.endOffset = (options.end == null) ? this.buffer.length : +options.end; | ||
writeStream.bytesWritten = 0; | ||
@@ -253,2 +254,3 @@ writeStream.pos = writeStream.start; | ||
writeStream.emit('progress'); | ||
callback(); | ||
}; | ||
@@ -276,1 +278,5 @@ writeStream.destroy = function() { | ||
} | ||
function createFromFd(fd, options) { | ||
return new FdSlicer(fd, options); | ||
} |
{ | ||
"name": "fd-slicer", | ||
"version": "0.4.0", | ||
"version": "1.0.0", | ||
"description": "safely create multiple ReadStream or WriteStream objects from the same file descriptor", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha --reporter spec" | ||
"test": "mocha --reporter spec --check-leaks", | ||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/test.js", | ||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --timeout 10000 --reporter spec --check-leaks test/test.js" | ||
}, | ||
@@ -12,7 +14,9 @@ "author": "Andrew Kelley <superjoe30@gmail.com>", | ||
"devDependencies": { | ||
"mocha": "~1.21.5", | ||
"stream-equal": "~0.1.5" | ||
"istanbul": "~0.3.3", | ||
"mocha": "~2.0.1", | ||
"stream-equal": "~0.1.5", | ||
"streamsink": "~1.2.0" | ||
}, | ||
"dependencies": { | ||
"pend": "~1.1.3" | ||
"pend": "~1.2.0" | ||
}, | ||
@@ -28,3 +32,7 @@ "directories": { | ||
"url": "https://github.com/andrewrk/node-fd-slicer/issues" | ||
} | ||
}, | ||
"keywords": [ | ||
"createReadStream", | ||
"createWriteStream" | ||
] | ||
} |
# fd-slicer | ||
[![Build Status](https://travis-ci.org/andrewrk/node-fd-slicer.svg?branch=master)](https://travis-ci.org/andrewrk/node-fd-slicer) | ||
[![Coverage Status](https://img.shields.io/coveralls/andrewrk/node-fd-slicer.svg)](https://coveralls.io/r/andrewrk/node-fd-slicer) | ||
Safe `fs.ReadStream` and `fs.WriteStream` using the same fd. | ||
@@ -45,3 +48,3 @@ | ||
```js | ||
var FdSlicer = require('fd-slicer'); | ||
var fdSlicer = require('fd-slicer'); | ||
var fs = require('fs'); | ||
@@ -51,5 +54,5 @@ | ||
if (err) throw err; | ||
var fdSlicer = new FdSlicer(fd); | ||
var firstPart = fdSlicer.createReadStream({start: 0, end: 100}); | ||
var secondPart = fdSlicer.createReadStream({start: 100}); | ||
var slicer = fdSlicer.createFromFd(fd); | ||
var firstPart = slicer.createReadStream({start: 0, end: 100}); | ||
var secondPart = slicer.createReadStream({start: 100}); | ||
var firstOut = fs.createWriteStream("first.txt"); | ||
@@ -65,6 +68,6 @@ var secondOut = fs.createWriteStream("second.txt"); | ||
```js | ||
var FdSlicer = require('fd-slicer'); | ||
var fdSlicer = FdSlicer.createFromBuffer(someBuffer); | ||
var firstPart = fdSlicer.createReadStream({start: 0, end: 100}); | ||
var secondPart = fdSlicer.createReadStream({start: 100}); | ||
var fdSlicer = require('fd-slicer'); | ||
var slicer = FdSlicer.createFromBuffer(someBuffer); | ||
var firstPart = slicer.createReadStream({start: 0, end: 100}); | ||
var secondPart = slicer.createReadStream({start: 100}); | ||
var firstOut = fs.createWriteStream("first.txt"); | ||
@@ -78,9 +81,9 @@ var secondOut = fs.createWriteStream("second.txt"); | ||
### new FdSlicer(fd, [options]) | ||
### fdSlicer.createFromFd(fd, [options]) | ||
```js | ||
var FdSlicer = require('fd-slicer'); | ||
var fdSlicer = require('fd-slicer'); | ||
fs.open("file.txt", 'r', function(err, fd) { | ||
if (err) throw err; | ||
var fdSlicer = new FdSlicer(fd); | ||
var slicer = fdSlicer.createFromFd(fd); | ||
// ... | ||
@@ -101,7 +104,7 @@ }); | ||
### FdSlicer.createFromBuffer(buffer) | ||
### fdSlicer.createFromBuffer(buffer) | ||
```js | ||
var FdSlicer = require('fd-slicer'); | ||
var fdSlicer = FdSlicer.createFromBuffer(someBuffer); | ||
var fdSlicer = require('fd-slicer'); | ||
var slicer = fdSlicer.createFromBuffer(someBuffer); | ||
// ... | ||
@@ -108,0 +111,0 @@ ``` |
175
test/test.js
@@ -1,2 +0,2 @@ | ||
var FdSlicer = require('../'); | ||
var fdSlicer = require('../'); | ||
var fs = require('fs'); | ||
@@ -8,2 +8,3 @@ var crypto = require('crypto'); | ||
var Pend = require('pend'); | ||
var StreamSink = require('streamsink'); | ||
@@ -45,4 +46,4 @@ var describe = global.describe; | ||
if (err) return done(err); | ||
var fdSlicer = new FdSlicer(fd, {autoClose: true}); | ||
var actualStream = fdSlicer.createReadStream(); | ||
var slicer = fdSlicer.createFromFd(fd, {autoClose: true}); | ||
var actualStream = slicer.createReadStream(); | ||
var expectedStream = fs.createReadStream(testBlobFile); | ||
@@ -52,3 +53,3 @@ | ||
pend.go(function(cb) { | ||
fdSlicer.on('close', cb); | ||
slicer.on('close', cb); | ||
}); | ||
@@ -68,11 +69,11 @@ pend.go(function(cb) { | ||
if (err) return done(err); | ||
var fdSlicer = new FdSlicer(fd); | ||
var actualPart1 = fdSlicer.createReadStream({start: testBlobFileSize * 0/4, end: testBlobFileSize * 1/4}); | ||
var actualPart2 = fdSlicer.createReadStream({start: testBlobFileSize * 1/4, end: testBlobFileSize * 2/4}); | ||
var actualPart3 = fdSlicer.createReadStream({start: testBlobFileSize * 2/4, end: testBlobFileSize * 3/4}); | ||
var actualPart4 = fdSlicer.createReadStream({start: testBlobFileSize * 3/4, end: testBlobFileSize * 4/4}); | ||
var expectedPart1 = fdSlicer.createReadStream({start: testBlobFileSize * 0/4, end: testBlobFileSize * 1/4}); | ||
var expectedPart2 = fdSlicer.createReadStream({start: testBlobFileSize * 1/4, end: testBlobFileSize * 2/4}); | ||
var expectedPart3 = fdSlicer.createReadStream({start: testBlobFileSize * 2/4, end: testBlobFileSize * 3/4}); | ||
var expectedPart4 = fdSlicer.createReadStream({start: testBlobFileSize * 3/4, end: testBlobFileSize * 4/4}); | ||
var slicer = fdSlicer.createFromFd(fd); | ||
var actualPart1 = slicer.createReadStream({start: testBlobFileSize * 0/4, end: testBlobFileSize * 1/4}); | ||
var actualPart2 = slicer.createReadStream({start: testBlobFileSize * 1/4, end: testBlobFileSize * 2/4}); | ||
var actualPart3 = slicer.createReadStream({start: testBlobFileSize * 2/4, end: testBlobFileSize * 3/4}); | ||
var actualPart4 = slicer.createReadStream({start: testBlobFileSize * 3/4, end: testBlobFileSize * 4/4}); | ||
var expectedPart1 = slicer.createReadStream({start: testBlobFileSize * 0/4, end: testBlobFileSize * 1/4}); | ||
var expectedPart2 = slicer.createReadStream({start: testBlobFileSize * 1/4, end: testBlobFileSize * 2/4}); | ||
var expectedPart3 = slicer.createReadStream({start: testBlobFileSize * 2/4, end: testBlobFileSize * 3/4}); | ||
var expectedPart4 = slicer.createReadStream({start: testBlobFileSize * 3/4, end: testBlobFileSize * 4/4}); | ||
var pend = new Pend(); | ||
@@ -113,7 +114,7 @@ pend.go(function(cb) { | ||
if (err) return done(err); | ||
var fdSlicer = new FdSlicer(fd, {autoClose: true}); | ||
var actualStream = fdSlicer.createWriteStream(); | ||
var slicer = fdSlicer.createFromFd(fd, {autoClose: true}); | ||
var actualStream = slicer.createWriteStream(); | ||
var inStream = fs.createReadStream(testBlobFile); | ||
fdSlicer.on('close', function() { | ||
slicer.on('close', function() { | ||
var expected = fs.createReadStream(testBlobFile); | ||
@@ -135,7 +136,7 @@ var actual = fs.createReadStream(testOutBlobFile); | ||
if (err) return done(err); | ||
var fdSlicer = new FdSlicer(fd); | ||
var actualPart1 = fdSlicer.createWriteStream({start: testBlobFileSize * 0/4}); | ||
var actualPart2 = fdSlicer.createWriteStream({start: testBlobFileSize * 1/4}); | ||
var actualPart3 = fdSlicer.createWriteStream({start: testBlobFileSize * 2/4}); | ||
var actualPart4 = fdSlicer.createWriteStream({start: testBlobFileSize * 3/4}); | ||
var slicer = fdSlicer.createFromFd(fd); | ||
var actualPart1 = slicer.createWriteStream({start: testBlobFileSize * 0/4}); | ||
var actualPart2 = slicer.createWriteStream({start: testBlobFileSize * 1/4}); | ||
var actualPart3 = slicer.createWriteStream({start: testBlobFileSize * 2/4}); | ||
var actualPart4 = slicer.createWriteStream({start: testBlobFileSize * 3/4}); | ||
var in1 = fs.createReadStream(testBlobFile, {start: testBlobFileSize * 0/4, end: testBlobFileSize * 1/4}); | ||
@@ -177,10 +178,21 @@ var in2 = fs.createReadStream(testBlobFile, {start: testBlobFileSize * 1/4, end: testBlobFileSize * 2/4}); | ||
it("throws on invalid ref", function(done) { | ||
fs.open(testOutBlobFile, 'w', function(err, fd) { | ||
if (err) return done(err); | ||
var slicer = fdSlicer.createFromFd(fd, {autoClose: true}); | ||
assert.throws(function() { | ||
slicer.unref(); | ||
}, /invalid unref/); | ||
fs.close(fd, done); | ||
}); | ||
}); | ||
it("write stream emits error when max size exceeded", function(done) { | ||
fs.open(testOutBlobFile, 'w', function(err, fd) { | ||
if (err) return done(err); | ||
var fdSlicer = new FdSlicer(fd, {autoClose: true}); | ||
var ws = fdSlicer.createWriteStream({start: 0, end: 1000}); | ||
var slicer = fdSlicer.createFromFd(fd, {autoClose: true}); | ||
var ws = slicer.createWriteStream({start: 0, end: 1000}); | ||
ws.on('error', function(err) { | ||
assert.strictEqual(err.code, 'ETOOBIG'); | ||
fdSlicer.on('close', done); | ||
slicer.on('close', done); | ||
}); | ||
@@ -194,5 +206,5 @@ ws.end(new Buffer(1001)); | ||
if (err) return done(err); | ||
var fdSlicer = new FdSlicer(fd, {autoClose: true}); | ||
var ws = fdSlicer.createWriteStream({end: 1000}); | ||
fdSlicer.on('close', done); | ||
var slicer = fdSlicer.createFromFd(fd, {autoClose: true}); | ||
var ws = slicer.createWriteStream({end: 1000}); | ||
slicer.on('close', done); | ||
ws.end(new Buffer(1000)); | ||
@@ -205,7 +217,7 @@ }); | ||
if (err) return done(err); | ||
var fdSlicer = new FdSlicer(fd, {autoClose: true}); | ||
var ws = fdSlicer.createWriteStream({start: 1, end: 1000}); | ||
var slicer = fdSlicer.createFromFd(fd, {autoClose: true}); | ||
var ws = slicer.createWriteStream({start: 1, end: 1000}); | ||
ws.on('error', function(err) { | ||
assert.strictEqual(err.code, 'ETOOBIG'); | ||
fdSlicer.on('close', done); | ||
slicer.on('close', done); | ||
}); | ||
@@ -219,4 +231,4 @@ ws.end(new Buffer(1000)); | ||
if (err) return done(err); | ||
var fdSlicer = new FdSlicer(fd, {autoClose: true}); | ||
var ws = fdSlicer.createWriteStream(); | ||
var slicer = fdSlicer.createFromFd(fd, {autoClose: true}); | ||
var ws = slicer.createWriteStream(); | ||
var progressEventCount = 0; | ||
@@ -229,3 +241,3 @@ var prevBytesWritten = 0; | ||
}); | ||
fdSlicer.on('close', function() { | ||
slicer.on('close', function() { | ||
assert.ok(progressEventCount > 5); | ||
@@ -244,5 +256,5 @@ done(); | ||
if (err) return done(err); | ||
var fdSlicer = new FdSlicer(fd, {autoClose: true}); | ||
var ws = fdSlicer.createWriteStream(); | ||
fdSlicer.on('close', done); | ||
var slicer = fdSlicer.createFromFd(fd, {autoClose: true}); | ||
var ws = slicer.createWriteStream(); | ||
slicer.on('close', done); | ||
ws.write(new Buffer(1000)); | ||
@@ -256,7 +268,7 @@ ws.destroy(); | ||
if (err) return done(err); | ||
var fdSlicer = new FdSlicer(fd, {autoClose: true}); | ||
var rs = fdSlicer.createReadStream(); | ||
var slicer = fdSlicer.createFromFd(fd, {autoClose: true}); | ||
var rs = slicer.createReadStream(); | ||
rs.on('error', function(err) { | ||
assert.strictEqual(err.message, "stream destroyed"); | ||
fdSlicer.on('close', done); | ||
slicer.on('close', done); | ||
}); | ||
@@ -266,2 +278,87 @@ rs.destroy(); | ||
}); | ||
it("fdSlicer.read", function(done) { | ||
fs.open(testBlobFile, 'r', function(err, fd) { | ||
if (err) return done(err); | ||
var slicer = fdSlicer.createFromFd(fd); | ||
var outBuf = new Buffer(1024); | ||
slicer.read(outBuf, 0, 10, 0, function(err, bytesRead, buf) { | ||
assert.strictEqual(bytesRead, 10); | ||
fs.close(fd, done); | ||
}); | ||
}); | ||
}); | ||
it("fdSlicer.write", function(done) { | ||
fs.open(testOutBlobFile, 'w', function(err, fd) { | ||
if (err) return done(err); | ||
var slicer = fdSlicer.createFromFd(fd); | ||
slicer.write(new Buffer("blah\n"), 0, 5, 0, function() { | ||
if (err) return done(err); | ||
fs.close(fd, done); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe("BufferSlicer", function() { | ||
it("invalid ref", function() { | ||
var slicer = fdSlicer.createFromBuffer(new Buffer(16)); | ||
slicer.ref(); | ||
slicer.unref(); | ||
assert.throws(function() { | ||
slicer.unref(); | ||
}, /invalid unref/); | ||
}); | ||
it("read and write", function(done) { | ||
var buf = new Buffer("through the tangled thread the needle finds its way"); | ||
var slicer = fdSlicer.createFromBuffer(buf); | ||
var outBuf = new Buffer(1024); | ||
slicer.read(outBuf, 10, 11, 8, function(err) { | ||
if (err) return done(err); | ||
assert.strictEqual(outBuf.toString('utf8', 10, 21), "the tangled"); | ||
slicer.write(new Buffer("derp"), 0, 4, 7, function(err) { | ||
if (err) return done(err); | ||
assert.strictEqual(buf.toString('utf8', 7, 19), "derp tangled"); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it("createReadStream", function(done) { | ||
var str = "I never conquered rarely came, 16 just held such better days"; | ||
var buf = new Buffer(str); | ||
var slicer = fdSlicer.createFromBuffer(buf); | ||
var inStream = slicer.createReadStream(); | ||
var sink = new StreamSink(); | ||
inStream.pipe(sink); | ||
sink.on('finish', function() { | ||
assert.strictEqual(sink.toString(), str); | ||
inStream.destroy(); | ||
done(); | ||
}); | ||
}); | ||
it("createWriteStream exceed buffer size", function(done) { | ||
var slicer = fdSlicer.createFromBuffer(new Buffer(4)); | ||
var outStream = slicer.createWriteStream(); | ||
outStream.on('error', function(err) { | ||
assert.strictEqual(err.code, 'ETOOBIG'); | ||
done(); | ||
}); | ||
outStream.write("hi!\n"); | ||
outStream.write("it warked\n"); | ||
outStream.end(); | ||
}); | ||
it("createWriteStream ok", function(done) { | ||
var buf = new Buffer(1024); | ||
var slicer = fdSlicer.createFromBuffer(buf); | ||
var outStream = slicer.createWriteStream(); | ||
outStream.on('finish', function() { | ||
assert.strictEqual(buf.toString('utf8', 0, "hi!\nit warked\n".length), "hi!\nit warked\n"); | ||
outStream.destroy(); | ||
done(); | ||
}); | ||
outStream.write("hi!\n"); | ||
outStream.write("it warked\n"); | ||
outStream.end(); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
28769
8
571
1
190
4
+ Addedpend@1.2.0(transitive)
- Removedpend@1.1.3(transitive)
Updatedpend@~1.2.0