json_pure 2.0.4 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +9 -5
- data/CHANGES.md +39 -0
- data/Gemfile +1 -3
- data/LICENSE +56 -0
- data/README.md +54 -21
- data/Rakefile +19 -93
- data/VERSION +1 -1
- data/ext/json/ext/generator/generator.c +214 -45
- data/ext/json/ext/generator/generator.h +5 -2
- data/ext/json/ext/parser/extconf.rb +25 -0
- data/ext/json/ext/parser/parser.c +155 -83
- data/ext/json/ext/parser/parser.h +2 -0
- data/ext/json/ext/parser/parser.rl +79 -7
- data/ext/json/extconf.rb +1 -0
- data/java/src/json/ext/Generator.java +28 -24
- data/java/src/json/ext/GeneratorState.java +30 -0
- data/java/src/json/ext/Parser.java +109 -82
- data/java/src/json/ext/Parser.rl +39 -12
- data/java/src/json/ext/StringEncoder.java +8 -2
- data/json-java.gemspec +22 -22
- data/json.gemspec +0 -0
- data/json_pure.gemspec +9 -14
- data/lib/json.rb +549 -29
- data/lib/json/add/bigdecimal.rb +2 -2
- data/lib/json/add/complex.rb +2 -3
- data/lib/json/add/ostruct.rb +1 -1
- data/lib/json/add/rational.rb +2 -3
- data/lib/json/add/regexp.rb +2 -2
- data/lib/json/add/set.rb +29 -0
- data/lib/json/common.rb +341 -115
- data/lib/json/pure/generator.rb +31 -10
- data/lib/json/pure/parser.rb +35 -5
- data/lib/json/version.rb +1 -1
- data/tests/json_addition_test.rb +6 -0
- data/tests/json_common_interface_test.rb +47 -4
- data/tests/json_encoding_test.rb +2 -2
- data/tests/json_fixtures_test.rb +9 -1
- data/tests/json_generator_test.rb +55 -0
- data/tests/json_parser_test.rb +43 -12
- data/tests/test_helper.rb +3 -7
- metadata +17 -13
- data/data/example.json +0 -1
- data/data/index.html +0 -38
- data/data/prototype.js +0 -4184
@@ -3,4 +3,29 @@ require 'mkmf'
|
|
3
3
|
|
4
4
|
have_func("rb_enc_raise", "ruby.h")
|
5
5
|
|
6
|
+
# checking if String#-@ (str_uminus) dedupes... '
|
7
|
+
begin
|
8
|
+
a = -(%w(t e s t).join)
|
9
|
+
b = -(%w(t e s t).join)
|
10
|
+
if a.equal?(b)
|
11
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 '
|
12
|
+
else
|
13
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
|
14
|
+
end
|
15
|
+
rescue NoMethodError
|
16
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
|
17
|
+
end
|
18
|
+
|
19
|
+
# checking if String#-@ (str_uminus) directly interns frozen strings... '
|
20
|
+
begin
|
21
|
+
s = rand.to_s.freeze
|
22
|
+
if (-s).equal?(s) && (-s.dup).equal?(s)
|
23
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=1 '
|
24
|
+
else
|
25
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
|
26
|
+
end
|
27
|
+
rescue NoMethodError
|
28
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
|
29
|
+
end
|
30
|
+
|
6
31
|
create_makefile 'json/ext/parser'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
/* This file is automatically generated from parser.rl by using ragel */
|
2
2
|
#line 1 "parser.rl"
|
3
3
|
#include "../fbuffer/fbuffer.h"
|
4
4
|
#include "parser.h"
|
@@ -27,7 +27,7 @@ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
|
|
27
27
|
|
28
28
|
/* unicode */
|
29
29
|
|
30
|
-
static const char digit_values[256] = {
|
30
|
+
static const signed char digit_values[256] = {
|
31
31
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
32
32
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
33
33
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
|
@@ -46,7 +46,7 @@ static const char digit_values[256] = {
|
|
46
46
|
|
47
47
|
static UTF32 unescape_unicode(const unsigned char *p)
|
48
48
|
{
|
49
|
-
char b;
|
49
|
+
signed char b;
|
50
50
|
UTF32 result = 0;
|
51
51
|
b = digit_values[p[0]];
|
52
52
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
@@ -91,18 +91,20 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
91
91
|
|
92
92
|
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
93
93
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
94
|
+
static VALUE cBigDecimal = Qundef;
|
94
95
|
|
95
96
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
96
97
|
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
97
|
-
i_object_class, i_array_class,
|
98
|
-
i_match_string, i_aset, i_aref,
|
98
|
+
i_object_class, i_array_class, i_decimal_class, i_key_p,
|
99
|
+
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
|
100
|
+
i_leftshift, i_new, i_BigDecimal, i_freeze, i_uminus;
|
99
101
|
|
100
102
|
|
101
|
-
#line
|
103
|
+
#line 126 "parser.rl"
|
102
104
|
|
103
105
|
|
104
106
|
|
105
|
-
#line
|
107
|
+
#line 108 "parser.c"
|
106
108
|
enum {JSON_object_start = 1};
|
107
109
|
enum {JSON_object_first_final = 27};
|
108
110
|
enum {JSON_object_error = 0};
|
@@ -110,7 +112,7 @@ enum {JSON_object_error = 0};
|
|
110
112
|
enum {JSON_object_en_main = 1};
|
111
113
|
|
112
114
|
|
113
|
-
#line
|
115
|
+
#line 168 "parser.rl"
|
114
116
|
|
115
117
|
|
116
118
|
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -126,14 +128,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
126
128
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
127
129
|
|
128
130
|
|
129
|
-
#line
|
131
|
+
#line 132 "parser.c"
|
130
132
|
{
|
131
133
|
cs = JSON_object_start;
|
132
134
|
}
|
133
135
|
|
134
|
-
#line
|
136
|
+
#line 183 "parser.rl"
|
135
137
|
|
136
|
-
#line
|
138
|
+
#line 139 "parser.c"
|
137
139
|
{
|
138
140
|
if ( p == pe )
|
139
141
|
goto _test_eof;
|
@@ -161,7 +163,7 @@ case 2:
|
|
161
163
|
goto st2;
|
162
164
|
goto st0;
|
163
165
|
tr2:
|
164
|
-
#line
|
166
|
+
#line 150 "parser.rl"
|
165
167
|
{
|
166
168
|
char *np;
|
167
169
|
json->parsing_name = 1;
|
@@ -174,7 +176,7 @@ st3:
|
|
174
176
|
if ( ++p == pe )
|
175
177
|
goto _test_eof3;
|
176
178
|
case 3:
|
177
|
-
#line
|
179
|
+
#line 180 "parser.c"
|
178
180
|
switch( (*p) ) {
|
179
181
|
case 13: goto st3;
|
180
182
|
case 32: goto st3;
|
@@ -241,7 +243,7 @@ case 8:
|
|
241
243
|
goto st8;
|
242
244
|
goto st0;
|
243
245
|
tr11:
|
244
|
-
#line
|
246
|
+
#line 134 "parser.rl"
|
245
247
|
{
|
246
248
|
VALUE v = Qnil;
|
247
249
|
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
@@ -249,6 +251,7 @@ tr11:
|
|
249
251
|
p--; {p++; cs = 9; goto _out;}
|
250
252
|
} else {
|
251
253
|
if (NIL_P(json->object_class)) {
|
254
|
+
OBJ_FREEZE(last_name);
|
252
255
|
rb_hash_aset(*result, last_name, v);
|
253
256
|
} else {
|
254
257
|
rb_funcall(*result, i_aset, 2, last_name, v);
|
@@ -261,7 +264,7 @@ st9:
|
|
261
264
|
if ( ++p == pe )
|
262
265
|
goto _test_eof9;
|
263
266
|
case 9:
|
264
|
-
#line
|
267
|
+
#line 268 "parser.c"
|
265
268
|
switch( (*p) ) {
|
266
269
|
case 13: goto st9;
|
267
270
|
case 32: goto st9;
|
@@ -350,14 +353,14 @@ case 18:
|
|
350
353
|
goto st9;
|
351
354
|
goto st18;
|
352
355
|
tr4:
|
353
|
-
#line
|
356
|
+
#line 158 "parser.rl"
|
354
357
|
{ p--; {p++; cs = 27; goto _out;} }
|
355
358
|
goto st27;
|
356
359
|
st27:
|
357
360
|
if ( ++p == pe )
|
358
361
|
goto _test_eof27;
|
359
362
|
case 27:
|
360
|
-
#line
|
363
|
+
#line 364 "parser.c"
|
361
364
|
goto st0;
|
362
365
|
st19:
|
363
366
|
if ( ++p == pe )
|
@@ -455,7 +458,7 @@ case 26:
|
|
455
458
|
_out: {}
|
456
459
|
}
|
457
460
|
|
458
|
-
#line
|
461
|
+
#line 184 "parser.rl"
|
459
462
|
|
460
463
|
if (cs >= JSON_object_first_final) {
|
461
464
|
if (json->create_additions) {
|
@@ -480,7 +483,7 @@ case 26:
|
|
480
483
|
|
481
484
|
|
482
485
|
|
483
|
-
#line
|
486
|
+
#line 487 "parser.c"
|
484
487
|
enum {JSON_value_start = 1};
|
485
488
|
enum {JSON_value_first_final = 29};
|
486
489
|
enum {JSON_value_error = 0};
|
@@ -488,7 +491,7 @@ enum {JSON_value_error = 0};
|
|
488
491
|
enum {JSON_value_en_main = 1};
|
489
492
|
|
490
493
|
|
491
|
-
#line
|
494
|
+
#line 284 "parser.rl"
|
492
495
|
|
493
496
|
|
494
497
|
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -496,14 +499,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
496
499
|
int cs = EVIL;
|
497
500
|
|
498
501
|
|
499
|
-
#line
|
502
|
+
#line 503 "parser.c"
|
500
503
|
{
|
501
504
|
cs = JSON_value_start;
|
502
505
|
}
|
503
506
|
|
504
|
-
#line
|
507
|
+
#line 291 "parser.rl"
|
505
508
|
|
506
|
-
#line
|
509
|
+
#line 510 "parser.c"
|
507
510
|
{
|
508
511
|
if ( p == pe )
|
509
512
|
goto _test_eof;
|
@@ -537,14 +540,14 @@ st0:
|
|
537
540
|
cs = 0;
|
538
541
|
goto _out;
|
539
542
|
tr2:
|
540
|
-
#line
|
543
|
+
#line 236 "parser.rl"
|
541
544
|
{
|
542
545
|
char *np = JSON_parse_string(json, p, pe, result);
|
543
546
|
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
544
547
|
}
|
545
548
|
goto st29;
|
546
549
|
tr3:
|
547
|
-
#line
|
550
|
+
#line 241 "parser.rl"
|
548
551
|
{
|
549
552
|
char *np;
|
550
553
|
if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
|
@@ -564,7 +567,7 @@ tr3:
|
|
564
567
|
}
|
565
568
|
goto st29;
|
566
569
|
tr7:
|
567
|
-
#line
|
570
|
+
#line 259 "parser.rl"
|
568
571
|
{
|
569
572
|
char *np;
|
570
573
|
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
|
@@ -572,7 +575,7 @@ tr7:
|
|
572
575
|
}
|
573
576
|
goto st29;
|
574
577
|
tr11:
|
575
|
-
#line
|
578
|
+
#line 265 "parser.rl"
|
576
579
|
{
|
577
580
|
char *np;
|
578
581
|
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
|
@@ -580,7 +583,7 @@ tr11:
|
|
580
583
|
}
|
581
584
|
goto st29;
|
582
585
|
tr25:
|
583
|
-
#line
|
586
|
+
#line 229 "parser.rl"
|
584
587
|
{
|
585
588
|
if (json->allow_nan) {
|
586
589
|
*result = CInfinity;
|
@@ -590,7 +593,7 @@ tr25:
|
|
590
593
|
}
|
591
594
|
goto st29;
|
592
595
|
tr27:
|
593
|
-
#line
|
596
|
+
#line 222 "parser.rl"
|
594
597
|
{
|
595
598
|
if (json->allow_nan) {
|
596
599
|
*result = CNaN;
|
@@ -600,19 +603,19 @@ tr27:
|
|
600
603
|
}
|
601
604
|
goto st29;
|
602
605
|
tr31:
|
603
|
-
#line
|
606
|
+
#line 216 "parser.rl"
|
604
607
|
{
|
605
608
|
*result = Qfalse;
|
606
609
|
}
|
607
610
|
goto st29;
|
608
611
|
tr34:
|
609
|
-
#line
|
612
|
+
#line 213 "parser.rl"
|
610
613
|
{
|
611
614
|
*result = Qnil;
|
612
615
|
}
|
613
616
|
goto st29;
|
614
617
|
tr37:
|
615
|
-
#line
|
618
|
+
#line 219 "parser.rl"
|
616
619
|
{
|
617
620
|
*result = Qtrue;
|
618
621
|
}
|
@@ -621,9 +624,9 @@ st29:
|
|
621
624
|
if ( ++p == pe )
|
622
625
|
goto _test_eof29;
|
623
626
|
case 29:
|
624
|
-
#line
|
627
|
+
#line 271 "parser.rl"
|
625
628
|
{ p--; {p++; cs = 29; goto _out;} }
|
626
|
-
#line
|
629
|
+
#line 630 "parser.c"
|
627
630
|
switch( (*p) ) {
|
628
631
|
case 13: goto st29;
|
629
632
|
case 32: goto st29;
|
@@ -864,7 +867,11 @@ case 28:
|
|
864
867
|
_out: {}
|
865
868
|
}
|
866
869
|
|
867
|
-
#line
|
870
|
+
#line 292 "parser.rl"
|
871
|
+
|
872
|
+
if (json->freeze) {
|
873
|
+
OBJ_FREEZE(*result);
|
874
|
+
}
|
868
875
|
|
869
876
|
if (cs >= JSON_value_first_final) {
|
870
877
|
return p;
|
@@ -874,7 +881,7 @@ case 28:
|
|
874
881
|
}
|
875
882
|
|
876
883
|
|
877
|
-
#line
|
884
|
+
#line 885 "parser.c"
|
878
885
|
enum {JSON_integer_start = 1};
|
879
886
|
enum {JSON_integer_first_final = 3};
|
880
887
|
enum {JSON_integer_error = 0};
|
@@ -882,7 +889,7 @@ enum {JSON_integer_error = 0};
|
|
882
889
|
enum {JSON_integer_en_main = 1};
|
883
890
|
|
884
891
|
|
885
|
-
#line
|
892
|
+
#line 312 "parser.rl"
|
886
893
|
|
887
894
|
|
888
895
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -890,15 +897,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|
890
897
|
int cs = EVIL;
|
891
898
|
|
892
899
|
|
893
|
-
#line
|
900
|
+
#line 901 "parser.c"
|
894
901
|
{
|
895
902
|
cs = JSON_integer_start;
|
896
903
|
}
|
897
904
|
|
898
|
-
#line
|
905
|
+
#line 319 "parser.rl"
|
899
906
|
json->memo = p;
|
900
907
|
|
901
|
-
#line
|
908
|
+
#line 909 "parser.c"
|
902
909
|
{
|
903
910
|
if ( p == pe )
|
904
911
|
goto _test_eof;
|
@@ -932,14 +939,14 @@ case 3:
|
|
932
939
|
goto st0;
|
933
940
|
goto tr4;
|
934
941
|
tr4:
|
935
|
-
#line
|
942
|
+
#line 309 "parser.rl"
|
936
943
|
{ p--; {p++; cs = 4; goto _out;} }
|
937
944
|
goto st4;
|
938
945
|
st4:
|
939
946
|
if ( ++p == pe )
|
940
947
|
goto _test_eof4;
|
941
948
|
case 4:
|
942
|
-
#line
|
949
|
+
#line 950 "parser.c"
|
943
950
|
goto st0;
|
944
951
|
st5:
|
945
952
|
if ( ++p == pe )
|
@@ -958,7 +965,7 @@ case 5:
|
|
958
965
|
_out: {}
|
959
966
|
}
|
960
967
|
|
961
|
-
#line
|
968
|
+
#line 321 "parser.rl"
|
962
969
|
|
963
970
|
if (cs >= JSON_integer_first_final) {
|
964
971
|
long len = p - json->memo;
|
@@ -973,7 +980,7 @@ case 5:
|
|
973
980
|
}
|
974
981
|
|
975
982
|
|
976
|
-
#line
|
983
|
+
#line 984 "parser.c"
|
977
984
|
enum {JSON_float_start = 1};
|
978
985
|
enum {JSON_float_first_final = 8};
|
979
986
|
enum {JSON_float_error = 0};
|
@@ -981,23 +988,36 @@ enum {JSON_float_error = 0};
|
|
981
988
|
enum {JSON_float_en_main = 1};
|
982
989
|
|
983
990
|
|
984
|
-
#line
|
991
|
+
#line 346 "parser.rl"
|
985
992
|
|
986
993
|
|
994
|
+
static int is_bigdecimal_class(VALUE obj)
|
995
|
+
{
|
996
|
+
if (cBigDecimal == Qundef) {
|
997
|
+
if (rb_const_defined(rb_cObject, i_BigDecimal)) {
|
998
|
+
cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
|
999
|
+
}
|
1000
|
+
else {
|
1001
|
+
return 0;
|
1002
|
+
}
|
1003
|
+
}
|
1004
|
+
return obj == cBigDecimal;
|
1005
|
+
}
|
1006
|
+
|
987
1007
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
988
1008
|
{
|
989
1009
|
int cs = EVIL;
|
990
1010
|
|
991
1011
|
|
992
|
-
#line
|
1012
|
+
#line 1013 "parser.c"
|
993
1013
|
{
|
994
1014
|
cs = JSON_float_start;
|
995
1015
|
}
|
996
1016
|
|
997
|
-
#line
|
1017
|
+
#line 366 "parser.rl"
|
998
1018
|
json->memo = p;
|
999
1019
|
|
1000
|
-
#line
|
1020
|
+
#line 1021 "parser.c"
|
1001
1021
|
{
|
1002
1022
|
if ( p == pe )
|
1003
1023
|
goto _test_eof;
|
@@ -1055,14 +1075,14 @@ case 8:
|
|
1055
1075
|
goto st0;
|
1056
1076
|
goto tr9;
|
1057
1077
|
tr9:
|
1058
|
-
#line
|
1078
|
+
#line 340 "parser.rl"
|
1059
1079
|
{ p--; {p++; cs = 9; goto _out;} }
|
1060
1080
|
goto st9;
|
1061
1081
|
st9:
|
1062
1082
|
if ( ++p == pe )
|
1063
1083
|
goto _test_eof9;
|
1064
1084
|
case 9:
|
1065
|
-
#line
|
1085
|
+
#line 1086 "parser.c"
|
1066
1086
|
goto st0;
|
1067
1087
|
st5:
|
1068
1088
|
if ( ++p == pe )
|
@@ -1123,14 +1143,24 @@ case 7:
|
|
1123
1143
|
_out: {}
|
1124
1144
|
}
|
1125
1145
|
|
1126
|
-
#line
|
1146
|
+
#line 368 "parser.rl"
|
1127
1147
|
|
1128
1148
|
if (cs >= JSON_float_first_final) {
|
1129
1149
|
long len = p - json->memo;
|
1130
1150
|
fbuffer_clear(json->fbuffer);
|
1131
1151
|
fbuffer_append(json->fbuffer, json->memo, len);
|
1132
1152
|
fbuffer_append_char(json->fbuffer, '\0');
|
1133
|
-
|
1153
|
+
if (NIL_P(json->decimal_class)) {
|
1154
|
+
*result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
1155
|
+
} else {
|
1156
|
+
VALUE text;
|
1157
|
+
text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
1158
|
+
if (is_bigdecimal_class(json->decimal_class)) {
|
1159
|
+
*result = rb_funcall(Qnil, i_BigDecimal, 1, text);
|
1160
|
+
} else {
|
1161
|
+
*result = rb_funcall(json->decimal_class, i_new, 1, text);
|
1162
|
+
}
|
1163
|
+
}
|
1134
1164
|
return p + 1;
|
1135
1165
|
} else {
|
1136
1166
|
return NULL;
|
@@ -1139,7 +1169,7 @@ case 7:
|
|
1139
1169
|
|
1140
1170
|
|
1141
1171
|
|
1142
|
-
#line
|
1172
|
+
#line 1173 "parser.c"
|
1143
1173
|
enum {JSON_array_start = 1};
|
1144
1174
|
enum {JSON_array_first_final = 17};
|
1145
1175
|
enum {JSON_array_error = 0};
|
@@ -1147,7 +1177,7 @@ enum {JSON_array_error = 0};
|
|
1147
1177
|
enum {JSON_array_en_main = 1};
|
1148
1178
|
|
1149
1179
|
|
1150
|
-
#line
|
1180
|
+
#line 421 "parser.rl"
|
1151
1181
|
|
1152
1182
|
|
1153
1183
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -1161,14 +1191,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
1161
1191
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
1162
1192
|
|
1163
1193
|
|
1164
|
-
#line
|
1194
|
+
#line 1195 "parser.c"
|
1165
1195
|
{
|
1166
1196
|
cs = JSON_array_start;
|
1167
1197
|
}
|
1168
1198
|
|
1169
|
-
#line
|
1199
|
+
#line 434 "parser.rl"
|
1170
1200
|
|
1171
|
-
#line
|
1201
|
+
#line 1202 "parser.c"
|
1172
1202
|
{
|
1173
1203
|
if ( p == pe )
|
1174
1204
|
goto _test_eof;
|
@@ -1207,7 +1237,7 @@ case 2:
|
|
1207
1237
|
goto st2;
|
1208
1238
|
goto st0;
|
1209
1239
|
tr2:
|
1210
|
-
#line
|
1240
|
+
#line 398 "parser.rl"
|
1211
1241
|
{
|
1212
1242
|
VALUE v = Qnil;
|
1213
1243
|
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
@@ -1227,7 +1257,7 @@ st3:
|
|
1227
1257
|
if ( ++p == pe )
|
1228
1258
|
goto _test_eof3;
|
1229
1259
|
case 3:
|
1230
|
-
#line
|
1260
|
+
#line 1261 "parser.c"
|
1231
1261
|
switch( (*p) ) {
|
1232
1262
|
case 13: goto st3;
|
1233
1263
|
case 32: goto st3;
|
@@ -1327,14 +1357,14 @@ case 12:
|
|
1327
1357
|
goto st3;
|
1328
1358
|
goto st12;
|
1329
1359
|
tr4:
|
1330
|
-
#line
|
1360
|
+
#line 413 "parser.rl"
|
1331
1361
|
{ p--; {p++; cs = 17; goto _out;} }
|
1332
1362
|
goto st17;
|
1333
1363
|
st17:
|
1334
1364
|
if ( ++p == pe )
|
1335
1365
|
goto _test_eof17;
|
1336
1366
|
case 17:
|
1337
|
-
#line
|
1367
|
+
#line 1368 "parser.c"
|
1338
1368
|
goto st0;
|
1339
1369
|
st13:
|
1340
1370
|
if ( ++p == pe )
|
@@ -1390,7 +1420,7 @@ case 16:
|
|
1390
1420
|
_out: {}
|
1391
1421
|
}
|
1392
1422
|
|
1393
|
-
#line
|
1423
|
+
#line 435 "parser.rl"
|
1394
1424
|
|
1395
1425
|
if(cs >= JSON_array_first_final) {
|
1396
1426
|
return p + 1;
|
@@ -1479,7 +1509,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
1479
1509
|
}
|
1480
1510
|
|
1481
1511
|
|
1482
|
-
#line
|
1512
|
+
#line 1513 "parser.c"
|
1483
1513
|
enum {JSON_string_start = 1};
|
1484
1514
|
enum {JSON_string_first_final = 8};
|
1485
1515
|
enum {JSON_string_error = 0};
|
@@ -1487,7 +1517,7 @@ enum {JSON_string_error = 0};
|
|
1487
1517
|
enum {JSON_string_en_main = 1};
|
1488
1518
|
|
1489
1519
|
|
1490
|
-
#line
|
1520
|
+
#line 542 "parser.rl"
|
1491
1521
|
|
1492
1522
|
|
1493
1523
|
static int
|
@@ -1509,15 +1539,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1509
1539
|
|
1510
1540
|
*result = rb_str_buf_new(0);
|
1511
1541
|
|
1512
|
-
#line
|
1542
|
+
#line 1543 "parser.c"
|
1513
1543
|
{
|
1514
1544
|
cs = JSON_string_start;
|
1515
1545
|
}
|
1516
1546
|
|
1517
|
-
#line
|
1547
|
+
#line 563 "parser.rl"
|
1518
1548
|
json->memo = p;
|
1519
1549
|
|
1520
|
-
#line
|
1550
|
+
#line 1551 "parser.c"
|
1521
1551
|
{
|
1522
1552
|
if ( p == pe )
|
1523
1553
|
goto _test_eof;
|
@@ -1538,11 +1568,11 @@ case 2:
|
|
1538
1568
|
case 34: goto tr2;
|
1539
1569
|
case 92: goto st3;
|
1540
1570
|
}
|
1541
|
-
if ( 0 <= (*p) && (*p) <= 31 )
|
1571
|
+
if ( 0 <= (signed char)(*p) && (*p) <= 31 )
|
1542
1572
|
goto st0;
|
1543
1573
|
goto st2;
|
1544
1574
|
tr2:
|
1545
|
-
#line
|
1575
|
+
#line 528 "parser.rl"
|
1546
1576
|
{
|
1547
1577
|
*result = json_string_unescape(*result, json->memo + 1, p);
|
1548
1578
|
if (NIL_P(*result)) {
|
@@ -1553,14 +1583,14 @@ tr2:
|
|
1553
1583
|
{p = (( p + 1))-1;}
|
1554
1584
|
}
|
1555
1585
|
}
|
1556
|
-
#line
|
1586
|
+
#line 539 "parser.rl"
|
1557
1587
|
{ p--; {p++; cs = 8; goto _out;} }
|
1558
1588
|
goto st8;
|
1559
1589
|
st8:
|
1560
1590
|
if ( ++p == pe )
|
1561
1591
|
goto _test_eof8;
|
1562
1592
|
case 8:
|
1563
|
-
#line
|
1593
|
+
#line 1594 "parser.c"
|
1564
1594
|
goto st0;
|
1565
1595
|
st3:
|
1566
1596
|
if ( ++p == pe )
|
@@ -1568,7 +1598,7 @@ st3:
|
|
1568
1598
|
case 3:
|
1569
1599
|
if ( (*p) == 117 )
|
1570
1600
|
goto st4;
|
1571
|
-
if ( 0 <= (*p) && (*p) <= 31 )
|
1601
|
+
if ( 0 <= (signed char)(*p) && (*p) <= 31 )
|
1572
1602
|
goto st0;
|
1573
1603
|
goto st2;
|
1574
1604
|
st4:
|
@@ -1636,7 +1666,7 @@ case 7:
|
|
1636
1666
|
_out: {}
|
1637
1667
|
}
|
1638
1668
|
|
1639
|
-
#line
|
1669
|
+
#line 565 "parser.rl"
|
1640
1670
|
|
1641
1671
|
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
1642
1672
|
VALUE klass;
|
@@ -1651,8 +1681,23 @@ case 7:
|
|
1651
1681
|
|
1652
1682
|
if (json->symbolize_names && json->parsing_name) {
|
1653
1683
|
*result = rb_str_intern(*result);
|
1654
|
-
} else {
|
1684
|
+
} else if (RB_TYPE_P(*result, T_STRING)) {
|
1685
|
+
# if STR_UMINUS_DEDUPE_FROZEN
|
1686
|
+
if (json->freeze) {
|
1687
|
+
// Starting from MRI 2.8 it is preferable to freeze the string
|
1688
|
+
// before deduplication so that it can be interned directly
|
1689
|
+
// otherwise it would be duplicated first which is wasteful.
|
1690
|
+
*result = rb_funcall(rb_str_freeze(*result), i_uminus, 0);
|
1691
|
+
}
|
1692
|
+
# elif STR_UMINUS_DEDUPE
|
1693
|
+
if (json->freeze) {
|
1694
|
+
// MRI 2.5 and older do not deduplicate strings that are already
|
1695
|
+
// frozen.
|
1696
|
+
*result = rb_funcall(*result, i_uminus, 0);
|
1697
|
+
}
|
1698
|
+
# else
|
1655
1699
|
rb_str_resize(*result, RSTRING_LEN(*result));
|
1700
|
+
# endif
|
1656
1701
|
}
|
1657
1702
|
if (cs >= JSON_string_first_final) {
|
1658
1703
|
return p + 1;
|
@@ -1760,6 +1805,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1760
1805
|
} else {
|
1761
1806
|
json->symbolize_names = 0;
|
1762
1807
|
}
|
1808
|
+
tmp = ID2SYM(i_freeze);
|
1809
|
+
if (option_given_p(opts, tmp)) {
|
1810
|
+
json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
1811
|
+
} else {
|
1812
|
+
json->freeze = 0;
|
1813
|
+
}
|
1763
1814
|
tmp = ID2SYM(i_create_additions);
|
1764
1815
|
if (option_given_p(opts, tmp)) {
|
1765
1816
|
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
@@ -1789,6 +1840,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1789
1840
|
} else {
|
1790
1841
|
json->array_class = Qnil;
|
1791
1842
|
}
|
1843
|
+
tmp = ID2SYM(i_decimal_class);
|
1844
|
+
if (option_given_p(opts, tmp)) {
|
1845
|
+
json->decimal_class = rb_hash_aref(opts, tmp);
|
1846
|
+
} else {
|
1847
|
+
json->decimal_class = Qnil;
|
1848
|
+
}
|
1792
1849
|
tmp = ID2SYM(i_match_string);
|
1793
1850
|
if (option_given_p(opts, tmp)) {
|
1794
1851
|
VALUE match_string = rb_hash_aref(opts, tmp);
|
@@ -1802,10 +1859,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1802
1859
|
} else {
|
1803
1860
|
json->max_nesting = 100;
|
1804
1861
|
json->allow_nan = 0;
|
1805
|
-
json->create_additions =
|
1862
|
+
json->create_additions = 0;
|
1806
1863
|
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
1807
1864
|
json->object_class = Qnil;
|
1808
1865
|
json->array_class = Qnil;
|
1866
|
+
json->decimal_class = Qnil;
|
1809
1867
|
}
|
1810
1868
|
source = convert_encoding(StringValue(source));
|
1811
1869
|
StringValue(source);
|
@@ -1816,7 +1874,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1816
1874
|
}
|
1817
1875
|
|
1818
1876
|
|
1819
|
-
#line
|
1877
|
+
#line 1878 "parser.c"
|
1820
1878
|
enum {JSON_start = 1};
|
1821
1879
|
enum {JSON_first_final = 10};
|
1822
1880
|
enum {JSON_error = 0};
|
@@ -1824,7 +1882,7 @@ enum {JSON_error = 0};
|
|
1824
1882
|
enum {JSON_en_main = 1};
|
1825
1883
|
|
1826
1884
|
|
1827
|
-
#line
|
1885
|
+
#line 786 "parser.rl"
|
1828
1886
|
|
1829
1887
|
|
1830
1888
|
/*
|
@@ -1841,16 +1899,16 @@ static VALUE cParser_parse(VALUE self)
|
|
1841
1899
|
GET_PARSER;
|
1842
1900
|
|
1843
1901
|
|
1844
|
-
#line
|
1902
|
+
#line 1903 "parser.c"
|
1845
1903
|
{
|
1846
1904
|
cs = JSON_start;
|
1847
1905
|
}
|
1848
1906
|
|
1849
|
-
#line
|
1907
|
+
#line 802 "parser.rl"
|
1850
1908
|
p = json->source;
|
1851
1909
|
pe = p + json->len;
|
1852
1910
|
|
1853
|
-
#line
|
1911
|
+
#line 1912 "parser.c"
|
1854
1912
|
{
|
1855
1913
|
if ( p == pe )
|
1856
1914
|
goto _test_eof;
|
@@ -1884,7 +1942,7 @@ st0:
|
|
1884
1942
|
cs = 0;
|
1885
1943
|
goto _out;
|
1886
1944
|
tr2:
|
1887
|
-
#line
|
1945
|
+
#line 778 "parser.rl"
|
1888
1946
|
{
|
1889
1947
|
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
1890
1948
|
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
@@ -1894,7 +1952,7 @@ st10:
|
|
1894
1952
|
if ( ++p == pe )
|
1895
1953
|
goto _test_eof10;
|
1896
1954
|
case 10:
|
1897
|
-
#line
|
1955
|
+
#line 1956 "parser.c"
|
1898
1956
|
switch( (*p) ) {
|
1899
1957
|
case 13: goto st10;
|
1900
1958
|
case 32: goto st10;
|
@@ -1983,7 +2041,7 @@ case 9:
|
|
1983
2041
|
_out: {}
|
1984
2042
|
}
|
1985
2043
|
|
1986
|
-
#line
|
2044
|
+
#line 805 "parser.rl"
|
1987
2045
|
|
1988
2046
|
if (cs >= JSON_first_final && p == pe) {
|
1989
2047
|
return result;
|
@@ -2000,6 +2058,7 @@ static void JSON_mark(void *ptr)
|
|
2000
2058
|
rb_gc_mark_maybe(json->create_id);
|
2001
2059
|
rb_gc_mark_maybe(json->object_class);
|
2002
2060
|
rb_gc_mark_maybe(json->array_class);
|
2061
|
+
rb_gc_mark_maybe(json->decimal_class);
|
2003
2062
|
rb_gc_mark_maybe(json->match_string);
|
2004
2063
|
}
|
2005
2064
|
|
@@ -2049,20 +2108,28 @@ static VALUE cParser_source(VALUE self)
|
|
2049
2108
|
|
2050
2109
|
void Init_parser(void)
|
2051
2110
|
{
|
2111
|
+
#undef rb_intern
|
2052
2112
|
rb_require("json/common");
|
2053
2113
|
mJSON = rb_define_module("JSON");
|
2054
2114
|
mExt = rb_define_module_under(mJSON, "Ext");
|
2055
2115
|
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
2056
2116
|
eParserError = rb_path2class("JSON::ParserError");
|
2057
2117
|
eNestingError = rb_path2class("JSON::NestingError");
|
2118
|
+
rb_gc_register_mark_object(eParserError);
|
2119
|
+
rb_gc_register_mark_object(eNestingError);
|
2058
2120
|
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
|
2059
2121
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
2060
2122
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
2061
2123
|
rb_define_method(cParser, "source", cParser_source, 0);
|
2062
2124
|
|
2063
2125
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
2126
|
+
rb_gc_register_mark_object(CNaN);
|
2127
|
+
|
2064
2128
|
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
|
2129
|
+
rb_gc_register_mark_object(CInfinity);
|
2130
|
+
|
2065
2131
|
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
|
2132
|
+
rb_gc_register_mark_object(CMinusInfinity);
|
2066
2133
|
|
2067
2134
|
i_json_creatable_p = rb_intern("json_creatable?");
|
2068
2135
|
i_json_create = rb_intern("json_create");
|
@@ -2074,6 +2141,7 @@ void Init_parser(void)
|
|
2074
2141
|
i_symbolize_names = rb_intern("symbolize_names");
|
2075
2142
|
i_object_class = rb_intern("object_class");
|
2076
2143
|
i_array_class = rb_intern("array_class");
|
2144
|
+
i_decimal_class = rb_intern("decimal_class");
|
2077
2145
|
i_match = rb_intern("match");
|
2078
2146
|
i_match_string = rb_intern("match_string");
|
2079
2147
|
i_key_p = rb_intern("key?");
|
@@ -2081,6 +2149,10 @@ void Init_parser(void)
|
|
2081
2149
|
i_aset = rb_intern("[]=");
|
2082
2150
|
i_aref = rb_intern("[]");
|
2083
2151
|
i_leftshift = rb_intern("<<");
|
2152
|
+
i_new = rb_intern("new");
|
2153
|
+
i_BigDecimal = rb_intern("BigDecimal");
|
2154
|
+
i_freeze = rb_intern("freeze");
|
2155
|
+
i_uminus = rb_intern("-@");
|
2084
2156
|
}
|
2085
2157
|
|
2086
2158
|
/*
|