Last active
December 21, 2015 15:59
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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