Skip to content

Instantly share code, notes, and snippets.

@ar-nelson
Last active December 21, 2015 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ar-nelson/6330373 to your computer and use it in GitHub Desktop.
Save ar-nelson/6330373 to your computer and use it in GitHub Desktop.
The first two functions of my node.js library for wmiir. Used in my blog.
var spawn = require('child_process').spawn;
// Spawns and returns a child process that runs `wmiir read`.
// The callback takes two parameters: (err, line).
// It is called once for each line in the file read.
// - err is any error that occurred, or null if no error occurred.
// - line is the last line read from the file.
exports.read = function(path, callback) {
// Start the process.
var child = spawn('wmiir', ['read', path]);
// Record the error stream, so that any error messages that wmiir produces
// can be passed on to the callback.
var stderr="";
child.stderr.on('data', function(chunk) {stderr += chunk;});
// If there's an error, pass it to the callback.
child.on('error', function(err) {if (callback) callback(err);});
// Read from the process's stdout until a newline is encountered, then pass
// the line to the callback.
var line="";
function handleData(chunk) {
try {
// Data from stdout is usually returned in the form of a Buffer,
// not a String. Make sure to convert it.
if (chunk instanceof Buffer)
chunk = chunk.toString();
// If a newline is encountered, call the callback with everything
// that was read up until the newline.
var newline = chunk.indexOf('\n');
if (newline > -1) {
if (callback) callback(null, line + chunk.slice(0, newline));
line = "";
var remaining = chunk.slice(newline+1);
if (remaining.length > 0)
handleData(remaining);
} else {
// Otherwise, store the output for later.
line += chunk;
}
} catch (e) {
if (callback) callback(e);
callback = null;
child.kill();
}
}
child.stdout.on('data', handleData);
// If the process exits with a nonzero exit code, throw an error with the
// content of stderr, which should contain a message.
child.on('exit', function(code, signal) {
if (code !== 0) {
if (callback) callback(new Error(stderr));
}
// Also, make sure to return the last line read, if there was one.
else if (line !== "") {
if (callback) callback(null, line);
}
});
// Return the child process, as a handle in case we need to kill it.
return child;
};
// Spawns and returns a child process that runs `wmiir write`.
// The given data is sent to this process's stdin.
// The callback takes one parameter: (err).
// - err is any error that occurred, or null if no error occurred.
exports.write = function(path, data, callback) {
// Some of this is the same as `read`, so I'll only comment the parts that
// are different.
var child = spawn('wmiir', ['write', path]);
var stderr="";
child.stderr.on('data', function(line) {stderr += line;});
child.on('error', function(err) {if (callback) callback(err);});
child.on('exit', function(code, signal) {
if (code === 0) {
// If the process exits normally, execute the callback.
if (callback) callback(null);
} else {
if (callback) callback(new Error(stderr));
}
});
// Write the data to the file.
// This closes stdin, which should also terminate the child process.
child.stdin.end(data);
return child;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment