Browse Source

Put file stream methods into prototype, small style fixes

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
7faf7d5c8d
  1. 303
      lib/fs.js

303
lib/fs.js

@ -492,99 +492,107 @@ var FileReadStream = fs.FileReadStream = function(path, options) {
options = options || {}; options = options || {};
for (var i in options) this[i] = options[i]; for (var i in options) this[i] = options[i];
var var self = this;
self = this,
buffer = null;
function read() { fs.open(this.path, this.flags, this.mode, function(err, fd) {
if (!self.readable || self.paused) { if (err) {
self.emit('error', err);
self.readable = false;
return; return;
} }
fs.read(self.fd, self.bufferSize, undefined, self.encoding, function(err, data, bytesRead) { self.fd = fd;
if (err) { self.emit('open', fd);
self.emit('error', err); self._read();
self.readable = false; });
return; };
} sys.inherits(FileReadStream, events.EventEmitter);
if (bytesRead === 0) {
self.emit('end');
self.forceClose();
return;
}
// do not emit events if the stream is paused
if (self.paused) {
buffer = data;
return;
}
// do not emit events anymore after we declared the stream unreadable
if (!self.readable) {
return;
}
self.emit('data', data); FileReadStream.prototype._read = function () {
read(); var self = this;
}); if (!self.readable || self.paused) return;
}
fs.open(this.path, this.flags, this.mode, function(err, fd) { fs.read(self.fd,
self.bufferSize,
undefined,
self.encoding,
function(err, data, bytesRead) {
if (err) { if (err) {
self.emit('error', err); self.emit('error', err);
self.readable = false; self.readable = false;
return; return;
} }
self.fd = fd; if (bytesRead === 0) {
self.emit('open', fd); self.emit('end');
read(); self.forceClose();
return;
}
// do not emit events if the stream is paused
if (self.paused) {
self.buffer = data;
return;
}
// do not emit events anymore after we declared the stream unreadable
if (!self.readable) {
return;
}
self.emit('data', data);
self._read();
}); });
};
this.forceClose = function(cb) {
this.readable = false;
function close() { FileReadStream.prototype.forceClose = function (cb) {
fs.close(self.fd, function(err) { var self = this;
if (err) { this.readable = false;
if (cb) {
cb(err);
}
self.emit('error', err);
return;
}
function close() {
fs.close(self.fd, function(err) {
if (err) {
if (cb) { if (cb) {
cb(null); cb(err);
} }
self.emit('close'); self.emit('error', err);
}); return;
} }
if (this.fd) { if (cb) {
close(); cb(null);
} else { }
this.addListener('open', close); self.emit('close');
} });
}; }
if (this.fd) {
close();
} else {
this.addListener('open', close);
}
};
this.pause = function() {
this.paused = true;
};
this.resume = function() { FileReadStream.prototype.pause = function() {
this.paused = false; this.paused = true;
};
if (buffer !== null) {
self.emit('data', buffer);
buffer = null;
}
read(); FileReadStream.prototype.resume = function() {
}; this.paused = false;
if (this.buffer) {
this.emit('data', this.buffer);
this.buffer = null;
}
this._read();
}; };
sys.inherits(FileReadStream, events.EventEmitter);
fs.createWriteStream = function(path, options) { fs.createWriteStream = function(path, options) {
return new FileWriteStream(path, options); return new FileWriteStream(path, options);
@ -604,105 +612,108 @@ var FileWriteStream = fs.FileWriteStream = function(path, options) {
options = options || {}; options = options || {};
for (var i in options) this[i] = options[i]; for (var i in options) this[i] = options[i];
var this.busy = false;
self = this, this._queue = [];
queue = [],
busy = false;
queue.push([fs.open, this.path, this.flags, this.mode, undefined]); this._queue.push([fs.open, this.path, this.flags, this.mode, undefined]);
this.flush();
};
sys.inherits(FileWriteStream, events.EventEmitter);
function flush() {
if (busy) {
return;
}
var args = queue.shift();
if (!args) {
return self.emit('drain');
}
busy = true; FileWriteStream.prototype.flush = function () {
if (this.busy) return;
var self = this;
var var args = this._queue.shift();
method = args.shift(), if (!args) return self.emit('drain');
cb = args.pop();
args.push(function(err) { this.busy = true;
busy = false;
if (err) { var
self.writeable = false; method = args.shift(),
if (cb) { cb = args.pop();
cb(err);
}
self.emit('error', err);
return;
}
// stop flushing after close var self = this;
if (method === fs.close) {
if (cb) {
cb(null);
}
self.emit('close');
return;
}
// save reference for file pointer args.push(function(err) {
if (method === fs.open) { self.busy = false;
self.fd = arguments[1];
self.emit('open', self.fd); if (err) {
} else if (cb) { self.writeable = false;
// write callback if (cb) {
cb(null, arguments[1]); cb(err);
} }
self.emit('error', err);
return;
}
flush(); // stop flushing after close
}); if (method === fs.close) {
if (cb) {
cb(null);
}
self.emit('close');
return;
}
// Inject the file pointer // save reference for file pointer
if (method !== fs.open) { if (method === fs.open) {
args.unshift(self.fd); self.fd = arguments[1];
self.emit('open', self.fd);
} else if (cb) {
// write callback
cb(null, arguments[1]);
} }
method.apply(this, args); self.flush();
}; });
this.write = function(data, cb) { // Inject the file pointer
if (!this.writeable) { if (method !== fs.open) {
throw new Error('stream not writeable'); args.unshift(self.fd);
} }
queue.push([fs.write, data, undefined, this.encoding, cb]); method.apply(this, args);
flush(); };
return false;
};
this.close = function(cb) {
this.writeable = false;
queue.push([fs.close, cb]);
flush();
};
this.forceClose = function(cb) { FileWriteStream.prototype.write = function(data, cb) {
this.writeable = false; if (!this.writeable) {
fs.close(self.fd, function(err) { throw new Error('stream not writeable');
if (err) { }
if (cb) {
cb(err);
}
self.emit('error', err); this._queue.push([fs.write, data, undefined, this.encoding, cb]);
return; this.flush();
}
return false;
};
FileWriteStream.prototype.close = function (cb) {
this.writeable = false;
this._queue.push([fs.close, cb]);
this.flush();
};
FileWriteStream.prototype.forceClose = function (cb) {
this.writeable = false;
fs.close(self.fd, function(err) {
if (err) {
if (cb) { if (cb) {
cb(null); cb(err);
} }
self.emit('close');
});
};
flush(); self.emit('error', err);
return;
}
if (cb) {
cb(null);
}
self.emit('close');
});
}; };
sys.inherits(FileWriteStream, events.EventEmitter);

Loading…
Cancel
Save