« index
Coverage for /Users/kris/q-io/writer.js : 85%
90 lines |
77 run |
13 missing |
1 partial |
12 blocks |
4 blocks run |
8 blocks missing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | var Q = require("q"); /** * Wraps a Node writable stream, providing an API similar to * Narwhal's synchronous `io` streams, except returning and * accepting promises for long-latency operations. * * @param stream any Node writable stream * @returns {Promise * Writer} a promise for the * text writer. */ module.exports = Writer; function Writer(_stream, charset) { var self = Object.create(Writer.prototype); if (charset && _stream.setEncoding) // TODO complain about inconsistency _stream.setEncoding(charset); var begin = Q.defer(); var drained = Q.defer(); _stream.on("error", function (reason) { begin.reject(reason); }); _stream.on("drain", function () { begin.resolve(self); drained.resolve(); drained = Q.defer(); }); /*** * Writes content to the stream. * @param {String} content * @returns {Promise * Undefined} a promise that will * be resolved when the buffer is empty, meaning * that all of the content has been sent. */ self.write = function (content) { if (!_stream.writeable && !_stream.writable) return Q.reject(new Error("Can't write to non-writable (possibly closed) stream")); if (_stream.encoding == "binary" && !(content instanceof Buffer)) { content = new Buffer(content); } if (!_stream.write(content)) { return drained.promise; } else { return Q.resolve(); } }; /*** * Waits for all data to flush on the stream. * * @returns {Promise * Undefined} a promise that will * be resolved when the buffer is empty */ self.flush = function () { return drained.promise; }; /*** * Closes the stream, waiting for the internal buffer * to flush. * * @returns {Promise * Undefined} a promise that will * be resolved when the stream has finished writing, * flushing, and closed. */ self.close = function () { _stream.end(); drained.resolve(); // we will get no further drain events return Q.resolve(); // closing not explicitly observable }; /*** * Terminates writing on a stream, closing before * the internal buffer drains. * * @returns {Promise * Undefined} a promise that will * be resolved when the stream has finished closing. */ self.destroy = function () { _stream.destroy(); drained.resolve(); // we will get no further drain events return Q.resolve(); // destruction not explicitly observable }; return Q.resolve(self); // todo returns the begin.promise } |