Permalink
Browse files

Replacing structured data parser.

This is a faster than regex implementation that is using a semi-convoluted
finite state machine which has room for optimisation, but strictly adhears to
the specification and no longer does data chopping and hacking to get the values
out.
  • Loading branch information...
1 parent d2409c7 commit 5ed695ed37c66e9addd63cf54fa7846a2a384d60 @squeeks committed Mar 8, 2013
Showing with 55 additions and 18 deletions.
  1. +55 −18 lib/glossy/parse.js
View
@@ -313,26 +313,63 @@ GlossyParser.prototype.parseTimeStamp = function(timeStamp) {
*/
GlossyParser.prototype.parseStructure = function(msg) {
var sdStructure = { };
- var sdElements = msg.split('][');
- //TODO could we improve things here?
- for(element in sdElements) {
- var element = sdElements[element];
- element = element.replace(/^\[|\]$/g, '');
- var sdID = element.match(/^([^\s=\]]+)\s/)[1];
- element = element.replace(sdID + ' ', '');
- var sdKeys = element.split(/"\s/);
-
- for(key in sdKeys) {
- var sdKeyValue = sdKeys[key].match(/^([^\s=\]]+)="(.*)$/);
- if(!sdKeyValue) continue;
- var sdKey = sdKeyValue[1];
- var sdValue = sdKeyValue[2];
- if(!sdStructure[sdID]) sdStructure[sdID] = { };
- sdStructure[sdID][sdKey] = sdValue;
- }
+ var state = 0,
+ ignore = false,
+ sdId = '',
+ sdParam = '',
+ sdValue = '';
+
+ /*
+ * Build the structure using a horrible FSM.
+ * The states we cycle are as following:
+ * 0 1 2 34 20
+ * [sdID sdParam="sdValue"]
+ */
+ for(var i = 0; i < msg.length; i++) {
+ var c = msg[i];
+ switch(state) {
+ case 0: // SD-ELEMENT
+ state = (c === '[') ? 1 : 0;
+ break;
+ case 1: // SD-ID
+ if(c != ' ') {
+ sdId += c;
+ } else {
+ sdStructure[sdId] = {};
+ state = 2;
+ }
+ break;
+ case 2: // SD-PARAM
+ if(c === '=') {
+ sdStructure[sdId][sdParam] = '';
+ state = 3;
+ } else if(c === ']') {
+ sdId = '';
+ state = 0;
+ } else if(c != ' '){
+ sdParam += c;
+ }
+ break;
+ case 3: // SD-PARAM/SD-VALUE
+ state = c === '"' ? 4 : null; // FIXME Handle rubbish better
+ break;
+ case 4: // SD-VALUE
+ if(c === '\\' && !ignore) {
+ ignore = true;
+ } else if(c === '"' && !ignore) {
+ sdStructure[sdId][sdParam] = sdValue;
+ sdParam = '', sdValue = '';
+ state = 2;
+ } else {
+ sdValue += c;
+ ignore = false;
+ }
+ break;
+ default:
+ break;
+ }
}
-
return sdStructure;
}

0 comments on commit 5ed695e

Please sign in to comment.