@@ -15,6 +15,7 @@ var STRING = C.STRING = 0xa;
1515var NUMBER = C . NUMBER = 0xb ;
1616// Tokenizer States
1717var START = C . START = 0x11 ;
18+ var STOP = C . STOP = 0x12 ;
1819var TRUE1 = C . TRUE1 = 0x21 ;
1920var TRUE2 = C . TRUE2 = 0x22 ;
2021var TRUE3 = C . TRUE3 = 0x23 ;
@@ -46,16 +47,6 @@ var KEY = C.KEY = 0x72;
4647var OBJECT = C . OBJECT = 0x81 ;
4748var ARRAY = C . ARRAY = 0x82 ;
4849
49- // Slow code to string converter (only used when throwing syntax errors)
50- function toknam ( code ) {
51- var keys = Object . keys ( C ) ;
52- for ( var i = 0 , l = keys . length ; i < l ; i ++ ) {
53- var key = keys [ i ] ;
54- if ( C [ key ] === code ) { return key ; }
55- }
56- return code && ( "0x" + code . toString ( 16 ) ) ;
57- }
58-
5950
6051function Parser ( ) {
6152 this . tState = START ;
@@ -83,15 +74,25 @@ function Parser() {
8374 // Stream offset
8475 this . offset = - 1 ;
8576}
77+
78+ // Slow code to string converter (only used when throwing syntax errors)
79+ Parser . toknam = function ( code ) {
80+ var keys = Object . keys ( C ) ;
81+ for ( var i = 0 , l = keys . length ; i < l ; i ++ ) {
82+ var key = keys [ i ] ;
83+ if ( C [ key ] === code ) { return key ; }
84+ }
85+ return code && ( "0x" + code . toString ( 16 ) ) ;
86+ }
87+
8688var proto = Parser . prototype ;
89+ proto . onError = function ( err ) { throw err ; } ;
8790proto . charError = function ( buffer , i ) {
88- this . onError ( new Error ( "Unexpected " + JSON . stringify ( String . fromCharCode ( buffer [ i ] ) ) + " at position " + i + " in state " + toknam ( this . tState ) ) ) ;
91+ this . tState = STOP ;
92+ this . onError ( new Error ( "Unexpected " + JSON . stringify ( String . fromCharCode ( buffer [ i ] ) ) + " at position " + i + " in state " + Parser . toknam ( this . tState ) ) ) ;
8993} ;
90- proto . onError = function ( err ) { throw err ; } ;
9194proto . write = function ( buffer ) {
9295 if ( typeof buffer === "string" ) buffer = new Buffer ( buffer ) ;
93- //process.stdout.write("Input: ");
94- //console.dir(buffer.toString());
9596 var n ;
9697 for ( var i = 0 , l = buffer . length ; i < l ; i ++ ) {
9798 if ( this . tState === START ) {
@@ -114,7 +115,9 @@ proto.write = function (buffer) {
114115 this . magnatude = n - 0x30 ; this . tState = NUMBER3 ;
115116 } else if ( n === 0x20 || n === 0x09 || n === 0x0a || n === 0x0d ) {
116117 // whitespace
117- } else { this . charError ( buffer , i ) ; }
118+ } else {
119+ return this . charError ( buffer , i ) ;
120+ }
118121 }
119122 } else if ( this . tState === STRING1 ) { // After open quote
120123 n = buffer [ i ] ; // get current byte from buffer
@@ -129,8 +132,7 @@ proto.write = function (buffer) {
129132 i = i + j - 1 ;
130133 } else if ( this . bytes_remaining === 0 && n >= 128 ) { // else if no remainder bytes carried over, parse multi byte (>=128) chars one at a time
131134 if ( n <= 193 ) {
132- this . onError ( new Error ( "Invalid UTF-8 character at position " + i + " in state " + toknam ( this . tState ) ) ) ;
133- return
135+ return this . onError ( new Error ( "Invalid UTF-8 character at position " + i + " in state " + Parser . toknam ( this . tState ) ) ) ;
134136 }
135137 if ( ( n >= 194 ) && ( n <= 223 ) ) this . bytes_in_sequence = 2 ;
136138 if ( ( n >= 224 ) && ( n <= 239 ) ) this . bytes_in_sequence = 3 ;
@@ -148,7 +150,9 @@ proto.write = function (buffer) {
148150 } else if ( n === 0x22 ) { this . tState = START ; this . onToken ( STRING , this . string ) ; this . offset += Buffer . byteLength ( this . string , 'utf8' ) + 1 ; this . string = undefined ; }
149151 else if ( n === 0x5c ) { this . tState = STRING2 ; }
150152 else if ( n >= 0x20 ) { this . string += String . fromCharCode ( n ) ; }
151- else { this . charError ( buffer , i ) ; }
153+ else {
154+ return this . charError ( buffer , i ) ;
155+ }
152156 } else if ( this . tState === STRING2 ) { // After backslash
153157 n = buffer [ i ] ;
154158 if ( n === 0x22 ) { this . string += "\"" ; this . tState = STRING1 ;
@@ -161,7 +165,7 @@ proto.write = function (buffer) {
161165 } else if ( n === 0x74 ) { this . string += "\t" ; this . tState = STRING1 ;
162166 } else if ( n === 0x75 ) { this . unicode = "" ; this . tState = STRING3 ;
163167 } else {
164- this . charError ( buffer , i ) ;
168+ return this . charError ( buffer , i ) ;
165169 }
166170 } else if ( this . tState === STRING3 || this . tState === STRING4 || this . tState === STRING5 || this . tState === STRING6 ) { // unicode hex codes
167171 n = buffer [ i ] ;
@@ -174,14 +178,16 @@ proto.write = function (buffer) {
174178 this . tState = STRING1 ;
175179 }
176180 } else {
177- this . charError ( buffer , i ) ;
181+ return this . charError ( buffer , i ) ;
178182 }
179183 } else if ( this . tState === NUMBER1 ) { // after minus
180184 n = buffer [ i ] ;
181185 this . numberLength ++ ;
182186 if ( n === 0x30 ) { this . magnatude = 0 ; this . tState = NUMBER2 ; }
183187 else if ( n > 0x30 && n < 0x40 ) { this . magnatude = n - 0x30 ; this . tState = NUMBER3 ; }
184- else { this . charError ( buffer , i ) ; }
188+ else {
189+ return this . charError ( buffer , i ) ;
190+ }
185191 } else if ( this . tState === NUMBER2 ) { // * After initial zero
186192 n = buffer [ i ] ;
187193 this . numberLength ++ ;
@@ -227,7 +233,9 @@ proto.write = function (buffer) {
227233 this . magnatude += this . position * ( n - 0x30 ) ;
228234 this . position /= 10 ;
229235 this . tState = NUMBER5 ;
230- } else { this . charError ( buffer , i ) ; }
236+ } else {
237+ return this . charError ( buffer , i ) ;
238+ }
231239 } else if ( this . tState === NUMBER5 ) { // * After digit (after period)
232240 n = buffer [ i ] ;
233241 this . numberLength ++ ;
@@ -260,15 +268,19 @@ proto.write = function (buffer) {
260268 this . exponent = this . exponent * 10 + ( n - 0x30 ) ;
261269 this . tState = NUMBER8 ;
262270 }
263- else { this . charError ( buffer , i ) ; }
271+ else {
272+ return this . charError ( buffer , i ) ;
273+ }
264274 } else if ( this . tState === NUMBER7 ) { // After +/-
265275 n = buffer [ i ] ;
266276 this . numberLength ++ ;
267277 if ( n >= 0x30 && n < 0x40 ) { // 0-9
268278 this . exponent = this . exponent * 10 + ( n - 0x30 ) ;
269279 this . tState = NUMBER8 ;
270280 }
271- else { this . charError ( buffer , i ) ; }
281+ else {
282+ return this . charError ( buffer , i ) ;
283+ }
272284 } else if ( this . tState === NUMBER8 ) { // * After digit (after +/-)
273285 n = buffer [ i ] ;
274286 this . numberLength ++ ;
@@ -295,34 +307,34 @@ proto.write = function (buffer) {
295307 }
296308 } else if ( this . tState === TRUE1 ) { // r
297309 if ( buffer [ i ] === 0x72 ) { this . tState = TRUE2 ; }
298- else { this . charError ( buffer , i ) ; }
310+ else { return this . charError ( buffer , i ) ; }
299311 } else if ( this . tState === TRUE2 ) { // u
300312 if ( buffer [ i ] === 0x75 ) { this . tState = TRUE3 ; }
301- else { this . charError ( buffer , i ) ; }
313+ else { return this . charError ( buffer , i ) ; }
302314 } else if ( this . tState === TRUE3 ) { // e
303315 if ( buffer [ i ] === 0x65 ) { this . tState = START ; this . onToken ( TRUE , true ) ; this . offset += 3 ; }
304- else { this . charError ( buffer , i ) ; }
316+ else { return this . charError ( buffer , i ) ; }
305317 } else if ( this . tState === FALSE1 ) { // a
306318 if ( buffer [ i ] === 0x61 ) { this . tState = FALSE2 ; }
307- else { this . charError ( buffer , i ) ; }
319+ else { return this . charError ( buffer , i ) ; }
308320 } else if ( this . tState === FALSE2 ) { // l
309321 if ( buffer [ i ] === 0x6c ) { this . tState = FALSE3 ; }
310- else { this . charError ( buffer , i ) ; }
322+ else { return this . charError ( buffer , i ) ; }
311323 } else if ( this . tState === FALSE3 ) { // s
312324 if ( buffer [ i ] === 0x73 ) { this . tState = FALSE4 ; }
313- else { this . charError ( buffer , i ) ; }
325+ else { return this . charError ( buffer , i ) ; }
314326 } else if ( this . tState === FALSE4 ) { // e
315327 if ( buffer [ i ] === 0x65 ) { this . tState = START ; this . onToken ( FALSE , false ) ; this . offset += 4 ; }
316- else { this . charError ( buffer , i ) ; }
328+ else { return this . charError ( buffer , i ) ; }
317329 } else if ( this . tState === NULL1 ) { // u
318330 if ( buffer [ i ] === 0x75 ) { this . tState = NULL2 ; }
319- else { this . charError ( buffer , i ) ; }
331+ else { return this . charError ( buffer , i ) ; }
320332 } else if ( this . tState === NULL2 ) { // l
321333 if ( buffer [ i ] === 0x6c ) { this . tState = NULL3 ; }
322- else { this . charError ( buffer , i ) ; }
334+ else { return this . charError ( buffer , i ) ; }
323335 } else if ( this . tState === NULL3 ) { // l
324336 if ( buffer [ i ] === 0x6c ) { this . tState = START ; this . onToken ( NULL , null ) ; this . offset += 3 ; }
325- else { this . charError ( buffer , i ) ; }
337+ else { return this . charError ( buffer , i ) ; }
326338 }
327339 }
328340} ;
@@ -331,7 +343,8 @@ proto.onToken = function (token, value) {
331343} ;
332344
333345proto . parseError = function ( token , value ) {
334- this . onError ( new Error ( "Unexpected " + toknam ( token ) + ( value ? ( "(" + JSON . stringify ( value ) + ")" ) : "" ) + " in state " + toknam ( this . state ) ) ) ;
346+ this . tState = STOP ;
347+ this . onError ( new Error ( "Unexpected " + Parser . toknam ( token ) + ( value ? ( "(" + JSON . stringify ( value ) + ")" ) : "" ) + " in state " + Parser . toknam ( this . state ) ) ) ;
335348} ;
336349proto . push = function ( ) {
337350 this . stack . push ( { value : this . value , key : this . key , mode : this . mode } ) ;
@@ -353,7 +366,6 @@ proto.onValue = function (value) {
353366 // Override me
354367} ;
355368proto . onToken = function ( token , value ) {
356- //console.log("OnToken: state=%s token=%s %s", toknam(this.state), toknam(token), value?JSON.stringify(value):"");
357369 if ( this . state === VALUE ) {
358370 if ( token === STRING || token === NUMBER || token === TRUE || token === FALSE || token === NULL ) {
359371 if ( this . value ) {
@@ -384,16 +396,16 @@ proto.onToken = function (token, value) {
384396 if ( this . mode === OBJECT ) {
385397 this . pop ( ) ;
386398 } else {
387- this . parseError ( token , value ) ;
399+ return this . parseError ( token , value ) ;
388400 }
389401 } else if ( token === RIGHT_BRACKET ) {
390402 if ( this . mode === ARRAY ) {
391403 this . pop ( ) ;
392404 } else {
393- this . parseError ( token , value ) ;
405+ return this . parseError ( token , value ) ;
394406 }
395407 } else {
396- this . parseError ( token , value ) ;
408+ return this . parseError ( token , value ) ;
397409 }
398410 } else if ( this . state === KEY ) {
399411 if ( token === STRING ) {
@@ -402,11 +414,11 @@ proto.onToken = function (token, value) {
402414 } else if ( token === RIGHT_BRACE ) {
403415 this . pop ( ) ;
404416 } else {
405- this . parseError ( token , value ) ;
417+ return this . parseError ( token , value ) ;
406418 }
407419 } else if ( this . state === COLON ) {
408420 if ( token === COLON ) { this . state = VALUE ; }
409- else { this . parseError ( token , value ) ; }
421+ else { return this . parseError ( token , value ) ; }
410422 } else if ( this . state === COMMA ) {
411423 if ( token === COMMA ) {
412424 if ( this . mode === ARRAY ) { this . key ++ ; this . state = VALUE ; }
@@ -415,10 +427,10 @@ proto.onToken = function (token, value) {
415427 } else if ( token === RIGHT_BRACKET && this . mode === ARRAY || token === RIGHT_BRACE && this . mode === OBJECT ) {
416428 this . pop ( ) ;
417429 } else {
418- this . parseError ( token , value ) ;
430+ return this . parseError ( token , value ) ;
419431 }
420432 } else {
421- this . parseError ( token , value ) ;
433+ return this . parseError ( token , value ) ;
422434 }
423435} ;
424436
0 commit comments