Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80679 views
1
/*
2
Copyright (c) 2012, Yahoo! Inc. All rights reserved.
3
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
4
*/
5
6
var path = require('path'),
7
util = require('util'),
8
fs = require('fs'),
9
async = require('async'),
10
mkdirp = require('mkdirp'),
11
writer = require('./writer'),
12
Writer = writer.Writer,
13
ContentWriter = writer.ContentWriter;
14
15
function extend(cons, proto) {
16
Object.keys(proto).forEach(function (k) {
17
cons.prototype[k] = proto[k];
18
});
19
}
20
21
function BufferedContentWriter() {
22
ContentWriter.call(this);
23
this.content = '';
24
}
25
util.inherits(BufferedContentWriter, ContentWriter);
26
27
extend(BufferedContentWriter, {
28
write: function (str) {
29
this.content += str;
30
},
31
getContent: function () {
32
return this.content;
33
}
34
});
35
36
function StreamContentWriter(stream) {
37
ContentWriter.call(this);
38
this.stream = stream;
39
}
40
util.inherits(StreamContentWriter, ContentWriter);
41
42
extend(StreamContentWriter, {
43
write: function (str) {
44
this.stream.write(str);
45
}
46
});
47
48
function SyncFileWriter() {
49
Writer.call(this);
50
}
51
util.inherits(SyncFileWriter, Writer);
52
53
extend(SyncFileWriter, {
54
writeFile: function (file, callback) {
55
mkdirp.sync(path.dirname(file));
56
var cw = new BufferedContentWriter();
57
callback(cw);
58
fs.writeFileSync(file, cw.getContent(), 'utf8');
59
},
60
done: function () {
61
this.emit('done'); //everything already done
62
}
63
});
64
65
function AsyncFileWriter() {
66
this.queue = async.queue(this.processFile.bind(this), 20);
67
this.openFileMap = {};
68
}
69
70
util.inherits(AsyncFileWriter, Writer);
71
72
extend(AsyncFileWriter, {
73
writeFile: function (file, callback) {
74
this.openFileMap[file] = true;
75
this.queue.push({ file: file, callback: callback });
76
},
77
processFile: function (task, cb) {
78
var file = task.file,
79
userCallback = task.callback,
80
that = this,
81
stream,
82
contentWriter;
83
84
mkdirp.sync(path.dirname(file));
85
stream = fs.createWriteStream(file);
86
stream.on('close', function () {
87
delete that.openFileMap[file];
88
cb();
89
that.checkDone();
90
});
91
stream.on('error', function (err) { that.emit('error', err); });
92
contentWriter = new StreamContentWriter(stream);
93
userCallback(contentWriter);
94
stream.end();
95
},
96
done: function () {
97
this.doneCalled = true;
98
this.checkDone();
99
},
100
checkDone: function () {
101
if (!this.doneCalled) { return; }
102
if (Object.keys(this.openFileMap).length === 0) {
103
this.emit('done');
104
}
105
}
106
});
107
/**
108
* a concrete writer implementation that can write files synchronously or
109
* asynchronously based on the constructor argument passed to it.
110
*
111
* Usage
112
* -----
113
*
114
* var sync = true,
115
* fileWriter = new require('istanbul').FileWriter(sync);
116
*
117
* fileWriter.on('done', function () { console.log('done'); });
118
* fileWriter.copyFile('/foo/bar.jpg', '/baz/bar.jpg');
119
* fileWriter.writeFile('/foo/index.html', function (contentWriter) {
120
* contentWriter.println('<html>');
121
* contentWriter.println('</html>');
122
* });
123
* fileWriter.done(); // will emit the `done` event when all files are written
124
*
125
* @class FileWriter
126
* @extends Writer
127
* @module io
128
* @param sync
129
* @constructor
130
*/
131
function FileWriter(sync) {
132
Writer.call(this);
133
var that = this;
134
this.delegate = sync ? new SyncFileWriter() : new AsyncFileWriter();
135
this.delegate.on('error', function (err) { that.emit('error', err); });
136
this.delegate.on('done', function () { that.emit('done'); });
137
}
138
139
util.inherits(FileWriter, Writer);
140
141
extend(FileWriter, {
142
copyFile: function (source, dest) {
143
mkdirp.sync(path.dirname(dest));
144
fs.writeFileSync(dest, fs.readFileSync(source));
145
},
146
writeFile: function (file, callback) {
147
this.delegate.writeFile(file, callback);
148
},
149
done: function () {
150
this.delegate.done();
151
}
152
});
153
154
module.exports = FileWriter;
155