Permalink
Browse files

v0.1.0

  • Loading branch information...
1 parent 7eb380c commit 4e45a027bac8d5a805e874aef858ea2a0b3deb96 Gabriel Llamas committed Apr 25, 2012
View
@@ -7,7 +7,11 @@ Node BufferedReader
[Availability](#availability) | [Compatibility](#compatibility) | [Documentation](#documentation)
-Version: 0.0.6
+Version: 0.1.0
+
+When you need to read a file you typically read a chunk of bytes called "buffer" to avoid multiple calls to the underliying I/O layer, so instead of reading directly from the disk, you read from the previous filled buffer. Doing that you win performance.
+
+This library allows you to read files using internal buffers, so you don't have to worry about them. In addition, you can read a text file line by line.
<a name="availability"></a>
#### Availability [](#start) ####
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -1,8 +1,9 @@
{
"name": "buffered-reader",
- "version": "0.0.6",
+ "version": "0.1.0",
"description": "Fully configurable buffered reader.",
- "keywords": ["buffer", "reader", "line", "read line", "read file", "read text file", "file"],
+ "keywords": ["buffer", "reader", "line", "read line", "file", "read file", "read text file",
+ "read binary file", "binary"],
"author": {
"name": "Gabriel Llamas"
},
View
@@ -0,0 +1,29 @@
+var BufferedReader = require ("../build/buffered-reader");
+
+console.log ("File size: 16");
+
+new BufferedReader ("file").readBytes (10, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+
+ console.log (bytes);
+ console.log ("Bytes read: " + bytesRead);
+
+ this.readBytes (8, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+
+ console.log (bytes);
+ console.log ("Bytes read: " + bytesRead);
+
+ this.readBytes (4, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+
+ //No more bytes, reached the end of the file
+ console.log (bytes);
+ console.log ("Bytes read: " + bytesRead);
+
+ this.close (function (error){
+ if (error) console.log (error);
+ });
+ });
+ });
+});
View
Binary file not shown.
View
@@ -4,17 +4,20 @@
*
* @author Gabriel Llamas
* @created 10/04/2012
- * @modified 21/04/2012
- * @version 0.0.6
+ * @modified 25/04/2012
+ * @version 0.1.0
*/
"use strict";
var EVENTS = require ("events");
var FS = require ("fs");
-var PATH = require ("path");
var BUFFER_SIZE = 16384;
+var INVALID_BUFFER_SIZE = new Error ("The buffer size must be greater than 0.");
+var INVALID_BYTES_RANGE_ERROR = new Error ("The number of bytes must be greater than 0.");
+var NO_FILE_ERROR = new Error ("The source is not a file.");
+
var BufferedReader = function (fileName, bufferSize, encoding){
EVENTS.EventEmitter.call (this);
@@ -27,12 +30,22 @@ var BufferedReader = function (fileName, bufferSize, encoding){
bufferSize = BUFFER_SIZE;
}
+ if (bufferSize < 1) throw INVALID_BUFFER_SIZE;
+
this._settings = {
encoding: encoding,
bufferSize: bufferSize
};
this._fileName = fileName;
+ this._fd = null;
+ this._buffer = null;
+ this._fileOffset = 0;
+ this._bufferOffset = 0;
+ this._eof = false;
+ this._noMoreBuffers = false;
+ this._fileSize = null;
+ this._dataOffset = 0;
};
BufferedReader.prototype = Object.create (EVENTS.EventEmitter.prototype);
@@ -104,4 +117,147 @@ BufferedReader.prototype.read = function (){
});
};
+BufferedReader.prototype._open = function (cb){
+ if (this._fd) return cb (null, this._fd);
+
+ var me = this;
+ FS.stat (this._fileName, function (error, stats){
+ if (error) return cb (error, null);
+ if (stats.isFile ()){
+ FS.open (me._fileName, "r", function (error, fd){
+ if (error) return cb (error, null);
+
+ me._fileSize = stats.size;
+ me._fd = fd;
+ me._buffer = new Buffer (me._settings.bufferSize);
+ me._read (function (error){
+ if (error){
+ return cb (error, null);
+ }else{
+ cb (null, me._fd);
+ }
+ });
+ });
+ }else{
+ cb (NO_FILE_ERROR, null);
+ }
+ });
+};
+
+BufferedReader.prototype._read = function (cb){
+ var me = this;
+ var size = this._settings.bufferSize;
+ FS.read (this._fd, this._buffer, 0, size, this._fileOffset, function (error, bytesRead){
+ if (error) return cb (error);
+
+ me._bufferValidSize = bytesRead;
+ me._fileOffset += bytesRead;
+ if (me._fileOffset === me._fileSize){
+ me._noMoreBuffers = true;
+ }
+ if (bytesRead < size){
+ me._buffer = me._buffer.slice (0, bytesRead);
+ }
+ cb ();
+ });
+};
+
+BufferedReader.prototype.close = function (cb){
+ if (cb) cb = cb.bind (this);
+ if (!this._fd){
+ if (cb) cb (null);
+ return;
+ }
+
+ var me = this;
+ FS.close (this._fd, function (error){
+ me._fd = null;
+ me._buffer = null;
+ if (cb) cb.call (me, error);
+ });
+};
+
+BufferedReader.prototype.readBytes = function (bytes, cb){
+ cb = cb.bind (this);
+ if (bytes < 1) return cb (INVALID_BYTES_RANGE_ERROR, null, -1);
+ if (this._eof) return cb (null, null, 0);
+
+ var fill = function (){
+ var endData = bytes - me._dataOffset;
+ var endBuffer = me._buffer.length - me._bufferOffset;
+ var end = endData > endBuffer ? endBuffer : endData;
+
+ me._buffer.copy (data, me._dataOffset, me._bufferOffset, me._bufferOffset + end);
+ me._bufferOffset += end;
+ if (me._bufferOffset === me._buffer.length) me._bufferOffset = 0;
+ me._dataOffset += end;
+
+ if (me._dataOffset === bytes){
+ me._dataOffset = 0;
+ me._eof = me._noMoreBuffers;
+ cb (null, data, bytes);
+ }else{
+ if (me._noMoreBuffers){
+ me._eof = true;
+ end = me._dataOffset;
+ me._dataOffset = 0;
+ cb (null, data.slice (0, end), end);
+ }else{
+ me._read (function (error){
+ if (error) return cb (error, null, -1);
+
+ fill ();
+ });
+ }
+ }
+ };
+
+ var me = this;
+ var data = new Buffer (bytes);
+
+ this._open (function (error, fd){
+ if (error) return cb (error, null, -1);
+
+ var len = me._buffer.length;
+
+ if (bytes < len){
+ var end = me._bufferOffset + bytes;
+
+ if (end <= len){
+ me._buffer.copy (data, 0, me._bufferOffset, end);
+ me._bufferOffset = end;
+ cb (null, data, bytes);
+ }else{
+ var last = len - me._bufferOffset;
+ if (last !== 0){
+ me._buffer.copy (data, 0, me._bufferOffset, me._bufferOffset + last);
+ }
+ if (me._noMoreBuffers){
+ me._eof = true;
+ return cb (null, data.slice (0, last), last);
+ }
+
+ me._read (function (error){
+ if (error) return cb (error, null);
+
+ len = me._buffer.length;
+ var remaining = bytes - last;
+ if (len <= remaining){
+ me._eof = true;
+ me._buffer.copy (data, last, 0, len);
+ var lastChunk = last + len;
+ cb (null, data.slice (0, lastChunk), lastChunk);
+ }else{
+ me._bufferOffset = remaining;
+ me._buffer.copy (data, last, 0, me._bufferOffset);
+ cb (null, data, bytes);
+ }
+ });
+ }
+ }else{
+ fill ();
+ }
+ });
+};
+
module.exports = BufferedReader;
View
@@ -1,8 +1,9 @@
{
"name": "buffered-reader",
- "version": "0.0.6",
+ "version": "0.1.0",
"description": "Fully configurable buffered reader.",
- "keywords": ["buffer", "reader", "line", "read line", "read file", "read text file", "file"],
+ "keywords": ["buffer", "reader", "line", "read line", "file", "read file", "read text file",
+ "read binary file", "binary"],
"author": {
"name": "Gabriel Llamas"
},
View
Binary file not shown.
View
@@ -0,0 +1,59 @@
+var BufferedReader = require ("../../build/buffered-reader");
+
+new BufferedReader ("file", 5).readBytes (2, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (2, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (2, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (2, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (2, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (2, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (2, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (2, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (2, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.close (function (error){
+ if (error) console.log (error);
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+});
View
@@ -0,0 +1,41 @@
+var BufferedReader = require ("../../build/buffered-reader");
+
+new BufferedReader ("file", 5).readBytes (4, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (3, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (2, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (1, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (4, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.readBytes (3, function (error, bytes, bytesRead){
+ if (error) console.log (error);
+ console.log (bytes);
+ console.log ("bytes read: " + bytesRead);
+
+ this.close (function (error){
+ if (error) console.log (error);
+ });
+ });
+ });
+ });
+ });
+ });
+});
Oops, something went wrong.

0 comments on commit 4e45a02

Please sign in to comment.