Skip to content

Support read(0) #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
84 changes: 42 additions & 42 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ module.exports.open = function (p, options){

var Reader = function (path, options){
events.EventEmitter.call (this);

options = options || {};
if (options.highWaterMark < 1){
throw new Error ("Invalid highWaterMark");
}
this._highWaterMark = options.highWaterMark || 16384;

this._path = path;
this._fd = null;
this._p = 0;
Expand All @@ -32,9 +32,9 @@ var Reader = function (path, options){
this._bufferMode = null;
this._readFile = false;
this._cancelled = false;

var me = this;

this._q = dq ().on ("error", function (error){
if (!me._fd){
me._q = null;
Expand All @@ -54,15 +54,15 @@ util.inherits (Reader, events.EventEmitter);

Reader.prototype._open = function (cb){
var me = this;

var open = function (){
fs.open (me._path, "r", function (error, fd){
if (error) return cb (error);
me._fd = fd;
cb ();
});
};

if (this._size === null){
this._stats (function (error){
if (error) return cb (error);
Expand All @@ -88,15 +88,15 @@ Reader.prototype._stats = function (cb){

Reader.prototype.cancel = function (err){
if (!this._q) throw new Error ("The reader is closed");

this._cancelled = true;
this._q.pause ();

if (!this._fd){
this._q = null;
return err ? this.emit ("error", err) : this.emit ("close");
}

var me = this;
fs.close (this._fd, function (error){
me._fd = null;
Expand All @@ -114,9 +114,9 @@ Reader.prototype.cancel = function (err){

Reader.prototype.close = function (){
if (!this._q) throw new Error ("The reader is closed");

var me = this;

this._q.push (function (done){
if (!me._fd){
me._q = null;
Expand All @@ -139,47 +139,47 @@ Reader.prototype.close = function (){
me.emit ("close");
}
});

return this;
};

Reader.prototype.isEOF = function (){
if (!this._q) throw new Error ("The reader is closed");

return this._size !== null && this._p >= this._size;
};

Reader.prototype._dump = function (target, offset, start, end, cb){
var me = this;

var reads = Math.ceil ((end - start)/this._highWaterMark);
var last = (end - start)%this._highWaterMark || this._highWaterMark;

(function read (reads){
if (reads === 1){
//Read to the buffer and copy to the target
fs.read (me._fd, me._b, 0, me._highWaterMark, start,
function (error, bytesRead){
if (error) return cb (error);

//Update the buffer limits
me._s = start;
me._e = start + bytesRead;

//Fill the target buffer
me._b.copy (target, offset, 0, last);

cb ();
});
}else{
//Read to the target
fs.read (me._fd, target, offset, me._highWaterMark, start,
function (error, bytesRead){
if (error) return cb (error);

offset += bytesRead;
start += bytesRead;

read (reads - 1);
});
}
Expand All @@ -188,24 +188,24 @@ Reader.prototype._dump = function (target, offset, start, end, cb){

Reader.prototype._read = function (bytes, cb){
var me = this;

//Trim the number of bytes to read
if (this._p + bytes >= this._size){
bytes = this._size - this._p;
}

var target = new Buffer (bytes);

if (!this._bufferMode){
//File size <= buffer size
if (!this._b) this._b = new Buffer (this._size);

var read = function (){
me._b.copy (target, 0, me._p, me._p + bytes);
me._p += bytes;
cb (null, bytes, target);
};

if (!this._readFile){
//Read all the file
fs.read (this._fd, this._b, 0, this._size, 0, function (error){
Expand All @@ -220,13 +220,13 @@ Reader.prototype._read = function (bytes, cb){
}else{
//File size > buffer size
if (!this._b) this._b = new Buffer (this._highWaterMark);

var s = this._p;
var e = this._p + bytes;
//Check whether the limits are inside the buffer
var is = s >= this._s && s < this._e;
var ie = e > this._s && e <= this._e;

if (is && ie){
//Case 1
//The bytes to read are already in the buffer
Expand All @@ -235,7 +235,7 @@ Reader.prototype._read = function (bytes, cb){
cb (null, bytes, target);
}else if (!is && !ie){
if (this._s >= s && this._s < e && this._e > s && this._e <= e){

//Case 5
//The buffer is inside the requested bytes
//Copy the bytes already in the buffer
Expand Down Expand Up @@ -287,10 +287,10 @@ Reader.prototype._read = function (bytes, cb){

Reader.prototype.read = function (bytes, cb){
if (!this._q) throw new Error ("The reader is closed");
if (~~bytes < 1) throw new Error ("Must read one or more bytes");
if (~~bytes < 0) throw new Error ("Cannot read a negative number of bytes");

var me = this;

this._q.push (function (done){
//Fast case
if (me.isEOF ()) return done (null, 0, new Buffer (0));
Expand All @@ -317,42 +317,42 @@ Reader.prototype.read = function (bytes, cb){
}
}
});

return this;
};

Reader.prototype._seek = function (offset, whence, cb){
if (!whence){
whence = { start: true };
}

if (whence.start){
this._p = offset;
}else if (whence.current){
this._p += offset;
}else if (whence.end){
this._p = this._size - 1 - offset;
}

//An offset beyond the size - 1 limit will always return 0 bytes read, no need
//to check and return an error
if (this._p < 0){
return cb (new Error ("The seek pointer must contain a positive value"));
}

cb ();
};

Reader.prototype.seek = function (offset, whence, cb){
if (!this._q) throw new Error ("The reader is closed");

var me = this;

if (arguments.length === 2 && typeof whence === "function"){
cb = whence;
whence = null;
}

this._q.push (function (done){
if (me._size === null){
me._stats (function (error){
Expand All @@ -377,18 +377,18 @@ Reader.prototype.seek = function (offset, whence, cb){
}
}
});

return this;
};

Reader.prototype.size = function (){
if (!this._q) throw new Error ("The reader is closed");

return this._size;
};

Reader.prototype.tell = function (){
if (!this._q) throw new Error ("The reader is closed");

return this._p;
};
};
8 changes: 6 additions & 2 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ var tests = {
assert.strictEqual (bytesRead, 3);
assert.deepEqual (buffer, new Buffer ([0, 1, 2]));
})
.read (0, function (bytesRead, buffer){
assert.strictEqual (bytesRead, 0);
assert.deepEqual (buffer, new Buffer ([]));
})
.close ();
},
"case 2": function (done){
Expand Down Expand Up @@ -243,7 +247,7 @@ var tests = {
br.open (file)
.on ("error", function (error){
assert.ok (error);

br.open (file)
.on ("error", function (error){
assert.ok (error);
Expand Down Expand Up @@ -326,4 +330,4 @@ var keysLength = keys.length;
again (i + 1);
}
}
})(0);
})(0);