00001
00002 #line 1 "parser.rl"
00003 #include "../fbuffer/fbuffer.h"
00004 #include "parser.h"
00005
00006
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
01557
01558
01559
01560
01561
01562
01563
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
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
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
02079
02080
02081
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
02126
02127
02128
02129
02130 static VALUE cParser_source(VALUE self)
02131 {
02132 GET_PARSER;
02133 return rb_str_dup(json->Vsource);
02134 }
02135
02136
02137
02138
02139
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
02200
02201
02202
02203
02204
02205