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