Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial Commit

  • Loading branch information...
commit 8ac075237cce64d3315f6ea6c8242076a663866a 0 parents
@creationix authored
Showing with 185 additions and 0 deletions.
  1. +118 −0 continuable.js
  2. +15 −0 package.json
  3. +52 −0 test-fs.js
118 continuable.js
@@ -0,0 +1,118 @@
+var nativeFs = process.binding('fs')
+
+var fs = exports.fs = (function () {
+
+ var constants = require('constants');
+
+ function stringToFlags(string) {
+ if (typeof string === "number") return string;
+ switch (string) {
+ case 'r': return constants.O_RDONLY;
+ case 'r+': return constants.O_RDWR;
+ case 'w': return constants.O_CREAT | constants.O_TRUNC | constants.O_WRONLY;
+ case 'w+': return constants.O_CREAT | constants.O_TRUNC | constants.O_RDWR;
+ case 'a': return constants.O_APPEND | constants.O_CREAT | constants.O_WRONLY;
+ case 'a+': return constants.O_APPEND | constants.O_CREAT | constants.O_RDWR;
+ default: throw new Error("Unknown flag string " + JSON.stringify(string));
+ }
+ }
+
+ function noop(err) {
+ if (err) console.error(err.stack);
+ }
+
+ function ReadStream(fd) {
+ this.fd = fd;
+ this.buffer = new Buffer(this.chunkSize);
+ this.position = 0;
+ }
+ ReadStream.prototype.chunkSize = 1024 * 40;
+ ReadStream.prototype.read = function () {
+ var self = this;
+ return function (callback) {
+ read(self.fd, self.buffer, 0, self.chunkSize, self.position)(function (err, bytesRead) {
+ if (err) return callback(err);
+ self.position += bytesRead;
+ if (bytesRead) {
+ return callback(null, self.buffer.slice(0, bytesRead));
+ }
+ callback();
+ });
+ }
+ }
+ ReadStream.prototype.close = function () {
+ return close(this.fd);
+ };
+
+ function WriteStream(fd) {
+ this.fd = fd;
+ this.position = 0;
+ }
+ WriteStream.prototype.write = function (chunk) {
+ var self = this;
+ return function (callback) {
+ if (!chunk) { return callback(); }
+ write(self.fd, chunk, 0, chunk.length, self.position)(function (err, bytesWritten) {
+ if (err) return callback(err);
+ self.position += bytesWritten;
+ callback(null, bytesWritten);
+ });
+ };
+ };
+ WriteStream.prototype.close = ReadStream.prototype.close;
+
+ function open(path, flags, mode) {
+ return function (callback) {
+ return nativeFs.open(path, stringToFlags(flags), mode || 0666, callback || noop);
+ };
+ }
+
+ function read(fd, buffer, offset, length, position) {
+ return function (callback) {
+ return nativeFs.read(fd, buffer, offset, length, position, callback || noop)
+ };
+ };
+
+ function write(fd, buffer, offset, length, position) {
+ return function (callback) {
+ return nativeFs.write(fd, buffer, offset, length, position, callback || noop);
+ };
+ };
+
+ function close(fd) {
+ return function (callback) {
+ return nativeFs.close(fd, callback || noop);
+ };
+ };
+
+ function stat(path) {
+ return function (callback) {
+ return nativeFs.stat(path, callback || noop);
+ };
+ };
+
+ function fstat(fd) {
+ return function (callback) {
+ return nativeFs.fstat(fd, callback || noop);
+ };
+ };
+
+ function lstat(path) {
+ return function (callback) {
+ return nativeFs.lstat(path, callback || noop);
+ };
+ };
+
+ return {
+ ReadStream: ReadStream,
+ WriteStream: WriteStream,
+ open: open,
+ read: read,
+ write: write,
+ close: close,
+ stat: stat,
+ fstat: fstat,
+ lstat: lstat
+ };
+
+})();
15 package.json
@@ -0,0 +1,15 @@
+{
+ "name": "continuable",
+ "version": "0.0.0",
+ "description": "A continuable style interface for node.js APIs",
+ "main": "continuable.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/creationix/continuable.git"
+ },
+ "author": "Tim Caswell",
+ "license": "MIT"
+}
52 test-fs.js
@@ -0,0 +1,52 @@
+var fs = require('./continuable').fs;
+
+copy(__filename, __filename + ".copy")(onCopy)
+
+function copy(inputPath, outputPath) {
+ console.log("Copying %s to %s", inputPath, outputPath);
+
+ return function (callback) {
+ var input, output;
+ var totalWritten = 0;
+
+ fs.open(inputPath, "r")(onOpenInput);
+
+ function onOpenInput(err, fd) {
+ if (err) return done(err);
+ input = new fs.ReadStream(fd);
+ fs.open(outputPath, "w")(onOpenOutput);
+ }
+
+ function onOpenOutput(err, fd) {
+ if (err) return done(err);
+ output = new fs.WriteStream(fd);
+ input.read()(onRead);
+ }
+
+ function onRead(err, chunk) {
+ if (err) return done(err);
+ output.write(chunk)(onWrite);
+ }
+
+ function onWrite(err, bytesWritten) {
+ if (err) return done(err);
+ if (bytesWritten) {
+ totalWritten += bytesWritten;
+ return input.read()(onRead);
+ }
+ return done();
+ }
+
+ function done(err) {
+ input && input.close()();
+ output && output.close()();
+ callback(err, totalWritten);
+ }
+
+ };
+}
+
+function onCopy(err, bytes) {
+ if (err) throw err;
+ console.log("copied %s bytes", bytes);
+}
Please sign in to comment.
Something went wrong with that request. Please try again.