Browse files

v0.2.1

  • Loading branch information...
1 parent b5a6cc4 commit 373cbaff2eedad2b7eed251678d8d7167509dd2c Gabriel Llamas committed May 13, 2012
Showing with 23 additions and 19 deletions.
  1. +1 −1 README.md
  2. +1 −1 build/buffered-reader.js
  3. +1 −1 build/package.json
  4. +1 −1 examples/binary.js
  5. +4 −4 examples/characters.js
  6. +4 −1 examples/readLine.js
  7. +10 −9 src/buffered-reader.js
  8. +1 −1 src/package.json
View
2 README.md
@@ -7,7 +7,7 @@ Node BufferedReader
[Availability](#availability) | [Compatibility](#compatibility) | [Documentation](#documentation)
-Version: 0.2.0
+Version: 0.2.1
When you need to read a file you typically read a chunk of bytes called "buffer" to avoid multiple calls to the underlying I/O layer, so instead of reading directly from the disk, you read from the previous filled buffer. Doing this you win performance.
View
2 build/buffered-reader.js
@@ -1 +1 @@
-"use strict";var EVENTS=require("events"),FS=require("fs"),BUFFER_SIZE=16384,INVALID_BUFFER_SIZE="The buffer size must be greater than 0.",INVALID_START_OFFSET="The start offset must be greater than or equals to 0.",INVALID_END_OFFSET="The end offset must be greater than or equals to 0.",INVALID_RANGE_OFFSET="The end offset must be greater than or equals to the start offset.",INVALID_BYTES_RANGE_ERROR="The number of bytes to read must be greater than 0.",INVALID_SEEK_OFFSET="The offset must be greater than or equals to 0.",NO_FILE_ERROR="The source is not a file.",BufferedReader=function(a,b){EVENTS.EventEmitter.call(this),b=b||{},b.bufferSize===0&&(b.bufferSize=-1),this._settings={bufferSize:b.bufferSize||BUFFER_SIZE,encoding:b.encoding||null,start:b.start||0,end:b.end};if(this._settings.bufferSize<1)throw new Error(INVALID_BUFFER_SIZE);if(this._settings.start<0)throw new Error(INVALID_START_OFFSET);if(this._settings.end<0)throw new Error(INVALID_END_OFFSET);if(this._settings.end<this._settings.start)throw new Error(INVALID_RANGE_OFFSET);this._fileName=a,this._fd=null,this._buffer=null,this._fileOffset=this._settings.start,this._bufferOffset=0,this._dataOffset=0,this._realOffset=this._settings.start,this._fileSize=null,this._initialized=!1,this._interrupted=!1,this._isEOF=!1,this._noMoreBuffers=!1,this._needRead=!1};BufferedReader.prototype=Object.create(EVENTS.EventEmitter.prototype),BufferedReader.prototype.constructor=BufferedReader,BufferedReader.prototype.interrupt=function(){this._interrupted=!0},BufferedReader.prototype.read=function(){var a=FS.createReadStream(this._fileName,this._settings),b,c,d=this,e=this.listeners("character").length!==0||this.listeners("line").length!==0||this.listeners("byte").length!==0;a.on("data",function(f){c=f;var g=0,h,i,j=f.length;if(e){for(var k=0;k<j;k++){if(d._interrupted)break;i=f[k];if(!a.encoding){d.emit("byte",i);continue}d.emit("character",i==="\r"?"\n":i);if(i==="\n"||i==="\r")h=f.slice(g,k),g=k+1,b&&(h=b.concat(h),b=null),k+1!==j&&i==="\r"&&f[k+1]==="\n"&&k++,d.emit("line",h)}if(a.encoding&&g!==j){var l=g===0?f:f.slice(g);b=b?b.concat(l):l}}d.emit("buffer",f),d._interrupted&&(d._interrupted=!1,a.destroy(),d.emit("end"))}),a.on("end",function(){d._interrupted=!1,e&&b&&d.emit("line",b),d.emit("end")}),a.on("error",function(a){d._interrupted=!1,d.emit("error",a)})},BufferedReader.prototype._init=function(a){var b=this;FS.stat(this._fileName,function(c,d){if(c)return a(c);if(d.isFile()){if(b._settings.start>=d.size)return b._isEOF=!0,a(null);!b._settings.end&&b._settings.end!==0&&(b._settings.end=d.size),b._settings.end>=d.size&&(b._settings.end=d.size-1),b._fileSize=d.size,a(null)}else a(new Error(NO_FILE_ERROR))})},BufferedReader.prototype._read=function(a){var b=this,c=this._settings.bufferSize;FS.read(this._fd,this._buffer,0,c,this._fileOffset,function(d,e){if(d)return a(d);b._fileOffset+=e,b._fileOffset===b._fileSize&&(b._noMoreBuffers=!0),e<c&&(b._buffer=b._buffer.slice(0,e)),a(null)})},BufferedReader.prototype._readBytes=function(a,b){if(this._needRead){this._needRead=!1;var c=this;this._read(function(d){if(d)return b(d,null,-1);c._readBytes(a,b)});return}var d=function(){var e=a-c._dataOffset,g=c._buffer.length-c._bufferOffset,h=g<=e?g:e;c._buffer.copy(f,c._dataOffset,c._bufferOffset,c._bufferOffset+h),c._bufferOffset+=h,c._realOffset+=h,c._bufferOffset===c._buffer.length&&(c._bufferOffset=0,c._needRead=!0),c._dataOffset+=h,c._dataOffset===a?(c._dataOffset=0,c._isEOF=c._noMoreBuffers,b(null,f,a)):c._noMoreBuffers?(c._isEOF=!0,h=c._dataOffset,c._dataOffset=0,b(null,f.slice(0,h),h)):(c._needRead=!1,c._read(function(a){if(a)return b(a,null,-1);d()}))},c=this,e=c._settings.end-c._realOffset+1;a=e<a?e:a;if(a===0)return b(null,null,0);var f=new Buffer(a),g=c._buffer.length;if(a<=g){var h=c._bufferOffset+a;if(h<=g)c._buffer.copy(f,0,c._bufferOffset,h),c._bufferOffset=h,c._realOffset+=a,b(null,f,a);else{var i=g-c._bufferOffset;c._realOffset+=i,i!==0&&c._buffer.copy(f,0,c._bufferOffset,c._bufferOffset+i);if(c._noMoreBuffers)return c._isEOF=!0,b(null,f.slice(0,i),i);c._read(function(d){if(d)return b(d,null,-1);g=c._buffer.length;var e=a-i;if(g<=e){c._realOffset+=g,c._isEOF=!0,c._buffer.copy(f,i,0,g);var h=i+g;b(null,f.slice(0,h),h)}else c._realOffset+=e,c._bufferOffset=e,c._buffer.copy(f,i,0,c._bufferOffset),b(null,f,a)})}}else d()},BufferedReader.prototype.close=function(a){a&&(a=a.bind(this));if(!this._fd){a&&a(null);return}var b=this;FS.close(this._fd,function(c){b._fd=null,b._buffer=null,a&&a(c)})},BufferedReader.prototype.readBytes=function(a,b){b=b.bind(this);if(a<1||this._isEOF)return b(null,null,0);var c=function(){if(d._isEOF)return b(null,null,0);FS.open(d._fileName,"r",function(c,e){if(c)return b(c,null,-1);d._fd=e,d._buffer=new Buffer(d._settings.bufferSize),d._read(function(c){if(c)return b(c,null,-1);d._readBytes(a,b)})})},d=this;if(!this._initialized)this._init(function(a){if(a)return b(a,null);d._initialized=!0,c()});else{if(!this._fd)return c();this._readBytes(a,b)}},BufferedReader.prototype.seek=function(a,b){b=b.bind(this);if(a<0)return b(new Error(INVALID_SEEK_OFFSET));var c=function(){a+=d._settings.start;if(a>=d._settings.end+1)d._isEOF=!0;else{d._isEOF=!1;var c=d._fileOffset-(d._buffer?d._buffer.length:0);a>=c&&a<d._fileOffset?(d._bufferOffset=a-c,d._realOffset=a):(d._needRead=d._fd?!0:!1,d._noMoreBuffers=!1,d._fileOffset=a,d._bufferOffset=0,d._realOffset=a)}b(null)},d=this;this._initialized?c():this._init(function(a){if(a)return b(a,null);d._initialized=!0,c()})},BufferedReader.prototype.skip=function(a,b){b=b.bind(this);if(a<1||this._isEOF)return b(null,0);var c=function(){var c=d._settings.end-d._realOffset+1;a=a<=c?a:c,d.seek(d._realOffset-d._settings.start+a,function(){b(null,a)})},d=this;this._initialized?c():this._init(function(a){if(a)return b(a,null);d._initialized=!0,c()})},module.exports=BufferedReader;
+"use strict";var EVENTS=require("events"),FS=require("fs"),BUFFER_SIZE=16384,INVALID_BUFFER_SIZE="The buffer size must be greater than 0.",INVALID_START_OFFSET="The start offset must be greater than or equals to 0.",INVALID_END_OFFSET="The end offset must be greater than or equals to 0.",INVALID_RANGE_OFFSET="The end offset must be greater than or equals to the start offset.",INVALID_BYTES_RANGE_ERROR="The number of bytes to read must be greater than 0.",INVALID_SEEK_OFFSET="The offset must be greater than or equals to 0.",NO_FILE_ERROR="The source is not a file.",BufferedReader=function(a,b){EVENTS.EventEmitter.call(this),b=b||{},b.bufferSize===0&&(b.bufferSize=-1),this._settings={bufferSize:b.bufferSize||BUFFER_SIZE,encoding:b.encoding||null,start:b.start||0,end:b.end};if(this._settings.bufferSize<1)throw new Error(INVALID_BUFFER_SIZE);if(this._settings.start<0)throw new Error(INVALID_START_OFFSET);if(this._settings.end<0)throw new Error(INVALID_END_OFFSET);if(this._settings.end<this._settings.start)throw new Error(INVALID_RANGE_OFFSET);this._fileName=a,this._fd=null,this._buffer=null,this._fileOffset=this._settings.start,this._bufferOffset=0,this._dataOffset=0,this._realOffset=this._settings.start,this._fileSize=null,this._initialized=!1,this._interrupted=!1,this._isEOF=!1,this._noMoreBuffers=!1,this._needRead=!1};BufferedReader.prototype=Object.create(EVENTS.EventEmitter.prototype),BufferedReader.prototype.constructor=BufferedReader,BufferedReader.prototype.interrupt=function(){this._interrupted=!0},BufferedReader.prototype.read=function(){var a=FS.createReadStream(this._fileName,this._settings),b,c=this,d=this.listeners("character").length!==0,e=this.listeners("line").length!==0,f=this.listeners("byte").length!==0,g=d||e||f;a.on("data",function(h){var i=0,j,k,l=h.length;if(g){for(var m=0;m<l;m++){if(c._interrupted)break;k=h[m];if(!a.encoding){f&&c.emit("byte",k);continue}d&&c.emit("character",k==="\r"?"\n":k);if(!e)continue;if(k==="\n"||k==="\r")j=h.slice(i,m),i=m+1,b&&(j=b.concat(j),b=null),m+1!==l&&k==="\r"&&h[m+1]==="\n"&&m++,c.emit("line",j)}if(e&&a.encoding&&i!==l){var n=i===0?h:h.slice(i);b=b?b.concat(n):n}}c.emit("buffer",h),c._interrupted&&(c._interrupted=!1,a.destroy(),c.emit("end"))}),a.on("end",function(){c._interrupted=!1,g&&b&&c.emit("line",b),c.emit("end")}),a.on("error",function(a){c._interrupted=!1,c.emit("error",a)})},BufferedReader.prototype._init=function(a){var b=this;FS.stat(this._fileName,function(c,d){if(c)return a(c);if(d.isFile()){if(b._settings.start>=d.size)return b._isEOF=!0,a(null);!b._settings.end&&b._settings.end!==0&&(b._settings.end=d.size),b._settings.end>=d.size&&(b._settings.end=d.size-1),b._fileSize=d.size,a(null)}else a(new Error(NO_FILE_ERROR))})},BufferedReader.prototype._read=function(a){var b=this,c=this._settings.bufferSize;FS.read(this._fd,this._buffer,0,c,this._fileOffset,function(d,e){if(d)return a(d);b._fileOffset+=e,b._fileOffset===b._fileSize&&(b._noMoreBuffers=!0),e<c&&(b._buffer=b._buffer.slice(0,e)),a(null)})},BufferedReader.prototype._readBytes=function(a,b){if(this._needRead){this._needRead=!1;var c=this;this._read(function(d){if(d)return b(d,null,-1);c._readBytes(a,b)});return}var d=function(){var e=a-c._dataOffset,g=c._buffer.length-c._bufferOffset,h=g<=e?g:e;c._buffer.copy(f,c._dataOffset,c._bufferOffset,c._bufferOffset+h),c._bufferOffset+=h,c._realOffset+=h,c._bufferOffset===c._buffer.length&&(c._bufferOffset=0,c._needRead=!0),c._dataOffset+=h,c._dataOffset===a?(c._dataOffset=0,c._isEOF=c._noMoreBuffers,b(null,f,a)):c._noMoreBuffers?(c._isEOF=!0,h=c._dataOffset,c._dataOffset=0,b(null,f.slice(0,h),h)):(c._needRead=!1,c._read(function(a){if(a)return b(a,null,-1);d()}))},c=this,e=c._settings.end-c._realOffset+1;a=e<a?e:a;if(a===0)return b(null,null,0);var f=new Buffer(a),g=c._buffer.length;if(a<=g){var h=c._bufferOffset+a;if(h<=g)c._buffer.copy(f,0,c._bufferOffset,h),c._bufferOffset=h,c._realOffset+=a,b(null,f,a);else{var i=g-c._bufferOffset;c._realOffset+=i,i!==0&&c._buffer.copy(f,0,c._bufferOffset,c._bufferOffset+i);if(c._noMoreBuffers)return c._isEOF=!0,b(null,f.slice(0,i),i);c._read(function(d){if(d)return b(d,null,-1);g=c._buffer.length;var e=a-i;if(g<=e){c._realOffset+=g,c._isEOF=!0,c._buffer.copy(f,i,0,g);var h=i+g;b(null,f.slice(0,h),h)}else c._realOffset+=e,c._bufferOffset=e,c._buffer.copy(f,i,0,c._bufferOffset),b(null,f,a)})}}else d()},BufferedReader.prototype.close=function(a){a&&(a=a.bind(this));if(!this._fd){a&&a(null);return}var b=this;FS.close(this._fd,function(c){b._fd=null,b._buffer=null,a&&a(c)})},BufferedReader.prototype.readBytes=function(a,b){b=b.bind(this);if(a<1||this._isEOF)return b(null,null,0);var c=function(){if(d._isEOF)return b(null,null,0);FS.open(d._fileName,"r",function(c,e){if(c)return b(c,null,-1);d._fd=e,d._buffer=new Buffer(d._settings.bufferSize),d._read(function(c){if(c)return b(c,null,-1);d._readBytes(a,b)})})},d=this;if(!this._initialized)this._init(function(a){if(a)return b(a,null);d._initialized=!0,c()});else{if(!this._fd)return c();this._readBytes(a,b)}},BufferedReader.prototype.seek=function(a,b){b=b.bind(this);if(a<0)return b(new Error(INVALID_SEEK_OFFSET));var c=function(){a+=d._settings.start;if(a>=d._settings.end+1)d._isEOF=!0;else{d._isEOF=!1;var c=d._fileOffset-(d._buffer?d._buffer.length:0);a>=c&&a<d._fileOffset?(d._bufferOffset=a-c,d._realOffset=a):(d._needRead=d._fd?!0:!1,d._noMoreBuffers=!1,d._fileOffset=a,d._bufferOffset=0,d._realOffset=a)}b(null)},d=this;this._initialized?c():this._init(function(a){if(a)return b(a,null);d._initialized=!0,c()})},BufferedReader.prototype.skip=function(a,b){b=b.bind(this);if(a<1||this._isEOF)return b(null,0);var c=function(){var c=d._settings.end-d._realOffset+1;a=a<=c?a:c,d.seek(d._realOffset-d._settings.start+a,function(){b(null,a)})},d=this;this._initialized?c():this._init(function(a){if(a)return b(a,null);d._initialized=!0,c()})},module.exports=BufferedReader;
View
2 build/package.json
@@ -1,6 +1,6 @@
{
"name": "buffered-reader",
- "version": "0.2.0",
+ "version": "0.2.1",
"description": "Fully configurable buffered reader.",
"keywords": ["buffer", "reader", "line", "read line", "file", "read file", "read text file",
"read binary file", "binary"],
View
2 examples/binary.js
@@ -2,7 +2,7 @@ var BufferedReader = require ("../build/buffered-reader");
new BufferedReader ("lorem ipsum 2")
.on ("error", function (error){
- console.log ("error: " + error);
+ console.log (error);
})
.on ("byte", function (b){
console.log ("byte: " + b);
View
8 examples/characters.js
@@ -2,16 +2,16 @@ var BufferedReader = require ("../build/buffered-reader");
/**
Two ways to read one character at a time:
-- using "buffer" event with a buffer size of 1. Don't do this, it's very inefficient, it's just
+- Using the "buffer" event with a buffer size of 1. Don't do this, it's very inefficient, it's just
to give an example of a buffer event and size. Default size is 16KB.
-- using "character" event.
+- Using the "character" event.
*/
console.log ("\"buffer\" event: ");
new BufferedReader ("lorem ipsum 2", { encoding: "utf8", bufferSize: 1 })
.on ("error", function (error){
- console.log ("error: " + error);
+ console.log (error);
})
.on ("buffer", function (buffer){
console.log ("buffer: " + buffer);
@@ -21,7 +21,7 @@ new BufferedReader ("lorem ipsum 2", { encoding: "utf8", bufferSize: 1 })
new BufferedReader ("lorem ipsum 2", { encoding: "utf8" })
.on ("error", function (error){
- console.log ("error: " + error);
+ console.log (error);
})
.on ("character", function (character){
console.log ("character: " + character);
View
5 examples/readLine.js
@@ -2,12 +2,15 @@ var BufferedReader = require ("../build/buffered-reader");
new BufferedReader ("lorem ipsum", { encoding: "utf8" })
.on ("error", function (error){
- console.log ("error: " + error);
+ console.log (error);
})
.on ("line", function (line){
console.log ("line: " + line);
if (line === "Phasellus pulvinar mauris in purus consequat vel congue orci hendrerit."){
this.interrupt ();
}
})
+ .on ("end", function (){
+ console.log ("EOF");
+ })
.read ();
View
19 src/buffered-reader.js
@@ -4,8 +4,8 @@
*
* @author Gabriel Llamas
* @created 10/04/2012
- * @modified 01/05/2012
- * @version 0.2.0
+ * @modified 13/05/2012
+ * @version 0.2.1
*/
"use strict";
@@ -68,14 +68,14 @@ BufferedReader.prototype.read = function (){
var stream = FS.createReadStream (this._fileName, this._settings);
var lastChunk;
- var buffer;
var me = this;
- var loop = this.listeners ("character").length !== 0 || this.listeners ("line").length !== 0 ||
- this.listeners ("byte").length !== 0;
+ var onChar = this.listeners ("character").length !== 0;
+ var onLine = this.listeners ("line").length !== 0;
+ var onByte = this.listeners ("byte").length !== 0;
+ var loop = onChar || onLine || onByte;
stream.on ("data", function (data){
- buffer = data;
var offset = 0;
var chunk;
var character;
@@ -87,12 +87,13 @@ BufferedReader.prototype.read = function (){
character = data[i];
if (stream.encoding){
- me.emit ("character", character === "\r" ? "\n" : character);
+ if (onChar) me.emit ("character", character === "\r" ? "\n" : character);
}else{
- me.emit ("byte", character);
+ if (onByte) me.emit ("byte", character);
continue;
}
+ if (!onLine) continue;
if (character === "\n" || character === "\r"){
chunk = data.slice (offset, i);
offset = i + 1;
@@ -110,7 +111,7 @@ BufferedReader.prototype.read = function (){
}
}
- if (stream.encoding && offset !== len){
+ if (onLine && stream.encoding && offset !== len){
var s = offset === 0 ? data : data.slice (offset);
lastChunk = lastChunk ? lastChunk.concat (s) : s;
}
View
2 src/package.json
@@ -1,6 +1,6 @@
{
"name": "buffered-reader",
- "version": "0.2.0",
+ "version": "0.2.1",
"description": "Fully configurable buffered reader.",
"keywords": ["buffer", "reader", "line", "read line", "file", "read file", "read text file",
"read binary file", "binary"],

0 comments on commit 373cbaf

Please sign in to comment.