Skip to content

Commit

Permalink
fix up sendCommand
Browse files Browse the repository at this point in the history
* uses response code to find the end of a response
* sendCommand callback data is always a string
* moves data parsing out of sendCommand

closes #9 and #10
  • Loading branch information
respectTheCode committed Oct 13, 2012
1 parent e44ce53 commit 8fd4d6d
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 69 deletions.
126 changes: 71 additions & 55 deletions lib/connection.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
var net = require("net");
var xml = require("./xml2json");

module.exports = function (ccg) {
ccg.prototype.connected = false;

var client;
var disconnecting = false;
var responseCode = false;
var responseMessage = "";
var response = "";
var readyForNextCommand = true;
var waitingForDoubleTerminator = false;
Expand Down Expand Up @@ -93,11 +94,8 @@ module.exports = function (ccg) {
// ccg.sendCommand
// ---------------
// Sends raw command to CasparCG
ccg.prototype.sendCommand = function (command, doubleTerminator, cb) {
if (!cb && typeof(doubleTerminator) == "function") {
cb = doubleTerminator;
doubleTerminator = false;
}
ccg.prototype.sendCommand = function (command, cb) {
var self = this;

if (typeof(cb) != "function") cb = false;

Expand All @@ -110,75 +108,93 @@ module.exports = function (ccg) {
return false;
}

if (command.substr(-2) != "\r\n") command += "\r\n";
if (command.substr(-2) == "\r\n") {
if (cb) {
cb(new Error("Invalid command"));
}

return false;
}

commandQueue.push([command, cb || false, doubleTerminator]);
command += "\r\n";

commandQueue.push({cmd: command, cb: cb});

if (readyForNextCommand) {
readyForNextCommand = false;
client.write(commandQueue[0][0]);
self.log("Send:",commandQueue[0].cmd.substr(0, commandQueue[0].cmd.length - 2));
client.write(commandQueue[0].cmd);
}
};

var finishedCommand = function (self) {
responseCode = false;
responseMessage = "";
response = "";

if (commandQueue.length > 0) {
// if there are queue commands send the next one
self.log("Send:",commandQueue[0].cmd.substr(0, commandQueue[0].cmd.length - 2));
client.write(commandQueue[0].cmd);
} else {
// queue is empty we are ready for another command
readyForNextCommand = true;
}
};

var onData = function (self) {
return function (chunk) {
response += chunk.toString();

// check for complete response before doing anything
if (
(commandQueue[0][2] && response.substr(-4) == "\r\n\r\n") ||
(!commandQueue[0][2] && response.substr(-2) == "\r\n")
) {
// response is complete remove command from queue
var item = commandQueue.shift();
var cb = item[1];

// remove the terminator
while (response.substr(-2) == "\r\n") {
response = response.substr(0, response.length - 2);
}
if (!responseCode) {
responseCode = parseInt(response.substr(0, 3), 10);
self.log("Response Code:", responseCode);
}

var responseMessage = response.substr(0, response.indexOf("\r\n"));
// if no \r\n then wait for more data
if (response.substr(-2) != "\r\n") return;

if (responseMessage == "") responseMessage = response;
if (responseMessage === "") {
responseMessage = response.substr(0, response.indexOf("\r\n"));
response = response.substr(responseMessage.length + 2);
}

self.log(responseMessage);
// 200 needs \r\n\r\n
if (responseCode == 200 && response.substr(-4) != "\r\n\r\n") return;

// check for error code
if (responseMessage.substr(0, 1) != "2") {
// callback with error
if (cb) {
cb(new Error(response));
}
} else {
if (cb) {
// remove response code and message from response data
response = response.substr(responseMessage.length + 2);

// check for XML response
if (response.substr(0, 1) == "<") {
response = response.substr(response.indexOf("\n") + 1);
xml(response, cb);
} else {
if (response == "") {
cb();
} else {
response = response.split("\r\n");
cb(null, response);
}
}
}
// strip trailing \r\n
while (response.substr(-2) == "\r\n") {
response = response.substr(0, response.length - 2);
}

// response is complete remove command from queue
var item = commandQueue.shift();
var cb = item.cb || false;

// check for error
if (
(responseCode >= 400) &&
(responseCode > 600)
) {
// callback with error
if (cb) {
cb(new Error(responseMessage));
}

response = "";
if (commandQueue.length > 0) {
// if there are queue commands send the next one
client.write(commandQueue[0][0]);
finishedCommand(self);

return;
}

if (cb) {
if (response !== "") {
cb(null, response);
} else {
// queue is empty we are ready for another command
readyForNextCommand = true;
cb(null);
}
}

finishedCommand(self);
};
};
};
34 changes: 28 additions & 6 deletions lib/query.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
var xml = require("./xml2json");

module.exports = function (ccg) {
// ccg.getMediaFiles
// ---
Expand All @@ -13,12 +15,14 @@ module.exports = function (ccg) {
return;
}

self.sendCommand("CLS", true, function (err, files) {
self.sendCommand("CLS", function (err, data) {
if (err) {
cb(err);
return;
}

var files = data.split("\r\n");

var out = [];

for (var index in files) {
Expand Down Expand Up @@ -51,7 +55,7 @@ module.exports = function (ccg) {
ccg.prototype.getMediaFileInfo = function (filename, cb) {
var self = this;

if (typeof(folder) != "string") {
if (typeof(filename) != "string") {
self.log("Invalid arguments");
return;
}
Expand All @@ -62,12 +66,14 @@ module.exports = function (ccg) {
return;
}

self.sendCommand("CINF \"" + filename + "\"", function (err, files) {
self.sendCommand("CINF \"" + filename + "\"", function (err, data) {
if (err) {
if (cb) cb(err);
return;
}

var files = data.split("\r\n");

var out = [];

for (var index in files) {
Expand All @@ -92,7 +98,7 @@ module.exports = function (ccg) {
};

// ---
// ccg.getMediaFiles
// ccg.getTemplates
// ---
// Returns info about all available templates
// Returns info about all available templates
Expand All @@ -116,12 +122,14 @@ module.exports = function (ccg) {

if (folder) command += " " + folder;

self.sendCommand(command, function (err, files) {
self.sendCommand(command, function (err, data) {
if (err) {
cb(err);
return;
}

var files = data.split("\r\n");

var out = [];

for (var index in files) {
Expand Down Expand Up @@ -166,6 +174,20 @@ module.exports = function (ccg) {

if (channel) command += " " + channel;

self.sendCommand(command, cb);
self.sendCommand(command, function (err, data) {
if (err) {
cb(err);
return;
}

console.log(typeof(data));

if (data.substr(0, 1) == "<") {
xml(data, cb);
} else {
data = data.split("\r\n");
cb(null, data);
}
});
};
};
4 changes: 2 additions & 2 deletions lib/xml2json.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ module.exports = function (xml, cb) {
object[path[index]].push({});
}
}
};
}

// helper function to set the value of a path
function setValueForPath(object, path, value, index) {
Expand All @@ -56,7 +56,7 @@ module.exports = function (xml, cb) {
// found the object so set its value
object[path[index]] = value;
}
};
}

parser.onerror = function (err) {
// should pass this to the callback
Expand Down
31 changes: 25 additions & 6 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,37 @@ ccg = new CasparCG({
});

ccg.connect(function () {
ccg.play("1-1", "AMB");

ccg.getMediaFiles(function (err, serverInfo) {
console.log("getMediaFiles", serverInfo);
});

ccg.getMediaFileInfo("AMB", function (err, serverInfo) {
console.log("getMediaFileInfo", serverInfo);
});

ccg.getTemplates(function (err, serverInfo) {
console.log("info", serverInfo);
});

ccg.info(function (err, serverInfo) {
console.log(serverInfo);
console.log("info", serverInfo);
});

ccg.play("1-1", "AMB");
ccg.info("1", function (err, serverInfo) {
console.log("info 1", serverInfo);
});

ccg.info("1-1", function (err, serverInfo) {
console.log("info 1-1", serverInfo);
});

setTimeout(function () {
ccg.clear("1");
}, 1 * 1000);

setTimeout(function () {
ccg.disconnect();
}, 5 * 1000);
});

ccg.on("connected", function () {
console.log("Connected");
});

0 comments on commit 8fd4d6d

Please sign in to comment.