mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
Add "/file.js" buffered disk I/O object.
This is similar to the class node.File which was removed in
82cb1b5acb.
Needs documentation.
This commit is contained in:
128
lib/file.js
Normal file
128
lib/file.js
Normal file
@@ -0,0 +1,128 @@
|
||||
exports.debugLevel = 0; // Increase to get more verbose debug output
|
||||
|
||||
function debugMessage (msg) {
|
||||
if (exports.debugLevel > 0) {
|
||||
node.error(__filename + ": " + msg.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function debugObject (obj) {
|
||||
if (exports.debugLevel > 0) {
|
||||
node.error(__filename + ": " + JSON.stringify(obj));
|
||||
}
|
||||
}
|
||||
|
||||
exports.File = function (filename, mode, options) {
|
||||
var self = this;
|
||||
|
||||
options = options || {};
|
||||
self.encoding = options.encoding || "utf8";
|
||||
|
||||
self.filename = filename;
|
||||
|
||||
self.actionQueue = [];
|
||||
self.currentAction = null;
|
||||
|
||||
switch (mode) {
|
||||
case "r":
|
||||
self.flags = node.O_RDONLY;
|
||||
break;
|
||||
|
||||
case "r+":
|
||||
self.flags = node.O_RDWR;
|
||||
break;
|
||||
|
||||
case "w":
|
||||
self.flags = node.O_CREAT | node.O_TRUNC | node.O_WRONLY;
|
||||
break;
|
||||
|
||||
case "w+":
|
||||
self.flags = node.O_CREAT | node.O_TRUNC | node.O_RDWR;
|
||||
break;
|
||||
|
||||
case "a":
|
||||
self.flags = node.O_APPEND | node.O_CREAT | node.O_WRONLY;
|
||||
break;
|
||||
|
||||
case "a+":
|
||||
self.flags = node.O_APPEND | node.O_CREAT | node.O_RDWR;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Unknown mode");
|
||||
}
|
||||
|
||||
self.open(self.filename, self.flags, 0666).addCallback(function (fd) {
|
||||
debugMessage(self.filename + " opened. fd = " + fd);
|
||||
self.fd = fd;
|
||||
}).addErrback(function () {
|
||||
self.emit("error", ["open"]);
|
||||
});
|
||||
};
|
||||
|
||||
var proto = exports.File.prototype;
|
||||
|
||||
proto._maybeDispatch = function () {
|
||||
var self = this;
|
||||
|
||||
if (self.currentAction) return;
|
||||
self.currentAction = self.actionQueue.shift();
|
||||
if (!self.currentAction) return;
|
||||
|
||||
debugObject(self.currentAction);
|
||||
|
||||
var args = self.currentAction.args || [];
|
||||
|
||||
if (self.currentAction.method != "open") {
|
||||
args.unshift(self.fd);
|
||||
}
|
||||
|
||||
var method = self.currentAction.method;
|
||||
|
||||
if (!args[3] && (method == "read" || method == "write")) {
|
||||
args[3] = self.encoding;
|
||||
}
|
||||
|
||||
var promise = node.fs[method].apply(self, args);
|
||||
|
||||
var userPromise = self.currentAction.promise;
|
||||
|
||||
promise.addCallback(function () {
|
||||
node.assert(self.currentAction.promise == userPromise);
|
||||
userPromise.emitSuccess.apply(userPromise, arguments);
|
||||
self.currentAction = null;
|
||||
self._maybeDispatch();
|
||||
}).addErrback(function () {
|
||||
debugMessage("Error in method " + method);
|
||||
node.assert(self.currentAction.promise == userPromise);
|
||||
userPromise.emitError.apply(userPromise, arguments);
|
||||
self.currentAction = null;
|
||||
self._maybeDispatch();
|
||||
});
|
||||
};
|
||||
|
||||
proto._queueAction = function (method, args) {
|
||||
var userPromise = new node.Promise;
|
||||
this.actionQueue.push({ method: method, args: args, promise: userPromise });
|
||||
this._maybeDispatch();
|
||||
return userPromise;
|
||||
};
|
||||
|
||||
// FIXME the following can probably be DRY'd up with some fancy getter
|
||||
// stuff.
|
||||
|
||||
proto.open = function (filename, flags, mode) {
|
||||
return this._queueAction("open", [filename, flags, mode]);
|
||||
};
|
||||
|
||||
proto.write = function (data, pos, encoding) {
|
||||
return this._queueAction("write", [data, pos, encoding]);
|
||||
};
|
||||
|
||||
proto.read = function (length, pos, encoding) {
|
||||
return this._queueAction("read", [length, pos, encoding]);
|
||||
};
|
||||
|
||||
proto.close = function () {
|
||||
return this._queueAction("close");
|
||||
};
|
||||
38
test/mjsunit/test-buffered-file.js
Normal file
38
test/mjsunit/test-buffered-file.js
Normal file
@@ -0,0 +1,38 @@
|
||||
include("common.js");
|
||||
|
||||
var testTxt = node.path.join(fixturesDir, "test.txt");
|
||||
|
||||
var libDir = node.path.join(testDir, "../../lib");
|
||||
node.libraryPaths.unshift(libDir);
|
||||
include("/file.js");
|
||||
|
||||
var fileUnlinked = false;
|
||||
|
||||
var file = new File(testTxt, "w+");
|
||||
file.write("hello\n");
|
||||
file.write("world\n");
|
||||
setTimeout(function () {
|
||||
file.write("hello\n");
|
||||
file.write("world\n");
|
||||
file.close().addCallback(function () {
|
||||
node.error("file closed...");
|
||||
var out = node.fs.cat(testTxt).wait();
|
||||
print("the file contains: ");
|
||||
p(out);
|
||||
assertEquals("hello\nworld\nhello\nworld\n", out);
|
||||
var file2 = new File(testTxt, "r");
|
||||
file2.read(5).addCallback(function (data) {
|
||||
puts("read(5): " + JSON.stringify(data));
|
||||
assertEquals("hello", data);
|
||||
node.fs.unlink(testTxt).addCallback(function () {
|
||||
fileUnlinked = true;
|
||||
});
|
||||
});
|
||||
file2.close();
|
||||
});
|
||||
}, 10);
|
||||
|
||||
process.addListener("exit", function () {
|
||||
assertTrue(fileUnlinked);
|
||||
puts("done");
|
||||
});
|
||||
Reference in New Issue
Block a user