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