From 1d00c8da715eec2e56e2602b001c28f33c32c046 Mon Sep 17 00:00:00 2001 From: Florian Frank Date: Fri, 23 Sep 2016 18:37:50 +0300 Subject: WIP --- Gemfile | 13 +- Rakefile | 2 +- VERSION | 2 +- ext/json/ext/parser/parser.c | 2461 +++++++++++++++++++---------------------- ext/json/ext/parser/parser.h | 1 + ext/json/ext/parser/parser.rl | 23 +- java/json.gemspec | 38 + java/src/json/ext/Parser.java | 169 +-- java/src/json/ext/Parser.rl | 33 +- json-java.gemspec | 38 - json.gemspec | Bin 5473 -> 4535 bytes json_pure.gemspec | 48 +- lib/json/pure/parser.rb | 6 +- lib/json/version.rb | 2 +- tests/test_helper.rb | 2 - 15 files changed, 1377 insertions(+), 1461 deletions(-) create mode 100644 java/json.gemspec delete mode 100644 json-java.gemspec diff --git a/Gemfile b/Gemfile index 51ff10a..747bc71 100644 --- a/Gemfile +++ b/Gemfile @@ -2,8 +2,15 @@ source 'https://rubygems.org' -gemspec :name => 'json' -gemspec :name => 'json_pure' -gemspec :name => 'json-java' +case ENV['JSON'] +when 'ext', nil + if ENV['RUBY_ENGINE'] == 'jruby' + gemspec :name => 'json', :path => 'java' + else + gemspec :name => 'json' + end +when 'pure' + gemspec :name => 'json_pure' +end gem 'simplecov' diff --git a/Rakefile b/Rakefile index f10f366..b2ee69d 100644 --- a/Rakefile +++ b/Rakefile @@ -251,7 +251,7 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' desc "Package the jruby gem" task :jruby_gem => :create_jar do - sh 'gem build json-java.gemspec' + sh 'gem build java/json-java.gemspec' mkdir_p 'pkg' mv "json-#{PKG_VERSION}-java.gem", 'pkg' end diff --git a/VERSION b/VERSION index e9307ca..7ec1d6d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.2 +2.1.0 diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 0dae674..cb7c68c 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1,5 +1,5 @@ -#line 1 "parser.rl" +#line 1 "ext/json/ext/parser/parser.rl" #include "../fbuffer/fbuffer.h" #include "parser.h" @@ -94,23 +94,98 @@ static VALUE CNaN, CInfinity, CMinusInfinity; static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, - i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match, - i_match_string, i_aset, i_aref, i_leftshift; + i_object_class, i_array_class, i_decimal_class, i_key_p, + i_deep_const_get, i_match, i_match_string, i_aset, i_aref, + i_leftshift, i_new; -#line 124 "parser.rl" +#line 125 "ext/json/ext/parser/parser.rl" -#line 106 "parser.c" -enum {JSON_object_start = 1}; -enum {JSON_object_first_final = 27}; -enum {JSON_object_error = 0}; +#line 107 "ext/json/ext/parser/parser.c" +static const char _JSON_object_actions[] = { + 0, 1, 0, 1, 1, 1, 2 +}; + +static const char _JSON_object_key_offsets[] = { + 0, 0, 1, 8, 14, 16, 17, 19, + 20, 36, 43, 49, 51, 52, 54, 55, + 57, 58, 60, 61, 63, 64, 66, 67, + 69, 70, 72, 73 +}; + +static const char _JSON_object_trans_keys[] = { + 123, 13, 32, 34, 47, 125, 9, 10, + 13, 32, 47, 58, 9, 10, 42, 47, + 42, 42, 47, 10, 13, 32, 34, 45, + 47, 73, 78, 91, 102, 110, 116, 123, + 9, 10, 48, 57, 13, 32, 44, 47, + 125, 9, 10, 13, 32, 34, 47, 9, + 10, 42, 47, 42, 42, 47, 10, 42, + 47, 42, 42, 47, 10, 42, 47, 42, + 42, 47, 10, 42, 47, 42, 42, 47, + 10, 0 +}; + +static const char _JSON_object_single_lengths[] = { + 0, 1, 5, 4, 2, 1, 2, 1, + 12, 5, 4, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 0 +}; + +static const char _JSON_object_range_lengths[] = { + 0, 0, 1, 1, 0, 0, 0, 0, + 2, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; + +static const char _JSON_object_index_offsets[] = { + 0, 0, 2, 9, 15, 18, 20, 23, + 25, 40, 47, 53, 56, 58, 61, 63, + 66, 68, 71, 73, 76, 78, 81, 83, + 86, 88, 91, 93 +}; + +static const char _JSON_object_indicies[] = { + 0, 1, 0, 0, 2, 3, 4, 0, + 1, 5, 5, 6, 7, 5, 1, 8, + 9, 1, 10, 8, 10, 5, 8, 5, + 9, 7, 7, 11, 11, 12, 11, 11, + 11, 11, 11, 11, 11, 7, 11, 1, + 13, 13, 14, 15, 4, 13, 1, 14, + 14, 2, 16, 14, 1, 17, 18, 1, + 19, 17, 19, 14, 17, 14, 18, 20, + 21, 1, 22, 20, 22, 13, 20, 13, + 21, 23, 24, 1, 25, 23, 25, 7, + 23, 7, 24, 26, 27, 1, 28, 26, + 28, 0, 26, 0, 27, 1, 0 +}; + +static const char _JSON_object_trans_targs[] = { + 2, 0, 3, 23, 27, 3, 4, 8, + 5, 7, 6, 9, 19, 9, 10, 15, + 11, 12, 14, 13, 16, 18, 17, 20, + 22, 21, 24, 26, 25 +}; + +static const char _JSON_object_trans_actions[] = { + 0, 0, 3, 0, 5, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; -enum {JSON_object_en_main = 1}; +static const int JSON_object_start = 1; +static const int JSON_object_first_final = 27; +static const int JSON_object_error = 0; +static const int JSON_object_en_main = 1; -#line 165 "parser.rl" + +#line 166 "ext/json/ext/parser/parser.rl" static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -125,128 +200,95 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class); - -#line 130 "parser.c" + +#line 205 "ext/json/ext/parser/parser.c" { cs = JSON_object_start; } -#line 180 "parser.rl" - -#line 137 "parser.c" +#line 181 "ext/json/ext/parser/parser.rl" + +#line 212 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_object_trans_keys + _JSON_object_key_offsets[cs]; + _trans = _JSON_object_index_offsets[cs]; + + _klen = _JSON_object_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_object_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_object_indicies[_trans]; + cs = _JSON_object_trans_targs[_trans]; + + if ( _JSON_object_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_object_actions + _JSON_object_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -case 1: - if ( (*p) == 123 ) - goto st2; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 13: goto st2; - case 32: goto st2; - case 34: goto tr2; - case 47: goto st23; - case 125: goto tr4; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st2; - goto st0; -tr2: -#line 147 "parser.rl" - { - char *np; - json->parsing_name = 1; - np = JSON_parse_string(json, p, pe, &last_name); - json->parsing_name = 0; - if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;} - } - goto st3; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: -#line 178 "parser.c" - switch( (*p) ) { - case 13: goto st3; - case 32: goto st3; - case 47: goto st4; - case 58: goto st8; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st3; - goto st0; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - switch( (*p) ) { - case 42: goto st5; - case 47: goto st7; - } - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( (*p) == 42 ) - goto st6; - goto st5; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - switch( (*p) ) { - case 42: goto st6; - case 47: goto st3; - } - goto st5; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - if ( (*p) == 10 ) - goto st3; - goto st7; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - switch( (*p) ) { - case 13: goto st8; - case 32: goto st8; - case 34: goto tr11; - case 45: goto tr11; - case 47: goto st19; - case 73: goto tr11; - case 78: goto tr11; - case 91: goto tr11; - case 102: goto tr11; - case 110: goto tr11; - case 116: goto tr11; - case 123: goto tr11; - } - if ( (*p) > 10 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr11; - } else if ( (*p) >= 9 ) - goto st8; - goto st0; -tr11: -#line 132 "parser.rl" + switch ( *_acts++ ) + { + case 0: +#line 133 "ext/json/ext/parser/parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); if (np == NULL) { - p--; {p++; cs = 9; goto _out;} + p--; {p++; goto _out; } } else { if (NIL_P(json->object_class)) { rb_hash_aset(*result, last_name, v); @@ -256,206 +298,35 @@ tr11: {p = (( np))-1;} } } - goto st9; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: -#line 265 "parser.c" - switch( (*p) ) { - case 13: goto st9; - case 32: goto st9; - case 44: goto st10; - case 47: goto st15; - case 125: goto tr4; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st9; - goto st0; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: - switch( (*p) ) { - case 13: goto st10; - case 32: goto st10; - case 34: goto tr2; - case 47: goto st11; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st10; - goto st0; -st11: - if ( ++p == pe ) - goto _test_eof11; -case 11: - switch( (*p) ) { - case 42: goto st12; - case 47: goto st14; - } - goto st0; -st12: - if ( ++p == pe ) - goto _test_eof12; -case 12: - if ( (*p) == 42 ) - goto st13; - goto st12; -st13: - if ( ++p == pe ) - goto _test_eof13; -case 13: - switch( (*p) ) { - case 42: goto st13; - case 47: goto st10; - } - goto st12; -st14: - if ( ++p == pe ) - goto _test_eof14; -case 14: - if ( (*p) == 10 ) - goto st10; - goto st14; -st15: - if ( ++p == pe ) - goto _test_eof15; -case 15: - switch( (*p) ) { - case 42: goto st16; - case 47: goto st18; - } - goto st0; -st16: - if ( ++p == pe ) - goto _test_eof16; -case 16: - if ( (*p) == 42 ) - goto st17; - goto st16; -st17: - if ( ++p == pe ) - goto _test_eof17; -case 17: - switch( (*p) ) { - case 42: goto st17; - case 47: goto st9; - } - goto st16; -st18: - if ( ++p == pe ) - goto _test_eof18; -case 18: - if ( (*p) == 10 ) - goto st9; - goto st18; -tr4: -#line 155 "parser.rl" - { p--; {p++; cs = 27; goto _out;} } - goto st27; -st27: - if ( ++p == pe ) - goto _test_eof27; -case 27: -#line 361 "parser.c" - goto st0; -st19: - if ( ++p == pe ) - goto _test_eof19; -case 19: - switch( (*p) ) { - case 42: goto st20; - case 47: goto st22; - } - goto st0; -st20: - if ( ++p == pe ) - goto _test_eof20; -case 20: - if ( (*p) == 42 ) - goto st21; - goto st20; -st21: - if ( ++p == pe ) - goto _test_eof21; -case 21: - switch( (*p) ) { - case 42: goto st21; - case 47: goto st8; - } - goto st20; -st22: - if ( ++p == pe ) - goto _test_eof22; -case 22: - if ( (*p) == 10 ) - goto st8; - goto st22; -st23: - if ( ++p == pe ) - goto _test_eof23; -case 23: - switch( (*p) ) { - case 42: goto st24; - case 47: goto st26; - } - goto st0; -st24: - if ( ++p == pe ) - goto _test_eof24; -case 24: - if ( (*p) == 42 ) - goto st25; - goto st24; -st25: - if ( ++p == pe ) - goto _test_eof25; -case 25: - switch( (*p) ) { - case 42: goto st25; - case 47: goto st2; - } - goto st24; -st26: - if ( ++p == pe ) - goto _test_eof26; -case 26: - if ( (*p) == 10 ) - goto st2; - goto st26; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof18: cs = 18; goto _test_eof; - _test_eof27: cs = 27; goto _test_eof; - _test_eof19: cs = 19; goto _test_eof; - _test_eof20: cs = 20; goto _test_eof; - _test_eof21: cs = 21; goto _test_eof; - _test_eof22: cs = 22; goto _test_eof; - _test_eof23: cs = 23; goto _test_eof; - _test_eof24: cs = 24; goto _test_eof; - _test_eof25: cs = 25; goto _test_eof; - _test_eof26: cs = 26; goto _test_eof; - + break; + case 1: +#line 148 "ext/json/ext/parser/parser.rl" + { + char *np; + json->parsing_name = 1; + np = JSON_parse_string(json, p, pe, &last_name); + json->parsing_name = 0; + if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} + } + break; + case 2: +#line 156 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 317 "ext/json/ext/parser/parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 181 "parser.rl" +#line 182 "ext/json/ext/parser/parser.rl" if (cs >= JSON_object_first_final) { if (json->create_additions) { @@ -480,78 +351,245 @@ case 26: -#line 484 "parser.c" -enum {JSON_value_start = 1}; -enum {JSON_value_first_final = 29}; -enum {JSON_value_error = 0}; +#line 355 "ext/json/ext/parser/parser.c" +static const char _JSON_value_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4, 1, 5, 1, 6, 1, + 7, 1, 8, 1, 9 +}; + +static const char _JSON_value_key_offsets[] = { + 0, 0, 16, 18, 19, 21, 22, 24, + 25, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47 +}; + +static const char _JSON_value_trans_keys[] = { + 13, 32, 34, 45, 47, 73, 78, 91, + 102, 110, 116, 123, 9, 10, 48, 57, + 42, 47, 42, 42, 47, 10, 42, 47, + 42, 42, 47, 10, 110, 102, 105, 110, + 105, 116, 121, 97, 78, 97, 108, 115, + 101, 117, 108, 108, 114, 117, 101, 13, + 32, 47, 9, 10, 0 +}; + +static const char _JSON_value_single_lengths[] = { + 0, 12, 2, 1, 2, 1, 2, 1, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3 +}; + +static const char _JSON_value_range_lengths[] = { + 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1 +}; + +static const char _JSON_value_index_offsets[] = { + 0, 0, 15, 18, 20, 23, 25, 28, + 30, 33, 35, 37, 39, 41, 43, 45, + 47, 49, 51, 53, 55, 57, 59, 61, + 63, 65, 67, 69, 71, 73 +}; + +static const char _JSON_value_trans_targs[] = { + 1, 1, 29, 29, 6, 10, 17, 29, + 19, 23, 26, 29, 1, 29, 0, 3, + 5, 0, 4, 3, 4, 29, 3, 29, + 5, 7, 9, 0, 8, 7, 8, 1, + 7, 1, 9, 11, 0, 12, 0, 13, + 0, 14, 0, 15, 0, 16, 0, 29, + 0, 18, 0, 29, 0, 20, 0, 21, + 0, 22, 0, 29, 0, 24, 0, 25, + 0, 29, 0, 27, 0, 28, 0, 29, + 0, 29, 29, 2, 29, 0, 0 +}; + +static const char _JSON_value_trans_actions[] = { + 0, 0, 11, 13, 0, 0, 0, 15, + 0, 0, 0, 17, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _JSON_value_from_state_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19 +}; + +static const int JSON_value_start = 1; +static const int JSON_value_first_final = 29; +static const int JSON_value_error = 0; -enum {JSON_value_en_main = 1}; +static const int JSON_value_en_main = 1; -#line 281 "parser.rl" +#line 282 "ext/json/ext/parser/parser.rl" static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) { int cs = EVIL; - -#line 500 "parser.c" + +#line 448 "ext/json/ext/parser/parser.c" { cs = JSON_value_start; } -#line 288 "parser.rl" - -#line 507 "parser.c" +#line 289 "ext/json/ext/parser/parser.rl" + +#line 455 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _acts = _JSON_value_actions + _JSON_value_from_state_actions[cs]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { + switch ( *_acts++ ) { + case 9: +#line 269 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 476 "ext/json/ext/parser/parser.c" + } + } + + _keys = _JSON_value_trans_keys + _JSON_value_key_offsets[cs]; + _trans = _JSON_value_index_offsets[cs]; + + _klen = _JSON_value_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_value_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _JSON_value_trans_targs[_trans]; + + if ( _JSON_value_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_value_actions + _JSON_value_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -st1: - if ( ++p == pe ) - goto _test_eof1; -case 1: - switch( (*p) ) { - case 13: goto st1; - case 32: goto st1; - case 34: goto tr2; - case 45: goto tr3; - case 47: goto st6; - case 73: goto st10; - case 78: goto st17; - case 91: goto tr7; - case 102: goto st19; - case 110: goto st23; - case 116: goto st26; - case 123: goto tr11; - } - if ( (*p) > 10 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr3; - } else if ( (*p) >= 9 ) - goto st1; - goto st0; -st0: -cs = 0; - goto _out; -tr2: -#line 233 "parser.rl" + switch ( *_acts++ ) + { + case 0: +#line 211 "ext/json/ext/parser/parser.rl" + { + *result = Qnil; + } + break; + case 1: +#line 214 "ext/json/ext/parser/parser.rl" + { + *result = Qfalse; + } + break; + case 2: +#line 217 "ext/json/ext/parser/parser.rl" + { + *result = Qtrue; + } + break; + case 3: +#line 220 "ext/json/ext/parser/parser.rl" + { + if (json->allow_nan) { + *result = CNaN; + } else { + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); + } + } + break; + case 4: +#line 227 "ext/json/ext/parser/parser.rl" + { + if (json->allow_nan) { + *result = CInfinity; + } else { + rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); + } + } + break; + case 5: +#line 234 "ext/json/ext/parser/parser.rl" { char *np = JSON_parse_string(json, p, pe, result); - if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} } - goto st29; -tr3: -#line 238 "parser.rl" + break; + case 6: +#line 239 "ext/json/ext/parser/parser.rl" { char *np; if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) { if (json->allow_nan) { *result = CMinusInfinity; {p = (( p + 10))-1;} - p--; {p++; cs = 29; goto _out;} + p--; {p++; goto _out; } } else { rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p); } @@ -560,311 +598,39 @@ tr3: if (np != NULL) {p = (( np))-1;} np = JSON_parse_integer(json, p, pe, result); if (np != NULL) {p = (( np))-1;} - p--; {p++; cs = 29; goto _out;} + p--; {p++; goto _out; } } - goto st29; -tr7: -#line 256 "parser.rl" + break; + case 7: +#line 257 "ext/json/ext/parser/parser.rl" { char *np; np = JSON_parse_array(json, p, pe, result, current_nesting + 1); - if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} } - goto st29; -tr11: -#line 262 "parser.rl" + break; + case 8: +#line 263 "ext/json/ext/parser/parser.rl" { char *np; np = JSON_parse_object(json, p, pe, result, current_nesting + 1); - if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;} - } - goto st29; -tr25: -#line 226 "parser.rl" - { - if (json->allow_nan) { - *result = CInfinity; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8); - } + if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} } - goto st29; -tr27: -#line 219 "parser.rl" - { - if (json->allow_nan) { - *result = CNaN; - } else { - rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2); - } - } - goto st29; -tr31: -#line 213 "parser.rl" - { - *result = Qfalse; - } - goto st29; -tr34: -#line 210 "parser.rl" - { - *result = Qnil; - } - goto st29; -tr37: -#line 216 "parser.rl" - { - *result = Qtrue; - } - goto st29; -st29: - if ( ++p == pe ) - goto _test_eof29; -case 29: -#line 268 "parser.rl" - { p--; {p++; cs = 29; goto _out;} } -#line 627 "parser.c" - switch( (*p) ) { - case 13: goto st29; - case 32: goto st29; - case 47: goto st2; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st29; - goto st0; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 42: goto st3; - case 47: goto st5; - } - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - if ( (*p) == 42 ) - goto st4; - goto st3; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - switch( (*p) ) { - case 42: goto st4; - case 47: goto st29; + break; +#line 621 "ext/json/ext/parser/parser.c" + } } - goto st3; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( (*p) == 10 ) - goto st29; - goto st5; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - switch( (*p) ) { - case 42: goto st7; - case 47: goto st9; - } - goto st0; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - if ( (*p) == 42 ) - goto st8; - goto st7; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - switch( (*p) ) { - case 42: goto st8; - case 47: goto st1; - } - goto st7; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: - if ( (*p) == 10 ) - goto st1; - goto st9; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: - if ( (*p) == 110 ) - goto st11; - goto st0; -st11: - if ( ++p == pe ) - goto _test_eof11; -case 11: - if ( (*p) == 102 ) - goto st12; - goto st0; -st12: - if ( ++p == pe ) - goto _test_eof12; -case 12: - if ( (*p) == 105 ) - goto st13; - goto st0; -st13: - if ( ++p == pe ) - goto _test_eof13; -case 13: - if ( (*p) == 110 ) - goto st14; - goto st0; -st14: - if ( ++p == pe ) - goto _test_eof14; -case 14: - if ( (*p) == 105 ) - goto st15; - goto st0; -st15: - if ( ++p == pe ) - goto _test_eof15; -case 15: - if ( (*p) == 116 ) - goto st16; - goto st0; -st16: - if ( ++p == pe ) - goto _test_eof16; -case 16: - if ( (*p) == 121 ) - goto tr25; - goto st0; -st17: - if ( ++p == pe ) - goto _test_eof17; -case 17: - if ( (*p) == 97 ) - goto st18; - goto st0; -st18: - if ( ++p == pe ) - goto _test_eof18; -case 18: - if ( (*p) == 78 ) - goto tr27; - goto st0; -st19: - if ( ++p == pe ) - goto _test_eof19; -case 19: - if ( (*p) == 97 ) - goto st20; - goto st0; -st20: - if ( ++p == pe ) - goto _test_eof20; -case 20: - if ( (*p) == 108 ) - goto st21; - goto st0; -st21: - if ( ++p == pe ) - goto _test_eof21; -case 21: - if ( (*p) == 115 ) - goto st22; - goto st0; -st22: - if ( ++p == pe ) - goto _test_eof22; -case 22: - if ( (*p) == 101 ) - goto tr31; - goto st0; -st23: - if ( ++p == pe ) - goto _test_eof23; -case 23: - if ( (*p) == 117 ) - goto st24; - goto st0; -st24: - if ( ++p == pe ) - goto _test_eof24; -case 24: - if ( (*p) == 108 ) - goto st25; - goto st0; -st25: - if ( ++p == pe ) - goto _test_eof25; -case 25: - if ( (*p) == 108 ) - goto tr34; - goto st0; -st26: - if ( ++p == pe ) - goto _test_eof26; -case 26: - if ( (*p) == 114 ) - goto st27; - goto st0; -st27: - if ( ++p == pe ) - goto _test_eof27; -case 27: - if ( (*p) == 117 ) - goto st28; - goto st0; -st28: - if ( ++p == pe ) - goto _test_eof28; -case 28: - if ( (*p) == 101 ) - goto tr37; - goto st0; - } - _test_eof1: cs = 1; goto _test_eof; - _test_eof29: cs = 29; goto _test_eof; - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof18: cs = 18; goto _test_eof; - _test_eof19: cs = 19; goto _test_eof; - _test_eof20: cs = 20; goto _test_eof; - _test_eof21: cs = 21; goto _test_eof; - _test_eof22: cs = 22; goto _test_eof; - _test_eof23: cs = 23; goto _test_eof; - _test_eof24: cs = 24; goto _test_eof; - _test_eof25: cs = 25; goto _test_eof; - _test_eof26: cs = 26; goto _test_eof; - _test_eof27: cs = 27; goto _test_eof; - _test_eof28: cs = 28; goto _test_eof; +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 289 "parser.rl" +#line 290 "ext/json/ext/parser/parser.rl" if (cs >= JSON_value_first_final) { return p; @@ -874,91 +640,160 @@ case 28: } -#line 878 "parser.c" -enum {JSON_integer_start = 1}; -enum {JSON_integer_first_final = 3}; -enum {JSON_integer_error = 0}; +#line 644 "ext/json/ext/parser/parser.c" +static const char _JSON_integer_actions[] = { + 0, 1, 0 +}; + +static const char _JSON_integer_key_offsets[] = { + 0, 0, 4, 7, 9, 9 +}; + +static const char _JSON_integer_trans_keys[] = { + 45, 48, 49, 57, 48, 49, 57, 48, + 57, 48, 57, 0 +}; + +static const char _JSON_integer_single_lengths[] = { + 0, 2, 1, 0, 0, 0 +}; + +static const char _JSON_integer_range_lengths[] = { + 0, 1, 1, 1, 0, 1 +}; + +static const char _JSON_integer_index_offsets[] = { + 0, 0, 4, 7, 9, 10 +}; + +static const char _JSON_integer_indicies[] = { + 0, 2, 3, 1, 2, 3, 1, 1, + 4, 1, 3, 4, 0 +}; + +static const char _JSON_integer_trans_targs[] = { + 2, 0, 3, 5, 4 +}; + +static const char _JSON_integer_trans_actions[] = { + 0, 0, 0, 0, 1 +}; + +static const int JSON_integer_start = 1; +static const int JSON_integer_first_final = 3; +static const int JSON_integer_error = 0; -enum {JSON_integer_en_main = 1}; +static const int JSON_integer_en_main = 1; -#line 305 "parser.rl" +#line 306 "ext/json/ext/parser/parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; - -#line 894 "parser.c" + +#line 698 "ext/json/ext/parser/parser.c" { cs = JSON_integer_start; } -#line 312 "parser.rl" +#line 313 "ext/json/ext/parser/parser.rl" json->memo = p; - -#line 902 "parser.c" + +#line 706 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_integer_trans_keys + _JSON_integer_key_offsets[cs]; + _trans = _JSON_integer_index_offsets[cs]; + + _klen = _JSON_integer_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_integer_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_integer_indicies[_trans]; + cs = _JSON_integer_trans_targs[_trans]; + + if ( _JSON_integer_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_integer_actions + _JSON_integer_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -case 1: - switch( (*p) ) { - case 45: goto st2; - case 48: goto st3; - } - if ( 49 <= (*p) && (*p) <= 57 ) - goto st5; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - if ( (*p) == 48 ) - goto st3; - if ( 49 <= (*p) && (*p) <= 57 ) - goto st5; - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st0; - goto tr4; -tr4: -#line 302 "parser.rl" - { p--; {p++; cs = 4; goto _out;} } - goto st4; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: -#line 943 "parser.c" - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st5; - goto tr4; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - + switch ( *_acts++ ) + { + case 0: +#line 303 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 784 "ext/json/ext/parser/parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 314 "parser.rl" +#line 315 "ext/json/ext/parser/parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; @@ -973,164 +808,186 @@ case 5: } -#line 977 "parser.c" -enum {JSON_float_start = 1}; -enum {JSON_float_first_final = 8}; -enum {JSON_float_error = 0}; +#line 812 "ext/json/ext/parser/parser.c" +static const char _JSON_float_actions[] = { + 0, 1, 0 +}; + +static const char _JSON_float_key_offsets[] = { + 0, 0, 4, 7, 10, 12, 16, 18, + 23, 29, 29 +}; + +static const char _JSON_float_trans_keys[] = { + 45, 48, 49, 57, 48, 49, 57, 46, + 69, 101, 48, 57, 43, 45, 48, 57, + 48, 57, 46, 69, 101, 48, 57, 69, + 101, 45, 46, 48, 57, 69, 101, 45, + 46, 48, 57, 0 +}; + +static const char _JSON_float_single_lengths[] = { + 0, 2, 1, 3, 0, 2, 0, 3, + 2, 0, 2 +}; + +static const char _JSON_float_range_lengths[] = { + 0, 1, 1, 0, 1, 1, 1, 1, + 2, 0, 2 +}; + +static const char _JSON_float_index_offsets[] = { + 0, 0, 4, 7, 11, 13, 17, 19, + 24, 29, 30 +}; + +static const char _JSON_float_indicies[] = { + 0, 2, 3, 1, 2, 3, 1, 4, + 5, 5, 1, 6, 1, 7, 7, 8, + 1, 8, 1, 4, 5, 5, 3, 1, + 5, 5, 1, 6, 9, 1, 1, 1, + 1, 8, 9, 0 +}; + +static const char _JSON_float_trans_targs[] = { + 2, 0, 3, 7, 4, 5, 8, 6, + 10, 9 +}; + +static const char _JSON_float_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1 +}; + +static const int JSON_float_start = 1; +static const int JSON_float_first_final = 8; +static const int JSON_float_error = 0; -enum {JSON_float_en_main = 1}; +static const int JSON_float_en_main = 1; -#line 339 "parser.rl" +#line 340 "ext/json/ext/parser/parser.rl" static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; - -#line 993 "parser.c" + +#line 878 "ext/json/ext/parser/parser.c" { cs = JSON_float_start; } -#line 346 "parser.rl" +#line 347 "ext/json/ext/parser/parser.rl" json->memo = p; - -#line 1001 "parser.c" + +#line 886 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_float_trans_keys + _JSON_float_key_offsets[cs]; + _trans = _JSON_float_index_offsets[cs]; + + _klen = _JSON_float_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_float_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_float_indicies[_trans]; + cs = _JSON_float_trans_targs[_trans]; + + if ( _JSON_float_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_float_actions + _JSON_float_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -case 1: - switch( (*p) ) { - case 45: goto st2; - case 48: goto st3; - } - if ( 49 <= (*p) && (*p) <= 57 ) - goto st7; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - if ( (*p) == 48 ) - goto st3; - if ( 49 <= (*p) && (*p) <= 57 ) - goto st7; - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - switch( (*p) ) { - case 46: goto st4; - case 69: goto st5; - case 101: goto st5; - } - goto st0; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st8; - goto st0; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - switch( (*p) ) { - case 69: goto st5; - case 101: goto st5; - } - if ( (*p) > 46 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st8; - } else if ( (*p) >= 45 ) - goto st0; - goto tr9; -tr9: -#line 333 "parser.rl" - { p--; {p++; cs = 9; goto _out;} } - goto st9; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: -#line 1066 "parser.c" - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - switch( (*p) ) { - case 43: goto st6; - case 45: goto st6; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st10; - goto st0; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - if ( 48 <= (*p) && (*p) <= 57 ) - goto st10; - goto st0; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: - switch( (*p) ) { - case 69: goto st0; - case 101: goto st0; - } - if ( (*p) > 46 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st10; - } else if ( (*p) >= 45 ) - goto st0; - goto tr9; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - switch( (*p) ) { - case 46: goto st4; - case 69: goto st5; - case 101: goto st5; - } - if ( 48 <= (*p) && (*p) <= 57 ) - goto st7; - goto st0; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - + switch ( *_acts++ ) + { + case 0: +#line 334 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 964 "ext/json/ext/parser/parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 348 "parser.rl" +#line 349 "ext/json/ext/parser/parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; fbuffer_clear(json->fbuffer); fbuffer_append(json->fbuffer, json->memo, len); fbuffer_append_char(json->fbuffer, '\0'); - *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); + if (NIL_P(json->decimal_class)) { + *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); + } + else { + VALUE text; + text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); + *result = rb_funcall(json->decimal_class, i_new, 1, text); + } return p + 1; } else { return NULL; @@ -1139,15 +996,78 @@ case 7: -#line 1143 "parser.c" -enum {JSON_array_start = 1}; -enum {JSON_array_first_final = 17}; -enum {JSON_array_error = 0}; +#line 1000 "ext/json/ext/parser/parser.c" +static const char _JSON_array_actions[] = { + 0, 1, 0, 1, 1 +}; -enum {JSON_array_en_main = 1}; +static const char _JSON_array_key_offsets[] = { + 0, 0, 1, 18, 25, 41, 43, 44, + 46, 47, 49, 50, 52, 53, 55, 56, + 58, 59 +}; +static const char _JSON_array_trans_keys[] = { + 91, 13, 32, 34, 45, 47, 73, 78, + 91, 93, 102, 110, 116, 123, 9, 10, + 48, 57, 13, 32, 44, 47, 93, 9, + 10, 13, 32, 34, 45, 47, 73, 78, + 91, 102, 110, 116, 123, 9, 10, 48, + 57, 42, 47, 42, 42, 47, 10, 42, + 47, 42, 42, 47, 10, 42, 47, 42, + 42, 47, 10, 0 +}; -#line 391 "parser.rl" +static const char _JSON_array_single_lengths[] = { + 0, 1, 13, 5, 12, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 0 +}; + +static const char _JSON_array_range_lengths[] = { + 0, 0, 2, 1, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +static const char _JSON_array_index_offsets[] = { + 0, 0, 2, 18, 25, 40, 43, 45, + 48, 50, 53, 55, 58, 60, 63, 65, + 68, 70 +}; + +static const char _JSON_array_indicies[] = { + 0, 1, 0, 0, 2, 2, 3, 2, + 2, 2, 4, 2, 2, 2, 2, 0, + 2, 1, 5, 5, 6, 7, 4, 5, + 1, 6, 6, 2, 2, 8, 2, 2, + 2, 2, 2, 2, 2, 6, 2, 1, + 9, 10, 1, 11, 9, 11, 6, 9, + 6, 10, 12, 13, 1, 14, 12, 14, + 5, 12, 5, 13, 15, 16, 1, 17, + 15, 17, 0, 15, 0, 16, 1, 0 +}; + +static const char _JSON_array_trans_targs[] = { + 2, 0, 3, 13, 17, 3, 4, 9, + 5, 6, 8, 7, 10, 12, 11, 14, + 16, 15 +}; + +static const char _JSON_array_trans_actions[] = { + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +static const int JSON_array_start = 1; +static const int JSON_array_first_final = 17; +static const int JSON_array_error = 0; + +static const int JSON_array_en_main = 1; + + +#line 399 "ext/json/ext/parser/parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -1160,59 +1080,95 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul } *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); - -#line 1165 "parser.c" + +#line 1085 "ext/json/ext/parser/parser.c" { cs = JSON_array_start; } -#line 404 "parser.rl" - -#line 1172 "parser.c" +#line 412 "ext/json/ext/parser/parser.rl" + +#line 1092 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_array_trans_keys + _JSON_array_key_offsets[cs]; + _trans = _JSON_array_index_offsets[cs]; + + _klen = _JSON_array_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_array_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_array_indicies[_trans]; + cs = _JSON_array_trans_targs[_trans]; + + if ( _JSON_array_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_array_actions + _JSON_array_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -case 1: - if ( (*p) == 91 ) - goto st2; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 13: goto st2; - case 32: goto st2; - case 34: goto tr2; - case 45: goto tr2; - case 47: goto st13; - case 73: goto tr2; - case 78: goto tr2; - case 91: goto tr2; - case 93: goto tr4; - case 102: goto tr2; - case 110: goto tr2; - case 116: goto tr2; - case 123: goto tr2; - } - if ( (*p) > 10 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr2; - } else if ( (*p) >= 9 ) - goto st2; - goto st0; -tr2: -#line 368 "parser.rl" + switch ( *_acts++ ) + { + case 0: +#line 376 "ext/json/ext/parser/parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); if (np == NULL) { - p--; {p++; cs = 3; goto _out;} + p--; {p++; goto _out; } } else { if (NIL_P(json->array_class)) { rb_ary_push(*result, v); @@ -1222,175 +1178,25 @@ tr2: {p = (( np))-1;} } } - goto st3; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: -#line 1231 "parser.c" - switch( (*p) ) { - case 13: goto st3; - case 32: goto st3; - case 44: goto st4; - case 47: goto st9; - case 93: goto tr4; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st3; - goto st0; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - switch( (*p) ) { - case 13: goto st4; - case 32: goto st4; - case 34: goto tr2; - case 45: goto tr2; - case 47: goto st5; - case 73: goto tr2; - case 78: goto tr2; - case 91: goto tr2; - case 102: goto tr2; - case 110: goto tr2; - case 116: goto tr2; - case 123: goto tr2; - } - if ( (*p) > 10 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr2; - } else if ( (*p) >= 9 ) - goto st4; - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - switch( (*p) ) { - case 42: goto st6; - case 47: goto st8; - } - goto st0; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - if ( (*p) == 42 ) - goto st7; - goto st6; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - switch( (*p) ) { - case 42: goto st7; - case 47: goto st4; - } - goto st6; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - if ( (*p) == 10 ) - goto st4; - goto st8; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: - switch( (*p) ) { - case 42: goto st10; - case 47: goto st12; - } - goto st0; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: - if ( (*p) == 42 ) - goto st11; - goto st10; -st11: - if ( ++p == pe ) - goto _test_eof11; -case 11: - switch( (*p) ) { - case 42: goto st11; - case 47: goto st3; - } - goto st10; -st12: - if ( ++p == pe ) - goto _test_eof12; -case 12: - if ( (*p) == 10 ) - goto st3; - goto st12; -tr4: -#line 383 "parser.rl" - { p--; {p++; cs = 17; goto _out;} } - goto st17; -st17: - if ( ++p == pe ) - goto _test_eof17; -case 17: -#line 1338 "parser.c" - goto st0; -st13: - if ( ++p == pe ) - goto _test_eof13; -case 13: - switch( (*p) ) { - case 42: goto st14; - case 47: goto st16; - } - goto st0; -st14: - if ( ++p == pe ) - goto _test_eof14; -case 14: - if ( (*p) == 42 ) - goto st15; - goto st14; -st15: - if ( ++p == pe ) - goto _test_eof15; -case 15: - switch( (*p) ) { - case 42: goto st15; - case 47: goto st2; - } - goto st14; -st16: - if ( ++p == pe ) - goto _test_eof16; -case 16: - if ( (*p) == 10 ) - goto st2; - goto st16; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof11: cs = 11; goto _test_eof; - _test_eof12: cs = 12; goto _test_eof; - _test_eof17: cs = 17; goto _test_eof; - _test_eof13: cs = 13; goto _test_eof; - _test_eof14: cs = 14; goto _test_eof; - _test_eof15: cs = 15; goto _test_eof; - _test_eof16: cs = 16; goto _test_eof; - + break; + case 1: +#line 391 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 1187 "ext/json/ext/parser/parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 405 "parser.rl" +#line 413 "ext/json/ext/parser/parser.rl" if(cs >= JSON_array_first_final) { return p + 1; @@ -1471,15 +1277,62 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1475 "parser.c" -enum {JSON_string_start = 1}; -enum {JSON_string_first_final = 8}; -enum {JSON_string_error = 0}; +#line 1281 "ext/json/ext/parser/parser.c" +static const char _JSON_string_actions[] = { + 0, 2, 0, 1 +}; -enum {JSON_string_en_main = 1}; +static const char _JSON_string_key_offsets[] = { + 0, 0, 1, 5, 8, 14, 20, 26, + 32 +}; +static const char _JSON_string_trans_keys[] = { + 34, 34, 92, 0, 31, 117, 0, 31, + 48, 57, 65, 70, 97, 102, 48, 57, + 65, 70, 97, 102, 48, 57, 65, 70, + 97, 102, 48, 57, 65, 70, 97, 102, + 0 +}; -#line 504 "parser.rl" +static const char _JSON_string_single_lengths[] = { + 0, 1, 2, 1, 0, 0, 0, 0, + 0 +}; + +static const char _JSON_string_range_lengths[] = { + 0, 0, 1, 1, 3, 3, 3, 3, + 0 +}; + +static const char _JSON_string_index_offsets[] = { + 0, 0, 2, 6, 9, 13, 17, 21, + 25 +}; + +static const char _JSON_string_indicies[] = { + 0, 1, 2, 3, 1, 0, 4, 1, + 0, 5, 5, 5, 1, 6, 6, 6, + 1, 7, 7, 7, 1, 0, 0, 0, + 1, 1, 0 +}; + +static const char _JSON_string_trans_targs[] = { + 2, 0, 8, 3, 4, 5, 6, 7 +}; + +static const char _JSON_string_trans_actions[] = { + 0, 0, 1, 0, 0, 0, 0, 0 +}; + +static const int JSON_string_start = 1; +static const int JSON_string_first_final = 8; +static const int JSON_string_error = 0; + +static const int JSON_string_en_main = 1; + + +#line 512 "ext/json/ext/parser/parser.rl" static int @@ -1500,135 +1353,120 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu VALUE match_string; *result = rb_str_buf_new(0); - -#line 1505 "parser.c" + +#line 1358 "ext/json/ext/parser/parser.c" { cs = JSON_string_start; } -#line 525 "parser.rl" +#line 533 "ext/json/ext/parser/parser.rl" json->memo = p; - -#line 1513 "parser.c" + +#line 1366 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_string_trans_keys + _JSON_string_key_offsets[cs]; + _trans = _JSON_string_index_offsets[cs]; + + _klen = _JSON_string_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_string_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_string_indicies[_trans]; + cs = _JSON_string_trans_targs[_trans]; + + if ( _JSON_string_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_string_actions + _JSON_string_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -case 1: - if ( (*p) == 34 ) - goto st2; - goto st0; -st0: -cs = 0; - goto _out; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 34: goto tr2; - case 92: goto st3; - } - if ( 0 <= (*p) && (*p) <= 31 ) - goto st0; - goto st2; -tr2: -#line 490 "parser.rl" + switch ( *_acts++ ) + { + case 0: +#line 498 "ext/json/ext/parser/parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { p--; - {p++; cs = 8; goto _out;} + {p++; goto _out; } } else { FORCE_UTF8(*result); {p = (( p + 1))-1;} } } -#line 501 "parser.rl" - { p--; {p++; cs = 8; goto _out;} } - goto st8; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: -#line 1556 "parser.c" - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - if ( (*p) == 117 ) - goto st4; - if ( 0 <= (*p) && (*p) <= 31 ) - goto st0; - goto st2; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st5; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st5; - } else - goto st5; - goto st0; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st6; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st6; - } else - goto st6; - goto st0; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st7; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st7; - } else - goto st7; - goto st0; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st2; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st2; - } else - goto st2; - goto st0; - } - _test_eof2: cs = 2; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - + break; + case 1: +#line 509 "ext/json/ext/parser/parser.rl" + { p--; {p++; goto _out; } } + break; +#line 1457 "ext/json/ext/parser/parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 527 "parser.rl" +#line 535 "ext/json/ext/parser/parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1781,6 +1619,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->array_class = Qnil; } + tmp = ID2SYM(i_decimal_class); + if (option_given_p(opts, tmp)) { + json->decimal_class = rb_hash_aref(opts, tmp); + } else { + json->decimal_class = Qnil; + } tmp = ID2SYM(i_match_string); if (option_given_p(opts, tmp)) { VALUE match_string = rb_hash_aref(opts, tmp); @@ -1798,6 +1642,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) json->create_id = rb_funcall(mJSON, i_create_id, 0); json->object_class = Qnil; json->array_class = Qnil; + json->decimal_class = Qnil; } source = convert_encoding(StringValue(source)); StringValue(source); @@ -1808,15 +1653,66 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1812 "parser.c" -enum {JSON_start = 1}; -enum {JSON_first_final = 10}; -enum {JSON_error = 0}; +#line 1657 "ext/json/ext/parser/parser.c" +static const char _JSON_actions[] = { + 0, 1, 0 +}; -enum {JSON_en_main = 1}; +static const char _JSON_key_offsets[] = { + 0, 0, 16, 18, 19, 21, 22, 24, + 25, 27, 28 +}; +static const char _JSON_trans_keys[] = { + 13, 32, 34, 45, 47, 73, 78, 91, + 102, 110, 116, 123, 9, 10, 48, 57, + 42, 47, 42, 42, 47, 10, 42, 47, + 42, 42, 47, 10, 13, 32, 47, 9, + 10, 0 +}; -#line 720 "parser.rl" +static const char _JSON_single_lengths[] = { + 0, 12, 2, 1, 2, 1, 2, 1, + 2, 1, 3 +}; + +static const char _JSON_range_lengths[] = { + 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 1 +}; + +static const char _JSON_index_offsets[] = { + 0, 0, 15, 18, 20, 23, 25, 28, + 30, 33, 35 +}; + +static const char _JSON_indicies[] = { + 0, 0, 2, 2, 3, 2, 2, 2, + 2, 2, 2, 2, 0, 2, 1, 4, + 5, 1, 6, 4, 6, 7, 4, 7, + 5, 8, 9, 1, 10, 8, 10, 0, + 8, 0, 9, 7, 7, 11, 7, 1, + 0 +}; + +static const char _JSON_trans_targs[] = { + 1, 0, 10, 6, 3, 5, 4, 10, + 7, 9, 8, 2 +}; + +static const char _JSON_trans_actions[] = { + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; + +static const int JSON_start = 1; +static const int JSON_first_final = 10; +static const int JSON_error = 0; + +static const int JSON_en_main = 1; + + +#line 735 "ext/json/ext/parser/parser.rl" /* @@ -1832,150 +1728,111 @@ static VALUE cParser_parse(VALUE self) VALUE result = Qnil; GET_PARSER; - -#line 1837 "parser.c" + +#line 1733 "ext/json/ext/parser/parser.c" { cs = JSON_start; } -#line 736 "parser.rl" +#line 751 "ext/json/ext/parser/parser.rl" p = json->source; pe = p + json->len; - -#line 1846 "parser.c" + +#line 1742 "ext/json/ext/parser/parser.c" { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + if ( p == pe ) goto _test_eof; - switch ( cs ) + if ( cs == 0 ) + goto _out; +_resume: + _keys = _JSON_trans_keys + _JSON_key_offsets[cs]; + _trans = _JSON_index_offsets[cs]; + + _klen = _JSON_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _JSON_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _JSON_indicies[_trans]; + cs = _JSON_trans_targs[_trans]; + + if ( _JSON_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _JSON_actions + _JSON_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { -st1: - if ( ++p == pe ) - goto _test_eof1; -case 1: - switch( (*p) ) { - case 13: goto st1; - case 32: goto st1; - case 34: goto tr2; - case 45: goto tr2; - case 47: goto st6; - case 73: goto tr2; - case 78: goto tr2; - case 91: goto tr2; - case 102: goto tr2; - case 110: goto tr2; - case 116: goto tr2; - case 123: goto tr2; - } - if ( (*p) > 10 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto tr2; - } else if ( (*p) >= 9 ) - goto st1; - goto st0; -st0: -cs = 0; - goto _out; -tr2: -#line 712 "parser.rl" + switch ( *_acts++ ) + { + case 0: +#line 727 "ext/json/ext/parser/parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); - if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} + if (np == NULL) { p--; {p++; goto _out; } } else {p = (( np))-1;} } - goto st10; -st10: - if ( ++p == pe ) - goto _test_eof10; -case 10: -#line 1890 "parser.c" - switch( (*p) ) { - case 13: goto st10; - case 32: goto st10; - case 47: goto st2; - } - if ( 9 <= (*p) && (*p) <= 10 ) - goto st10; - goto st0; -st2: - if ( ++p == pe ) - goto _test_eof2; -case 2: - switch( (*p) ) { - case 42: goto st3; - case 47: goto st5; - } - goto st0; -st3: - if ( ++p == pe ) - goto _test_eof3; -case 3: - if ( (*p) == 42 ) - goto st4; - goto st3; -st4: - if ( ++p == pe ) - goto _test_eof4; -case 4: - switch( (*p) ) { - case 42: goto st4; - case 47: goto st10; - } - goto st3; -st5: - if ( ++p == pe ) - goto _test_eof5; -case 5: - if ( (*p) == 10 ) - goto st10; - goto st5; -st6: - if ( ++p == pe ) - goto _test_eof6; -case 6: - switch( (*p) ) { - case 42: goto st7; - case 47: goto st9; - } - goto st0; -st7: - if ( ++p == pe ) - goto _test_eof7; -case 7: - if ( (*p) == 42 ) - goto st8; - goto st7; -st8: - if ( ++p == pe ) - goto _test_eof8; -case 8: - switch( (*p) ) { - case 42: goto st8; - case 47: goto st1; - } - goto st7; -st9: - if ( ++p == pe ) - goto _test_eof9; -case 9: - if ( (*p) == 10 ) - goto st1; - goto st9; + break; +#line 1823 "ext/json/ext/parser/parser.c" + } } - _test_eof1: cs = 1; goto _test_eof; - _test_eof10: cs = 10; goto _test_eof; - _test_eof2: cs = 2; goto _test_eof; - _test_eof3: cs = 3; goto _test_eof; - _test_eof4: cs = 4; goto _test_eof; - _test_eof5: cs = 5; goto _test_eof; - _test_eof6: cs = 6; goto _test_eof; - _test_eof7: cs = 7; goto _test_eof; - _test_eof8: cs = 8; goto _test_eof; - _test_eof9: cs = 9; goto _test_eof; +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; _test_eof: {} _out: {} } -#line 739 "parser.rl" +#line 754 "ext/json/ext/parser/parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -1992,6 +1849,7 @@ static void JSON_mark(void *ptr) rb_gc_mark_maybe(json->create_id); rb_gc_mark_maybe(json->object_class); rb_gc_mark_maybe(json->array_class); + rb_gc_mark_maybe(json->decimal_class); rb_gc_mark_maybe(json->match_string); } @@ -2066,6 +1924,7 @@ void Init_parser(void) i_symbolize_names = rb_intern("symbolize_names"); i_object_class = rb_intern("object_class"); i_array_class = rb_intern("array_class"); + i_decimal_class = rb_intern("decimal_class"); i_match = rb_intern("match"); i_match_string = rb_intern("match_string"); i_key_p = rb_intern("key?"); diff --git a/ext/json/ext/parser/parser.h b/ext/json/ext/parser/parser.h index 1d46831..e6cf779 100644 --- a/ext/json/ext/parser/parser.h +++ b/ext/json/ext/parser/parser.h @@ -39,6 +39,7 @@ typedef struct JSON_ParserStruct { int symbolize_names; VALUE object_class; VALUE array_class; + VALUE decimal_class; int create_additions; VALUE match_string; FBuffer *fbuffer; diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index dd24cf9..03b4c89 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -92,8 +92,9 @@ static VALUE CNaN, CInfinity, CMinusInfinity; static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, - i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match, - i_match_string, i_aset, i_aref, i_leftshift; + i_object_class, i_array_class, i_decimal_class, i_key_p, + i_deep_const_get, i_match, i_match_string, i_aset, i_aref, + i_leftshift, i_new; %%{ machine JSON_common; @@ -351,7 +352,14 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul fbuffer_clear(json->fbuffer); fbuffer_append(json->fbuffer, json->memo, len); fbuffer_append_char(json->fbuffer, '\0'); - *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); + if (NIL_P(json->decimal_class)) { + *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1)); + } + else { + VALUE text; + text = rb_str_new2(FBUFFER_PTR(json->fbuffer)); + *result = rb_funcall(json->decimal_class, i_new, 1, text); + } return p + 1; } else { return NULL; @@ -676,6 +684,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->array_class = Qnil; } + tmp = ID2SYM(i_decimal_class); + if (option_given_p(opts, tmp)) { + json->decimal_class = rb_hash_aref(opts, tmp); + } else { + json->decimal_class = Qnil; + } tmp = ID2SYM(i_match_string); if (option_given_p(opts, tmp)) { VALUE match_string = rb_hash_aref(opts, tmp); @@ -693,6 +707,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) json->create_id = rb_funcall(mJSON, i_create_id, 0); json->object_class = Qnil; json->array_class = Qnil; + json->decimal_class = Qnil; } source = convert_encoding(StringValue(source)); StringValue(source); @@ -752,6 +767,7 @@ static void JSON_mark(void *ptr) rb_gc_mark_maybe(json->create_id); rb_gc_mark_maybe(json->object_class); rb_gc_mark_maybe(json->array_class); + rb_gc_mark_maybe(json->decimal_class); rb_gc_mark_maybe(json->match_string); } @@ -826,6 +842,7 @@ void Init_parser(void) i_symbolize_names = rb_intern("symbolize_names"); i_object_class = rb_intern("object_class"); i_array_class = rb_intern("array_class"); + i_decimal_class = rb_intern("decimal_class"); i_match = rb_intern("match"); i_match_string = rb_intern("match_string"); i_key_p = rb_intern("key?"); diff --git a/java/json.gemspec b/java/json.gemspec new file mode 100644 index 0000000..c1cc094 --- /dev/null +++ b/java/json.gemspec @@ -0,0 +1,38 @@ +#!/usr/bin/env jruby +require "rubygems" + +spec = Gem::Specification.new do |s| + s.name = "json" + s.version = File.read("../VERSION").chomp + s.summary = "JSON implementation for JRuby" + s.description = "A JSON implementation as a JRuby extension." + s.author = "Daniel Luz" + s.email = "dev+ruby@mernen.com" + s.homepage = "http://json-jruby.rubyforge.org/" + s.platform = 'java' + s.rubyforge_project = "json-jruby" + s.licenses = ["Ruby"] + + s.files = Dir["{docs,lib,tests}/**/*"] + + if s.respond_to? :specification_version then + s.specification_version = 4 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 2.0"]) + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) + end + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) + end +end + +if $0 == __FILE__ + Gem::Builder.new(spec).build +else + spec +end diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index 2a7d9f5..2ba9f8f 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -54,6 +54,7 @@ public class Parser extends RubyObject { private boolean symbolizeNames; private RubyClass objectClass; private RubyClass arrayClass; + private RubyClass decimalClass; private RubyHash matchString; private static final int DEFAULT_MAX_NESTING = 100; @@ -133,6 +134,10 @@ public class Parser extends RubyObject { *
:array_class *
Defaults to Array. * + *
:decimal_class + *
Specifies which class to use instead of the default (Float) when + * parsing decimal numbers. This class must accept a single string argument + * in its constructor. * */ @JRubyMethod(name = "new", required = 1, optional = 1, meta = true) @@ -159,6 +164,7 @@ public class Parser extends RubyObject { this.createAdditions = opts.getBool("create_additions", false); this.objectClass = opts.getClass("object_class", runtime.getHash()); this.arrayClass = opts.getClass("array_class", runtime.getArray()); + this.decimalClass = opts.getClass("decimal_class", null); this.matchString = opts.getHash("match_string"); if(symbolizeNames && createAdditions) { @@ -307,11 +313,11 @@ public class Parser extends RubyObject { } -// line 333 "Parser.rl" +// line 339 "Parser.rl" -// line 315 "Parser.java" +// line 321 "Parser.java" private static byte[] init__JSON_value_actions_0() { return new byte [] { @@ -425,7 +431,7 @@ static final int JSON_value_error = 0; static final int JSON_value_en_main = 1; -// line 439 "Parser.rl" +// line 445 "Parser.rl" void parseValue(ParserResult res, int p, int pe) { @@ -433,14 +439,14 @@ static final int JSON_value_en_main = 1; IRubyObject result = null; -// line 437 "Parser.java" +// line 443 "Parser.java" { cs = JSON_value_start; } -// line 446 "Parser.rl" +// line 452 "Parser.rl" -// line 444 "Parser.java" +// line 450 "Parser.java" { int _klen; int _trans = 0; @@ -466,13 +472,13 @@ case 1: while ( _nacts-- > 0 ) { switch ( _JSON_value_actions[_acts++] ) { case 9: -// line 424 "Parser.rl" +// line 430 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 476 "Parser.java" +// line 482 "Parser.java" } } @@ -535,25 +541,25 @@ case 1: switch ( _JSON_value_actions[_acts++] ) { case 0: -// line 341 "Parser.rl" +// line 347 "Parser.rl" { result = getRuntime().getNil(); } break; case 1: -// line 344 "Parser.rl" +// line 350 "Parser.rl" { result = getRuntime().getFalse(); } break; case 2: -// line 347 "Parser.rl" +// line 353 "Parser.rl" { result = getRuntime().getTrue(); } break; case 3: -// line 350 "Parser.rl" +// line 356 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_NAN); @@ -563,7 +569,7 @@ case 1: } break; case 4: -// line 357 "Parser.rl" +// line 363 "Parser.rl" { if (parser.allowNaN) { result = getConstant(CONST_INFINITY); @@ -573,7 +579,7 @@ case 1: } break; case 5: -// line 364 "Parser.rl" +// line 370 "Parser.rl" { if (pe > p + 8 && absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) { @@ -602,7 +608,7 @@ case 1: } break; case 6: -// line 390 "Parser.rl" +// line 396 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -615,7 +621,7 @@ case 1: } break; case 7: -// line 400 "Parser.rl" +// line 406 "Parser.rl" { currentNesting++; parseArray(res, p, pe); @@ -630,7 +636,7 @@ case 1: } break; case 8: -// line 412 "Parser.rl" +// line 418 "Parser.rl" { currentNesting++; parseObject(res, p, pe); @@ -644,7 +650,7 @@ case 1: } } break; -// line 648 "Parser.java" +// line 654 "Parser.java" } } } @@ -664,7 +670,7 @@ case 5: break; } } -// line 447 "Parser.rl" +// line 453 "Parser.rl" if (cs >= JSON_value_first_final && result != null) { res.update(result, p); @@ -674,7 +680,7 @@ case 5: } -// line 678 "Parser.java" +// line 684 "Parser.java" private static byte[] init__JSON_integer_actions_0() { return new byte [] { @@ -773,7 +779,7 @@ static final int JSON_integer_error = 0; static final int JSON_integer_en_main = 1; -// line 466 "Parser.rl" +// line 472 "Parser.rl" void parseInteger(ParserResult res, int p, int pe) { @@ -791,15 +797,15 @@ static final int JSON_integer_en_main = 1; int cs = EVIL; -// line 795 "Parser.java" +// line 801 "Parser.java" { cs = JSON_integer_start; } -// line 483 "Parser.rl" +// line 489 "Parser.rl" int memo = p; -// line 803 "Parser.java" +// line 809 "Parser.java" { int _klen; int _trans = 0; @@ -880,13 +886,13 @@ case 1: switch ( _JSON_integer_actions[_acts++] ) { case 0: -// line 460 "Parser.rl" +// line 466 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 890 "Parser.java" +// line 896 "Parser.java" } } } @@ -906,7 +912,7 @@ case 5: break; } } -// line 485 "Parser.rl" +// line 491 "Parser.rl" if (cs < JSON_integer_first_final) { return -1; @@ -914,13 +920,13 @@ case 5: return p; } - + RubyInteger createInteger(int p, int new_p) { Ruby runtime = getRuntime(); ByteList num = absSubSequence(p, new_p); return bytesToInum(runtime, num); } - + RubyInteger bytesToInum(Ruby runtime, ByteList num) { return runtime.is1_9() ? ConvertBytes.byteListToInum19(runtime, num, 10, true) : @@ -928,7 +934,7 @@ case 5: } -// line 932 "Parser.java" +// line 938 "Parser.java" private static byte[] init__JSON_float_actions_0() { return new byte [] { @@ -1030,7 +1036,7 @@ static final int JSON_float_error = 0; static final int JSON_float_en_main = 1; -// line 520 "Parser.rl" +// line 526 "Parser.rl" void parseFloat(ParserResult res, int p, int pe) { @@ -1039,7 +1045,9 @@ static final int JSON_float_en_main = 1; res.update(null, p); return; } - RubyFloat number = createFloat(p, new_p); + IRubyObject number = parser.decimalClass == null ? + createFloat(p, new_p) : createCustomDecimal(p, new_p); + res.update(number, new_p + 1); return; } @@ -1048,15 +1056,15 @@ static final int JSON_float_en_main = 1; int cs = EVIL; -// line 1052 "Parser.java" +// line 1060 "Parser.java" { cs = JSON_float_start; } -// line 537 "Parser.rl" +// line 545 "Parser.rl" int memo = p; -// line 1060 "Parser.java" +// line 1068 "Parser.java" { int _klen; int _trans = 0; @@ -1137,13 +1145,13 @@ case 1: switch ( _JSON_float_actions[_acts++] ) { case 0: -// line 511 "Parser.rl" +// line 517 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1147 "Parser.java" +// line 1155 "Parser.java" } } } @@ -1163,23 +1171,30 @@ case 5: break; } } -// line 539 "Parser.rl" +// line 547 "Parser.rl" if (cs < JSON_float_first_final) { return -1; } - + return p; } - + RubyFloat createFloat(int p, int new_p) { Ruby runtime = getRuntime(); ByteList num = absSubSequence(p, new_p); return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9())); } + IRubyObject createCustomDecimal(int p, int new_p) { + Ruby runtime = getRuntime(); + ByteList num = absSubSequence(p, new_p); + IRubyObject numString = runtime.newString(num.toString()); + return parser.decimalClass.callMethod(context, "new", numString); + } + -// line 1183 "Parser.java" +// line 1198 "Parser.java" private static byte[] init__JSON_string_actions_0() { return new byte [] { @@ -1281,7 +1296,7 @@ static final int JSON_string_error = 0; static final int JSON_string_en_main = 1; -// line 584 "Parser.rl" +// line 599 "Parser.rl" void parseString(ParserResult res, int p, int pe) { @@ -1289,15 +1304,15 @@ static final int JSON_string_en_main = 1; IRubyObject result = null; -// line 1293 "Parser.java" +// line 1308 "Parser.java" { cs = JSON_string_start; } -// line 591 "Parser.rl" +// line 606 "Parser.rl" int memo = p; -// line 1301 "Parser.java" +// line 1316 "Parser.java" { int _klen; int _trans = 0; @@ -1378,7 +1393,7 @@ case 1: switch ( _JSON_string_actions[_acts++] ) { case 0: -// line 559 "Parser.rl" +// line 574 "Parser.rl" { int offset = byteList.begin(); ByteList decoded = decoder.decode(byteList, memo + 1 - offset, @@ -1393,13 +1408,13 @@ case 1: } break; case 1: -// line 572 "Parser.rl" +// line 587 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1403 "Parser.java" +// line 1418 "Parser.java" } } } @@ -1419,7 +1434,7 @@ case 5: break; } } -// line 593 "Parser.rl" +// line 608 "Parser.rl" if (parser.createAdditions) { RubyHash matchString = parser.matchString; @@ -1446,7 +1461,7 @@ case 5: } } - if (cs >= JSON_string_first_final && result != null) { + if (cs >= JSON_string_first_final && result != null) { if (result instanceof RubyString) { ((RubyString)result).force_encoding(context, info.utf8.get()); } @@ -1457,7 +1472,7 @@ case 5: } -// line 1461 "Parser.java" +// line 1476 "Parser.java" private static byte[] init__JSON_array_actions_0() { return new byte [] { @@ -1570,7 +1585,7 @@ static final int JSON_array_error = 0; static final int JSON_array_en_main = 1; -// line 666 "Parser.rl" +// line 681 "Parser.rl" void parseArray(ParserResult res, int p, int pe) { @@ -1590,14 +1605,14 @@ static final int JSON_array_en_main = 1; } -// line 1594 "Parser.java" +// line 1609 "Parser.java" { cs = JSON_array_start; } -// line 685 "Parser.rl" +// line 700 "Parser.rl" -// line 1601 "Parser.java" +// line 1616 "Parser.java" { int _klen; int _trans = 0; @@ -1678,7 +1693,7 @@ case 1: switch ( _JSON_array_actions[_acts++] ) { case 0: -// line 635 "Parser.rl" +// line 650 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1695,13 +1710,13 @@ case 1: } break; case 1: -// line 650 "Parser.rl" +// line 665 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 1705 "Parser.java" +// line 1720 "Parser.java" } } } @@ -1721,7 +1736,7 @@ case 5: break; } } -// line 686 "Parser.rl" +// line 701 "Parser.rl" if (cs >= JSON_array_first_final) { res.update(result, p + 1); @@ -1731,7 +1746,7 @@ case 5: } -// line 1735 "Parser.java" +// line 1750 "Parser.java" private static byte[] init__JSON_object_actions_0() { return new byte [] { @@ -1854,7 +1869,7 @@ static final int JSON_object_error = 0; static final int JSON_object_en_main = 1; -// line 745 "Parser.rl" +// line 760 "Parser.rl" void parseObject(ParserResult res, int p, int pe) { @@ -1879,14 +1894,14 @@ static final int JSON_object_en_main = 1; } -// line 1883 "Parser.java" +// line 1898 "Parser.java" { cs = JSON_object_start; } -// line 769 "Parser.rl" +// line 784 "Parser.rl" -// line 1890 "Parser.java" +// line 1905 "Parser.java" { int _klen; int _trans = 0; @@ -1967,7 +1982,7 @@ case 1: switch ( _JSON_object_actions[_acts++] ) { case 0: -// line 700 "Parser.rl" +// line 715 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -1984,7 +1999,7 @@ case 1: } break; case 1: -// line 715 "Parser.rl" +// line 730 "Parser.rl" { parseString(res, p, pe); if (res.result == null) { @@ -2004,13 +2019,13 @@ case 1: } break; case 2: -// line 733 "Parser.rl" +// line 748 "Parser.rl" { p--; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; -// line 2014 "Parser.java" +// line 2029 "Parser.java" } } } @@ -2030,7 +2045,7 @@ case 5: break; } } -// line 770 "Parser.rl" +// line 785 "Parser.rl" if (cs < JSON_object_first_final) { res.update(null, p + 1); @@ -2063,7 +2078,7 @@ case 5: } -// line 2067 "Parser.java" +// line 2082 "Parser.java" private static byte[] init__JSON_actions_0() { return new byte [] { @@ -2166,7 +2181,7 @@ static final int JSON_error = 0; static final int JSON_en_main = 1; -// line 821 "Parser.rl" +// line 836 "Parser.rl" public IRubyObject parseImplemetation() { @@ -2176,16 +2191,16 @@ static final int JSON_en_main = 1; ParserResult res = new ParserResult(); -// line 2180 "Parser.java" +// line 2195 "Parser.java" { cs = JSON_start; } -// line 830 "Parser.rl" +// line 845 "Parser.rl" p = byteList.begin(); pe = p + byteList.length(); -// line 2189 "Parser.java" +// line 2204 "Parser.java" { int _klen; int _trans = 0; @@ -2266,7 +2281,7 @@ case 1: switch ( _JSON_actions[_acts++] ) { case 0: -// line 807 "Parser.rl" +// line 822 "Parser.rl" { parseValue(res, p, pe); if (res.result == null) { @@ -2278,7 +2293,7 @@ case 1: } } break; -// line 2282 "Parser.java" +// line 2297 "Parser.java" } } } @@ -2298,7 +2313,7 @@ case 5: break; } } -// line 833 "Parser.rl" +// line 848 "Parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 1ad8f21..4d170e1 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -52,7 +52,8 @@ public class Parser extends RubyObject { private boolean symbolizeNames; private RubyClass objectClass; private RubyClass arrayClass; - private RubyHash matchString; + private RubyClass decimalClass; + private RubyHash match_string; private static final int DEFAULT_MAX_NESTING = 100; @@ -131,6 +132,10 @@ public class Parser extends RubyObject { *
:array_class *
Defaults to Array. * + *
:decimal_class + *
Specifies which class to use instead of the default (Float) when + * parsing decimal numbers. This class must accept a single string argument + * in its constructor. * */ @JRubyMethod(name = "new", required = 1, optional = 1, meta = true) @@ -157,7 +162,8 @@ public class Parser extends RubyObject { this.createAdditions = opts.getBool("create_additions", false); this.objectClass = opts.getClass("object_class", runtime.getHash()); this.arrayClass = opts.getClass("array_class", runtime.getArray()); - this.matchString = opts.getHash("match_string"); + this.decimalClass = opts.getClass("decimal_class", null); + this.match_string = opts.getHash("match_string"); if(symbolizeNames && createAdditions) { throw runtime.newArgumentError( @@ -489,13 +495,13 @@ public class Parser extends RubyObject { return p; } - + RubyInteger createInteger(int p, int new_p) { Ruby runtime = getRuntime(); ByteList num = absSubSequence(p, new_p); return bytesToInum(runtime, num); } - + RubyInteger bytesToInum(Ruby runtime, ByteList num) { return runtime.is1_9() ? ConvertBytes.byteListToInum19(runtime, num, 10, true) : @@ -525,7 +531,9 @@ public class Parser extends RubyObject { res.update(null, p); return; } - RubyFloat number = createFloat(p, new_p); + IRubyObject number = parser.decimalClass == null ? + createFloat(p, new_p) : createCustomDecimal(p, new_p); + res.update(number, new_p + 1); return; } @@ -540,16 +548,23 @@ public class Parser extends RubyObject { if (cs < JSON_float_first_final) { return -1; } - + return p; } - + RubyFloat createFloat(int p, int new_p) { Ruby runtime = getRuntime(); ByteList num = absSubSequence(p, new_p); return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9())); } + IRubyObject createCustomDecimal(int p, int new_p) { + Ruby runtime = getRuntime(); + ByteList num = absSubSequence(p, new_p); + IRubyObject numString = runtime.newString(num.toString()); + return parser.decimalClass.callMethod(context, "new", numString); + } + %%{ machine JSON_string; include JSON_common; @@ -616,7 +631,7 @@ public class Parser extends RubyObject { } } - if (cs >= JSON_string_first_final && result != null) { + if (cs >= JSON_string_first_final && result != null) { if (result instanceof RubyString) { ((RubyString)result).force_encoding(context, info.utf8.get()); } @@ -734,7 +749,7 @@ public class Parser extends RubyObject { fhold; fbreak; } - + pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value; next_pair = ignore* value_separator pair; diff --git a/json-java.gemspec b/json-java.gemspec deleted file mode 100644 index 1524b1f..0000000 --- a/json-java.gemspec +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env jruby -require "rubygems" - -spec = Gem::Specification.new do |s| - s.name = "json" - s.version = File.read("VERSION").chomp - s.summary = "JSON implementation for JRuby" - s.description = "A JSON implementation as a JRuby extension." - s.author = "Daniel Luz" - s.email = "dev+ruby@mernen.com" - s.homepage = "http://json-jruby.rubyforge.org/" - s.platform = 'java' - s.rubyforge_project = "json-jruby" - s.licenses = ["Ruby"] - - s.files = Dir["{docs,lib,tests}/**/*"] - - if s.respond_to? :specification_version then - s.specification_version = 4 - - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, ["~> 2.0"]) - else - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 2.0"]) - end - else - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 2.0"]) - end -end - -if $0 == __FILE__ - Gem::Builder.new(spec).build -else - spec -end diff --git a/json.gemspec b/json.gemspec index 7c862b0..83b68ca 100644 Binary files a/json.gemspec and b/json.gemspec differ diff --git a/json_pure.gemspec b/json_pure.gemspec index a0fdfe9..f446ace 100644 --- a/json_pure.gemspec +++ b/json_pure.gemspec @@ -1,38 +1,38 @@ # -*- encoding: utf-8 -*- -# stub: json_pure 2.0.2 ruby lib +# stub: json_pure 2.1.0 ruby lib Gem::Specification.new do |s| - s.name = "json_pure".freeze - s.version = "2.0.2" + s.name = "json_pure" + s.version = "2.1.0" - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.require_paths = ["lib".freeze] - s.authors = ["Florian Frank".freeze] - s.date = "2016-09-12" - s.description = "This is a JSON implementation in pure Ruby.".freeze - s.email = "flori@ping.de".freeze - s.extra_rdoc_files = ["README.md".freeze] - s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze] - s.homepage = "http://flori.github.com/json".freeze - s.licenses = ["Ruby".freeze] - s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze] - s.required_ruby_version = Gem::Requirement.new("~> 2.0".freeze) - s.rubygems_version = "2.6.6".freeze - s.summary = "JSON Implementation for Ruby".freeze - s.test_files = ["./tests/test_helper.rb".freeze] + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] + s.authors = ["Florian Frank"] + s.date = "2016-09-23" + s.description = "This is a JSON implementation in pure Ruby." + s.email = "flori@ping.de" + s.extra_rdoc_files = ["README.md"] + s.files = ["./tests/test_helper.rb", ".gitignore", ".travis.yml", "CHANGES.md", "Gemfile", "README-json-jruby.md", "README.md", "Rakefile", "VERSION", "data/example.json", "data/index.html", "data/prototype.js", "diagrams/.keep", "ext/json/ext/fbuffer/fbuffer.h", "ext/json/ext/generator/depend", "ext/json/ext/generator/extconf.rb", "ext/json/ext/generator/generator.c", "ext/json/ext/generator/generator.h", "ext/json/ext/parser/depend", "ext/json/ext/parser/extconf.rb", "ext/json/ext/parser/parser.c", "ext/json/ext/parser/parser.h", "ext/json/ext/parser/parser.rl", "ext/json/extconf.rb", "install.rb", "java/json.gemspec", "java/src/json/ext/ByteListTranscoder.java", "java/src/json/ext/Generator.java", "java/src/json/ext/GeneratorMethods.java", "java/src/json/ext/GeneratorService.java", "java/src/json/ext/GeneratorState.java", "java/src/json/ext/OptionsReader.java", "java/src/json/ext/Parser.java", "java/src/json/ext/Parser.rl", "java/src/json/ext/ParserService.java", "java/src/json/ext/RuntimeInfo.java", "java/src/json/ext/StringDecoder.java", "java/src/json/ext/StringEncoder.java", "java/src/json/ext/Utils.java", "json.gemspec", "json_pure.gemspec", "lib/json.rb", "lib/json/add/bigdecimal.rb", "lib/json/add/complex.rb", "lib/json/add/core.rb", "lib/json/add/date.rb", "lib/json/add/date_time.rb", "lib/json/add/exception.rb", "lib/json/add/ostruct.rb", "lib/json/add/range.rb", "lib/json/add/rational.rb", "lib/json/add/regexp.rb", "lib/json/add/struct.rb", "lib/json/add/symbol.rb", "lib/json/add/time.rb", "lib/json/common.rb", "lib/json/ext.rb", "lib/json/ext/.keep", "lib/json/generic_object.rb", "lib/json/pure.rb", "lib/json/pure/generator.rb", "lib/json/pure/parser.rb", "lib/json/version.rb", "references/rfc7159.txt", "tests/fixtures/fail10.json", "tests/fixtures/fail11.json", "tests/fixtures/fail12.json", "tests/fixtures/fail13.json", "tests/fixtures/fail14.json", "tests/fixtures/fail18.json", "tests/fixtures/fail19.json", "tests/fixtures/fail2.json", "tests/fixtures/fail20.json", "tests/fixtures/fail21.json", "tests/fixtures/fail22.json", "tests/fixtures/fail23.json", "tests/fixtures/fail24.json", "tests/fixtures/fail25.json", "tests/fixtures/fail27.json", "tests/fixtures/fail28.json", "tests/fixtures/fail3.json", "tests/fixtures/fail4.json", "tests/fixtures/fail5.json", "tests/fixtures/fail6.json", "tests/fixtures/fail7.json", "tests/fixtures/fail8.json", "tests/fixtures/fail9.json", "tests/fixtures/obsolete_fail1.json", "tests/fixtures/pass1.json", "tests/fixtures/pass15.json", "tests/fixtures/pass16.json", "tests/fixtures/pass17.json", "tests/fixtures/pass2.json", "tests/fixtures/pass26.json", "tests/fixtures/pass3.json", "tests/json_addition_test.rb", "tests/json_common_interface_test.rb", "tests/json_encoding_test.rb", "tests/json_ext_parser_test.rb", "tests/json_fixtures_test.rb", "tests/json_generator_test.rb", "tests/json_generic_object_test.rb", "tests/json_parser_test.rb", "tests/json_string_matching_test.rb", "tests/test_helper.rb", "tools/diff.sh", "tools/fuzz.rb", "tools/server.rb"] + s.homepage = "http://flori.github.com/json" + s.licenses = ["Ruby"] + s.rdoc_options = ["--title", "JSON implemention for ruby", "--main", "README.md"] + s.required_ruby_version = Gem::Requirement.new("~> 2.0") + s.rubygems_version = "2.5.1" + s.summary = "JSON Implementation for Ruby" + s.test_files = ["./tests/test_helper.rb"] if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_development_dependency(%q.freeze, [">= 0"]) - s.add_development_dependency(%q.freeze, ["~> 2.0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 2.0"]) else - s.add_dependency(%q.freeze, [">= 0"]) - s.add_dependency(%q.freeze, ["~> 2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end else - s.add_dependency(%q.freeze, [">= 0"]) - s.add_dependency(%q.freeze, ["~> 2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.0"]) end end diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index b907236..3a6343b 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -70,6 +70,9 @@ module JSON # option defaults to false. # * *object_class*: Defaults to Hash # * *array_class*: Defaults to Array + # * *decimal_class*: Specifies which class to use instead of the default + # (Float) when parsing decimal numbers. This class must accept a single + # string argument in its constructor. def initialize(source, opts = {}) opts ||= {} source = convert_encoding source @@ -94,6 +97,7 @@ module JSON @create_id = @create_additions ? JSON.create_id : nil @object_class = opts[:object_class] || Hash @array_class = opts[:array_class] || Array + @decimal_class = opts[:decimal_class] @match_string = opts[:match_string] end @@ -193,7 +197,7 @@ module JSON def parse_value case when scan(FLOAT) - Float(self[1]) + @decimal_class && @decimal_class.new(self[1]) || Float(self[1]) when scan(INTEGER) Integer(self[1]) when scan(TRUE) diff --git a/lib/json/version.rb b/lib/json/version.rb index 8997def..b65ed87 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module JSON # JSON version - VERSION = '2.0.2' + VERSION = '2.1.0' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: diff --git a/tests/test_helper.rb b/tests/test_helper.rb index 9d3665d..7e99c29 100644 --- a/tests/test_helper.rb +++ b/tests/test_helper.rb @@ -1,5 +1,3 @@ -gem 'json', File.read('VERSION').chomp - case ENV['JSON'] when 'pure' $:.unshift 'lib' -- cgit v1.2.1