| /* |
| Copyright (c) 2012, Yahoo! Inc. All rights reserved. |
| Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. |
| */ |
| |
| var path = require('path'), |
| util = require('util'), |
| fs = require('fs'), |
| async = require('async'), |
| mkdirp = require('mkdirp'), |
| writer = require('./writer'), |
| Writer = writer.Writer, |
| ContentWriter = writer.ContentWriter; |
| |
| function extend(cons, proto) { |
| Object.keys(proto).forEach(function (k) { |
| cons.prototype[k] = proto[k]; |
| }); |
| } |
| |
| function BufferedContentWriter() { |
| ContentWriter.call(this); |
| this.content = ''; |
| } |
| util.inherits(BufferedContentWriter, ContentWriter); |
| |
| extend(BufferedContentWriter, { |
| write: function (str) { |
| this.content += str; |
| }, |
| getContent: function () { |
| return this.content; |
| } |
| }); |
| |
| function StreamContentWriter(stream) { |
| ContentWriter.call(this); |
| this.stream = stream; |
| } |
| util.inherits(StreamContentWriter, ContentWriter); |
| |
| extend(StreamContentWriter, { |
| write: function (str) { |
| this.stream.write(str); |
| } |
| }); |
| |
| function SyncFileWriter() { |
| Writer.call(this); |
| } |
| util.inherits(SyncFileWriter, Writer); |
| |
| extend(SyncFileWriter, { |
| writeFile: function (file, callback) { |
| mkdirp.sync(path.dirname(file)); |
| var cw = new BufferedContentWriter(); |
| callback(cw); |
| fs.writeFileSync(file, cw.getContent(), 'utf8'); |
| }, |
| done: function () { |
| this.emit('done'); //everything already done |
| } |
| }); |
| |
| function AsyncFileWriter() { |
| this.queue = async.queue(this.processFile.bind(this), 20); |
| this.openFileMap = {}; |
| } |
| |
| util.inherits(AsyncFileWriter, Writer); |
| |
| extend(AsyncFileWriter, { |
| writeFile: function (file, callback) { |
| this.openFileMap[file] = true; |
| this.queue.push({ file: file, callback: callback }); |
| }, |
| processFile: function (task, cb) { |
| var file = task.file, |
| userCallback = task.callback, |
| that = this, |
| stream, |
| contentWriter; |
| |
| mkdirp.sync(path.dirname(file)); |
| stream = fs.createWriteStream(file); |
| stream.on('close', function () { |
| delete that.openFileMap[file]; |
| cb(); |
| that.checkDone(); |
| }); |
| stream.on('error', function (err) { that.emit('error', err); }); |
| contentWriter = new StreamContentWriter(stream); |
| userCallback(contentWriter); |
| stream.end(); |
| }, |
| done: function () { |
| this.doneCalled = true; |
| this.checkDone(); |
| }, |
| checkDone: function () { |
| if (!this.doneCalled) { return; } |
| if (Object.keys(this.openFileMap).length === 0) { |
| this.emit('done'); |
| } |
| } |
| }); |
| /** |
| * a concrete writer implementation that can write files synchronously or |
| * asynchronously based on the constructor argument passed to it. |
| * |
| * Usage |
| * ----- |
| * |
| * var sync = true, |
| * fileWriter = new require('istanbul').FileWriter(sync); |
| * |
| * fileWriter.on('done', function () { console.log('done'); }); |
| * fileWriter.copyFile('/foo/bar.jpg', '/baz/bar.jpg'); |
| * fileWriter.writeFile('/foo/index.html', function (contentWriter) { |
| * contentWriter.println('<html>'); |
| * contentWriter.println('</html>'); |
| * }); |
| * fileWriter.done(); // will emit the `done` event when all files are written |
| * |
| * @class FileWriter |
| * @extends Writer |
| * @module io |
| * @param sync |
| * @constructor |
| */ |
| function FileWriter(sync) { |
| Writer.call(this); |
| var that = this; |
| this.delegate = sync ? new SyncFileWriter() : new AsyncFileWriter(); |
| this.delegate.on('error', function (err) { that.emit('error', err); }); |
| this.delegate.on('done', function () { that.emit('done'); }); |
| } |
| |
| util.inherits(FileWriter, Writer); |
| |
| extend(FileWriter, { |
| copyFile: function (source, dest) { |
| mkdirp.sync(path.dirname(dest)); |
| fs.writeFileSync(dest, fs.readFileSync(source)); |
| }, |
| writeFile: function (file, callback) { |
| this.delegate.writeFile(file, callback); |
| }, |
| done: function () { |
| this.delegate.done(); |
| } |
| }); |
| |
| module.exports = FileWriter; |