11cb0ef41Sopenharmony_ci/*global Buffer*/ 21cb0ef41Sopenharmony_ci// Named constants with unique integer values 31cb0ef41Sopenharmony_civar C = {}; 41cb0ef41Sopenharmony_ci// Tokens 51cb0ef41Sopenharmony_civar LEFT_BRACE = C.LEFT_BRACE = 0x1; 61cb0ef41Sopenharmony_civar RIGHT_BRACE = C.RIGHT_BRACE = 0x2; 71cb0ef41Sopenharmony_civar LEFT_BRACKET = C.LEFT_BRACKET = 0x3; 81cb0ef41Sopenharmony_civar RIGHT_BRACKET = C.RIGHT_BRACKET = 0x4; 91cb0ef41Sopenharmony_civar COLON = C.COLON = 0x5; 101cb0ef41Sopenharmony_civar COMMA = C.COMMA = 0x6; 111cb0ef41Sopenharmony_civar TRUE = C.TRUE = 0x7; 121cb0ef41Sopenharmony_civar FALSE = C.FALSE = 0x8; 131cb0ef41Sopenharmony_civar NULL = C.NULL = 0x9; 141cb0ef41Sopenharmony_civar STRING = C.STRING = 0xa; 151cb0ef41Sopenharmony_civar NUMBER = C.NUMBER = 0xb; 161cb0ef41Sopenharmony_ci// Tokenizer States 171cb0ef41Sopenharmony_civar START = C.START = 0x11; 181cb0ef41Sopenharmony_civar STOP = C.STOP = 0x12; 191cb0ef41Sopenharmony_civar TRUE1 = C.TRUE1 = 0x21; 201cb0ef41Sopenharmony_civar TRUE2 = C.TRUE2 = 0x22; 211cb0ef41Sopenharmony_civar TRUE3 = C.TRUE3 = 0x23; 221cb0ef41Sopenharmony_civar FALSE1 = C.FALSE1 = 0x31; 231cb0ef41Sopenharmony_civar FALSE2 = C.FALSE2 = 0x32; 241cb0ef41Sopenharmony_civar FALSE3 = C.FALSE3 = 0x33; 251cb0ef41Sopenharmony_civar FALSE4 = C.FALSE4 = 0x34; 261cb0ef41Sopenharmony_civar NULL1 = C.NULL1 = 0x41; 271cb0ef41Sopenharmony_civar NULL2 = C.NULL2 = 0x42; 281cb0ef41Sopenharmony_civar NULL3 = C.NULL3 = 0x43; 291cb0ef41Sopenharmony_civar NUMBER1 = C.NUMBER1 = 0x51; 301cb0ef41Sopenharmony_civar NUMBER3 = C.NUMBER3 = 0x53; 311cb0ef41Sopenharmony_civar STRING1 = C.STRING1 = 0x61; 321cb0ef41Sopenharmony_civar STRING2 = C.STRING2 = 0x62; 331cb0ef41Sopenharmony_civar STRING3 = C.STRING3 = 0x63; 341cb0ef41Sopenharmony_civar STRING4 = C.STRING4 = 0x64; 351cb0ef41Sopenharmony_civar STRING5 = C.STRING5 = 0x65; 361cb0ef41Sopenharmony_civar STRING6 = C.STRING6 = 0x66; 371cb0ef41Sopenharmony_ci// Parser States 381cb0ef41Sopenharmony_civar VALUE = C.VALUE = 0x71; 391cb0ef41Sopenharmony_civar KEY = C.KEY = 0x72; 401cb0ef41Sopenharmony_ci// Parser Modes 411cb0ef41Sopenharmony_civar OBJECT = C.OBJECT = 0x81; 421cb0ef41Sopenharmony_civar ARRAY = C.ARRAY = 0x82; 431cb0ef41Sopenharmony_ci// Character constants 441cb0ef41Sopenharmony_civar BACK_SLASH = "\\".charCodeAt(0); 451cb0ef41Sopenharmony_civar FORWARD_SLASH = "\/".charCodeAt(0); 461cb0ef41Sopenharmony_civar BACKSPACE = "\b".charCodeAt(0); 471cb0ef41Sopenharmony_civar FORM_FEED = "\f".charCodeAt(0); 481cb0ef41Sopenharmony_civar NEWLINE = "\n".charCodeAt(0); 491cb0ef41Sopenharmony_civar CARRIAGE_RETURN = "\r".charCodeAt(0); 501cb0ef41Sopenharmony_civar TAB = "\t".charCodeAt(0); 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_civar STRING_BUFFER_SIZE = 64 * 1024; 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_cifunction Parser() { 551cb0ef41Sopenharmony_ci this.tState = START; 561cb0ef41Sopenharmony_ci this.value = undefined; 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci this.string = undefined; // string data 591cb0ef41Sopenharmony_ci this.stringBuffer = Buffer.alloc ? Buffer.alloc(STRING_BUFFER_SIZE) : new Buffer(STRING_BUFFER_SIZE); 601cb0ef41Sopenharmony_ci this.stringBufferOffset = 0; 611cb0ef41Sopenharmony_ci this.unicode = undefined; // unicode escapes 621cb0ef41Sopenharmony_ci this.highSurrogate = undefined; 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci this.key = undefined; 651cb0ef41Sopenharmony_ci this.mode = undefined; 661cb0ef41Sopenharmony_ci this.stack = []; 671cb0ef41Sopenharmony_ci this.state = VALUE; 681cb0ef41Sopenharmony_ci this.bytes_remaining = 0; // number of bytes remaining in multi byte utf8 char to read after split boundary 691cb0ef41Sopenharmony_ci this.bytes_in_sequence = 0; // bytes in multi byte utf8 char to read 701cb0ef41Sopenharmony_ci this.temp_buffs = { "2": new Buffer(2), "3": new Buffer(3), "4": new Buffer(4) }; // for rebuilding chars split before boundary is reached 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci // Stream offset 731cb0ef41Sopenharmony_ci this.offset = -1; 741cb0ef41Sopenharmony_ci} 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci// Slow code to string converter (only used when throwing syntax errors) 771cb0ef41Sopenharmony_ciParser.toknam = function (code) { 781cb0ef41Sopenharmony_ci var keys = Object.keys(C); 791cb0ef41Sopenharmony_ci for (var i = 0, l = keys.length; i < l; i++) { 801cb0ef41Sopenharmony_ci var key = keys[i]; 811cb0ef41Sopenharmony_ci if (C[key] === code) { return key; } 821cb0ef41Sopenharmony_ci } 831cb0ef41Sopenharmony_ci return code && ("0x" + code.toString(16)); 841cb0ef41Sopenharmony_ci}; 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_civar proto = Parser.prototype; 871cb0ef41Sopenharmony_ciproto.onError = function (err) { throw err; }; 881cb0ef41Sopenharmony_ciproto.charError = function (buffer, i) { 891cb0ef41Sopenharmony_ci this.tState = STOP; 901cb0ef41Sopenharmony_ci this.onError(new Error("Unexpected " + JSON.stringify(String.fromCharCode(buffer[i])) + " at position " + i + " in state " + Parser.toknam(this.tState))); 911cb0ef41Sopenharmony_ci}; 921cb0ef41Sopenharmony_ciproto.appendStringChar = function (char) { 931cb0ef41Sopenharmony_ci if (this.stringBufferOffset >= STRING_BUFFER_SIZE) { 941cb0ef41Sopenharmony_ci this.string += this.stringBuffer.toString('utf8'); 951cb0ef41Sopenharmony_ci this.stringBufferOffset = 0; 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci this.stringBuffer[this.stringBufferOffset++] = char; 991cb0ef41Sopenharmony_ci}; 1001cb0ef41Sopenharmony_ciproto.appendStringBuf = function (buf, start, end) { 1011cb0ef41Sopenharmony_ci var size = buf.length; 1021cb0ef41Sopenharmony_ci if (typeof start === 'number') { 1031cb0ef41Sopenharmony_ci if (typeof end === 'number') { 1041cb0ef41Sopenharmony_ci if (end < 0) { 1051cb0ef41Sopenharmony_ci // adding a negative end decreeses the size 1061cb0ef41Sopenharmony_ci size = buf.length - start + end; 1071cb0ef41Sopenharmony_ci } else { 1081cb0ef41Sopenharmony_ci size = end - start; 1091cb0ef41Sopenharmony_ci } 1101cb0ef41Sopenharmony_ci } else { 1111cb0ef41Sopenharmony_ci size = buf.length - start; 1121cb0ef41Sopenharmony_ci } 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci if (size < 0) { 1161cb0ef41Sopenharmony_ci size = 0; 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci if (this.stringBufferOffset + size > STRING_BUFFER_SIZE) { 1201cb0ef41Sopenharmony_ci this.string += this.stringBuffer.toString('utf8', 0, this.stringBufferOffset); 1211cb0ef41Sopenharmony_ci this.stringBufferOffset = 0; 1221cb0ef41Sopenharmony_ci } 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci buf.copy(this.stringBuffer, this.stringBufferOffset, start, end); 1251cb0ef41Sopenharmony_ci this.stringBufferOffset += size; 1261cb0ef41Sopenharmony_ci}; 1271cb0ef41Sopenharmony_ciproto.write = function (buffer) { 1281cb0ef41Sopenharmony_ci if (typeof buffer === "string") buffer = new Buffer(buffer); 1291cb0ef41Sopenharmony_ci var n; 1301cb0ef41Sopenharmony_ci for (var i = 0, l = buffer.length; i < l; i++) { 1311cb0ef41Sopenharmony_ci if (this.tState === START){ 1321cb0ef41Sopenharmony_ci n = buffer[i]; 1331cb0ef41Sopenharmony_ci this.offset++; 1341cb0ef41Sopenharmony_ci if(n === 0x7b){ this.onToken(LEFT_BRACE, "{"); // { 1351cb0ef41Sopenharmony_ci }else if(n === 0x7d){ this.onToken(RIGHT_BRACE, "}"); // } 1361cb0ef41Sopenharmony_ci }else if(n === 0x5b){ this.onToken(LEFT_BRACKET, "["); // [ 1371cb0ef41Sopenharmony_ci }else if(n === 0x5d){ this.onToken(RIGHT_BRACKET, "]"); // ] 1381cb0ef41Sopenharmony_ci }else if(n === 0x3a){ this.onToken(COLON, ":"); // : 1391cb0ef41Sopenharmony_ci }else if(n === 0x2c){ this.onToken(COMMA, ","); // , 1401cb0ef41Sopenharmony_ci }else if(n === 0x74){ this.tState = TRUE1; // t 1411cb0ef41Sopenharmony_ci }else if(n === 0x66){ this.tState = FALSE1; // f 1421cb0ef41Sopenharmony_ci }else if(n === 0x6e){ this.tState = NULL1; // n 1431cb0ef41Sopenharmony_ci }else if(n === 0x22){ // " 1441cb0ef41Sopenharmony_ci this.string = ""; 1451cb0ef41Sopenharmony_ci this.stringBufferOffset = 0; 1461cb0ef41Sopenharmony_ci this.tState = STRING1; 1471cb0ef41Sopenharmony_ci }else if(n === 0x2d){ this.string = "-"; this.tState = NUMBER1; // - 1481cb0ef41Sopenharmony_ci }else{ 1491cb0ef41Sopenharmony_ci if (n >= 0x30 && n < 0x40) { // 1-9 1501cb0ef41Sopenharmony_ci this.string = String.fromCharCode(n); this.tState = NUMBER3; 1511cb0ef41Sopenharmony_ci } else if (n === 0x20 || n === 0x09 || n === 0x0a || n === 0x0d) { 1521cb0ef41Sopenharmony_ci // whitespace 1531cb0ef41Sopenharmony_ci } else { 1541cb0ef41Sopenharmony_ci return this.charError(buffer, i); 1551cb0ef41Sopenharmony_ci } 1561cb0ef41Sopenharmony_ci } 1571cb0ef41Sopenharmony_ci }else if (this.tState === STRING1){ // After open quote 1581cb0ef41Sopenharmony_ci n = buffer[i]; // get current byte from buffer 1591cb0ef41Sopenharmony_ci // check for carry over of a multi byte char split between data chunks 1601cb0ef41Sopenharmony_ci // & fill temp buffer it with start of this data chunk up to the boundary limit set in the last iteration 1611cb0ef41Sopenharmony_ci if (this.bytes_remaining > 0) { 1621cb0ef41Sopenharmony_ci for (var j = 0; j < this.bytes_remaining; j++) { 1631cb0ef41Sopenharmony_ci this.temp_buffs[this.bytes_in_sequence][this.bytes_in_sequence - this.bytes_remaining + j] = buffer[j]; 1641cb0ef41Sopenharmony_ci } 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci this.appendStringBuf(this.temp_buffs[this.bytes_in_sequence]); 1671cb0ef41Sopenharmony_ci this.bytes_in_sequence = this.bytes_remaining = 0; 1681cb0ef41Sopenharmony_ci i = i + j - 1; 1691cb0ef41Sopenharmony_ci } else if (this.bytes_remaining === 0 && n >= 128) { // else if no remainder bytes carried over, parse multi byte (>=128) chars one at a time 1701cb0ef41Sopenharmony_ci if (n <= 193 || n > 244) { 1711cb0ef41Sopenharmony_ci return this.onError(new Error("Invalid UTF-8 character at position " + i + " in state " + Parser.toknam(this.tState))); 1721cb0ef41Sopenharmony_ci } 1731cb0ef41Sopenharmony_ci if ((n >= 194) && (n <= 223)) this.bytes_in_sequence = 2; 1741cb0ef41Sopenharmony_ci if ((n >= 224) && (n <= 239)) this.bytes_in_sequence = 3; 1751cb0ef41Sopenharmony_ci if ((n >= 240) && (n <= 244)) this.bytes_in_sequence = 4; 1761cb0ef41Sopenharmony_ci if ((this.bytes_in_sequence + i) > buffer.length) { // if bytes needed to complete char fall outside buffer length, we have a boundary split 1771cb0ef41Sopenharmony_ci for (var k = 0; k <= (buffer.length - 1 - i); k++) { 1781cb0ef41Sopenharmony_ci this.temp_buffs[this.bytes_in_sequence][k] = buffer[i + k]; // fill temp buffer of correct size with bytes available in this chunk 1791cb0ef41Sopenharmony_ci } 1801cb0ef41Sopenharmony_ci this.bytes_remaining = (i + this.bytes_in_sequence) - buffer.length; 1811cb0ef41Sopenharmony_ci i = buffer.length - 1; 1821cb0ef41Sopenharmony_ci } else { 1831cb0ef41Sopenharmony_ci this.appendStringBuf(buffer, i, i + this.bytes_in_sequence); 1841cb0ef41Sopenharmony_ci i = i + this.bytes_in_sequence - 1; 1851cb0ef41Sopenharmony_ci } 1861cb0ef41Sopenharmony_ci } else if (n === 0x22) { 1871cb0ef41Sopenharmony_ci this.tState = START; 1881cb0ef41Sopenharmony_ci this.string += this.stringBuffer.toString('utf8', 0, this.stringBufferOffset); 1891cb0ef41Sopenharmony_ci this.stringBufferOffset = 0; 1901cb0ef41Sopenharmony_ci this.onToken(STRING, this.string); 1911cb0ef41Sopenharmony_ci this.offset += Buffer.byteLength(this.string, 'utf8') + 1; 1921cb0ef41Sopenharmony_ci this.string = undefined; 1931cb0ef41Sopenharmony_ci } 1941cb0ef41Sopenharmony_ci else if (n === 0x5c) { 1951cb0ef41Sopenharmony_ci this.tState = STRING2; 1961cb0ef41Sopenharmony_ci } 1971cb0ef41Sopenharmony_ci else if (n >= 0x20) { this.appendStringChar(n); } 1981cb0ef41Sopenharmony_ci else { 1991cb0ef41Sopenharmony_ci return this.charError(buffer, i); 2001cb0ef41Sopenharmony_ci } 2011cb0ef41Sopenharmony_ci }else if (this.tState === STRING2){ // After backslash 2021cb0ef41Sopenharmony_ci n = buffer[i]; 2031cb0ef41Sopenharmony_ci if(n === 0x22){ this.appendStringChar(n); this.tState = STRING1; 2041cb0ef41Sopenharmony_ci }else if(n === 0x5c){ this.appendStringChar(BACK_SLASH); this.tState = STRING1; 2051cb0ef41Sopenharmony_ci }else if(n === 0x2f){ this.appendStringChar(FORWARD_SLASH); this.tState = STRING1; 2061cb0ef41Sopenharmony_ci }else if(n === 0x62){ this.appendStringChar(BACKSPACE); this.tState = STRING1; 2071cb0ef41Sopenharmony_ci }else if(n === 0x66){ this.appendStringChar(FORM_FEED); this.tState = STRING1; 2081cb0ef41Sopenharmony_ci }else if(n === 0x6e){ this.appendStringChar(NEWLINE); this.tState = STRING1; 2091cb0ef41Sopenharmony_ci }else if(n === 0x72){ this.appendStringChar(CARRIAGE_RETURN); this.tState = STRING1; 2101cb0ef41Sopenharmony_ci }else if(n === 0x74){ this.appendStringChar(TAB); this.tState = STRING1; 2111cb0ef41Sopenharmony_ci }else if(n === 0x75){ this.unicode = ""; this.tState = STRING3; 2121cb0ef41Sopenharmony_ci }else{ 2131cb0ef41Sopenharmony_ci return this.charError(buffer, i); 2141cb0ef41Sopenharmony_ci } 2151cb0ef41Sopenharmony_ci }else if (this.tState === STRING3 || this.tState === STRING4 || this.tState === STRING5 || this.tState === STRING6){ // unicode hex codes 2161cb0ef41Sopenharmony_ci n = buffer[i]; 2171cb0ef41Sopenharmony_ci // 0-9 A-F a-f 2181cb0ef41Sopenharmony_ci if ((n >= 0x30 && n < 0x40) || (n > 0x40 && n <= 0x46) || (n > 0x60 && n <= 0x66)) { 2191cb0ef41Sopenharmony_ci this.unicode += String.fromCharCode(n); 2201cb0ef41Sopenharmony_ci if (this.tState++ === STRING6) { 2211cb0ef41Sopenharmony_ci var intVal = parseInt(this.unicode, 16); 2221cb0ef41Sopenharmony_ci this.unicode = undefined; 2231cb0ef41Sopenharmony_ci if (this.highSurrogate !== undefined && intVal >= 0xDC00 && intVal < (0xDFFF + 1)) { //<56320,57343> - lowSurrogate 2241cb0ef41Sopenharmony_ci this.appendStringBuf(new Buffer(String.fromCharCode(this.highSurrogate, intVal))); 2251cb0ef41Sopenharmony_ci this.highSurrogate = undefined; 2261cb0ef41Sopenharmony_ci } else if (this.highSurrogate === undefined && intVal >= 0xD800 && intVal < (0xDBFF + 1)) { //<55296,56319> - highSurrogate 2271cb0ef41Sopenharmony_ci this.highSurrogate = intVal; 2281cb0ef41Sopenharmony_ci } else { 2291cb0ef41Sopenharmony_ci if (this.highSurrogate !== undefined) { 2301cb0ef41Sopenharmony_ci this.appendStringBuf(new Buffer(String.fromCharCode(this.highSurrogate))); 2311cb0ef41Sopenharmony_ci this.highSurrogate = undefined; 2321cb0ef41Sopenharmony_ci } 2331cb0ef41Sopenharmony_ci this.appendStringBuf(new Buffer(String.fromCharCode(intVal))); 2341cb0ef41Sopenharmony_ci } 2351cb0ef41Sopenharmony_ci this.tState = STRING1; 2361cb0ef41Sopenharmony_ci } 2371cb0ef41Sopenharmony_ci } else { 2381cb0ef41Sopenharmony_ci return this.charError(buffer, i); 2391cb0ef41Sopenharmony_ci } 2401cb0ef41Sopenharmony_ci } else if (this.tState === NUMBER1 || this.tState === NUMBER3) { 2411cb0ef41Sopenharmony_ci n = buffer[i]; 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci switch (n) { 2441cb0ef41Sopenharmony_ci case 0x30: // 0 2451cb0ef41Sopenharmony_ci case 0x31: // 1 2461cb0ef41Sopenharmony_ci case 0x32: // 2 2471cb0ef41Sopenharmony_ci case 0x33: // 3 2481cb0ef41Sopenharmony_ci case 0x34: // 4 2491cb0ef41Sopenharmony_ci case 0x35: // 5 2501cb0ef41Sopenharmony_ci case 0x36: // 6 2511cb0ef41Sopenharmony_ci case 0x37: // 7 2521cb0ef41Sopenharmony_ci case 0x38: // 8 2531cb0ef41Sopenharmony_ci case 0x39: // 9 2541cb0ef41Sopenharmony_ci case 0x2e: // . 2551cb0ef41Sopenharmony_ci case 0x65: // e 2561cb0ef41Sopenharmony_ci case 0x45: // E 2571cb0ef41Sopenharmony_ci case 0x2b: // + 2581cb0ef41Sopenharmony_ci case 0x2d: // - 2591cb0ef41Sopenharmony_ci this.string += String.fromCharCode(n); 2601cb0ef41Sopenharmony_ci this.tState = NUMBER3; 2611cb0ef41Sopenharmony_ci break; 2621cb0ef41Sopenharmony_ci default: 2631cb0ef41Sopenharmony_ci this.tState = START; 2641cb0ef41Sopenharmony_ci var result = Number(this.string); 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_ci if (isNaN(result)){ 2671cb0ef41Sopenharmony_ci return this.charError(buffer, i); 2681cb0ef41Sopenharmony_ci } 2691cb0ef41Sopenharmony_ci 2701cb0ef41Sopenharmony_ci if ((this.string.match(/[0-9]+/) == this.string) && (result.toString() != this.string)) { 2711cb0ef41Sopenharmony_ci // Long string of digits which is an ID string and not valid and/or safe JavaScript integer Number 2721cb0ef41Sopenharmony_ci this.onToken(STRING, this.string); 2731cb0ef41Sopenharmony_ci } else { 2741cb0ef41Sopenharmony_ci this.onToken(NUMBER, result); 2751cb0ef41Sopenharmony_ci } 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ci this.offset += this.string.length - 1; 2781cb0ef41Sopenharmony_ci this.string = undefined; 2791cb0ef41Sopenharmony_ci i--; 2801cb0ef41Sopenharmony_ci break; 2811cb0ef41Sopenharmony_ci } 2821cb0ef41Sopenharmony_ci }else if (this.tState === TRUE1){ // r 2831cb0ef41Sopenharmony_ci if (buffer[i] === 0x72) { this.tState = TRUE2; } 2841cb0ef41Sopenharmony_ci else { return this.charError(buffer, i); } 2851cb0ef41Sopenharmony_ci }else if (this.tState === TRUE2){ // u 2861cb0ef41Sopenharmony_ci if (buffer[i] === 0x75) { this.tState = TRUE3; } 2871cb0ef41Sopenharmony_ci else { return this.charError(buffer, i); } 2881cb0ef41Sopenharmony_ci }else if (this.tState === TRUE3){ // e 2891cb0ef41Sopenharmony_ci if (buffer[i] === 0x65) { this.tState = START; this.onToken(TRUE, true); this.offset+= 3; } 2901cb0ef41Sopenharmony_ci else { return this.charError(buffer, i); } 2911cb0ef41Sopenharmony_ci }else if (this.tState === FALSE1){ // a 2921cb0ef41Sopenharmony_ci if (buffer[i] === 0x61) { this.tState = FALSE2; } 2931cb0ef41Sopenharmony_ci else { return this.charError(buffer, i); } 2941cb0ef41Sopenharmony_ci }else if (this.tState === FALSE2){ // l 2951cb0ef41Sopenharmony_ci if (buffer[i] === 0x6c) { this.tState = FALSE3; } 2961cb0ef41Sopenharmony_ci else { return this.charError(buffer, i); } 2971cb0ef41Sopenharmony_ci }else if (this.tState === FALSE3){ // s 2981cb0ef41Sopenharmony_ci if (buffer[i] === 0x73) { this.tState = FALSE4; } 2991cb0ef41Sopenharmony_ci else { return this.charError(buffer, i); } 3001cb0ef41Sopenharmony_ci }else if (this.tState === FALSE4){ // e 3011cb0ef41Sopenharmony_ci if (buffer[i] === 0x65) { this.tState = START; this.onToken(FALSE, false); this.offset+= 4; } 3021cb0ef41Sopenharmony_ci else { return this.charError(buffer, i); } 3031cb0ef41Sopenharmony_ci }else if (this.tState === NULL1){ // u 3041cb0ef41Sopenharmony_ci if (buffer[i] === 0x75) { this.tState = NULL2; } 3051cb0ef41Sopenharmony_ci else { return this.charError(buffer, i); } 3061cb0ef41Sopenharmony_ci }else if (this.tState === NULL2){ // l 3071cb0ef41Sopenharmony_ci if (buffer[i] === 0x6c) { this.tState = NULL3; } 3081cb0ef41Sopenharmony_ci else { return this.charError(buffer, i); } 3091cb0ef41Sopenharmony_ci }else if (this.tState === NULL3){ // l 3101cb0ef41Sopenharmony_ci if (buffer[i] === 0x6c) { this.tState = START; this.onToken(NULL, null); this.offset += 3; } 3111cb0ef41Sopenharmony_ci else { return this.charError(buffer, i); } 3121cb0ef41Sopenharmony_ci } 3131cb0ef41Sopenharmony_ci } 3141cb0ef41Sopenharmony_ci}; 3151cb0ef41Sopenharmony_ciproto.onToken = function (token, value) { 3161cb0ef41Sopenharmony_ci // Override this to get events 3171cb0ef41Sopenharmony_ci}; 3181cb0ef41Sopenharmony_ci 3191cb0ef41Sopenharmony_ciproto.parseError = function (token, value) { 3201cb0ef41Sopenharmony_ci this.tState = STOP; 3211cb0ef41Sopenharmony_ci this.onError(new Error("Unexpected " + Parser.toknam(token) + (value ? ("(" + JSON.stringify(value) + ")") : "") + " in state " + Parser.toknam(this.state))); 3221cb0ef41Sopenharmony_ci}; 3231cb0ef41Sopenharmony_ciproto.push = function () { 3241cb0ef41Sopenharmony_ci this.stack.push({value: this.value, key: this.key, mode: this.mode}); 3251cb0ef41Sopenharmony_ci}; 3261cb0ef41Sopenharmony_ciproto.pop = function () { 3271cb0ef41Sopenharmony_ci var value = this.value; 3281cb0ef41Sopenharmony_ci var parent = this.stack.pop(); 3291cb0ef41Sopenharmony_ci this.value = parent.value; 3301cb0ef41Sopenharmony_ci this.key = parent.key; 3311cb0ef41Sopenharmony_ci this.mode = parent.mode; 3321cb0ef41Sopenharmony_ci this.emit(value); 3331cb0ef41Sopenharmony_ci if (!this.mode) { this.state = VALUE; } 3341cb0ef41Sopenharmony_ci}; 3351cb0ef41Sopenharmony_ciproto.emit = function (value) { 3361cb0ef41Sopenharmony_ci if (this.mode) { this.state = COMMA; } 3371cb0ef41Sopenharmony_ci this.onValue(value); 3381cb0ef41Sopenharmony_ci}; 3391cb0ef41Sopenharmony_ciproto.onValue = function (value) { 3401cb0ef41Sopenharmony_ci // Override me 3411cb0ef41Sopenharmony_ci}; 3421cb0ef41Sopenharmony_ciproto.onToken = function (token, value) { 3431cb0ef41Sopenharmony_ci if(this.state === VALUE){ 3441cb0ef41Sopenharmony_ci if(token === STRING || token === NUMBER || token === TRUE || token === FALSE || token === NULL){ 3451cb0ef41Sopenharmony_ci if (this.value) { 3461cb0ef41Sopenharmony_ci this.value[this.key] = value; 3471cb0ef41Sopenharmony_ci } 3481cb0ef41Sopenharmony_ci this.emit(value); 3491cb0ef41Sopenharmony_ci }else if(token === LEFT_BRACE){ 3501cb0ef41Sopenharmony_ci this.push(); 3511cb0ef41Sopenharmony_ci if (this.value) { 3521cb0ef41Sopenharmony_ci this.value = this.value[this.key] = {}; 3531cb0ef41Sopenharmony_ci } else { 3541cb0ef41Sopenharmony_ci this.value = {}; 3551cb0ef41Sopenharmony_ci } 3561cb0ef41Sopenharmony_ci this.key = undefined; 3571cb0ef41Sopenharmony_ci this.state = KEY; 3581cb0ef41Sopenharmony_ci this.mode = OBJECT; 3591cb0ef41Sopenharmony_ci }else if(token === LEFT_BRACKET){ 3601cb0ef41Sopenharmony_ci this.push(); 3611cb0ef41Sopenharmony_ci if (this.value) { 3621cb0ef41Sopenharmony_ci this.value = this.value[this.key] = []; 3631cb0ef41Sopenharmony_ci } else { 3641cb0ef41Sopenharmony_ci this.value = []; 3651cb0ef41Sopenharmony_ci } 3661cb0ef41Sopenharmony_ci this.key = 0; 3671cb0ef41Sopenharmony_ci this.mode = ARRAY; 3681cb0ef41Sopenharmony_ci this.state = VALUE; 3691cb0ef41Sopenharmony_ci }else if(token === RIGHT_BRACE){ 3701cb0ef41Sopenharmony_ci if (this.mode === OBJECT) { 3711cb0ef41Sopenharmony_ci this.pop(); 3721cb0ef41Sopenharmony_ci } else { 3731cb0ef41Sopenharmony_ci return this.parseError(token, value); 3741cb0ef41Sopenharmony_ci } 3751cb0ef41Sopenharmony_ci }else if(token === RIGHT_BRACKET){ 3761cb0ef41Sopenharmony_ci if (this.mode === ARRAY) { 3771cb0ef41Sopenharmony_ci this.pop(); 3781cb0ef41Sopenharmony_ci } else { 3791cb0ef41Sopenharmony_ci return this.parseError(token, value); 3801cb0ef41Sopenharmony_ci } 3811cb0ef41Sopenharmony_ci }else{ 3821cb0ef41Sopenharmony_ci return this.parseError(token, value); 3831cb0ef41Sopenharmony_ci } 3841cb0ef41Sopenharmony_ci }else if(this.state === KEY){ 3851cb0ef41Sopenharmony_ci if (token === STRING) { 3861cb0ef41Sopenharmony_ci this.key = value; 3871cb0ef41Sopenharmony_ci this.state = COLON; 3881cb0ef41Sopenharmony_ci } else if (token === RIGHT_BRACE) { 3891cb0ef41Sopenharmony_ci this.pop(); 3901cb0ef41Sopenharmony_ci } else { 3911cb0ef41Sopenharmony_ci return this.parseError(token, value); 3921cb0ef41Sopenharmony_ci } 3931cb0ef41Sopenharmony_ci }else if(this.state === COLON){ 3941cb0ef41Sopenharmony_ci if (token === COLON) { this.state = VALUE; } 3951cb0ef41Sopenharmony_ci else { return this.parseError(token, value); } 3961cb0ef41Sopenharmony_ci }else if(this.state === COMMA){ 3971cb0ef41Sopenharmony_ci if (token === COMMA) { 3981cb0ef41Sopenharmony_ci if (this.mode === ARRAY) { this.key++; this.state = VALUE; } 3991cb0ef41Sopenharmony_ci else if (this.mode === OBJECT) { this.state = KEY; } 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ci } else if (token === RIGHT_BRACKET && this.mode === ARRAY || token === RIGHT_BRACE && this.mode === OBJECT) { 4021cb0ef41Sopenharmony_ci this.pop(); 4031cb0ef41Sopenharmony_ci } else { 4041cb0ef41Sopenharmony_ci return this.parseError(token, value); 4051cb0ef41Sopenharmony_ci } 4061cb0ef41Sopenharmony_ci }else{ 4071cb0ef41Sopenharmony_ci return this.parseError(token, value); 4081cb0ef41Sopenharmony_ci } 4091cb0ef41Sopenharmony_ci}; 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_ciParser.C = C; 4121cb0ef41Sopenharmony_ci 4131cb0ef41Sopenharmony_cimodule.exports = Parser; 414