Permalink
Browse files

better object assembly

  • Loading branch information...
1 parent 03e0d2a commit 29a9edb6e2bb1486fce52a5d6a989c2fc6299f1a @chjj chjj committed Oct 18, 2011
Showing with 86 additions and 93 deletions.
  1. +86 −93 lib/json.js
View
@@ -57,10 +57,10 @@ Parser.prototype.end = function(data) {
if (this.value) {
switch (this.state) {
case 'number':
- this.emit('number', +this.value);
+ this.assemble('number', +this.value);
break;
case 'value':
- this.emit('string', this.value);
+ this.assemble('string', this.value);
break;
default:
return this._error('Unexpected EOF.');
@@ -99,27 +99,27 @@ Parser.prototype._parse = function(data) {
if (this.value) {
return this._unexpected(ch);
}
- this.emit('object start');
+ this.assemble('object start');
break;
case '}':
if (this.value) {
- this.emit('string', this.value);
+ this.assemble('string', this.value);
this.value = '';
}
- this.emit('object end');
+ this.assemble('object end');
break;
case '[':
if (this.value) {
return this._unexpected(ch);
}
- this.emit('array start');
+ this.assemble('array start');
break;
case ']':
if (this.value) {
- this.emit('string', this.value);
+ this.assemble('string', this.value);
this.value = '';
}
- this.emit('array end');
+ this.assemble('array end');
break;
case '"':
if (this.value) {
@@ -129,15 +129,15 @@ Parser.prototype._parse = function(data) {
break;
case ',':
if (this.value) {
- this.emit('string', this.value);
+ this.assemble('string', this.value);
this.value = '';
}
break;
case ':':
if (!this.value) {
return this._unexpected(ch);
}
- this.emit('object key', this.value);
+ this.assemble('object key', this.value);
this.value = '';
break;
case '-':
@@ -179,19 +179,19 @@ Parser.prototype._parse = function(data) {
// check last byte of .value
// make sure it is a digit
this.state = 'value';
- this.emit('number', +this.value);
+ this.assemble('number', +this.value);
this.value = '';
- this.emit('object end');
+ this.assemble('object end');
break;
case ']':
this.state = 'value';
- this.emit('number', +this.value);
+ this.assemble('number', +this.value);
this.value = '';
- this.emit('array end');
+ this.assemble('array end');
break;
case ',':
this.state = 'value';
- this.emit('number', +this.value);
+ this.assemble('number', +this.value);
this.value = '';
break;
case 'e':
@@ -235,7 +235,7 @@ Parser.prototype._parse = function(data) {
default:
if (ch <= ' ') {
this.state = 'value';
- this.emit('number', +this.value);
+ this.assemble('number', +this.value);
this.value = '';
} else {
return this._unexpected(ch);
@@ -326,7 +326,7 @@ Parser.prototype._parse = function(data) {
}
case 'nul': {
this._expect(ch, 'l');
- this.emit('null', null);
+ this.assemble('null', null);
this.state = 'value';
break;
}
@@ -347,7 +347,7 @@ Parser.prototype._parse = function(data) {
}
case 'fals': {
this._expect(ch, 'e');
- this.emit('boolean', false);
+ this.assemble('boolean', false);
this.state = 'value';
break;
}
@@ -363,21 +363,82 @@ Parser.prototype._parse = function(data) {
}
case 'tru': {
this._expect(ch, 'e');
- this.emit('boolean', true);
+ this.assemble('boolean', true);
this.state = 'value';
break;
}
}
}
};
+/**
+ * Object Assembler
+ */
+
+Parser.prototype.assemble = function(type, val) {
+ switch (type) {
+ case 'object start':
+ var object = {};
+ this.assemble('value', object);
+ this.stack.push(object);
+ break;
+ case 'object key':
+ this.key = val;
+ break;
+ case 'object end':
+ this.emit('object', this.stack.pop());
+ break;
+ case 'array start':
+ var array = [];
+ this.assemble('value', array);
+ this.stack.push(array);
+ break;
+ case 'array end':
+ this.emit('array', this.stack.pop());
+ break;
+ case 'number':
+ case 'string':
+ case 'boolean':
+ case 'null':
+ this.emit(type, val);
+ this.assemble('value', val);
+ break;
+ case 'value':
+ var top = this.stack[this.stack.length-1];
+ if (!top) {
+ if (this.key) {
+ return this._error('Unexpected key.');
+ }
+ this.data = val;
+ this.stack.push(val);
+ return;
+ }
+ if (!this.key) {
+ if (!Array.isArray(top)) {
+ return this._error('Expected key.');
+ }
+ top.push(val);
+ } else {
+ if (Array.isArray(top)) {
+ return this._error('Unexpected key.');
+ }
+ top[this.key] = val;
+ this.key = null;
+ }
+ break;
+ }
+};
+
Parser.prototype._reset = function() {
+ this.stack = [];
+ this.key = null;
+ this.data = null;
+
this.state = 'value';
this.value = '';
this.unicode = '';
this.written = 0;
this.decode = new StringDecoder('utf8');
- this.data = null;
this._events = {};
};
@@ -395,87 +456,19 @@ Parser.prototype.destroy = function(err) {
};
/**
- * Object Assembler
+ * Legacy
*/
-Parser.create = function(parser) {
- var parser = parser || new Parser()
- , stack = []
- , key;
-
- parser.on('object start', function() {
- var object = {};
- this.emit('.value', object);
- stack.push(object);
- });
-
- parser.on('object key', function(val) {
- key = val;
- });
-
- parser.on('object end', function() {
- this.emit('object', stack.pop());
- });
-
- parser.on('array start', function() {
- var array = [];
- this.emit('.value', array);
- stack.push(array);
- });
-
- parser.on('array end', function() {
- this.emit('array', stack.pop());
- });
-
- parser.on('number', function(val) {
- this.emit('.value', val);
- });
-
- parser.on('string', function(val) {
- this.emit('.value', val);
- });
-
- parser.on('boolean', function(val) {
- this.emit('.value', val);
- });
-
- parser.on('null', function(val) {
- this.emit('.value', val);
- });
-
- parser.on('.value', function(val) {
- var top = stack[stack.length-1];
- if (!top) {
- if (key) {
- return this._error('Unexpected key.');
- }
- this.data = val;
- stack.push(val);
- return;
- }
- if (!key) {
- if (!Array.isArray(top)) {
- return this._error('Expected key.');
- }
- top.push(val);
- } else {
- if (Array.isArray(top)) {
- return this._error('Unexpected key.');
- }
- top[key] = val;
- key = null;
- }
- });
-
- return parser;
+Parser.create = function() {
+ return new Parser();
};
/**
* Pool
*/
//var parsers = new FreeList('parsers', 20, function() {
-// return Parser.create();
+// return new Parser();
//});
/**
@@ -508,7 +501,7 @@ exports.middleware = function(options) {
};
exports.handle = function(req, res, next, options) {
- var parser = Parser.create() //parsers.alloc()
+ var parser = new Parser() //parsers.alloc()
, limit = options.jsonLimit || options.limit;
parser.on('error', function(err) {

0 comments on commit 29a9edb

Please sign in to comment.