• Main Page
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

ext/json/parser/parser.c

Go to the documentation of this file.
00001 
00002 #line 1 "parser.rl"
00003 #include "parser.h"
00004 
00005 /* unicode */
00006 
00007 static const char digit_values[256] = {
00008     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00009     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00010     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
00011     -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
00012     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00013     10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00014     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00015     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00016     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00017     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00018     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00019     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00020     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00021     -1, -1, -1, -1, -1, -1, -1
00022 };
00023 
00024 static UTF32 unescape_unicode(const unsigned char *p)
00025 {
00026     char b;
00027     UTF32 result = 0;
00028     b = digit_values[p[0]];
00029     if (b < 0) return UNI_REPLACEMENT_CHAR;
00030     result = (result << 4) | b;
00031     b = digit_values[p[1]];
00032     result = (result << 4) | b;
00033     if (b < 0) return UNI_REPLACEMENT_CHAR;
00034     b = digit_values[p[2]];
00035     result = (result << 4) | b;
00036     if (b < 0) return UNI_REPLACEMENT_CHAR;
00037     b = digit_values[p[3]];
00038     result = (result << 4) | b;
00039     if (b < 0) return UNI_REPLACEMENT_CHAR;
00040     return result;
00041 }
00042 
00043 static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
00044 {
00045     int len = 1;
00046     if (ch <= 0x7F) {
00047         buf[0] = (char) ch;
00048     } else if (ch <= 0x07FF) {
00049         buf[0] = (char) ((ch >> 6) | 0xC0);
00050         buf[1] = (char) ((ch & 0x3F) | 0x80);
00051         len++;
00052     } else if (ch <= 0xFFFF) {
00053         buf[0] = (char) ((ch >> 12) | 0xE0);
00054         buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
00055         buf[2] = (char) ((ch & 0x3F) | 0x80);
00056         len += 2;
00057     } else if (ch <= 0x1fffff) {
00058         buf[0] =(char) ((ch >> 18) | 0xF0);
00059         buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
00060         buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
00061         buf[3] =(char) ((ch & 0x3F) | 0x80);
00062         len += 3;
00063     } else {
00064         buf[0] = '?';
00065     }
00066     return len;
00067 }
00068 
00069 #ifdef HAVE_RUBY_ENCODING_H
00070 static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
00071     CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
00072 static ID i_encoding, i_encode, i_encode_bang, i_force_encoding;
00073 #else
00074 static ID i_iconv;
00075 #endif
00076 
00077 static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
00078 static VALUE CNaN, CInfinity, CMinusInfinity;
00079 
00080 static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
00081           i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
00082           i_array_class, i_key_p, i_deep_const_get;
00083 
00084 
00085 #line 108 "parser.rl"
00086 
00087 
00088 
00089 #line 90 "parser.c"
00090 static const int JSON_object_start = 1;
00091 static const int JSON_object_first_final = 27;
00092 static const int JSON_object_error = 0;
00093 
00094 static const int JSON_object_en_main = 1;
00095 
00096 
00097 #line 144 "parser.rl"
00098 
00099 
00100 static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
00101 {
00102     int cs = EVIL;
00103     VALUE last_name = Qnil;
00104     VALUE object_class = json->object_class;
00105 
00106     if (json->max_nesting && json->current_nesting > json->max_nesting) {
00107         rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
00108     }
00109 
00110     *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
00111 
00112     
00113 #line 114 "parser.c"
00114         {
00115         cs = JSON_object_start;
00116         }
00117 
00118 #line 159 "parser.rl"
00119     
00120 #line 121 "parser.c"
00121         {
00122         if ( p == pe )
00123                 goto _test_eof;
00124         switch ( cs )
00125         {
00126 case 1:
00127         if ( (*p) == 123 )
00128                 goto st2;
00129         goto st0;
00130 st0:
00131 cs = 0;
00132         goto _out;
00133 st2:
00134         if ( ++p == pe )
00135                 goto _test_eof2;
00136 case 2:
00137         switch( (*p) ) {
00138                 case 13: goto st2;
00139                 case 32: goto st2;
00140                 case 34: goto tr2;
00141                 case 47: goto st23;
00142                 case 125: goto tr4;
00143         }
00144         if ( 9 <= (*p) && (*p) <= 10 )
00145                 goto st2;
00146         goto st0;
00147 tr2:
00148 #line 127 "parser.rl"
00149         {
00150         char *np;
00151         json->parsing_name = 1;
00152         np = JSON_parse_string(json, p, pe, &last_name);
00153         json->parsing_name = 0;
00154         if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;}
00155     }
00156         goto st3;
00157 st3:
00158         if ( ++p == pe )
00159                 goto _test_eof3;
00160 case 3:
00161 #line 162 "parser.c"
00162         switch( (*p) ) {
00163                 case 13: goto st3;
00164                 case 32: goto st3;
00165                 case 47: goto st4;
00166                 case 58: goto st8;
00167         }
00168         if ( 9 <= (*p) && (*p) <= 10 )
00169                 goto st3;
00170         goto st0;
00171 st4:
00172         if ( ++p == pe )
00173                 goto _test_eof4;
00174 case 4:
00175         switch( (*p) ) {
00176                 case 42: goto st5;
00177                 case 47: goto st7;
00178         }
00179         goto st0;
00180 st5:
00181         if ( ++p == pe )
00182                 goto _test_eof5;
00183 case 5:
00184         if ( (*p) == 42 )
00185                 goto st6;
00186         goto st5;
00187 st6:
00188         if ( ++p == pe )
00189                 goto _test_eof6;
00190 case 6:
00191         switch( (*p) ) {
00192                 case 42: goto st6;
00193                 case 47: goto st3;
00194         }
00195         goto st5;
00196 st7:
00197         if ( ++p == pe )
00198                 goto _test_eof7;
00199 case 7:
00200         if ( (*p) == 10 )
00201                 goto st3;
00202         goto st7;
00203 st8:
00204         if ( ++p == pe )
00205                 goto _test_eof8;
00206 case 8:
00207         switch( (*p) ) {
00208                 case 13: goto st8;
00209                 case 32: goto st8;
00210                 case 34: goto tr11;
00211                 case 45: goto tr11;
00212                 case 47: goto st19;
00213                 case 73: goto tr11;
00214                 case 78: goto tr11;
00215                 case 91: goto tr11;
00216                 case 102: goto tr11;
00217                 case 110: goto tr11;
00218                 case 116: goto tr11;
00219                 case 123: goto tr11;
00220         }
00221         if ( (*p) > 10 ) {
00222                 if ( 48 <= (*p) && (*p) <= 57 )
00223                         goto tr11;
00224         } else if ( (*p) >= 9 )
00225                 goto st8;
00226         goto st0;
00227 tr11:
00228 #line 116 "parser.rl"
00229         {
00230         VALUE v = Qnil;
00231         char *np = JSON_parse_value(json, p, pe, &v);
00232         if (np == NULL) {
00233             p--; {p++; cs = 9; goto _out;}
00234         } else {
00235             rb_hash_aset(*result, last_name, v);
00236             {p = (( np))-1;}
00237         }
00238     }
00239         goto st9;
00240 st9:
00241         if ( ++p == pe )
00242                 goto _test_eof9;
00243 case 9:
00244 #line 245 "parser.c"
00245         switch( (*p) ) {
00246                 case 13: goto st9;
00247                 case 32: goto st9;
00248                 case 44: goto st10;
00249                 case 47: goto st15;
00250                 case 125: goto tr4;
00251         }
00252         if ( 9 <= (*p) && (*p) <= 10 )
00253                 goto st9;
00254         goto st0;
00255 st10:
00256         if ( ++p == pe )
00257                 goto _test_eof10;
00258 case 10:
00259         switch( (*p) ) {
00260                 case 13: goto st10;
00261                 case 32: goto st10;
00262                 case 34: goto tr2;
00263                 case 47: goto st11;
00264         }
00265         if ( 9 <= (*p) && (*p) <= 10 )
00266                 goto st10;
00267         goto st0;
00268 st11:
00269         if ( ++p == pe )
00270                 goto _test_eof11;
00271 case 11:
00272         switch( (*p) ) {
00273                 case 42: goto st12;
00274                 case 47: goto st14;
00275         }
00276         goto st0;
00277 st12:
00278         if ( ++p == pe )
00279                 goto _test_eof12;
00280 case 12:
00281         if ( (*p) == 42 )
00282                 goto st13;
00283         goto st12;
00284 st13:
00285         if ( ++p == pe )
00286                 goto _test_eof13;
00287 case 13:
00288         switch( (*p) ) {
00289                 case 42: goto st13;
00290                 case 47: goto st10;
00291         }
00292         goto st12;
00293 st14:
00294         if ( ++p == pe )
00295                 goto _test_eof14;
00296 case 14:
00297         if ( (*p) == 10 )
00298                 goto st10;
00299         goto st14;
00300 st15:
00301         if ( ++p == pe )
00302                 goto _test_eof15;
00303 case 15:
00304         switch( (*p) ) {
00305                 case 42: goto st16;
00306                 case 47: goto st18;
00307         }
00308         goto st0;
00309 st16:
00310         if ( ++p == pe )
00311                 goto _test_eof16;
00312 case 16:
00313         if ( (*p) == 42 )
00314                 goto st17;
00315         goto st16;
00316 st17:
00317         if ( ++p == pe )
00318                 goto _test_eof17;
00319 case 17:
00320         switch( (*p) ) {
00321                 case 42: goto st17;
00322                 case 47: goto st9;
00323         }
00324         goto st16;
00325 st18:
00326         if ( ++p == pe )
00327                 goto _test_eof18;
00328 case 18:
00329         if ( (*p) == 10 )
00330                 goto st9;
00331         goto st18;
00332 tr4:
00333 #line 135 "parser.rl"
00334         { p--; {p++; cs = 27; goto _out;} }
00335         goto st27;
00336 st27:
00337         if ( ++p == pe )
00338                 goto _test_eof27;
00339 case 27:
00340 #line 341 "parser.c"
00341         goto st0;
00342 st19:
00343         if ( ++p == pe )
00344                 goto _test_eof19;
00345 case 19:
00346         switch( (*p) ) {
00347                 case 42: goto st20;
00348                 case 47: goto st22;
00349         }
00350         goto st0;
00351 st20:
00352         if ( ++p == pe )
00353                 goto _test_eof20;
00354 case 20:
00355         if ( (*p) == 42 )
00356                 goto st21;
00357         goto st20;
00358 st21:
00359         if ( ++p == pe )
00360                 goto _test_eof21;
00361 case 21:
00362         switch( (*p) ) {
00363                 case 42: goto st21;
00364                 case 47: goto st8;
00365         }
00366         goto st20;
00367 st22:
00368         if ( ++p == pe )
00369                 goto _test_eof22;
00370 case 22:
00371         if ( (*p) == 10 )
00372                 goto st8;
00373         goto st22;
00374 st23:
00375         if ( ++p == pe )
00376                 goto _test_eof23;
00377 case 23:
00378         switch( (*p) ) {
00379                 case 42: goto st24;
00380                 case 47: goto st26;
00381         }
00382         goto st0;
00383 st24:
00384         if ( ++p == pe )
00385                 goto _test_eof24;
00386 case 24:
00387         if ( (*p) == 42 )
00388                 goto st25;
00389         goto st24;
00390 st25:
00391         if ( ++p == pe )
00392                 goto _test_eof25;
00393 case 25:
00394         switch( (*p) ) {
00395                 case 42: goto st25;
00396                 case 47: goto st2;
00397         }
00398         goto st24;
00399 st26:
00400         if ( ++p == pe )
00401                 goto _test_eof26;
00402 case 26:
00403         if ( (*p) == 10 )
00404                 goto st2;
00405         goto st26;
00406         }
00407         _test_eof2: cs = 2; goto _test_eof; 
00408         _test_eof3: cs = 3; goto _test_eof; 
00409         _test_eof4: cs = 4; goto _test_eof; 
00410         _test_eof5: cs = 5; goto _test_eof; 
00411         _test_eof6: cs = 6; goto _test_eof; 
00412         _test_eof7: cs = 7; goto _test_eof; 
00413         _test_eof8: cs = 8; goto _test_eof; 
00414         _test_eof9: cs = 9; goto _test_eof; 
00415         _test_eof10: cs = 10; goto _test_eof; 
00416         _test_eof11: cs = 11; goto _test_eof; 
00417         _test_eof12: cs = 12; goto _test_eof; 
00418         _test_eof13: cs = 13; goto _test_eof; 
00419         _test_eof14: cs = 14; goto _test_eof; 
00420         _test_eof15: cs = 15; goto _test_eof; 
00421         _test_eof16: cs = 16; goto _test_eof; 
00422         _test_eof17: cs = 17; goto _test_eof; 
00423         _test_eof18: cs = 18; goto _test_eof; 
00424         _test_eof27: cs = 27; goto _test_eof; 
00425         _test_eof19: cs = 19; goto _test_eof; 
00426         _test_eof20: cs = 20; goto _test_eof; 
00427         _test_eof21: cs = 21; goto _test_eof; 
00428         _test_eof22: cs = 22; goto _test_eof; 
00429         _test_eof23: cs = 23; goto _test_eof; 
00430         _test_eof24: cs = 24; goto _test_eof; 
00431         _test_eof25: cs = 25; goto _test_eof; 
00432         _test_eof26: cs = 26; goto _test_eof; 
00433 
00434         _test_eof: {}
00435         _out: {}
00436         }
00437 
00438 #line 160 "parser.rl"
00439 
00440     if (cs >= JSON_object_first_final) {
00441         if (RTEST(json->create_id)) {
00442             VALUE klassname = rb_hash_aref(*result, json->create_id);
00443             if (!NIL_P(klassname)) {
00444                 VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
00445                 if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) {
00446                     *result = rb_funcall(klass, i_json_create, 1, *result);
00447                 }
00448             }
00449         }
00450         return p + 1;
00451     } else {
00452         return NULL;
00453     }
00454 }
00455 
00456 
00457 #line 458 "parser.c"
00458 static const int JSON_value_start = 1;
00459 static const int JSON_value_first_final = 21;
00460 static const int JSON_value_error = 0;
00461 
00462 static const int JSON_value_en_main = 1;
00463 
00464 
00465 #line 258 "parser.rl"
00466 
00467 
00468 static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
00469 {
00470     int cs = EVIL;
00471 
00472     
00473 #line 474 "parser.c"
00474         {
00475         cs = JSON_value_start;
00476         }
00477 
00478 #line 265 "parser.rl"
00479     
00480 #line 481 "parser.c"
00481         {
00482         if ( p == pe )
00483                 goto _test_eof;
00484         switch ( cs )
00485         {
00486 case 1:
00487         switch( (*p) ) {
00488                 case 34: goto tr0;
00489                 case 45: goto tr2;
00490                 case 73: goto st2;
00491                 case 78: goto st9;
00492                 case 91: goto tr5;
00493                 case 102: goto st11;
00494                 case 110: goto st15;
00495                 case 116: goto st18;
00496                 case 123: goto tr9;
00497         }
00498         if ( 48 <= (*p) && (*p) <= 57 )
00499                 goto tr2;
00500         goto st0;
00501 st0:
00502 cs = 0;
00503         goto _out;
00504 tr0:
00505 #line 206 "parser.rl"
00506         {
00507         char *np = JSON_parse_string(json, p, pe, result);
00508         if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
00509     }
00510         goto st21;
00511 tr2:
00512 #line 211 "parser.rl"
00513         {
00514         char *np;
00515         if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) {
00516             if (json->allow_nan) {
00517                 *result = CMinusInfinity;
00518                 {p = (( p + 10))-1;}
00519                 p--; {p++; cs = 21; goto _out;}
00520             } else {
00521                 rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
00522             }
00523         }
00524         np = JSON_parse_float(json, p, pe, result);
00525         if (np != NULL) {p = (( np))-1;}
00526         np = JSON_parse_integer(json, p, pe, result);
00527         if (np != NULL) {p = (( np))-1;}
00528         p--; {p++; cs = 21; goto _out;}
00529     }
00530         goto st21;
00531 tr5:
00532 #line 229 "parser.rl"
00533         {
00534         char *np;
00535         json->current_nesting++;
00536         np = JSON_parse_array(json, p, pe, result);
00537         json->current_nesting--;
00538         if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
00539     }
00540         goto st21;
00541 tr9:
00542 #line 237 "parser.rl"
00543         {
00544         char *np;
00545         json->current_nesting++;
00546         np =  JSON_parse_object(json, p, pe, result);
00547         json->current_nesting--;
00548         if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
00549     }
00550         goto st21;
00551 tr16:
00552 #line 199 "parser.rl"
00553         {
00554         if (json->allow_nan) {
00555             *result = CInfinity;
00556         } else {
00557             rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
00558         }
00559     }
00560         goto st21;
00561 tr18:
00562 #line 192 "parser.rl"
00563         {
00564         if (json->allow_nan) {
00565             *result = CNaN;
00566         } else {
00567             rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
00568         }
00569     }
00570         goto st21;
00571 tr22:
00572 #line 186 "parser.rl"
00573         {
00574         *result = Qfalse;
00575     }
00576         goto st21;
00577 tr25:
00578 #line 183 "parser.rl"
00579         {
00580         *result = Qnil;
00581     }
00582         goto st21;
00583 tr28:
00584 #line 189 "parser.rl"
00585         {
00586         *result = Qtrue;
00587     }
00588         goto st21;
00589 st21:
00590         if ( ++p == pe )
00591                 goto _test_eof21;
00592 case 21:
00593 #line 245 "parser.rl"
00594         { p--; {p++; cs = 21; goto _out;} }
00595 #line 596 "parser.c"
00596         goto st0;
00597 st2:
00598         if ( ++p == pe )
00599                 goto _test_eof2;
00600 case 2:
00601         if ( (*p) == 110 )
00602                 goto st3;
00603         goto st0;
00604 st3:
00605         if ( ++p == pe )
00606                 goto _test_eof3;
00607 case 3:
00608         if ( (*p) == 102 )
00609                 goto st4;
00610         goto st0;
00611 st4:
00612         if ( ++p == pe )
00613                 goto _test_eof4;
00614 case 4:
00615         if ( (*p) == 105 )
00616                 goto st5;
00617         goto st0;
00618 st5:
00619         if ( ++p == pe )
00620                 goto _test_eof5;
00621 case 5:
00622         if ( (*p) == 110 )
00623                 goto st6;
00624         goto st0;
00625 st6:
00626         if ( ++p == pe )
00627                 goto _test_eof6;
00628 case 6:
00629         if ( (*p) == 105 )
00630                 goto st7;
00631         goto st0;
00632 st7:
00633         if ( ++p == pe )
00634                 goto _test_eof7;
00635 case 7:
00636         if ( (*p) == 116 )
00637                 goto st8;
00638         goto st0;
00639 st8:
00640         if ( ++p == pe )
00641                 goto _test_eof8;
00642 case 8:
00643         if ( (*p) == 121 )
00644                 goto tr16;
00645         goto st0;
00646 st9:
00647         if ( ++p == pe )
00648                 goto _test_eof9;
00649 case 9:
00650         if ( (*p) == 97 )
00651                 goto st10;
00652         goto st0;
00653 st10:
00654         if ( ++p == pe )
00655                 goto _test_eof10;
00656 case 10:
00657         if ( (*p) == 78 )
00658                 goto tr18;
00659         goto st0;
00660 st11:
00661         if ( ++p == pe )
00662                 goto _test_eof11;
00663 case 11:
00664         if ( (*p) == 97 )
00665                 goto st12;
00666         goto st0;
00667 st12:
00668         if ( ++p == pe )
00669                 goto _test_eof12;
00670 case 12:
00671         if ( (*p) == 108 )
00672                 goto st13;
00673         goto st0;
00674 st13:
00675         if ( ++p == pe )
00676                 goto _test_eof13;
00677 case 13:
00678         if ( (*p) == 115 )
00679                 goto st14;
00680         goto st0;
00681 st14:
00682         if ( ++p == pe )
00683                 goto _test_eof14;
00684 case 14:
00685         if ( (*p) == 101 )
00686                 goto tr22;
00687         goto st0;
00688 st15:
00689         if ( ++p == pe )
00690                 goto _test_eof15;
00691 case 15:
00692         if ( (*p) == 117 )
00693                 goto st16;
00694         goto st0;
00695 st16:
00696         if ( ++p == pe )
00697                 goto _test_eof16;
00698 case 16:
00699         if ( (*p) == 108 )
00700                 goto st17;
00701         goto st0;
00702 st17:
00703         if ( ++p == pe )
00704                 goto _test_eof17;
00705 case 17:
00706         if ( (*p) == 108 )
00707                 goto tr25;
00708         goto st0;
00709 st18:
00710         if ( ++p == pe )
00711                 goto _test_eof18;
00712 case 18:
00713         if ( (*p) == 114 )
00714                 goto st19;
00715         goto st0;
00716 st19:
00717         if ( ++p == pe )
00718                 goto _test_eof19;
00719 case 19:
00720         if ( (*p) == 117 )
00721                 goto st20;
00722         goto st0;
00723 st20:
00724         if ( ++p == pe )
00725                 goto _test_eof20;
00726 case 20:
00727         if ( (*p) == 101 )
00728                 goto tr28;
00729         goto st0;
00730         }
00731         _test_eof21: cs = 21; goto _test_eof; 
00732         _test_eof2: cs = 2; goto _test_eof; 
00733         _test_eof3: cs = 3; goto _test_eof; 
00734         _test_eof4: cs = 4; goto _test_eof; 
00735         _test_eof5: cs = 5; goto _test_eof; 
00736         _test_eof6: cs = 6; goto _test_eof; 
00737         _test_eof7: cs = 7; goto _test_eof; 
00738         _test_eof8: cs = 8; goto _test_eof; 
00739         _test_eof9: cs = 9; goto _test_eof; 
00740         _test_eof10: cs = 10; goto _test_eof; 
00741         _test_eof11: cs = 11; goto _test_eof; 
00742         _test_eof12: cs = 12; goto _test_eof; 
00743         _test_eof13: cs = 13; goto _test_eof; 
00744         _test_eof14: cs = 14; goto _test_eof; 
00745         _test_eof15: cs = 15; goto _test_eof; 
00746         _test_eof16: cs = 16; goto _test_eof; 
00747         _test_eof17: cs = 17; goto _test_eof; 
00748         _test_eof18: cs = 18; goto _test_eof; 
00749         _test_eof19: cs = 19; goto _test_eof; 
00750         _test_eof20: cs = 20; goto _test_eof; 
00751 
00752         _test_eof: {}
00753         _out: {}
00754         }
00755 
00756 #line 266 "parser.rl"
00757 
00758     if (cs >= JSON_value_first_final) {
00759         return p;
00760     } else {
00761         return NULL;
00762     }
00763 }
00764 
00765 
00766 #line 767 "parser.c"
00767 static const int JSON_integer_start = 1;
00768 static const int JSON_integer_first_final = 5;
00769 static const int JSON_integer_error = 0;
00770 
00771 static const int JSON_integer_en_main = 1;
00772 
00773 
00774 #line 282 "parser.rl"
00775 
00776 
00777 static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
00778 {
00779     int cs = EVIL;
00780 
00781     
00782 #line 783 "parser.c"
00783         {
00784         cs = JSON_integer_start;
00785         }
00786 
00787 #line 289 "parser.rl"
00788     json->memo = p;
00789     
00790 #line 791 "parser.c"
00791         {
00792         if ( p == pe )
00793                 goto _test_eof;
00794         switch ( cs )
00795         {
00796 case 1:
00797         switch( (*p) ) {
00798                 case 45: goto st2;
00799                 case 48: goto st3;
00800         }
00801         if ( 49 <= (*p) && (*p) <= 57 )
00802                 goto st4;
00803         goto st0;
00804 st0:
00805 cs = 0;
00806         goto _out;
00807 st2:
00808         if ( ++p == pe )
00809                 goto _test_eof2;
00810 case 2:
00811         if ( (*p) == 48 )
00812                 goto st3;
00813         if ( 49 <= (*p) && (*p) <= 57 )
00814                 goto st4;
00815         goto st0;
00816 st3:
00817         if ( ++p == pe )
00818                 goto _test_eof3;
00819 case 3:
00820         if ( 48 <= (*p) && (*p) <= 57 )
00821                 goto st0;
00822         goto tr4;
00823 tr4:
00824 #line 279 "parser.rl"
00825         { p--; {p++; cs = 5; goto _out;} }
00826         goto st5;
00827 st5:
00828         if ( ++p == pe )
00829                 goto _test_eof5;
00830 case 5:
00831 #line 832 "parser.c"
00832         goto st0;
00833 st4:
00834         if ( ++p == pe )
00835                 goto _test_eof4;
00836 case 4:
00837         if ( 48 <= (*p) && (*p) <= 57 )
00838                 goto st4;
00839         goto tr4;
00840         }
00841         _test_eof2: cs = 2; goto _test_eof; 
00842         _test_eof3: cs = 3; goto _test_eof; 
00843         _test_eof5: cs = 5; goto _test_eof; 
00844         _test_eof4: cs = 4; goto _test_eof; 
00845 
00846         _test_eof: {}
00847         _out: {}
00848         }
00849 
00850 #line 291 "parser.rl"
00851 
00852     if (cs >= JSON_integer_first_final) {
00853         long len = p - json->memo;
00854         *result = rb_Integer(rb_str_new(json->memo, len));
00855         return p + 1;
00856     } else {
00857         return NULL;
00858     }
00859 }
00860 
00861 
00862 #line 863 "parser.c"
00863 static const int JSON_float_start = 1;
00864 static const int JSON_float_first_final = 10;
00865 static const int JSON_float_error = 0;
00866 
00867 static const int JSON_float_en_main = 1;
00868 
00869 
00870 #line 313 "parser.rl"
00871 
00872 
00873 static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
00874 {
00875     int cs = EVIL;
00876 
00877     
00878 #line 879 "parser.c"
00879         {
00880         cs = JSON_float_start;
00881         }
00882 
00883 #line 320 "parser.rl"
00884     json->memo = p;
00885     
00886 #line 887 "parser.c"
00887         {
00888         if ( p == pe )
00889                 goto _test_eof;
00890         switch ( cs )
00891         {
00892 case 1:
00893         switch( (*p) ) {
00894                 case 45: goto st2;
00895                 case 48: goto st3;
00896         }
00897         if ( 49 <= (*p) && (*p) <= 57 )
00898                 goto st9;
00899         goto st0;
00900 st0:
00901 cs = 0;
00902         goto _out;
00903 st2:
00904         if ( ++p == pe )
00905                 goto _test_eof2;
00906 case 2:
00907         if ( (*p) == 48 )
00908                 goto st3;
00909         if ( 49 <= (*p) && (*p) <= 57 )
00910                 goto st9;
00911         goto st0;
00912 st3:
00913         if ( ++p == pe )
00914                 goto _test_eof3;
00915 case 3:
00916         switch( (*p) ) {
00917                 case 46: goto st4;
00918                 case 69: goto st6;
00919                 case 101: goto st6;
00920         }
00921         goto st0;
00922 st4:
00923         if ( ++p == pe )
00924                 goto _test_eof4;
00925 case 4:
00926         if ( 48 <= (*p) && (*p) <= 57 )
00927                 goto st5;
00928         goto st0;
00929 st5:
00930         if ( ++p == pe )
00931                 goto _test_eof5;
00932 case 5:
00933         switch( (*p) ) {
00934                 case 69: goto st6;
00935                 case 101: goto st6;
00936         }
00937         if ( (*p) > 46 ) {
00938                 if ( 48 <= (*p) && (*p) <= 57 )
00939                         goto st5;
00940         } else if ( (*p) >= 45 )
00941                 goto st0;
00942         goto tr7;
00943 tr7:
00944 #line 307 "parser.rl"
00945         { p--; {p++; cs = 10; goto _out;} }
00946         goto st10;
00947 st10:
00948         if ( ++p == pe )
00949                 goto _test_eof10;
00950 case 10:
00951 #line 952 "parser.c"
00952         goto st0;
00953 st6:
00954         if ( ++p == pe )
00955                 goto _test_eof6;
00956 case 6:
00957         switch( (*p) ) {
00958                 case 43: goto st7;
00959                 case 45: goto st7;
00960         }
00961         if ( 48 <= (*p) && (*p) <= 57 )
00962                 goto st8;
00963         goto st0;
00964 st7:
00965         if ( ++p == pe )
00966                 goto _test_eof7;
00967 case 7:
00968         if ( 48 <= (*p) && (*p) <= 57 )
00969                 goto st8;
00970         goto st0;
00971 st8:
00972         if ( ++p == pe )
00973                 goto _test_eof8;
00974 case 8:
00975         switch( (*p) ) {
00976                 case 69: goto st0;
00977                 case 101: goto st0;
00978         }
00979         if ( (*p) > 46 ) {
00980                 if ( 48 <= (*p) && (*p) <= 57 )
00981                         goto st8;
00982         } else if ( (*p) >= 45 )
00983                 goto st0;
00984         goto tr7;
00985 st9:
00986         if ( ++p == pe )
00987                 goto _test_eof9;
00988 case 9:
00989         switch( (*p) ) {
00990                 case 46: goto st4;
00991                 case 69: goto st6;
00992                 case 101: goto st6;
00993         }
00994         if ( 48 <= (*p) && (*p) <= 57 )
00995                 goto st9;
00996         goto st0;
00997         }
00998         _test_eof2: cs = 2; goto _test_eof; 
00999         _test_eof3: cs = 3; goto _test_eof; 
01000         _test_eof4: cs = 4; goto _test_eof; 
01001         _test_eof5: cs = 5; goto _test_eof; 
01002         _test_eof10: cs = 10; goto _test_eof; 
01003         _test_eof6: cs = 6; goto _test_eof; 
01004         _test_eof7: cs = 7; goto _test_eof; 
01005         _test_eof8: cs = 8; goto _test_eof; 
01006         _test_eof9: cs = 9; goto _test_eof; 
01007 
01008         _test_eof: {}
01009         _out: {}
01010         }
01011 
01012 #line 322 "parser.rl"
01013 
01014     if (cs >= JSON_float_first_final) {
01015         long len = p - json->memo;
01016         *result = rb_Float(rb_str_new(json->memo, len));
01017         return p + 1;
01018     } else {
01019         return NULL;
01020     }
01021 }
01022 
01023 
01024 
01025 #line 1026 "parser.c"
01026 static const int JSON_array_start = 1;
01027 static const int JSON_array_first_final = 17;
01028 static const int JSON_array_error = 0;
01029 
01030 static const int JSON_array_en_main = 1;
01031 
01032 
01033 #line 358 "parser.rl"
01034 
01035 
01036 static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
01037 {
01038     int cs = EVIL;
01039     VALUE array_class = json->array_class;
01040 
01041     if (json->max_nesting && json->current_nesting > json->max_nesting) {
01042         rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
01043     }
01044     *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
01045 
01046     
01047 #line 1048 "parser.c"
01048         {
01049         cs = JSON_array_start;
01050         }
01051 
01052 #line 371 "parser.rl"
01053     
01054 #line 1055 "parser.c"
01055         {
01056         if ( p == pe )
01057                 goto _test_eof;
01058         switch ( cs )
01059         {
01060 case 1:
01061         if ( (*p) == 91 )
01062                 goto st2;
01063         goto st0;
01064 st0:
01065 cs = 0;
01066         goto _out;
01067 st2:
01068         if ( ++p == pe )
01069                 goto _test_eof2;
01070 case 2:
01071         switch( (*p) ) {
01072                 case 13: goto st2;
01073                 case 32: goto st2;
01074                 case 34: goto tr2;
01075                 case 45: goto tr2;
01076                 case 47: goto st13;
01077                 case 73: goto tr2;
01078                 case 78: goto tr2;
01079                 case 91: goto tr2;
01080                 case 93: goto tr4;
01081                 case 102: goto tr2;
01082                 case 110: goto tr2;
01083                 case 116: goto tr2;
01084                 case 123: goto tr2;
01085         }
01086         if ( (*p) > 10 ) {
01087                 if ( 48 <= (*p) && (*p) <= 57 )
01088                         goto tr2;
01089         } else if ( (*p) >= 9 )
01090                 goto st2;
01091         goto st0;
01092 tr2:
01093 #line 339 "parser.rl"
01094         {
01095         VALUE v = Qnil;
01096         char *np = JSON_parse_value(json, p, pe, &v);
01097         if (np == NULL) {
01098             p--; {p++; cs = 3; goto _out;}
01099         } else {
01100             rb_ary_push(*result, v);
01101             {p = (( np))-1;}
01102         }
01103     }
01104         goto st3;
01105 st3:
01106         if ( ++p == pe )
01107                 goto _test_eof3;
01108 case 3:
01109 #line 1110 "parser.c"
01110         switch( (*p) ) {
01111                 case 13: goto st3;
01112                 case 32: goto st3;
01113                 case 44: goto st4;
01114                 case 47: goto st9;
01115                 case 93: goto tr4;
01116         }
01117         if ( 9 <= (*p) && (*p) <= 10 )
01118                 goto st3;
01119         goto st0;
01120 st4:
01121         if ( ++p == pe )
01122                 goto _test_eof4;
01123 case 4:
01124         switch( (*p) ) {
01125                 case 13: goto st4;
01126                 case 32: goto st4;
01127                 case 34: goto tr2;
01128                 case 45: goto tr2;
01129                 case 47: goto st5;
01130                 case 73: goto tr2;
01131                 case 78: goto tr2;
01132                 case 91: goto tr2;
01133                 case 102: goto tr2;
01134                 case 110: goto tr2;
01135                 case 116: goto tr2;
01136                 case 123: goto tr2;
01137         }
01138         if ( (*p) > 10 ) {
01139                 if ( 48 <= (*p) && (*p) <= 57 )
01140                         goto tr2;
01141         } else if ( (*p) >= 9 )
01142                 goto st4;
01143         goto st0;
01144 st5:
01145         if ( ++p == pe )
01146                 goto _test_eof5;
01147 case 5:
01148         switch( (*p) ) {
01149                 case 42: goto st6;
01150                 case 47: goto st8;
01151         }
01152         goto st0;
01153 st6:
01154         if ( ++p == pe )
01155                 goto _test_eof6;
01156 case 6:
01157         if ( (*p) == 42 )
01158                 goto st7;
01159         goto st6;
01160 st7:
01161         if ( ++p == pe )
01162                 goto _test_eof7;
01163 case 7:
01164         switch( (*p) ) {
01165                 case 42: goto st7;
01166                 case 47: goto st4;
01167         }
01168         goto st6;
01169 st8:
01170         if ( ++p == pe )
01171                 goto _test_eof8;
01172 case 8:
01173         if ( (*p) == 10 )
01174                 goto st4;
01175         goto st8;
01176 st9:
01177         if ( ++p == pe )
01178                 goto _test_eof9;
01179 case 9:
01180         switch( (*p) ) {
01181                 case 42: goto st10;
01182                 case 47: goto st12;
01183         }
01184         goto st0;
01185 st10:
01186         if ( ++p == pe )
01187                 goto _test_eof10;
01188 case 10:
01189         if ( (*p) == 42 )
01190                 goto st11;
01191         goto st10;
01192 st11:
01193         if ( ++p == pe )
01194                 goto _test_eof11;
01195 case 11:
01196         switch( (*p) ) {
01197                 case 42: goto st11;
01198                 case 47: goto st3;
01199         }
01200         goto st10;
01201 st12:
01202         if ( ++p == pe )
01203                 goto _test_eof12;
01204 case 12:
01205         if ( (*p) == 10 )
01206                 goto st3;
01207         goto st12;
01208 tr4:
01209 #line 350 "parser.rl"
01210         { p--; {p++; cs = 17; goto _out;} }
01211         goto st17;
01212 st17:
01213         if ( ++p == pe )
01214                 goto _test_eof17;
01215 case 17:
01216 #line 1217 "parser.c"
01217         goto st0;
01218 st13:
01219         if ( ++p == pe )
01220                 goto _test_eof13;
01221 case 13:
01222         switch( (*p) ) {
01223                 case 42: goto st14;
01224                 case 47: goto st16;
01225         }
01226         goto st0;
01227 st14:
01228         if ( ++p == pe )
01229                 goto _test_eof14;
01230 case 14:
01231         if ( (*p) == 42 )
01232                 goto st15;
01233         goto st14;
01234 st15:
01235         if ( ++p == pe )
01236                 goto _test_eof15;
01237 case 15:
01238         switch( (*p) ) {
01239                 case 42: goto st15;
01240                 case 47: goto st2;
01241         }
01242         goto st14;
01243 st16:
01244         if ( ++p == pe )
01245                 goto _test_eof16;
01246 case 16:
01247         if ( (*p) == 10 )
01248                 goto st2;
01249         goto st16;
01250         }
01251         _test_eof2: cs = 2; goto _test_eof; 
01252         _test_eof3: cs = 3; goto _test_eof; 
01253         _test_eof4: cs = 4; goto _test_eof; 
01254         _test_eof5: cs = 5; goto _test_eof; 
01255         _test_eof6: cs = 6; goto _test_eof; 
01256         _test_eof7: cs = 7; goto _test_eof; 
01257         _test_eof8: cs = 8; goto _test_eof; 
01258         _test_eof9: cs = 9; goto _test_eof; 
01259         _test_eof10: cs = 10; goto _test_eof; 
01260         _test_eof11: cs = 11; goto _test_eof; 
01261         _test_eof12: cs = 12; goto _test_eof; 
01262         _test_eof17: cs = 17; goto _test_eof; 
01263         _test_eof13: cs = 13; goto _test_eof; 
01264         _test_eof14: cs = 14; goto _test_eof; 
01265         _test_eof15: cs = 15; goto _test_eof; 
01266         _test_eof16: cs = 16; goto _test_eof; 
01267 
01268         _test_eof: {}
01269         _out: {}
01270         }
01271 
01272 #line 372 "parser.rl"
01273 
01274     if(cs >= JSON_array_first_final) {
01275         return p + 1;
01276     } else {
01277         rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
01278         return NULL;
01279     }
01280 }
01281 
01282 static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
01283 {
01284     char *p = string, *pe = string, *unescape;
01285     int unescape_len;
01286 
01287     while (pe < stringEnd) {
01288         if (*pe == '\\') {
01289             unescape = (char *) "?";
01290             unescape_len = 1;
01291             if (pe > p) rb_str_buf_cat(result, p, pe - p);
01292             switch (*++pe) {
01293                 case 'n':
01294                     unescape = (char *) "\n";
01295                     break;
01296                 case 'r':
01297                     unescape = (char *) "\r";
01298                     break;
01299                 case 't':
01300                     unescape = (char *) "\t";
01301                     break;
01302                 case '"':
01303                     unescape = (char *) "\"";
01304                     break;
01305                 case '\\':
01306                     unescape = (char *) "\\";
01307                     break;
01308                 case 'b':
01309                     unescape = (char *) "\b";
01310                     break;
01311                 case 'f':
01312                     unescape = (char *) "\f";
01313                     break;
01314                 case 'u':
01315                     if (pe > stringEnd - 4) {
01316                         return Qnil;
01317                     } else {
01318                         char buf[4];
01319                         UTF32 ch = unescape_unicode((unsigned char *) ++pe);
01320                         pe += 3;
01321                         if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
01322                             pe++;
01323                             if (pe > stringEnd - 6) return Qnil;
01324                             if (pe[0] == '\\' && pe[1] == 'u') {
01325                                 UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
01326                                 ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
01327                                         | (sur & 0x3FF));
01328                                 pe += 5;
01329                             } else {
01330                                 unescape = (char *) "?";
01331                                 break;
01332                             }
01333                         }
01334                         unescape_len = convert_UTF32_to_UTF8(buf, ch);
01335                         unescape = buf;
01336                     }
01337                     break;
01338                 default:
01339                     p = pe;
01340                     continue;
01341             }
01342             rb_str_buf_cat(result, unescape, unescape_len);
01343             p = ++pe;
01344         } else {
01345             pe++;
01346         }
01347     }
01348     rb_str_buf_cat(result, p, pe - p);
01349     return result;
01350 }
01351 
01352 
01353 #line 1354 "parser.c"
01354 static const int JSON_string_start = 1;
01355 static const int JSON_string_first_final = 8;
01356 static const int JSON_string_error = 0;
01357 
01358 static const int JSON_string_en_main = 1;
01359 
01360 
01361 #line 471 "parser.rl"
01362 
01363 
01364 static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
01365 {
01366     int cs = EVIL;
01367 
01368     *result = rb_str_buf_new(0);
01369     
01370 #line 1371 "parser.c"
01371         {
01372         cs = JSON_string_start;
01373         }
01374 
01375 #line 479 "parser.rl"
01376     json->memo = p;
01377     
01378 #line 1379 "parser.c"
01379         {
01380         if ( p == pe )
01381                 goto _test_eof;
01382         switch ( cs )
01383         {
01384 case 1:
01385         if ( (*p) == 34 )
01386                 goto st2;
01387         goto st0;
01388 st0:
01389 cs = 0;
01390         goto _out;
01391 st2:
01392         if ( ++p == pe )
01393                 goto _test_eof2;
01394 case 2:
01395         switch( (*p) ) {
01396                 case 34: goto tr2;
01397                 case 92: goto st3;
01398         }
01399         if ( 0 <= (*p) && (*p) <= 31 )
01400                 goto st0;
01401         goto st2;
01402 tr2:
01403 #line 457 "parser.rl"
01404         {
01405         *result = json_string_unescape(*result, json->memo + 1, p);
01406         if (NIL_P(*result)) {
01407             p--;
01408             {p++; cs = 8; goto _out;}
01409         } else {
01410             FORCE_UTF8(*result);
01411             {p = (( p + 1))-1;}
01412         }
01413     }
01414 #line 468 "parser.rl"
01415         { p--; {p++; cs = 8; goto _out;} }
01416         goto st8;
01417 st8:
01418         if ( ++p == pe )
01419                 goto _test_eof8;
01420 case 8:
01421 #line 1422 "parser.c"
01422         goto st0;
01423 st3:
01424         if ( ++p == pe )
01425                 goto _test_eof3;
01426 case 3:
01427         if ( (*p) == 117 )
01428                 goto st4;
01429         if ( 0 <= (*p) && (*p) <= 31 )
01430                 goto st0;
01431         goto st2;
01432 st4:
01433         if ( ++p == pe )
01434                 goto _test_eof4;
01435 case 4:
01436         if ( (*p) < 65 ) {
01437                 if ( 48 <= (*p) && (*p) <= 57 )
01438                         goto st5;
01439         } else if ( (*p) > 70 ) {
01440                 if ( 97 <= (*p) && (*p) <= 102 )
01441                         goto st5;
01442         } else
01443                 goto st5;
01444         goto st0;
01445 st5:
01446         if ( ++p == pe )
01447                 goto _test_eof5;
01448 case 5:
01449         if ( (*p) < 65 ) {
01450                 if ( 48 <= (*p) && (*p) <= 57 )
01451                         goto st6;
01452         } else if ( (*p) > 70 ) {
01453                 if ( 97 <= (*p) && (*p) <= 102 )
01454                         goto st6;
01455         } else
01456                 goto st6;
01457         goto st0;
01458 st6:
01459         if ( ++p == pe )
01460                 goto _test_eof6;
01461 case 6:
01462         if ( (*p) < 65 ) {
01463                 if ( 48 <= (*p) && (*p) <= 57 )
01464                         goto st7;
01465         } else if ( (*p) > 70 ) {
01466                 if ( 97 <= (*p) && (*p) <= 102 )
01467                         goto st7;
01468         } else
01469                 goto st7;
01470         goto st0;
01471 st7:
01472         if ( ++p == pe )
01473                 goto _test_eof7;
01474 case 7:
01475         if ( (*p) < 65 ) {
01476                 if ( 48 <= (*p) && (*p) <= 57 )
01477                         goto st2;
01478         } else if ( (*p) > 70 ) {
01479                 if ( 97 <= (*p) && (*p) <= 102 )
01480                         goto st2;
01481         } else
01482                 goto st2;
01483         goto st0;
01484         }
01485         _test_eof2: cs = 2; goto _test_eof; 
01486         _test_eof8: cs = 8; goto _test_eof; 
01487         _test_eof3: cs = 3; goto _test_eof; 
01488         _test_eof4: cs = 4; goto _test_eof; 
01489         _test_eof5: cs = 5; goto _test_eof; 
01490         _test_eof6: cs = 6; goto _test_eof; 
01491         _test_eof7: cs = 7; goto _test_eof; 
01492 
01493         _test_eof: {}
01494         _out: {}
01495         }
01496 
01497 #line 481 "parser.rl"
01498 
01499     if (json->symbolize_names && json->parsing_name) {
01500       *result = rb_str_intern(*result);
01501     }
01502     if (cs >= JSON_string_first_final) {
01503         return p + 1;
01504     } else {
01505         return NULL;
01506     }
01507 }
01508 
01509 
01510 
01511 #line 1512 "parser.c"
01512 static const int JSON_start = 1;
01513 static const int JSON_first_final = 10;
01514 static const int JSON_error = 0;
01515 
01516 static const int JSON_en_main = 1;
01517 
01518 
01519 #line 518 "parser.rl"
01520 
01521 
01522 /*
01523  * Document-class: JSON::Ext::Parser
01524  *
01525  * This is the JSON parser implemented as a C extension. It can be configured
01526  * to be used by setting
01527  *
01528  *  JSON.parser = JSON::Ext::Parser
01529  *
01530  * with the method parser= in JSON.
01531  *
01532  */
01533 
01534 static VALUE convert_encoding(VALUE source)
01535 {
01536     char *ptr = RSTRING_PTR(source);
01537     long len = RSTRING_LEN(source);
01538     if (len < 2) {
01539         rb_raise(eParserError, "A JSON text must at least contain two octets!");
01540     }
01541 #ifdef HAVE_RUBY_ENCODING_H
01542     {
01543         VALUE encoding = rb_funcall(source, i_encoding, 0);
01544         if (encoding == CEncoding_ASCII_8BIT) {
01545             if (len >= 4 &&  ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
01546                 source = rb_str_dup(source);
01547                 rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32BE);
01548                 source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
01549             } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
01550                 source = rb_str_dup(source);
01551                 rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16BE);
01552                 source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
01553             } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
01554                 source = rb_str_dup(source);
01555                 rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32LE);
01556                 source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
01557             } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
01558                 source = rb_str_dup(source);
01559                 rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16LE);
01560                 source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
01561             } else {
01562                 FORCE_UTF8(source);
01563             }
01564         } else {
01565             source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
01566         }
01567     }
01568 #else
01569     if (len >= 4 &&  ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
01570       source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
01571     } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
01572       source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
01573     } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
01574       source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
01575     } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
01576       source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
01577     }
01578 #endif
01579     return source;
01580 }
01581 
01582 /*
01583  * call-seq: new(source, opts => {})
01584  *
01585  * Creates a new JSON::Ext::Parser instance for the string _source_.
01586  *
01587  * Creates a new JSON::Ext::Parser instance for the string _source_.
01588  *
01589  * It will be configured by the _opts_ hash. _opts_ can have the following
01590  * keys:
01591  *
01592  * _opts_ can have the following keys:
01593  * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
01594  *   structures. Disable depth checking with :max_nesting => false|nil|0, it
01595  *   defaults to 19.
01596  * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
01597  *   defiance of RFC 4627 to be parsed by the Parser. This option defaults to
01598  *   false.
01599  * * *symbolize_names*: If set to true, returns symbols for the names
01600  *   (keys) in a JSON object. Otherwise strings are returned, which is also
01601  *   the default.
01602  * * *create_additions*: If set to false, the Parser doesn't create
01603  *   additions even if a matchin class and create_id was found. This option
01604  *   defaults to true.
01605  * * *object_class*: Defaults to Hash
01606  * * *array_class*: Defaults to Array
01607  */
01608 static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
01609 {
01610     char *ptr;
01611     long len;
01612     VALUE source, opts;
01613     GET_PARSER;
01614     rb_scan_args(argc, argv, "11", &source, &opts);
01615     source = convert_encoding(StringValue(source));
01616     ptr = RSTRING_PTR(source);
01617     len = RSTRING_LEN(source);
01618     if (!NIL_P(opts)) {
01619         opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
01620         if (NIL_P(opts)) {
01621             rb_raise(rb_eArgError, "opts needs to be like a hash");
01622         } else {
01623             VALUE tmp = ID2SYM(i_max_nesting);
01624             if (option_given_p(opts, tmp)) {
01625                 VALUE max_nesting = rb_hash_aref(opts, tmp);
01626                 if (RTEST(max_nesting)) {
01627                     Check_Type(max_nesting, T_FIXNUM);
01628                     json->max_nesting = FIX2INT(max_nesting);
01629                 } else {
01630                     json->max_nesting = 0;
01631                 }
01632             } else {
01633                 json->max_nesting = 19;
01634             }
01635             tmp = ID2SYM(i_allow_nan);
01636             if (option_given_p(opts, tmp)) {
01637                 VALUE allow_nan = rb_hash_aref(opts, tmp);
01638                 json->allow_nan = RTEST(allow_nan) ? 1 : 0;
01639             } else {
01640                 json->allow_nan = 0;
01641             }
01642             tmp = ID2SYM(i_symbolize_names);
01643             if (option_given_p(opts, tmp)) {
01644                 VALUE symbolize_names = rb_hash_aref(opts, tmp);
01645                 json->symbolize_names = RTEST(symbolize_names) ? 1 : 0;
01646             } else {
01647                 json->symbolize_names = 0;
01648             }
01649             tmp = ID2SYM(i_create_additions);
01650             if (option_given_p(opts, tmp)) {
01651                 VALUE create_additions = rb_hash_aref(opts, tmp);
01652                 if (RTEST(create_additions)) {
01653                     json->create_id = rb_funcall(mJSON, i_create_id, 0);
01654                 } else {
01655                     json->create_id = Qnil;
01656                 }
01657             } else {
01658                 json->create_id = rb_funcall(mJSON, i_create_id, 0);
01659             }
01660             tmp = ID2SYM(i_object_class);
01661             if (option_given_p(opts, tmp)) {
01662                 json->object_class = rb_hash_aref(opts, tmp);
01663             } else {
01664                 json->object_class = Qnil;
01665             }
01666             tmp = ID2SYM(i_array_class);
01667             if (option_given_p(opts, tmp)) {
01668                 json->array_class = rb_hash_aref(opts, tmp);
01669             } else {
01670                 json->array_class = Qnil;
01671             }
01672         }
01673     } else {
01674         json->max_nesting = 19;
01675         json->allow_nan = 0;
01676         json->create_id = rb_funcall(mJSON, i_create_id, 0);
01677         json->object_class = Qnil;
01678         json->array_class = Qnil;
01679     }
01680     json->current_nesting = 0;
01681     json->len = len;
01682     json->source = ptr;
01683     json->Vsource = source;
01684     return self;
01685 }
01686 
01687 /*
01688  * call-seq: parse()
01689  *
01690  *  Parses the current JSON text _source_ and returns the complete data
01691  *  structure as a result.
01692  */
01693 static VALUE cParser_parse(VALUE self)
01694 {
01695     char *p, *pe;
01696     int cs = EVIL;
01697     VALUE result = Qnil;
01698     GET_PARSER;
01699 
01700     
01701 #line 1702 "parser.c"
01702         {
01703         cs = JSON_start;
01704         }
01705 
01706 #line 699 "parser.rl"
01707     p = json->source;
01708     pe = p + json->len;
01709     
01710 #line 1711 "parser.c"
01711         {
01712         if ( p == pe )
01713                 goto _test_eof;
01714         switch ( cs )
01715         {
01716 st1:
01717         if ( ++p == pe )
01718                 goto _test_eof1;
01719 case 1:
01720         switch( (*p) ) {
01721                 case 13: goto st1;
01722                 case 32: goto st1;
01723                 case 47: goto st2;
01724                 case 91: goto tr3;
01725                 case 123: goto tr4;
01726         }
01727         if ( 9 <= (*p) && (*p) <= 10 )
01728                 goto st1;
01729         goto st0;
01730 st0:
01731 cs = 0;
01732         goto _out;
01733 st2:
01734         if ( ++p == pe )
01735                 goto _test_eof2;
01736 case 2:
01737         switch( (*p) ) {
01738                 case 42: goto st3;
01739                 case 47: goto st5;
01740         }
01741         goto st0;
01742 st3:
01743         if ( ++p == pe )
01744                 goto _test_eof3;
01745 case 3:
01746         if ( (*p) == 42 )
01747                 goto st4;
01748         goto st3;
01749 st4:
01750         if ( ++p == pe )
01751                 goto _test_eof4;
01752 case 4:
01753         switch( (*p) ) {
01754                 case 42: goto st4;
01755                 case 47: goto st1;
01756         }
01757         goto st3;
01758 st5:
01759         if ( ++p == pe )
01760                 goto _test_eof5;
01761 case 5:
01762         if ( (*p) == 10 )
01763                 goto st1;
01764         goto st5;
01765 tr3:
01766 #line 507 "parser.rl"
01767         {
01768         char *np;
01769         json->current_nesting = 1;
01770         np = JSON_parse_array(json, p, pe, &result);
01771         if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
01772     }
01773         goto st10;
01774 tr4:
01775 #line 500 "parser.rl"
01776         {
01777         char *np;
01778         json->current_nesting = 1;
01779         np = JSON_parse_object(json, p, pe, &result);
01780         if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
01781     }
01782         goto st10;
01783 st10:
01784         if ( ++p == pe )
01785                 goto _test_eof10;
01786 case 10:
01787 #line 1788 "parser.c"
01788         switch( (*p) ) {
01789                 case 13: goto st10;
01790                 case 32: goto st10;
01791                 case 47: goto st6;
01792         }
01793         if ( 9 <= (*p) && (*p) <= 10 )
01794                 goto st10;
01795         goto st0;
01796 st6:
01797         if ( ++p == pe )
01798                 goto _test_eof6;
01799 case 6:
01800         switch( (*p) ) {
01801                 case 42: goto st7;
01802                 case 47: goto st9;
01803         }
01804         goto st0;
01805 st7:
01806         if ( ++p == pe )
01807                 goto _test_eof7;
01808 case 7:
01809         if ( (*p) == 42 )
01810                 goto st8;
01811         goto st7;
01812 st8:
01813         if ( ++p == pe )
01814                 goto _test_eof8;
01815 case 8:
01816         switch( (*p) ) {
01817                 case 42: goto st8;
01818                 case 47: goto st10;
01819         }
01820         goto st7;
01821 st9:
01822         if ( ++p == pe )
01823                 goto _test_eof9;
01824 case 9:
01825         if ( (*p) == 10 )
01826                 goto st10;
01827         goto st9;
01828         }
01829         _test_eof1: cs = 1; goto _test_eof; 
01830         _test_eof2: cs = 2; goto _test_eof; 
01831         _test_eof3: cs = 3; goto _test_eof; 
01832         _test_eof4: cs = 4; goto _test_eof; 
01833         _test_eof5: cs = 5; goto _test_eof; 
01834         _test_eof10: cs = 10; goto _test_eof; 
01835         _test_eof6: cs = 6; goto _test_eof; 
01836         _test_eof7: cs = 7; goto _test_eof; 
01837         _test_eof8: cs = 8; goto _test_eof; 
01838         _test_eof9: cs = 9; goto _test_eof; 
01839 
01840         _test_eof: {}
01841         _out: {}
01842         }
01843 
01844 #line 702 "parser.rl"
01845 
01846     if (cs >= JSON_first_final && p == pe) {
01847         return result;
01848     } else {
01849         rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
01850         return Qnil;
01851     }
01852 }
01853 
01854 static JSON_Parser *JSON_allocate()
01855 {
01856     JSON_Parser *json = ALLOC(JSON_Parser);
01857     MEMZERO(json, JSON_Parser, 1);
01858     return json;
01859 }
01860 
01861 static void JSON_mark(JSON_Parser *json)
01862 {
01863     rb_gc_mark_maybe(json->Vsource);
01864     rb_gc_mark_maybe(json->create_id);
01865     rb_gc_mark_maybe(json->object_class);
01866     rb_gc_mark_maybe(json->array_class);
01867 }
01868 
01869 static void JSON_free(JSON_Parser *json)
01870 {
01871     ruby_xfree(json);
01872 }
01873 
01874 static VALUE cJSON_parser_s_allocate(VALUE klass)
01875 {
01876     JSON_Parser *json = JSON_allocate();
01877     return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
01878 }
01879 
01880 /*
01881  * call-seq: source()
01882  *
01883  * Returns a copy of the current _source_ string, that was used to construct
01884  * this Parser.
01885  */
01886 static VALUE cParser_source(VALUE self)
01887 {
01888     GET_PARSER;
01889     return rb_str_dup(json->Vsource);
01890 }
01891 
01892 void Init_parser()
01893 {
01894     rb_require("json/common");
01895     mJSON = rb_define_module("JSON");
01896     mExt = rb_define_module_under(mJSON, "Ext");
01897     cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
01898     eParserError = rb_path2class("JSON::ParserError");
01899     eNestingError = rb_path2class("JSON::NestingError");
01900     rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
01901     rb_define_method(cParser, "initialize", cParser_initialize, -1);
01902     rb_define_method(cParser, "parse", cParser_parse, 0);
01903     rb_define_method(cParser, "source", cParser_source, 0);
01904 
01905     CNaN = rb_const_get(mJSON, rb_intern("NaN"));
01906     CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
01907     CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
01908 
01909     i_json_creatable_p = rb_intern("json_creatable?");
01910     i_json_create = rb_intern("json_create");
01911     i_create_id = rb_intern("create_id");
01912     i_create_additions = rb_intern("create_additions");
01913     i_chr = rb_intern("chr");
01914     i_max_nesting = rb_intern("max_nesting");
01915     i_allow_nan = rb_intern("allow_nan");
01916     i_symbolize_names = rb_intern("symbolize_names");
01917     i_object_class = rb_intern("object_class");
01918     i_array_class = rb_intern("array_class");
01919     i_key_p = rb_intern("key?");
01920     i_deep_const_get = rb_intern("deep_const_get");
01921 #ifdef HAVE_RUBY_ENCODING_H
01922     CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
01923     CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
01924     CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
01925     CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
01926     CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
01927     CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
01928     i_encoding = rb_intern("encoding");
01929     i_encode = rb_intern("encode");
01930     i_encode_bang = rb_intern("encode!");
01931     i_force_encoding = rb_intern("force_encoding");
01932 #else
01933     i_iconv = rb_intern("iconv");
01934 #endif
01935 }
01936 

Generated on Wed Sep 8 2010 21:53:51 for Ruby by  doxygen 1.7.1