Skip to content

Commit 40ab7b5

Browse files
committed
(refactoring) Extract objects for encapsulating stdout and stderr behaviour
1 parent 887481a commit 40ab7b5

File tree

1 file changed

+36
-31
lines changed

1 file changed

+36
-31
lines changed

imagemagick.js

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,41 @@ function exec2(file, args /*, options, callback */) {
2121
}
2222

2323
var child = childproc.spawn(file, args);
24-
var outputToStream = options.output != null;
25-
var stdout = outputToStream ? options.output : "";
26-
var stderr = "";
2724
var killed = false;
2825
var timedOut = false;
2926

27+
var Wrapper = function(output) {
28+
this.stdout = output;
29+
this.stderr = new Accumulator();
30+
};
31+
Wrapper.prototype.out = function(chunk, encoding) { this.stdout.write(chunk, encoding); };
32+
Wrapper.prototype.err = function(chunk, encoding) { this.stderr.write(chunk, encoding); };
33+
Wrapper.prototype.finish = function(err) {
34+
this.stdout.end();
35+
return [err, this.stderr.current()];
36+
};
37+
38+
var Accumulator = function() {
39+
this.stdout = {contents: ""};
40+
this.stderr = {contents: ""};
41+
42+
var limitedWrite = function(stream) {
43+
return function(chunk) {
44+
stream.contents += chunk;
45+
if (!killed && stream.contents.length > options.maxBuffer) {
46+
child.kill(options.killSignal);
47+
killed = true;
48+
}
49+
};
50+
};
51+
this.out = limitedWrite(this.stdout);
52+
this.err = limitedWrite(this.stderr);
53+
};
54+
Accumulator.prototype.current = function() { return this.stdout.contents; }
55+
Accumulator.prototype.finish = function(err) { return [err, this.stdout.contents, this.stderr.contents]; };
56+
57+
var std = options.output != null ? new Wrapper(options.output) : new Accumulator();
58+
3059
var timeoutId;
3160
if (options.timeout > 0) {
3261
timeoutId = setTimeout(function () {
@@ -42,44 +71,20 @@ function exec2(file, args /*, options, callback */) {
4271
child.stdout.setEncoding(options.encoding);
4372
child.stderr.setEncoding(options.encoding);
4473

45-
child.stdout.addListener("data", function (chunk) {
46-
if (outputToStream) {
47-
stdout.write(chunk, options.encoding);
48-
} else {
49-
stdout += chunk;
50-
}
51-
if (!killed && stdout.length > options.maxBuffer) {
52-
child.kill(options.killSignal);
53-
killed = true;
54-
}
55-
});
56-
57-
child.stderr.addListener("data", function (chunk) {
58-
stderr += chunk;
59-
if (!killed && stderr.length > options.maxBuffer) {
60-
child.kill(options.killSignal);
61-
killed = true
62-
}
63-
});
74+
child.stdout.addListener("data", function (chunk) { std.out(chunk, options.encoding); });
75+
child.stderr.addListener("data", function (chunk) { std.err(chunk, options.encoding); });
6476

6577
child.addListener("exit", function (code, signal) {
6678
if (timeoutId) clearTimeout(timeoutId);
6779
if (code === 0 && signal === null) {
68-
if (callback) {
69-
if (outputToStream) {
70-
stdout.end();
71-
callback(null, stderr);
72-
} else {
73-
callback(null, stdout, stderr);
74-
}
75-
}
80+
if (callback) callback.apply(undefined, std.finish(null));
7681
} else {
7782
var e = new Error("Command "+(timedOut ? "timed out" : "failed")+": " + stderr);
7883
e.timedOut = timedOut;
7984
e.killed = killed;
8085
e.code = code;
8186
e.signal = signal;
82-
if (callback) callback(e, stdout, stderr);
87+
if (callback) callback.apply(undefined, std.finish(e));
8388
}
8489
});
8590

0 commit comments

Comments
 (0)