Ruby
2.0.0p247(2013-06-27revision41674)
|
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