Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

stream-json

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

stream-json - npm Package Compare versions

Comparing version 0.4.1 to 0.4.2

1149

AltParser.js

@@ -70,594 +70,589 @@ "use strict";

try {
main: do{
if(this._literal){
switch(this._literal){
case ESCAPED_CHAR:
switch(s[0]){
case "\"": case "/": case "b": case "f":
case "\\": case "n": case "r": case "t":
this.push({id: "escapedChars", value: "\\" + s[0], line: this._line, pos: this._pos});
++i;
++this._pos;
break;
case "u":
k = Math.min(5, n);
for(j = 1, ++i; i < k; ++j, ++i){
if(!hex[s[i]]) {
throw Error("While matching hexadecimals encountered '" + s[i] + "'");
}
this._stash += s[i];
main: do{
if(this._literal){
switch(this._literal){
case ESCAPED_CHAR:
switch(s[0]){
case "\"": case "/": case "b": case "f":
case "\\": case "n": case "r": case "t":
this.push({id: "escapedChars", value: "\\" + s[0], line: this._line, pos: this._pos});
++i;
++this._pos;
break;
case "u":
k = Math.min(5, n);
for(j = 1, ++i; i < k; ++j, ++i){
if(!hex[s[i]]) {
return callback(new Error("While matching hexadecimals encountered '" + s[i] + "'"));
}
if(j < 5){
this._literal = HEXADECIMALS;
this._literalFrom = j;
break main;
}
this.push({id: "escapedChars", value: "\\u" + this._stash, line: this._line, pos: this._pos});
this._stash = "";
this._pos += 5;
break;
default:
throw Error("Wrong escaped symbol '" + c + "'");
}
break;
case HEXADECIMALS:
k = Math.min(5 - this._literalFrom, n);
for(j = this._literalFrom; i < k; ++j, ++i){
if(!hex[s[i]]) {
throw Error("While matching hexadecimals encountered '" + s[i] + "'");
this._stash += s[i];
}
this._stash += s[i];
}
if(j < 5){
this._literalFrom = j;
break main;
}
this.push({id: "escapedChars", value: "\\u" + this._stash, line: this._line, pos: this._pos});
this._stash = "";
this._pos += 5;
break;
default:
k = Math.min(this._literal.length - this._literalFrom, n);
for(j = this._literalFrom; i < k; ++j, ++i){
if(this._literal[j] !== s[i]) {
throw Error("While matching '" + this._literal + "' encountered '" + s[j] + "' instead of '" + LITERAL_TRUE[j - i] + "'");
if(j < 5){
this._literal = HEXADECIMALS;
this._literalFrom = j;
break main;
}
this.push({id: "escapedChars", value: "\\u" + this._stash, line: this._line, pos: this._pos});
this._stash = "";
this._pos += 5;
break;
default:
return callback(new Error("Wrong escaped symbol '" + c + "'"));
}
break;
case HEXADECIMALS:
k = Math.min(5 - this._literalFrom, n);
for(j = this._literalFrom; i < k; ++j, ++i){
if(!hex[s[i]]) {
return callback(new Error("While matching hexadecimals encountered '" + s[i] + "'"));
}
if(j < this._literal.length){
this._literalFrom = j;
break main;
this._stash += s[i];
}
if(j < 5){
this._literalFrom = j;
break main;
}
this.push({id: "escapedChars", value: "\\u" + this._stash, line: this._line, pos: this._pos});
this._stash = "";
this._pos += 5;
break;
default:
k = Math.min(this._literal.length - this._literalFrom, n);
for(j = this._literalFrom; i < k; ++j, ++i){
if(this._literal[j] !== s[i]) {
return callback(new Error("While matching '" + this._literal + "' encountered '" + s[j] + "' instead of '" + LITERAL_TRUE[j - i] + "'"));
}
this.push({id: this._literal, value: this._literal, line: this._line, pos: this._pos});
this._pos += this._literal.length;
// end of value
switch(this._parent){
case PARSING_OBJECT:
this._state = EXPECTING_OBJECT_STOP;
break;
case PARSING_ARRAY:
this._state = EXPECTING_ARRAY_STOP;
break;
default:
this._state = EXPECTING_NOTHING;
break;
}
break;
}
this._literal = null;
}
if(j < this._literal.length){
this._literalFrom = j;
break main;
}
this.push({id: this._literal, value: this._literal, line: this._line, pos: this._pos});
this._pos += this._literal.length;
// end of value
switch(this._parent){
case PARSING_OBJECT:
this._state = EXPECTING_OBJECT_STOP;
break;
case PARSING_ARRAY:
this._state = EXPECTING_ARRAY_STOP;
break;
default:
this._state = EXPECTING_NOTHING;
break;
}
break;
}
this._literal = null;
}
for(; i < n; ++i, ++this._pos){
var c = s[i];
// calculate (line, pos)
switch(c){
case "\r":
for(; i < n; ++i, ++this._pos){
var c = s[i];
// calculate (line, pos)
switch(c){
case "\r":
++this._line;
this._pos = 1;
break;
case "\n":
if(this._lastChar !== "\r"){
++this._line;
this._pos = 1;
break;
case "\n":
if(this._lastChar !== "\r"){
++this._line;
}
this._pos = 1;
break;
}
this._lastChar = c;
// process a character
switch(this._state){
case EXPECTING_NOTHING:
switch(c){
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this._pos = 1;
break;
}
this._lastChar = c;
// process a character
switch(this._state){
case EXPECTING_NOTHING:
switch(c){
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
default:
return callback(new Error("Expected whitespace"));
}
break;
case EXPECTING_VALUE:
case EXPECTING_ARRAY_FIRST:
switch(c){
case "{": // object
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_KEY_FIRST;
this._stack.push(this._parent);
this._parent = PARSING_OBJECT;
continue;
case "[": // array
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_ARRAY_FIRST;
this._stack.push(this._parent);
this._parent = PARSING_ARRAY;
continue;
case "\"": // string
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_STRING_VALUE;
continue;
case "-": // number
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_NUMBER_START;
continue;
case "0": // number
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_FRACTION;
continue;
case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": // number
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: "nonZero", value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_NUMBER_DIGIT;
continue;
case "t": // true
case "f": // false
case "n": // null
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this._literal = LITERALS[c];
k = Math.min(this._literal.length + i, n);
for(j = 1, ++i; i < k; ++j, ++i){
if(this._literal[j] !== s[i]) {
return callback(new Error("While matching '" + this._literal + "' encountered '" + s[i] + "' instead of '" + this._literal[j] + "'"));
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
}
if(j < this._literal.length){
this._literalFrom = j;
break main;
}
this.push({id: this._literal, value: this._literal, line: this._line, pos: this._pos});
--i;
this._pos += this._literal.length - 1;
this._literal = null;
break;
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
case "]":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(this._state !== EXPECTING_ARRAY_FIRST){
return callback(new Error("Expected a value but got ']' instead"));
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._parent = this._stack.pop();
break;
default:
return callback(new Error("Expected a value"));
}
break;
case EXPECTING_KEY_FIRST:
case EXPECTING_KEY:
switch(c){
case "}":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(this._state !== EXPECTING_KEY_FIRST){
return callback(new Error("Expected a key value"));
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._parent = this._stack.pop();
break;
case "\"":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_KEY_VALUE;
continue;
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
default:
return callback(new Error("Expected a key"));
}
break;
case EXPECTING_KEY_COLON:
switch(c){
case ":":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_VALUE;
continue;
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
default:
return callback(new Error("Expected ':'"));
}
break;
case EXPECTING_OBJECT_STOP:
switch(c){
case "}":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._parent = this._stack.pop();
break;
case ",":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_KEY;
continue;
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
default:
return callback(new Error("Expected ','"));
}
break;
case EXPECTING_ARRAY_STOP:
switch(c){
case "]":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._parent = this._stack.pop();
break;
case ",":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_VALUE;
continue;
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
default:
return callback(new Error("Expected ','"));
}
break;
case EXPECTING_KEY_VALUE:
case EXPECTING_STRING_VALUE:
switch(c){
case "\"":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
if(this._state === EXPECTING_KEY_VALUE){
this._state = EXPECTING_KEY_COLON;
continue;
default:
throw Error("Expected whitespace");
}
break;
case EXPECTING_VALUE:
case EXPECTING_ARRAY_FIRST:
switch(c){
case "{": // object
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_KEY_FIRST;
this._stack.push(this._parent);
this._parent = PARSING_OBJECT;
continue;
case "[": // array
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_ARRAY_FIRST;
this._stack.push(this._parent);
this._parent = PARSING_ARRAY;
continue;
case "\"": // string
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_STRING_VALUE;
continue;
case "-": // number
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_NUMBER_START;
continue;
case "0": // number
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_FRACTION;
continue;
case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": // number
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: "nonZero", value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_NUMBER_DIGIT;
continue;
case "t": // true
case "f": // false
case "n": // null
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this._literal = LITERALS[c];
k = Math.min(this._literal.length + i, n);
for(j = 1, ++i; i < k; ++j, ++i){
if(this._literal[j] !== s[i]) {
throw Error("While matching '" + this._literal + "' encountered '" + s[i] + "' instead of '" + this._literal[j] + "'");
}
}
if(j < this._literal.length){
this._literalFrom = j;
break main;
}
this.push({id: this._literal, value: this._literal, line: this._line, pos: this._pos});
--i;
this._pos += this._literal.length - 1;
this._literal = null;
break;
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
case "]":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(this._state !== EXPECTING_ARRAY_FIRST){
throw Error("Expected a value but got ']' instead");
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._parent = this._stack.pop();
break;
default:
throw Error("Expected a value");
}
break;
case EXPECTING_KEY_FIRST:
case EXPECTING_KEY:
switch(c){
case "}":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(this._state !== EXPECTING_KEY_FIRST){
throw Error("Expected a key value");
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._parent = this._stack.pop();
break;
case "\"":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_KEY_VALUE;
continue;
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
default:
throw Error("Expected a key");
}
break;
case EXPECTING_KEY_COLON:
switch(c){
case ":":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_VALUE;
continue;
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
default:
throw Error("Expected ':'");
}
break;
case EXPECTING_OBJECT_STOP:
switch(c){
case "}":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._parent = this._stack.pop();
break;
case ",":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_KEY;
continue;
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
default:
throw Error("Expected ','");
}
break;
case EXPECTING_ARRAY_STOP:
switch(c){
case "]":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._parent = this._stack.pop();
break;
case ",":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_VALUE;
continue;
case " ": case "\t": case "\r": case "\n": // ws
if(this._chunk && this._chunk.id !== "ws"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "ws", value: i, line: this._line, pos: this._pos};
}
continue;
default:
throw Error("Expected ','");
}
break;
case EXPECTING_KEY_VALUE:
case EXPECTING_STRING_VALUE:
switch(c){
case "\"":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
if(this._state === EXPECTING_KEY_VALUE){
this._state = EXPECTING_KEY_COLON;
continue;
}
break;
case "\\":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(i + 1 < n){
c = s[++i];
switch(c){
case "\"": case "/": case "b": case "f":
case "\\": case "n": case "r": case "t":
this.push({id: "escapedChars", value: "\\" + c, line: this._line, pos: this._pos});
++this._pos;
continue;
case "u":
k = Math.min(i + 5, n);
for(j = 1, ++i; i < k; ++j, ++i){
if(!hex[s[i]]) {
throw Error("While matching hexadecimals encountered '" + s[i] + "'");
}
}
break;
case "\\":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(i + 1 < n){
c = s[++i];
switch(c){
case "\"": case "/": case "b": case "f":
case "\\": case "n": case "r": case "t":
this.push({id: "escapedChars", value: "\\" + c, line: this._line, pos: this._pos});
++this._pos;
continue;
case "u":
k = Math.min(i + 5, n);
for(j = 1, ++i; i < k; ++j, ++i){
if(!hex[s[i]]) {
return callback(new Error("While matching hexadecimals encountered '" + s[i] + "'"));
}
if(j < 5){
// emit this._literal
this._literal = HEXADECIMALS;
this._literalFrom = j;
break main;
}
this.push({id: "escapedChars", value: "\\u" + s.substr(i - 4, 4),
line: this._line, pos: this._pos});
--i;
this._pos += 5;
continue;
default:
throw Error("Wrong escaped symbol '" + c + "'");
}
}
if(j < 5){
// emit this._literal
this._literal = HEXADECIMALS;
this._literalFrom = j;
break main;
}
this.push({id: "escapedChars", value: "\\u" + s.substr(i - 4, 4),
line: this._line, pos: this._pos});
--i;
this._pos += 5;
continue;
default:
return callback(new Error("Wrong escaped symbol '" + c + "'"));
}
this._literal = ESCAPED_CHAR;
break main;
default:
if(this._chunk && this._chunk.id !== "plainChunk"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "plainChunk", value: i, line: this._line, pos: this._pos};
}
continue;
}
break;
case EXPECTING_NUMBER_START:
switch(c){
case "0":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_FRACTION;
continue;
case "1": case "2": case "3":
case "4": case "5": case "6":
case "7": case "8": case "9":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: "nonZero", value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_NUMBER_DIGIT;
continue;
default:
throw Error("Expected a digit");
}
break;
case EXPECTING_NUMBER_DIGIT:
case EXPECTING_FRACTION:
case EXPECTING_FRAC_DIGIT:
switch(c){
case "0": case "1": case "2": case "3": case "4":
case "5": case "6": case "7": case "8": case "9":
if(this._chunk && this._chunk.id !== "numericChunk"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(this._state === EXPECTING_FRACTION){
throw Error("Expected '.' or 'e'");
}
if(!this._chunk){
this._chunk = {id: "numericChunk", value: i, line: this._line, pos: this._pos};
}
continue;
case ".":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(this._state === EXPECTING_FRAC_DIGIT){
throw Error("Expected a digit");
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_FRAC_START;
continue;
case "e": case "E":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: "exponent", value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_EXP_SIGN;
continue;
default:
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
--i;
--this._pos;
break;
}
break;
case EXPECTING_FRAC_START:
switch(c){
case "0": case "1": case "2": case "3": case "4":
case "5": case "6": case "7": case "8": case "9":
if(this._chunk && this._chunk.id !== "numericChunk"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "numericChunk", value: i, line: this._line, pos: this._pos};
}
this._state = EXPECTING_FRAC_DIGIT;
continue;
default:
throw Error("Expected a digit");
}
break;
case EXPECTING_EXP_SIGN:
case EXPECTING_EXP_START:
switch(c){
case "-": case "+":
if(this._state === EXPECTING_EXP_START){
throw Error("Expected a digit");
}
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_EXP_START;
continue;
case "0": case "1": case "2": case "3": case "4":
case "5": case "6": case "7": case "8": case "9":
if(this._chunk && this._chunk.id !== "numericChunk"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "numericChunk", value: i, line: this._line, pos: this._pos};
}
this._state = EXPECTING_EXP_DIGIT;
continue;
default:
throw Error("Expected a digit");
}
break;
case EXPECTING_EXP_DIGIT:
switch(c){
case "0": case "1": case "2": case "3": case "4":
case "5": case "6": case "7": case "8": case "9":
if(this._chunk && this._chunk.id !== "numericChunk"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "numericChunk", value: i, line: this._line, pos: this._pos};
}
continue;
default:
--i;
--this._pos;
break;
}
break;
default:
throw Error("Unexpected this._state: " + this._state);
}
// end of value
switch(this._parent){
case PARSING_OBJECT:
this._state = EXPECTING_OBJECT_STOP;
break;
case PARSING_ARRAY:
this._state = EXPECTING_ARRAY_STOP;
break;
default:
this._state = EXPECTING_NOTHING;
break;
}
}
this._literal = ESCAPED_CHAR;
break main;
default:
if(this._chunk && this._chunk.id !== "plainChunk"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "plainChunk", value: i, line: this._line, pos: this._pos};
}
continue;
}
break;
case EXPECTING_NUMBER_START:
switch(c){
case "0":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_FRACTION;
continue;
case "1": case "2": case "3":
case "4": case "5": case "6":
case "7": case "8": case "9":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: "nonZero", value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_NUMBER_DIGIT;
continue;
default:
return callback(new Error("Expected a digit"));
}
break;
case EXPECTING_NUMBER_DIGIT:
case EXPECTING_FRACTION:
case EXPECTING_FRAC_DIGIT:
switch(c){
case "0": case "1": case "2": case "3": case "4":
case "5": case "6": case "7": case "8": case "9":
if(this._chunk && this._chunk.id !== "numericChunk"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(this._state === EXPECTING_FRACTION){
return callback(new Error("Expected '.' or 'e'"));
}
if(!this._chunk){
this._chunk = {id: "numericChunk", value: i, line: this._line, pos: this._pos};
}
continue;
case ".":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(this._state === EXPECTING_FRAC_DIGIT){
return callback(new Error("Expected a digit"));
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_FRAC_START;
continue;
case "e": case "E":
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: "exponent", value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_EXP_SIGN;
continue;
default:
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
--i;
--this._pos;
break;
}
break;
case EXPECTING_FRAC_START:
switch(c){
case "0": case "1": case "2": case "3": case "4":
case "5": case "6": case "7": case "8": case "9":
if(this._chunk && this._chunk.id !== "numericChunk"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "numericChunk", value: i, line: this._line, pos: this._pos};
}
this._state = EXPECTING_FRAC_DIGIT;
continue;
default:
return callback(new Error("Expected a digit"));
}
break;
case EXPECTING_EXP_SIGN:
case EXPECTING_EXP_START:
switch(c){
case "-": case "+":
if(this._state === EXPECTING_EXP_START){
return callback(new Error("Expected a digit"));
}
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
this.push({id: c, value: c, line: this._line, pos: this._pos});
this._state = EXPECTING_EXP_START;
continue;
case "0": case "1": case "2": case "3": case "4":
case "5": case "6": case "7": case "8": case "9":
if(this._chunk && this._chunk.id !== "numericChunk"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "numericChunk", value: i, line: this._line, pos: this._pos};
}
this._state = EXPECTING_EXP_DIGIT;
continue;
default:
return callback(new Error("Expected a digit"));
}
break;
case EXPECTING_EXP_DIGIT:
switch(c){
case "0": case "1": case "2": case "3": case "4":
case "5": case "6": case "7": case "8": case "9":
if(this._chunk && this._chunk.id !== "numericChunk"){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
if(!this._chunk){
this._chunk = {id: "numericChunk", value: i, line: this._line, pos: this._pos};
}
continue;
default:
--i;
--this._pos;
break;
}
break;
default:
return callback(new Error("Unexpected this._state: " + this._state));
}
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
// end of value
switch(this._parent){
case PARSING_OBJECT:
this._state = EXPECTING_OBJECT_STOP;
break;
case PARSING_ARRAY:
this._state = EXPECTING_ARRAY_STOP;
break;
default:
this._state = EXPECTING_NOTHING;
break;
}
}while(false);
}catch(err){
callback(err);
return;
}
}
if(this._chunk){
this._chunk.value = s.substring(this._chunk.value, i);
this.push(this._chunk);
this._chunk = null;
}
}while(false);
callback();

@@ -664,0 +659,0 @@ };

@@ -79,285 +79,238 @@ "use strict";

Parser.prototype._processInput = function(callback){
try{
var match, value;
main: for(;;){
switch(this._expect){
case "value1":
case "value":
match = value1.exec(this._buffer);
if(!match){
if(this._buffer){
if(this._done){
throw Error("Parser cannot parse input: expected a value");
}
}
var match, value;
main: for(;;){
switch(this._expect){
case "value1":
case "value":
match = value1.exec(this._buffer);
if(!match){
if(this._buffer){
if(this._done){
throw Error("Parser has expected a value");
return callback(new Error("Parser cannot parse input: expected a value"));
}
// wait for more input
break main;
}
value = match[0];
switch(value){
case "\"":
this.push({name: "startString"});
this._expect = "string";
break;
case "{":
this.push({name: "startObject"});
this._stack.push(this._parent);
this._parent = "object";
this._expect = "key1";
break;
case "[":
this.push({name: "startArray"});
this._stack.push(this._parent);
this._parent = "array";
this._expect = "value1";
break;
case "]":
if(this._expect !== "value1"){
throw Error("Parser cannot parse input: unexpected token ']'");
}
if(this._open_number){
this.push({name: "endNumber"});
this._open_number = false;
if(this._packNumbers){
this.push({name: "numberValue", value: this._accumulator});
this._accumulator = "";
}
}
this.push({name: "endArray"});
this._parent = this._stack.pop();
this._expect = expected[this._parent];
break;
case "-":
this._open_number = true;
this.push({name: "startNumber"});
this.push({name: "numberChunk", value: "-"});
if(this._packNumbers){
this._accumulator = "-";
}
this._expect = "numberStart";
break;
case "0":
this._open_number = true;
this.push({name: "startNumber"});
this.push({name: "numberChunk", value: "0"});
if(this._packNumbers){
this._accumulator = "0";
}
this._expect = "numberFraction";
break;
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
this._open_number = true;
this.push({name: "startNumber"});
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator = value;
}
this._expect = "numberDigit";
break;
case "true":
case "false":
case "null":
if(this._buffer.length === value.length && !this._done){
// wait for more input
break main;
}
this.push({name: value + "Value", value: values[value]});
this._expect = expected[this._parent];
break;
// default: // ws
if(this._done){
return callback(new Error("Parser has expected a value"));
}
this._buffer = this._buffer.substring(value.length);
break;
case "keyVal":
case "string":
match = string.exec(this._buffer);
if(!match){
if(this._buffer){
if(this._done || this._buffer.length >= 6){
throw Error("Parser cannot parse input: escaped characters");
}
// wait for more input
break main;
}
value = match[0];
switch(value){
case "\"":
this.push({name: "startString"});
this._expect = "string";
break;
case "{":
this.push({name: "startObject"});
this._stack.push(this._parent);
this._parent = "object";
this._expect = "key1";
break;
case "[":
this.push({name: "startArray"});
this._stack.push(this._parent);
this._parent = "array";
this._expect = "value1";
break;
case "]":
if(this._expect !== "value1"){
return callback(new Error("Parser cannot parse input: unexpected token ']'"));
}
if(this._done){
throw Error("Parser has expected a string value");
}
// wait for more input
break main;
}
value = match[0];
if(value === "\""){
if(this._expect === "keyVal"){
this.push({name: "endKey"});
if(this._packKeys){
this.push({name: "keyValue", value: this._accumulator});
if(this._open_number){
this.push({name: "endNumber"});
this._open_number = false;
if(this._packNumbers){
this.push({name: "numberValue", value: this._accumulator});
this._accumulator = "";
}
this._expect = "colon";
}else{
this.push({name: "endString"});
if(this._packStrings){
this.push({name: "stringValue", value: this._accumulator});
this._accumulator = "";
}
this._expect = expected[this._parent];
}
}else if(value.length > 1 && value.charAt(0) === "\\"){
var t = value.length == 2 ? codes[value.charAt(1)] : fromHex(value);
this.push({name: "stringChunk", value: t});
if(this._expect === "keyVal" ? this._packKeys : this._packStrings){
this._accumulator += t;
this.push({name: "endArray"});
this._parent = this._stack.pop();
this._expect = expected[this._parent];
break;
case "-":
this._open_number = true;
this.push({name: "startNumber"});
this.push({name: "numberChunk", value: "-"});
if(this._packNumbers){
this._accumulator = "-";
}
}else{
this.push({name: "stringChunk", value: value});
if(this._expect === "keyVal" ? this._packKeys : this._packStrings){
this._accumulator += value;
this._expect = "numberStart";
break;
case "0":
this._open_number = true;
this.push({name: "startNumber"});
this.push({name: "numberChunk", value: "0"});
if(this._packNumbers){
this._accumulator = "0";
}
}
this._buffer = this._buffer.substring(value.length);
break;
case "key1":
case "key":
match = key1.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected an object key");
this._expect = "numberFraction";
break;
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
this._open_number = true;
this.push({name: "startNumber"});
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator = value;
}
// wait for more input
break main;
}
value = match[0];
if(value === "\""){
this.push({name: "startKey"});
this._expect = "keyVal";
}else if(value === "}"){
if(this._expect !== "key1"){
throw Error("Parser cannot parse input: unexpected token '}'");
this._expect = "numberDigit";
break;
case "true":
case "false":
case "null":
if(this._buffer.length === value.length && !this._done){
// wait for more input
break main;
}
this.push({name: "endObject"});
this._parent = this._stack.pop();
this.push({name: value + "Value", value: values[value]});
this._expect = expected[this._parent];
}
this._buffer = this._buffer.substring(value.length);
break;
case "colon":
match = colon.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected ':'");
break;
// default: // ws
}
this._buffer = this._buffer.substring(value.length);
break;
case "keyVal":
case "string":
match = string.exec(this._buffer);
if(!match){
if(this._buffer){
if(this._done || this._buffer.length >= 6){
return callback(new Error("Parser cannot parse input: escaped characters"));
}
// wait for more input
break main;
}
value = match[0];
if(value === ":"){
this._expect = "value";
if(this._done){
return callback(new Error("Parser has expected a string value"));
}
this._buffer = this._buffer.substring(value.length);
break;
case "arrayStop":
case "objectStop":
match = comma.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected ','");
// wait for more input
break main;
}
value = match[0];
if(value === "\""){
if(this._expect === "keyVal"){
this.push({name: "endKey"});
if(this._packKeys){
this.push({name: "keyValue", value: this._accumulator});
this._accumulator = "";
}
// wait for more input
break main;
}
if(this._open_number){
this.push({name: "endNumber"});
this._open_number = false;
if(this._packNumbers){
this.push({name: "numberValue", value: this._accumulator});
this._expect = "colon";
}else{
this.push({name: "endString"});
if(this._packStrings){
this.push({name: "stringValue", value: this._accumulator});
this._accumulator = "";
}
}
value = match[0];
if(value === ","){
this._expect = this._expect === "arrayStop" ? "value" : "key";
}else if(value === "}" || value === "]"){
this.push({name: value === "}" ? "endObject" : "endArray"});
this._parent = this._stack.pop();
this._expect = expected[this._parent];
}
this._buffer = this._buffer.substring(value.length);
break;
// number chunks
case "numberStart": // [0-9]
match = numberStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected a digit");
}
// wait for more input
break main;
}else if(value.length > 1 && value.charAt(0) === "\\"){
var t = value.length == 2 ? codes[value.charAt(1)] : fromHex(value);
this.push({name: "stringChunk", value: t});
if(this._expect === "keyVal" ? this._packKeys : this._packStrings){
this._accumulator += t;
}
value = match[0];
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
}else{
this.push({name: "stringChunk", value: value});
if(this._expect === "keyVal" ? this._packKeys : this._packStrings){
this._accumulator += value;
}
this._expect = value === "0" ? "numberFraction" : "numberDigit";
this._buffer = this._buffer.substring(value.length);
break;
case "numberDigit": // [0-9]*
match = numberDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator += value;
}
this._buffer = this._buffer.substring(value.length);
}else{
if(this._buffer){
this._expect = "numberFraction";
break;
}
if(this._done){
this._expect = expected[this._parent];
break;
}
// wait for more input
break main;
}
this._buffer = this._buffer.substring(value.length);
break;
case "key1":
case "key":
match = key1.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected an object key"));
}
break;
case "numberFraction": // [\.eE]?
match = numberFraction.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
this._expect = expected[this._parent];
break;
}
// wait for more input
break main;
// wait for more input
break main;
}
value = match[0];
if(value === "\""){
this.push({name: "startKey"});
this._expect = "keyVal";
}else if(value === "}"){
if(this._expect !== "key1"){
return callback(new Error("Parser cannot parse input: unexpected token '}'"));
}
value = match[0];
this.push({name: "numberChunk", value: value});
this.push({name: "endObject"});
this._parent = this._stack.pop();
this._expect = expected[this._parent];
}
this._buffer = this._buffer.substring(value.length);
break;
case "colon":
match = colon.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected ':'"));
}
// wait for more input
break main;
}
value = match[0];
if(value === ":"){
this._expect = "value";
}
this._buffer = this._buffer.substring(value.length);
break;
case "arrayStop":
case "objectStop":
match = comma.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected ','"));
}
// wait for more input
break main;
}
if(this._open_number){
this.push({name: "endNumber"});
this._open_number = false;
if(this._packNumbers){
this._accumulator += value;
this.push({name: "numberValue", value: this._accumulator});
this._accumulator = "";
}
this._expect = value === "." ? "numberFracStart" : "numberExpSign";
this._buffer = this._buffer.substring(value.length);
break;
case "numberFracStart": // [0-9]
match = numberFracStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected a fractional part of a number");
}
// wait for more input
break main;
}
value = match[0];
if(value === ","){
this._expect = this._expect === "arrayStop" ? "value" : "key";
}else if(value === "}" || value === "]"){
this.push({name: value === "}" ? "endObject" : "endArray"});
this._parent = this._stack.pop();
this._expect = expected[this._parent];
}
this._buffer = this._buffer.substring(value.length);
break;
// number chunks
case "numberStart": // [0-9]
match = numberStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected a digit"));
}
value = match[0];
// wait for more input
break main;
}
value = match[0];
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator += value;
}
this._expect = value === "0" ? "numberFraction" : "numberDigit";
this._buffer = this._buffer.substring(value.length);
break;
case "numberDigit": // [0-9]*
match = numberDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({name: "numberChunk", value: value});

@@ -367,63 +320,55 @@ if(this._packNumbers){

}
this._expect = "numberFracDigit";
this._buffer = this._buffer.substring(value.length);
break;
case "numberFracDigit": // [0-9]*
match = numberFracDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator += value;
}
this._buffer = this._buffer.substring(value.length);
}else{
if(this._buffer){
this._expect = "numberExponent";
break;
}
if(this._done){
this._expect = expected[this._parent];
break;
}
// wait for more input
break main;
}else{
if(this._buffer){
this._expect = "numberFraction";
break;
}
break;
case "numberExponent": // [eE]?
match = numberExponent.exec(this._buffer);
if(!match){
if(this._buffer){
this._expect = expected[this._parent];
break;
}
if(this._done){
this._expect = "done";
break;
}
// wait for more input
break main;
if(this._done){
this._expect = expected[this._parent];
break;
}
value = match[0];
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator += value;
// wait for more input
break main;
}
break;
case "numberFraction": // [\.eE]?
match = numberFraction.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
this._expect = expected[this._parent];
break;
}
this._expect = "numberExpSign";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpSign": // [-+]?
match = numberExpSign.exec(this._buffer);
if(!match){
if(this._buffer){
this._expect = "numberExpStart";
break;
}
if(this._done){
throw Error("Parser has expected an exponent value of a number");
}
// wait for more input
break main;
// wait for more input
break main;
}
value = match[0];
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator += value;
}
this._expect = value === "." ? "numberFracStart" : "numberExpSign";
this._buffer = this._buffer.substring(value.length);
break;
case "numberFracStart": // [0-9]
match = numberFracStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected a fractional part of a number"));
}
value = match[0];
// wait for more input
break main;
}
value = match[0];
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator += value;
}
this._expect = "numberFracDigit";
this._buffer = this._buffer.substring(value.length);
break;
case "numberFracDigit": // [0-9]*
match = numberFracDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({name: "numberChunk", value: value});

@@ -433,15 +378,80 @@ if(this._packNumbers){

}
this._expect = "numberExpStart";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpStart": // [0-9]
match = numberExpStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected an exponent part of a number");
}
// wait for more input
break main;
}else{
if(this._buffer){
this._expect = "numberExponent";
break;
}
value = match[0];
if(this._done){
this._expect = expected[this._parent];
break;
}
// wait for more input
break main;
}
break;
case "numberExponent": // [eE]?
match = numberExponent.exec(this._buffer);
if(!match){
if(this._buffer){
this._expect = expected[this._parent];
break;
}
if(this._done){
this._expect = "done";
break;
}
// wait for more input
break main;
}
value = match[0];
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator += value;
}
this._expect = "numberExpSign";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpSign": // [-+]?
match = numberExpSign.exec(this._buffer);
if(!match){
if(this._buffer){
this._expect = "numberExpStart";
break;
}
if(this._done){
return callback(new Error("Parser has expected an exponent value of a number"));
}
// wait for more input
break main;
}
value = match[0];
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator += value;
}
this._expect = "numberExpStart";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpStart": // [0-9]
match = numberExpStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected an exponent part of a number"));
}
// wait for more input
break main;
}
value = match[0];
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator += value;
}
this._expect = "numberExpDigit";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpDigit": // [0-9]*
match = numberExpDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({name: "numberChunk", value: value});

@@ -451,47 +461,32 @@ if(this._packNumbers){

}
this._expect = "numberExpDigit";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpDigit": // [0-9]*
match = numberExpDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({name: "numberChunk", value: value});
if(this._packNumbers){
this._accumulator += value;
}
this._buffer = this._buffer.substring(value.length);
}else{
if(this._buffer || this._done){
this._expect = expected[this._parent];
break;
}
// wait for more input
break main;
}else{
if(this._buffer || this._done){
this._expect = expected[this._parent];
break;
}
break;
case "done":
match = ws.exec(this._buffer);
if(!match){
if(this._buffer){
throw Error("Parser cannot parse input: unexpected characters");
}
// wait for more input
break main;
// wait for more input
break main;
}
break;
case "done":
match = ws.exec(this._buffer);
if(!match){
if(this._buffer){
return callback(new Error("Parser cannot parse input: unexpected characters"));
}
if(this._open_number){
this.push({name: "endNumber"});
this._open_number = false;
if(this._packNumbers){
this.push({name: "numberValue", value: this._accumulator});
this._accumulator = "";
}
// wait for more input
break main;
}
if(this._open_number){
this.push({name: "endNumber"});
this._open_number = false;
if(this._packNumbers){
this.push({name: "numberValue", value: this._accumulator});
this._accumulator = "";
}
this._buffer = this._buffer.substring(match[0].length);
break;
}
}
this._buffer = this._buffer.substring(match[0].length);
break;
}
}catch(err){
callback(err);
return;
}

@@ -498,0 +493,0 @@ callback();

{
"name": "stream-json",
"version": "0.4.1",
"version": "0.4.2",
"description": "stream-json is a SAX-inspired stream components with a minimal memory footprint to parse huge JSON files. Includes utilities to stream Django-like JSON database dumps.",

@@ -15,3 +15,3 @@ "homepage": "http://github.com/uhop/stream-json",

"devDependencies": {
"heya-unit": "^0.2.0"
"heya-unit": "^0.3.0"
},

@@ -18,0 +18,0 @@ "scripts": {

@@ -48,143 +48,78 @@ "use strict";

Parser.prototype._processInput = function(callback){
try{
var match, value;
main: for(;;){
switch(this._expect){
case "value1":
case "value":
match = value1.exec(this._buffer);
if(!match){
if(this._buffer){
if(this._done){
throw Error("Parser cannot parse input: expected a value");
}
}
var match, value;
main: for(;;){
switch(this._expect){
case "value1":
case "value":
match = value1.exec(this._buffer);
if(!match){
if(this._buffer){
if(this._done){
throw Error("Parser has expected a value");
return callback(new Error("Parser cannot parse input: expected a value"));
}
// wait for more input
break main;
}
value = match[0];
switch(value){
case "\"":
this.push({id: value, value: value});
this._expect = "string";
break;
case "{":
this.push({id: value, value: value});
this._stack.push(this._parent);
this._parent = "object";
this._expect = "key1";
break;
case "[":
this.push({id: value, value: value});
this._stack.push(this._parent);
this._parent = "array";
this._expect = "value1";
break;
case "]":
if(this._expect !== "value1"){
throw Error("Parser cannot parse input: unexpected token ']'");
}
this.push({id: value, value: value});
this._parent = this._stack.pop();
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
break;
case "-":
this.push({id: value, value: value});
this._expect = "numberStart";
break;
case "0":
this.push({id: value, value: value});
this._expect = "numberFraction";
break;
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
this.push({id: "nonZero", value: value});
this._expect = "numberDigit";
break;
case "true":
case "false":
case "null":
if(this._buffer.length === value.length && !this._done){
// wait for more input
break main;
}
this.push({id: value, value: value});
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
break;
// default: // ws
if(this._done){
return callback(new Error("Parser has expected a value"));
}
this._buffer = this._buffer.substring(value.length);
break;
case "keyVal":
case "string":
match = string.exec(this._buffer);
if(!match){
if(this._buffer){
if(this._done || this._buffer.length >= 6){
throw Error("Parser cannot parse input: escaped characters");
}
// wait for more input
break main;
}
value = match[0];
switch(value){
case "\"":
this.push({id: value, value: value});
this._expect = "string";
break;
case "{":
this.push({id: value, value: value});
this._stack.push(this._parent);
this._parent = "object";
this._expect = "key1";
break;
case "[":
this.push({id: value, value: value});
this._stack.push(this._parent);
this._parent = "array";
this._expect = "value1";
break;
case "]":
if(this._expect !== "value1"){
return callback(new Error("Parser cannot parse input: unexpected token ']'"));
}
if(this._done){
throw Error("Parser has expected a string value");
}
// wait for more input
break main;
}
value = match[0];
if(value === "\""){
this.push({id: value, value: value});
if(this._expect === "keyVal"){
this._expect = "colon";
this._parent = this._stack.pop();
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
this._expect = "done";
}
}else if(value.length > 1 && value.charAt(0) === "\\"){
this.push({id: "escapedChars", value: value});
}else{
this.push({id: "plainChunk", value: value});
}
this._buffer = this._buffer.substring(value.length);
break;
case "key1":
case "key":
match = key1.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected an object key");
}
// wait for more input
break main;
}
value = match[0];
if(value === "\""){
break;
case "-":
this.push({id: value, value: value});
this._expect = "keyVal";
}else if(value === "}"){
if(this._expect !== "key1"){
throw Error("Parser cannot parse input: unexpected token '}'");
this._expect = "numberStart";
break;
case "0":
this.push({id: value, value: value});
this._expect = "numberFraction";
break;
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
this.push({id: "nonZero", value: value});
this._expect = "numberDigit";
break;
case "true":
case "false":
case "null":
if(this._buffer.length === value.length && !this._done){
// wait for more input
break main;
}
this.push({id: value, value: value});
this._parent = this._stack.pop();
if(this._parent){

@@ -195,38 +130,28 @@ this._expect = this._parent === "object" ? "objectStop" : "arrayStop";

}
}
this._buffer = this._buffer.substring(value.length);
break;
case "colon":
match = colon.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected ':'");
break;
// default: // ws
}
this._buffer = this._buffer.substring(value.length);
break;
case "keyVal":
case "string":
match = string.exec(this._buffer);
if(!match){
if(this._buffer){
if(this._done || this._buffer.length >= 6){
return callback(new Error("Parser cannot parse input: escaped characters"));
}
// wait for more input
break main;
}
value = match[0];
if(value === ":"){
this.push({id: value, value: value});
this._expect = "value";
if(this._done){
return callback(new Error("Parser has expected a string value"));
}
this._buffer = this._buffer.substring(value.length);
break;
case "arrayStop":
case "objectStop":
match = comma.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected ','");
}
// wait for more input
break main;
}
value = match[0];
if(value === ","){
this.push({id: value, value: value});
this._expect = this._expect === "arrayStop" ? "value" : "key";
}else if(value === "}" || value === "]"){
this.push({id: value, value: value});
this._parent = this._stack.pop();
// wait for more input
break main;
}
value = match[0];
if(value === "\""){
this.push({id: value, value: value});
if(this._expect === "keyVal"){
this._expect = "colon";
}else{
if(this._parent){

@@ -238,198 +163,268 @@ this._expect = this._parent === "object" ? "objectStop" : "arrayStop";

}
this._buffer = this._buffer.substring(value.length);
break;
// number chunks
case "numberStart": // [0-9]
match = numberStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected a digit");
}
// wait for more input
break main;
}else if(value.length > 1 && value.charAt(0) === "\\"){
this.push({id: "escapedChars", value: value});
}else{
this.push({id: "plainChunk", value: value});
}
this._buffer = this._buffer.substring(value.length);
break;
case "key1":
case "key":
match = key1.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected an object key"));
}
value = match[0];
if(value === "0"){
this.push({id: value, value: value});
this._expect = "numberFraction";
}else{
this.push({id: "nonZero", value: value});
this._expect = "numberDigit";
// wait for more input
break main;
}
value = match[0];
if(value === "\""){
this.push({id: value, value: value});
this._expect = "keyVal";
}else if(value === "}"){
if(this._expect !== "key1"){
return callback(new Error("Parser cannot parse input: unexpected token '}'"));
}
this._buffer = this._buffer.substring(value.length);
break;
case "numberDigit": // [0-9]*
match = numberDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({id: "numericChunk", value: value});
this._buffer = this._buffer.substring(value.length);
this.push({id: value, value: value});
this._parent = this._stack.pop();
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
if(this._buffer){
this._expect = "numberFraction";
break;
}
if(this._done){
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
break;
}
// wait for more input
break main;
this._expect = "done";
}
break;
case "numberFraction": // [\.eE]?
match = numberFraction.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
break;
}
// wait for more input
break main;
}
this._buffer = this._buffer.substring(value.length);
break;
case "colon":
match = colon.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected ':'"));
}
value = match[0];
if(value === "."){
this.push({id: value, value: value});
this._expect = "numberFracStart";
// wait for more input
break main;
}
value = match[0];
if(value === ":"){
this.push({id: value, value: value});
this._expect = "value";
}
this._buffer = this._buffer.substring(value.length);
break;
case "arrayStop":
case "objectStop":
match = comma.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected ','"));
}
// wait for more input
break main;
}
value = match[0];
if(value === ","){
this.push({id: value, value: value});
this._expect = this._expect === "arrayStop" ? "value" : "key";
}else if(value === "}" || value === "]"){
this.push({id: value, value: value});
this._parent = this._stack.pop();
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this.push({id: "exponent", value: value});
this._expect = "numberExpSign";
this._expect = "done";
}
this._buffer = this._buffer.substring(value.length);
break;
case "numberFracStart": // [0-9]
match = numberFracStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected a fractional part of a number");
}
// wait for more input
break main;
}
this._buffer = this._buffer.substring(value.length);
break;
// number chunks
case "numberStart": // [0-9]
match = numberStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected a digit"));
}
value = match[0];
// wait for more input
break main;
}
value = match[0];
if(value === "0"){
this.push({id: value, value: value});
this._expect = "numberFraction";
}else{
this.push({id: "nonZero", value: value});
this._expect = "numberDigit";
}
this._buffer = this._buffer.substring(value.length);
break;
case "numberDigit": // [0-9]*
match = numberDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({id: "numericChunk", value: value});
this._expect = "numberFracDigit";
this._buffer = this._buffer.substring(value.length);
break;
case "numberFracDigit": // [0-9]*
match = numberFracDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({id: "numericChunk", value: value});
this._buffer = this._buffer.substring(value.length);
}else{
if(this._buffer){
this._expect = "numberExponent";
break;
}else{
if(this._buffer){
this._expect = "numberFraction";
break;
}
if(this._done){
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
if(this._done){
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
break;
}
// wait for more input
break main;
break;
}
break;
case "numberExponent": // [eE]?
match = numberExponent.exec(this._buffer);
if(!match){
if(this._buffer){
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
break;
}
if(this._done){
// wait for more input
break main;
}
break;
case "numberFraction": // [\.eE]?
match = numberFraction.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
break;
}
// wait for more input
break main;
break;
}
value = match[0];
// wait for more input
break main;
}
value = match[0];
if(value === "."){
this.push({id: value, value: value});
this._expect = "numberFracStart";
}else{
this.push({id: "exponent", value: value});
this._expect = "numberExpSign";
}
this._buffer = this._buffer.substring(value.length);
break;
case "numberFracStart": // [0-9]
match = numberFracStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected a fractional part of a number"));
}
// wait for more input
break main;
}
value = match[0];
this.push({id: "numericChunk", value: value});
this._expect = "numberFracDigit";
this._buffer = this._buffer.substring(value.length);
break;
case "numberFracDigit": // [0-9]*
match = numberFracDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({id: "numericChunk", value: value});
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpSign": // [-+]?
match = numberExpSign.exec(this._buffer);
if(!match){
if(this._buffer){
this._expect = "numberExpStart";
break;
}else{
if(this._buffer){
this._expect = "numberExponent";
break;
}
if(this._done){
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
if(this._done){
throw Error("Parser has expected an exponent value of a number");
}
// wait for more input
break main;
break;
}
value = match[0];
this.push({id: value, value: value});
this._expect = "numberExpStart";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpStart": // [0-9]
match = numberExpStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
throw Error("Parser cannot parse input: expected an exponent part of a number");
// wait for more input
break main;
}
break;
case "numberExponent": // [eE]?
match = numberExponent.exec(this._buffer);
if(!match){
if(this._buffer){
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
// wait for more input
break main;
break;
}
value = match[0];
if(this._done){
this._expect = "done";
break;
}
// wait for more input
break main;
}
value = match[0];
this.push({id: "exponent", value: value});
this._expect = "numberExpSign";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpSign": // [-+]?
match = numberExpSign.exec(this._buffer);
if(!match){
if(this._buffer){
this._expect = "numberExpStart";
break;
}
if(this._done){
return callback(new Error("Parser has expected an exponent value of a number"));
}
// wait for more input
break main;
}
value = match[0];
this.push({id: value, value: value});
this._expect = "numberExpStart";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpStart": // [0-9]
match = numberExpStart.exec(this._buffer);
if(!match){
if(this._buffer || this._done){
return callback(new Error("Parser cannot parse input: expected an exponent part of a number"));
}
// wait for more input
break main;
}
value = match[0];
this.push({id: "numericChunk", value: value});
this._expect = "numberExpDigit";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpDigit": // [0-9]*
match = numberExpDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({id: "numericChunk", value: value});
this._expect = "numberExpDigit";
this._buffer = this._buffer.substring(value.length);
break;
case "numberExpDigit": // [0-9]*
match = numberExpDigit.exec(this._buffer);
value = match[0];
if(value){
this.push({id: "numericChunk", value: value});
this._buffer = this._buffer.substring(value.length);
}else{
if(this._buffer || this._done){
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
break;
}else{
if(this._buffer || this._done){
if(this._parent){
this._expect = this._parent === "object" ? "objectStop" : "arrayStop";
}else{
this._expect = "done";
}
// wait for more input
break main;
break;
}
break;
case "done":
match = ws.exec(this._buffer);
if(!match){
if(this._buffer){
throw Error("Parser cannot parse input: unexpected characters");
}
// wait for more input
break main;
// wait for more input
break main;
}
break;
case "done":
match = ws.exec(this._buffer);
if(!match){
if(this._buffer){
return callback(new Error("Parser cannot parse input: unexpected characters"));
}
this._buffer = this._buffer.substring(match[0].length);
break;
}
// wait for more input
break main;
}
this._buffer = this._buffer.substring(match[0].length);
break;
}
}catch(err){
callback(err);
return;
}

@@ -436,0 +431,0 @@ callback();

@@ -574,3 +574,3 @@ # stream-json

The whole library is organized as set of small components, which can be combined to produce the most effective pipeline. All components are based on node.js [streams](http://nodejs.org/api/stream.html), and [events](http://nodejs.org/api/events.html). They implement all required standard APIs. It is easy to add your own components to solve your unique tasks.
The whole library is organized as a set of small components, which can be combined to produce the most effective pipeline. All components are based on node.js [streams](http://nodejs.org/api/stream.html), and [events](http://nodejs.org/api/events.html). They implement all required standard APIs. It is easy to add your own components to solve your unique tasks.

@@ -585,3 +585,3 @@ The code of all components are compact and simple. Please take a look at their source code to see how things are implemented, so you can produce your own components in no time.

* a snapshot of publicly available [Japanese statistics on birth and marriage in JSON)](http://dataforjapan.org/dataset/birth-stat/resource/42799d3c-ecee-4b35-9f5a-7fec30596aa2).
* a snapshot of publicly available [Japanese statistics on birth and marriage in JSON](http://dataforjapan.org/dataset/birth-stat/resource/42799d3c-ecee-4b35-9f5a-7fec30596aa2).
* a snapshot of publicly available [US Department of Housing and Urban Development - HUD's published metadata catalog (Schema Version 1.1)](https://catalog.data.gov/dataset/data-catalog).

@@ -630,2 +630,3 @@ * a small fake sample made up by me featuring non-ASCII keys, non-ASCII strings, and primitive data missing in other two samples.

- 0.4.2 *refreshed dependencies.*
- 0.4.1 *added `StreamObject` by [Sam Noedel](https://github.com/delta62)*

@@ -632,0 +633,0 @@ - 0.4.0 *new high-performant Combo component, switched to the previous parser.*

@@ -18,3 +18,3 @@ "use strict";

//stringValue: stringValue, // aliased above as _saveValue
//stringValue: stringValue, // aliased below as _saveValue
numberValue: function(value){ this._saveValue(parseFloat(value)); },

@@ -21,0 +21,0 @@ nullValue: function(){ this._saveValue(null); },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc