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