json 1.8.6 → 2.3.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 +11 -5
- data/{CHANGES → CHANGES.md} +179 -95
- data/Gemfile +10 -3
- data/LICENSE +56 -0
- data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
- data/README.md +171 -107
- data/Rakefile +33 -22
- data/VERSION +1 -1
- data/ext/json/ext/fbuffer/fbuffer.h +0 -3
- data/ext/json/ext/generator/generator.c +105 -98
- data/ext/json/ext/generator/generator.h +0 -6
- data/ext/json/ext/parser/extconf.rb +3 -0
- data/ext/json/ext/parser/parser.c +376 -480
- data/ext/json/ext/parser/parser.h +4 -5
- data/ext/json/ext/parser/parser.rl +108 -175
- data/ext/json/extconf.rb +0 -1
- data/java/src/json/ext/Generator.java +35 -15
- data/java/src/json/ext/GeneratorState.java +2 -54
- data/java/src/json/ext/OptionsReader.java +1 -1
- data/java/src/json/ext/Parser.java +131 -413
- data/java/src/json/ext/Parser.rl +47 -122
- data/java/src/json/ext/RuntimeInfo.java +0 -4
- data/json-java.gemspec +1 -2
- data/json.gemspec +0 -0
- data/json_pure.gemspec +8 -7
- data/lib/json.rb +1 -0
- data/lib/json/add/bigdecimal.rb +3 -2
- data/lib/json/add/complex.rb +4 -3
- data/lib/json/add/core.rb +1 -0
- data/lib/json/add/date.rb +1 -1
- data/lib/json/add/date_time.rb +1 -1
- data/lib/json/add/exception.rb +1 -1
- data/lib/json/add/ostruct.rb +3 -3
- data/lib/json/add/range.rb +1 -1
- data/lib/json/add/rational.rb +3 -2
- data/lib/json/add/regexp.rb +3 -3
- data/lib/json/add/set.rb +29 -0
- data/lib/json/add/struct.rb +1 -1
- data/lib/json/add/symbol.rb +1 -1
- data/lib/json/add/time.rb +1 -1
- data/lib/json/common.rb +26 -54
- data/lib/json/ext.rb +0 -6
- data/lib/json/generic_object.rb +5 -4
- data/lib/json/pure.rb +2 -8
- data/lib/json/pure/generator.rb +53 -124
- data/lib/json/pure/parser.rb +41 -81
- data/lib/json/version.rb +2 -1
- data/references/rfc7159.txt +899 -0
- data/tests/fixtures/obsolete_fail1.json +1 -0
- data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
- data/tests/json_common_interface_test.rb +126 -0
- data/tests/json_encoding_test.rb +107 -0
- data/tests/json_ext_parser_test.rb +15 -0
- data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
- data/tests/{test_json_generate.rb → json_generator_test.rb} +112 -39
- data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
- data/tests/json_parser_test.rb +472 -0
- data/tests/json_string_matching_test.rb +38 -0
- data/tests/{setup_variant.rb → test_helper.rb} +6 -0
- data/tools/fuzz.rb +1 -9
- metadata +22 -37
- data/TODO +0 -1
- data/data/example.json +0 -1
- data/data/index.html +0 -38
- data/data/prototype.js +0 -4184
- data/tests/fixtures/fail1.json +0 -1
- data/tests/test_json.rb +0 -519
- data/tests/test_json_encoding.rb +0 -65
- data/tests/test_json_string_matching.rb +0 -39
- data/tests/test_json_unicode.rb +0 -72
@@ -1,7 +1,6 @@
|
|
1
1
|
#ifndef _GENERATOR_H_
|
2
2
|
#define _GENERATOR_H_
|
3
3
|
|
4
|
-
#include <string.h>
|
5
4
|
#include <math.h>
|
6
5
|
#include <ctype.h>
|
7
6
|
|
@@ -21,10 +20,6 @@
|
|
21
20
|
#define rb_obj_instance_variables(object) rb_funcall(object, rb_intern("instance_variables"), 0)
|
22
21
|
#endif
|
23
22
|
|
24
|
-
#ifndef RB_TYPE_P
|
25
|
-
#define RB_TYPE_P(obj, type) (rb_type(obj) == type)
|
26
|
-
#endif
|
27
|
-
|
28
23
|
#define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
|
29
24
|
|
30
25
|
/* unicode definitions */
|
@@ -77,7 +72,6 @@ typedef struct JSON_Generator_StateStruct {
|
|
77
72
|
long max_nesting;
|
78
73
|
char allow_nan;
|
79
74
|
char ascii_only;
|
80
|
-
char quirks_mode;
|
81
75
|
long depth;
|
82
76
|
long buffer_initial_length;
|
83
77
|
} JSON_Generator_State;
|
@@ -4,7 +4,7 @@
|
|
4
4
|
#include "parser.h"
|
5
5
|
|
6
6
|
#if defined HAVE_RUBY_ENCODING_H
|
7
|
-
# define EXC_ENCODING
|
7
|
+
# define EXC_ENCODING rb_utf8_encoding(),
|
8
8
|
# ifndef HAVE_RB_ENC_RAISE
|
9
9
|
static void
|
10
10
|
enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
|
@@ -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;
|
@@ -89,57 +89,53 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
89
89
|
return len;
|
90
90
|
}
|
91
91
|
|
92
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
93
|
-
static rb_encoding *UTF_8, *UTF_16BE, *UTF_16LE, *UTF_32BE, *UTF_32LE;
|
94
|
-
#else
|
95
|
-
static ID i_iconv;
|
96
|
-
#endif
|
97
|
-
|
98
92
|
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
99
93
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
94
|
+
static VALUE cBigDecimal = Qundef;
|
100
95
|
|
101
96
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
102
|
-
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
103
|
-
i_object_class, i_array_class,
|
104
|
-
i_match_string, i_aset, i_aref,
|
97
|
+
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
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;
|
105
101
|
|
106
102
|
|
107
|
-
#line
|
103
|
+
#line 126 "parser.rl"
|
108
104
|
|
109
105
|
|
110
106
|
|
111
|
-
#line
|
112
|
-
|
113
|
-
|
114
|
-
|
107
|
+
#line 108 "parser.c"
|
108
|
+
enum {JSON_object_start = 1};
|
109
|
+
enum {JSON_object_first_final = 27};
|
110
|
+
enum {JSON_object_error = 0};
|
115
111
|
|
116
|
-
|
112
|
+
enum {JSON_object_en_main = 1};
|
117
113
|
|
118
114
|
|
119
|
-
#line
|
115
|
+
#line 167 "parser.rl"
|
120
116
|
|
121
117
|
|
122
|
-
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
118
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
123
119
|
{
|
124
120
|
int cs = EVIL;
|
125
121
|
VALUE last_name = Qnil;
|
126
122
|
VALUE object_class = json->object_class;
|
127
123
|
|
128
|
-
if (json->max_nesting &&
|
129
|
-
rb_raise(eNestingError, "nesting of %d is too deep",
|
124
|
+
if (json->max_nesting && current_nesting > json->max_nesting) {
|
125
|
+
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
130
126
|
}
|
131
127
|
|
132
128
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
133
129
|
|
134
130
|
|
135
|
-
#line
|
131
|
+
#line 132 "parser.c"
|
136
132
|
{
|
137
133
|
cs = JSON_object_start;
|
138
134
|
}
|
139
135
|
|
140
|
-
#line
|
136
|
+
#line 182 "parser.rl"
|
141
137
|
|
142
|
-
#line
|
138
|
+
#line 139 "parser.c"
|
143
139
|
{
|
144
140
|
if ( p == pe )
|
145
141
|
goto _test_eof;
|
@@ -167,7 +163,7 @@ case 2:
|
|
167
163
|
goto st2;
|
168
164
|
goto st0;
|
169
165
|
tr2:
|
170
|
-
#line
|
166
|
+
#line 149 "parser.rl"
|
171
167
|
{
|
172
168
|
char *np;
|
173
169
|
json->parsing_name = 1;
|
@@ -180,7 +176,7 @@ st3:
|
|
180
176
|
if ( ++p == pe )
|
181
177
|
goto _test_eof3;
|
182
178
|
case 3:
|
183
|
-
#line
|
179
|
+
#line 180 "parser.c"
|
184
180
|
switch( (*p) ) {
|
185
181
|
case 13: goto st3;
|
186
182
|
case 32: goto st3;
|
@@ -247,10 +243,10 @@ case 8:
|
|
247
243
|
goto st8;
|
248
244
|
goto st0;
|
249
245
|
tr11:
|
250
|
-
#line
|
246
|
+
#line 134 "parser.rl"
|
251
247
|
{
|
252
248
|
VALUE v = Qnil;
|
253
|
-
char *np = JSON_parse_value(json, p, pe, &v);
|
249
|
+
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
254
250
|
if (np == NULL) {
|
255
251
|
p--; {p++; cs = 9; goto _out;}
|
256
252
|
} else {
|
@@ -267,7 +263,7 @@ st9:
|
|
267
263
|
if ( ++p == pe )
|
268
264
|
goto _test_eof9;
|
269
265
|
case 9:
|
270
|
-
#line
|
266
|
+
#line 267 "parser.c"
|
271
267
|
switch( (*p) ) {
|
272
268
|
case 13: goto st9;
|
273
269
|
case 32: goto st9;
|
@@ -356,14 +352,14 @@ case 18:
|
|
356
352
|
goto st9;
|
357
353
|
goto st18;
|
358
354
|
tr4:
|
359
|
-
#line
|
355
|
+
#line 157 "parser.rl"
|
360
356
|
{ p--; {p++; cs = 27; goto _out;} }
|
361
357
|
goto st27;
|
362
358
|
st27:
|
363
359
|
if ( ++p == pe )
|
364
360
|
goto _test_eof27;
|
365
361
|
case 27:
|
366
|
-
#line
|
362
|
+
#line 363 "parser.c"
|
367
363
|
goto st0;
|
368
364
|
st19:
|
369
365
|
if ( ++p == pe )
|
@@ -461,7 +457,7 @@ case 26:
|
|
461
457
|
_out: {}
|
462
458
|
}
|
463
459
|
|
464
|
-
#line
|
460
|
+
#line 183 "parser.rl"
|
465
461
|
|
466
462
|
if (cs >= JSON_object_first_final) {
|
467
463
|
if (json->create_additions) {
|
@@ -486,69 +482,78 @@ case 26:
|
|
486
482
|
|
487
483
|
|
488
484
|
|
489
|
-
#line
|
490
|
-
|
491
|
-
|
492
|
-
|
485
|
+
#line 486 "parser.c"
|
486
|
+
enum {JSON_value_start = 1};
|
487
|
+
enum {JSON_value_first_final = 29};
|
488
|
+
enum {JSON_value_error = 0};
|
493
489
|
|
494
|
-
|
490
|
+
enum {JSON_value_en_main = 1};
|
495
491
|
|
496
492
|
|
497
|
-
#line
|
493
|
+
#line 283 "parser.rl"
|
498
494
|
|
499
495
|
|
500
|
-
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
496
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
501
497
|
{
|
502
498
|
int cs = EVIL;
|
503
499
|
|
504
500
|
|
505
|
-
#line
|
501
|
+
#line 502 "parser.c"
|
506
502
|
{
|
507
503
|
cs = JSON_value_start;
|
508
504
|
}
|
509
505
|
|
510
|
-
#line
|
506
|
+
#line 290 "parser.rl"
|
511
507
|
|
512
|
-
#line
|
508
|
+
#line 509 "parser.c"
|
513
509
|
{
|
514
510
|
if ( p == pe )
|
515
511
|
goto _test_eof;
|
516
512
|
switch ( cs )
|
517
513
|
{
|
514
|
+
st1:
|
515
|
+
if ( ++p == pe )
|
516
|
+
goto _test_eof1;
|
518
517
|
case 1:
|
519
518
|
switch( (*p) ) {
|
520
|
-
case
|
521
|
-
case
|
522
|
-
case
|
523
|
-
case
|
524
|
-
case
|
525
|
-
case
|
526
|
-
case
|
527
|
-
case
|
528
|
-
case
|
519
|
+
case 13: goto st1;
|
520
|
+
case 32: goto st1;
|
521
|
+
case 34: goto tr2;
|
522
|
+
case 45: goto tr3;
|
523
|
+
case 47: goto st6;
|
524
|
+
case 73: goto st10;
|
525
|
+
case 78: goto st17;
|
526
|
+
case 91: goto tr7;
|
527
|
+
case 102: goto st19;
|
528
|
+
case 110: goto st23;
|
529
|
+
case 116: goto st26;
|
530
|
+
case 123: goto tr11;
|
529
531
|
}
|
530
|
-
if (
|
531
|
-
|
532
|
+
if ( (*p) > 10 ) {
|
533
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
534
|
+
goto tr3;
|
535
|
+
} else if ( (*p) >= 9 )
|
536
|
+
goto st1;
|
532
537
|
goto st0;
|
533
538
|
st0:
|
534
539
|
cs = 0;
|
535
540
|
goto _out;
|
536
|
-
|
537
|
-
#line
|
541
|
+
tr2:
|
542
|
+
#line 235 "parser.rl"
|
538
543
|
{
|
539
544
|
char *np = JSON_parse_string(json, p, pe, result);
|
540
|
-
if (np == NULL) { p--; {p++; cs =
|
545
|
+
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
541
546
|
}
|
542
|
-
goto
|
543
|
-
|
544
|
-
#line
|
547
|
+
goto st29;
|
548
|
+
tr3:
|
549
|
+
#line 240 "parser.rl"
|
545
550
|
{
|
546
551
|
char *np;
|
547
|
-
if(pe > p +
|
552
|
+
if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
|
548
553
|
if (json->allow_nan) {
|
549
554
|
*result = CMinusInfinity;
|
550
555
|
{p = (( p + 10))-1;}
|
551
|
-
p--; {p++; cs =
|
556
|
+
p--; {p++; cs = 29; goto _out;}
|
552
557
|
} else {
|
553
558
|
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
554
559
|
}
|
@@ -557,31 +562,27 @@ tr2:
|
|
557
562
|
if (np != NULL) {p = (( np))-1;}
|
558
563
|
np = JSON_parse_integer(json, p, pe, result);
|
559
564
|
if (np != NULL) {p = (( np))-1;}
|
560
|
-
p--; {p++; cs =
|
565
|
+
p--; {p++; cs = 29; goto _out;}
|
561
566
|
}
|
562
|
-
goto
|
563
|
-
|
564
|
-
#line
|
567
|
+
goto st29;
|
568
|
+
tr7:
|
569
|
+
#line 258 "parser.rl"
|
565
570
|
{
|
566
571
|
char *np;
|
567
|
-
json
|
568
|
-
np =
|
569
|
-
json->current_nesting--;
|
570
|
-
if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
|
572
|
+
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
|
573
|
+
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
571
574
|
}
|
572
|
-
goto
|
573
|
-
|
574
|
-
#line
|
575
|
+
goto st29;
|
576
|
+
tr11:
|
577
|
+
#line 264 "parser.rl"
|
575
578
|
{
|
576
579
|
char *np;
|
577
|
-
json
|
578
|
-
np =
|
579
|
-
json->current_nesting--;
|
580
|
-
if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
|
580
|
+
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
|
581
|
+
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
581
582
|
}
|
582
|
-
goto
|
583
|
-
|
584
|
-
#line
|
583
|
+
goto st29;
|
584
|
+
tr25:
|
585
|
+
#line 228 "parser.rl"
|
585
586
|
{
|
586
587
|
if (json->allow_nan) {
|
587
588
|
*result = CInfinity;
|
@@ -589,9 +590,9 @@ tr16:
|
|
589
590
|
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
|
590
591
|
}
|
591
592
|
}
|
592
|
-
goto
|
593
|
-
|
594
|
-
#line
|
593
|
+
goto st29;
|
594
|
+
tr27:
|
595
|
+
#line 221 "parser.rl"
|
595
596
|
{
|
596
597
|
if (json->allow_nan) {
|
597
598
|
*result = CNaN;
|
@@ -599,168 +600,240 @@ tr18:
|
|
599
600
|
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
|
600
601
|
}
|
601
602
|
}
|
602
|
-
goto
|
603
|
-
|
604
|
-
#line
|
603
|
+
goto st29;
|
604
|
+
tr31:
|
605
|
+
#line 215 "parser.rl"
|
605
606
|
{
|
606
607
|
*result = Qfalse;
|
607
608
|
}
|
608
|
-
goto
|
609
|
-
|
610
|
-
#line
|
609
|
+
goto st29;
|
610
|
+
tr34:
|
611
|
+
#line 212 "parser.rl"
|
611
612
|
{
|
612
613
|
*result = Qnil;
|
613
614
|
}
|
614
|
-
goto
|
615
|
-
|
616
|
-
#line
|
615
|
+
goto st29;
|
616
|
+
tr37:
|
617
|
+
#line 218 "parser.rl"
|
617
618
|
{
|
618
619
|
*result = Qtrue;
|
619
620
|
}
|
620
|
-
goto
|
621
|
-
|
621
|
+
goto st29;
|
622
|
+
st29:
|
622
623
|
if ( ++p == pe )
|
623
|
-
goto
|
624
|
-
case
|
625
|
-
#line
|
626
|
-
{ p--; {p++; cs =
|
627
|
-
#line
|
624
|
+
goto _test_eof29;
|
625
|
+
case 29:
|
626
|
+
#line 270 "parser.rl"
|
627
|
+
{ p--; {p++; cs = 29; goto _out;} }
|
628
|
+
#line 629 "parser.c"
|
629
|
+
switch( (*p) ) {
|
630
|
+
case 13: goto st29;
|
631
|
+
case 32: goto st29;
|
632
|
+
case 47: goto st2;
|
633
|
+
}
|
634
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
635
|
+
goto st29;
|
628
636
|
goto st0;
|
629
637
|
st2:
|
630
638
|
if ( ++p == pe )
|
631
639
|
goto _test_eof2;
|
632
640
|
case 2:
|
633
|
-
|
634
|
-
goto st3;
|
641
|
+
switch( (*p) ) {
|
642
|
+
case 42: goto st3;
|
643
|
+
case 47: goto st5;
|
644
|
+
}
|
635
645
|
goto st0;
|
636
646
|
st3:
|
637
647
|
if ( ++p == pe )
|
638
648
|
goto _test_eof3;
|
639
649
|
case 3:
|
640
|
-
if ( (*p) ==
|
650
|
+
if ( (*p) == 42 )
|
641
651
|
goto st4;
|
642
|
-
goto
|
652
|
+
goto st3;
|
643
653
|
st4:
|
644
654
|
if ( ++p == pe )
|
645
655
|
goto _test_eof4;
|
646
656
|
case 4:
|
647
|
-
|
648
|
-
goto
|
649
|
-
|
657
|
+
switch( (*p) ) {
|
658
|
+
case 42: goto st4;
|
659
|
+
case 47: goto st29;
|
660
|
+
}
|
661
|
+
goto st3;
|
650
662
|
st5:
|
651
663
|
if ( ++p == pe )
|
652
664
|
goto _test_eof5;
|
653
665
|
case 5:
|
654
|
-
if ( (*p) ==
|
655
|
-
goto
|
656
|
-
goto
|
666
|
+
if ( (*p) == 10 )
|
667
|
+
goto st29;
|
668
|
+
goto st5;
|
657
669
|
st6:
|
658
670
|
if ( ++p == pe )
|
659
671
|
goto _test_eof6;
|
660
672
|
case 6:
|
661
|
-
|
662
|
-
goto st7;
|
673
|
+
switch( (*p) ) {
|
674
|
+
case 42: goto st7;
|
675
|
+
case 47: goto st9;
|
676
|
+
}
|
663
677
|
goto st0;
|
664
678
|
st7:
|
665
679
|
if ( ++p == pe )
|
666
680
|
goto _test_eof7;
|
667
681
|
case 7:
|
668
|
-
if ( (*p) ==
|
682
|
+
if ( (*p) == 42 )
|
669
683
|
goto st8;
|
670
|
-
goto
|
684
|
+
goto st7;
|
671
685
|
st8:
|
672
686
|
if ( ++p == pe )
|
673
687
|
goto _test_eof8;
|
674
688
|
case 8:
|
675
|
-
|
676
|
-
goto
|
677
|
-
|
689
|
+
switch( (*p) ) {
|
690
|
+
case 42: goto st8;
|
691
|
+
case 47: goto st1;
|
692
|
+
}
|
693
|
+
goto st7;
|
678
694
|
st9:
|
679
695
|
if ( ++p == pe )
|
680
696
|
goto _test_eof9;
|
681
697
|
case 9:
|
682
|
-
if ( (*p) ==
|
683
|
-
goto
|
684
|
-
goto
|
698
|
+
if ( (*p) == 10 )
|
699
|
+
goto st1;
|
700
|
+
goto st9;
|
685
701
|
st10:
|
686
702
|
if ( ++p == pe )
|
687
703
|
goto _test_eof10;
|
688
704
|
case 10:
|
689
|
-
if ( (*p) ==
|
690
|
-
goto
|
705
|
+
if ( (*p) == 110 )
|
706
|
+
goto st11;
|
691
707
|
goto st0;
|
692
708
|
st11:
|
693
709
|
if ( ++p == pe )
|
694
710
|
goto _test_eof11;
|
695
711
|
case 11:
|
696
|
-
if ( (*p) ==
|
712
|
+
if ( (*p) == 102 )
|
697
713
|
goto st12;
|
698
714
|
goto st0;
|
699
715
|
st12:
|
700
716
|
if ( ++p == pe )
|
701
717
|
goto _test_eof12;
|
702
718
|
case 12:
|
703
|
-
if ( (*p) ==
|
719
|
+
if ( (*p) == 105 )
|
704
720
|
goto st13;
|
705
721
|
goto st0;
|
706
722
|
st13:
|
707
723
|
if ( ++p == pe )
|
708
724
|
goto _test_eof13;
|
709
725
|
case 13:
|
710
|
-
if ( (*p) ==
|
726
|
+
if ( (*p) == 110 )
|
711
727
|
goto st14;
|
712
728
|
goto st0;
|
713
729
|
st14:
|
714
730
|
if ( ++p == pe )
|
715
731
|
goto _test_eof14;
|
716
732
|
case 14:
|
717
|
-
if ( (*p) ==
|
718
|
-
goto
|
733
|
+
if ( (*p) == 105 )
|
734
|
+
goto st15;
|
719
735
|
goto st0;
|
720
736
|
st15:
|
721
737
|
if ( ++p == pe )
|
722
738
|
goto _test_eof15;
|
723
739
|
case 15:
|
724
|
-
if ( (*p) ==
|
740
|
+
if ( (*p) == 116 )
|
725
741
|
goto st16;
|
726
742
|
goto st0;
|
727
743
|
st16:
|
728
744
|
if ( ++p == pe )
|
729
745
|
goto _test_eof16;
|
730
746
|
case 16:
|
731
|
-
if ( (*p) ==
|
732
|
-
goto
|
747
|
+
if ( (*p) == 121 )
|
748
|
+
goto tr25;
|
733
749
|
goto st0;
|
734
750
|
st17:
|
735
751
|
if ( ++p == pe )
|
736
752
|
goto _test_eof17;
|
737
753
|
case 17:
|
738
|
-
if ( (*p) ==
|
739
|
-
goto
|
754
|
+
if ( (*p) == 97 )
|
755
|
+
goto st18;
|
740
756
|
goto st0;
|
741
757
|
st18:
|
742
758
|
if ( ++p == pe )
|
743
759
|
goto _test_eof18;
|
744
760
|
case 18:
|
745
|
-
if ( (*p) ==
|
746
|
-
goto
|
761
|
+
if ( (*p) == 78 )
|
762
|
+
goto tr27;
|
747
763
|
goto st0;
|
748
764
|
st19:
|
749
765
|
if ( ++p == pe )
|
750
766
|
goto _test_eof19;
|
751
767
|
case 19:
|
752
|
-
if ( (*p) ==
|
768
|
+
if ( (*p) == 97 )
|
753
769
|
goto st20;
|
754
770
|
goto st0;
|
755
771
|
st20:
|
756
772
|
if ( ++p == pe )
|
757
773
|
goto _test_eof20;
|
758
774
|
case 20:
|
775
|
+
if ( (*p) == 108 )
|
776
|
+
goto st21;
|
777
|
+
goto st0;
|
778
|
+
st21:
|
779
|
+
if ( ++p == pe )
|
780
|
+
goto _test_eof21;
|
781
|
+
case 21:
|
782
|
+
if ( (*p) == 115 )
|
783
|
+
goto st22;
|
784
|
+
goto st0;
|
785
|
+
st22:
|
786
|
+
if ( ++p == pe )
|
787
|
+
goto _test_eof22;
|
788
|
+
case 22:
|
789
|
+
if ( (*p) == 101 )
|
790
|
+
goto tr31;
|
791
|
+
goto st0;
|
792
|
+
st23:
|
793
|
+
if ( ++p == pe )
|
794
|
+
goto _test_eof23;
|
795
|
+
case 23:
|
796
|
+
if ( (*p) == 117 )
|
797
|
+
goto st24;
|
798
|
+
goto st0;
|
799
|
+
st24:
|
800
|
+
if ( ++p == pe )
|
801
|
+
goto _test_eof24;
|
802
|
+
case 24:
|
803
|
+
if ( (*p) == 108 )
|
804
|
+
goto st25;
|
805
|
+
goto st0;
|
806
|
+
st25:
|
807
|
+
if ( ++p == pe )
|
808
|
+
goto _test_eof25;
|
809
|
+
case 25:
|
810
|
+
if ( (*p) == 108 )
|
811
|
+
goto tr34;
|
812
|
+
goto st0;
|
813
|
+
st26:
|
814
|
+
if ( ++p == pe )
|
815
|
+
goto _test_eof26;
|
816
|
+
case 26:
|
817
|
+
if ( (*p) == 114 )
|
818
|
+
goto st27;
|
819
|
+
goto st0;
|
820
|
+
st27:
|
821
|
+
if ( ++p == pe )
|
822
|
+
goto _test_eof27;
|
823
|
+
case 27:
|
824
|
+
if ( (*p) == 117 )
|
825
|
+
goto st28;
|
826
|
+
goto st0;
|
827
|
+
st28:
|
828
|
+
if ( ++p == pe )
|
829
|
+
goto _test_eof28;
|
830
|
+
case 28:
|
759
831
|
if ( (*p) == 101 )
|
760
|
-
goto
|
832
|
+
goto tr37;
|
761
833
|
goto st0;
|
762
834
|
}
|
763
|
-
|
835
|
+
_test_eof1: cs = 1; goto _test_eof;
|
836
|
+
_test_eof29: cs = 29; goto _test_eof;
|
764
837
|
_test_eof2: cs = 2; goto _test_eof;
|
765
838
|
_test_eof3: cs = 3; goto _test_eof;
|
766
839
|
_test_eof4: cs = 4; goto _test_eof;
|
@@ -780,12 +853,20 @@ case 20:
|
|
780
853
|
_test_eof18: cs = 18; goto _test_eof;
|
781
854
|
_test_eof19: cs = 19; goto _test_eof;
|
782
855
|
_test_eof20: cs = 20; goto _test_eof;
|
856
|
+
_test_eof21: cs = 21; goto _test_eof;
|
857
|
+
_test_eof22: cs = 22; goto _test_eof;
|
858
|
+
_test_eof23: cs = 23; goto _test_eof;
|
859
|
+
_test_eof24: cs = 24; goto _test_eof;
|
860
|
+
_test_eof25: cs = 25; goto _test_eof;
|
861
|
+
_test_eof26: cs = 26; goto _test_eof;
|
862
|
+
_test_eof27: cs = 27; goto _test_eof;
|
863
|
+
_test_eof28: cs = 28; goto _test_eof;
|
783
864
|
|
784
865
|
_test_eof: {}
|
785
866
|
_out: {}
|
786
867
|
}
|
787
868
|
|
788
|
-
#line
|
869
|
+
#line 291 "parser.rl"
|
789
870
|
|
790
871
|
if (cs >= JSON_value_first_final) {
|
791
872
|
return p;
|
@@ -795,15 +876,15 @@ case 20:
|
|
795
876
|
}
|
796
877
|
|
797
878
|
|
798
|
-
#line
|
799
|
-
|
800
|
-
|
801
|
-
|
879
|
+
#line 880 "parser.c"
|
880
|
+
enum {JSON_integer_start = 1};
|
881
|
+
enum {JSON_integer_first_final = 3};
|
882
|
+
enum {JSON_integer_error = 0};
|
802
883
|
|
803
|
-
|
884
|
+
enum {JSON_integer_en_main = 1};
|
804
885
|
|
805
886
|
|
806
|
-
#line
|
887
|
+
#line 307 "parser.rl"
|
807
888
|
|
808
889
|
|
809
890
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -811,15 +892,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|
811
892
|
int cs = EVIL;
|
812
893
|
|
813
894
|
|
814
|
-
#line
|
895
|
+
#line 896 "parser.c"
|
815
896
|
{
|
816
897
|
cs = JSON_integer_start;
|
817
898
|
}
|
818
899
|
|
819
|
-
#line
|
900
|
+
#line 314 "parser.rl"
|
820
901
|
json->memo = p;
|
821
902
|
|
822
|
-
#line
|
903
|
+
#line 904 "parser.c"
|
823
904
|
{
|
824
905
|
if ( p == pe )
|
825
906
|
goto _test_eof;
|
@@ -853,14 +934,14 @@ case 3:
|
|
853
934
|
goto st0;
|
854
935
|
goto tr4;
|
855
936
|
tr4:
|
856
|
-
#line
|
937
|
+
#line 304 "parser.rl"
|
857
938
|
{ p--; {p++; cs = 4; goto _out;} }
|
858
939
|
goto st4;
|
859
940
|
st4:
|
860
941
|
if ( ++p == pe )
|
861
942
|
goto _test_eof4;
|
862
943
|
case 4:
|
863
|
-
#line
|
944
|
+
#line 945 "parser.c"
|
864
945
|
goto st0;
|
865
946
|
st5:
|
866
947
|
if ( ++p == pe )
|
@@ -879,7 +960,7 @@ case 5:
|
|
879
960
|
_out: {}
|
880
961
|
}
|
881
962
|
|
882
|
-
#line
|
963
|
+
#line 316 "parser.rl"
|
883
964
|
|
884
965
|
if (cs >= JSON_integer_first_final) {
|
885
966
|
long len = p - json->memo;
|
@@ -894,31 +975,44 @@ case 5:
|
|
894
975
|
}
|
895
976
|
|
896
977
|
|
897
|
-
#line
|
898
|
-
|
899
|
-
|
900
|
-
|
978
|
+
#line 979 "parser.c"
|
979
|
+
enum {JSON_float_start = 1};
|
980
|
+
enum {JSON_float_first_final = 8};
|
981
|
+
enum {JSON_float_error = 0};
|
901
982
|
|
902
|
-
|
983
|
+
enum {JSON_float_en_main = 1};
|
903
984
|
|
904
985
|
|
905
|
-
#line
|
986
|
+
#line 341 "parser.rl"
|
906
987
|
|
907
988
|
|
989
|
+
static int is_bigdecimal_class(VALUE obj)
|
990
|
+
{
|
991
|
+
if (cBigDecimal == Qundef) {
|
992
|
+
if (rb_const_defined(rb_cObject, i_BigDecimal)) {
|
993
|
+
cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
|
994
|
+
}
|
995
|
+
else {
|
996
|
+
return 0;
|
997
|
+
}
|
998
|
+
}
|
999
|
+
return obj == cBigDecimal;
|
1000
|
+
}
|
1001
|
+
|
908
1002
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
909
1003
|
{
|
910
1004
|
int cs = EVIL;
|
911
1005
|
|
912
1006
|
|
913
|
-
#line
|
1007
|
+
#line 1008 "parser.c"
|
914
1008
|
{
|
915
1009
|
cs = JSON_float_start;
|
916
1010
|
}
|
917
1011
|
|
918
|
-
#line
|
1012
|
+
#line 361 "parser.rl"
|
919
1013
|
json->memo = p;
|
920
1014
|
|
921
|
-
#line
|
1015
|
+
#line 1016 "parser.c"
|
922
1016
|
{
|
923
1017
|
if ( p == pe )
|
924
1018
|
goto _test_eof;
|
@@ -976,14 +1070,14 @@ case 8:
|
|
976
1070
|
goto st0;
|
977
1071
|
goto tr9;
|
978
1072
|
tr9:
|
979
|
-
#line
|
1073
|
+
#line 335 "parser.rl"
|
980
1074
|
{ p--; {p++; cs = 9; goto _out;} }
|
981
1075
|
goto st9;
|
982
1076
|
st9:
|
983
1077
|
if ( ++p == pe )
|
984
1078
|
goto _test_eof9;
|
985
1079
|
case 9:
|
986
|
-
#line
|
1080
|
+
#line 1081 "parser.c"
|
987
1081
|
goto st0;
|
988
1082
|
st5:
|
989
1083
|
if ( ++p == pe )
|
@@ -1044,14 +1138,24 @@ case 7:
|
|
1044
1138
|
_out: {}
|
1045
1139
|
}
|
1046
1140
|
|
1047
|
-
#line
|
1141
|
+
#line 363 "parser.rl"
|
1048
1142
|
|
1049
1143
|
if (cs >= JSON_float_first_final) {
|
1050
1144
|
long len = p - json->memo;
|
1051
1145
|
fbuffer_clear(json->fbuffer);
|
1052
1146
|
fbuffer_append(json->fbuffer, json->memo, len);
|
1053
1147
|
fbuffer_append_char(json->fbuffer, '\0');
|
1054
|
-
|
1148
|
+
if (NIL_P(json->decimal_class)) {
|
1149
|
+
*result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
1150
|
+
} else {
|
1151
|
+
VALUE text;
|
1152
|
+
text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
1153
|
+
if (is_bigdecimal_class(json->decimal_class)) {
|
1154
|
+
*result = rb_funcall(Qnil, i_BigDecimal, 1, text);
|
1155
|
+
} else {
|
1156
|
+
*result = rb_funcall(json->decimal_class, i_new, 1, text);
|
1157
|
+
}
|
1158
|
+
}
|
1055
1159
|
return p + 1;
|
1056
1160
|
} else {
|
1057
1161
|
return NULL;
|
@@ -1060,36 +1164,36 @@ case 7:
|
|
1060
1164
|
|
1061
1165
|
|
1062
1166
|
|
1063
|
-
#line
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1167
|
+
#line 1168 "parser.c"
|
1168
|
+
enum {JSON_array_start = 1};
|
1169
|
+
enum {JSON_array_first_final = 17};
|
1170
|
+
enum {JSON_array_error = 0};
|
1067
1171
|
|
1068
|
-
|
1172
|
+
enum {JSON_array_en_main = 1};
|
1069
1173
|
|
1070
1174
|
|
1071
|
-
#line
|
1175
|
+
#line 416 "parser.rl"
|
1072
1176
|
|
1073
1177
|
|
1074
|
-
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
1178
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
1075
1179
|
{
|
1076
1180
|
int cs = EVIL;
|
1077
1181
|
VALUE array_class = json->array_class;
|
1078
1182
|
|
1079
|
-
if (json->max_nesting &&
|
1080
|
-
rb_raise(eNestingError, "nesting of %d is too deep",
|
1183
|
+
if (json->max_nesting && current_nesting > json->max_nesting) {
|
1184
|
+
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
1081
1185
|
}
|
1082
1186
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
1083
1187
|
|
1084
1188
|
|
1085
|
-
#line
|
1189
|
+
#line 1190 "parser.c"
|
1086
1190
|
{
|
1087
1191
|
cs = JSON_array_start;
|
1088
1192
|
}
|
1089
1193
|
|
1090
|
-
#line
|
1194
|
+
#line 429 "parser.rl"
|
1091
1195
|
|
1092
|
-
#line
|
1196
|
+
#line 1197 "parser.c"
|
1093
1197
|
{
|
1094
1198
|
if ( p == pe )
|
1095
1199
|
goto _test_eof;
|
@@ -1128,10 +1232,10 @@ case 2:
|
|
1128
1232
|
goto st2;
|
1129
1233
|
goto st0;
|
1130
1234
|
tr2:
|
1131
|
-
#line
|
1235
|
+
#line 393 "parser.rl"
|
1132
1236
|
{
|
1133
1237
|
VALUE v = Qnil;
|
1134
|
-
char *np = JSON_parse_value(json, p, pe, &v);
|
1238
|
+
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
1135
1239
|
if (np == NULL) {
|
1136
1240
|
p--; {p++; cs = 3; goto _out;}
|
1137
1241
|
} else {
|
@@ -1148,7 +1252,7 @@ st3:
|
|
1148
1252
|
if ( ++p == pe )
|
1149
1253
|
goto _test_eof3;
|
1150
1254
|
case 3:
|
1151
|
-
#line
|
1255
|
+
#line 1256 "parser.c"
|
1152
1256
|
switch( (*p) ) {
|
1153
1257
|
case 13: goto st3;
|
1154
1258
|
case 32: goto st3;
|
@@ -1248,14 +1352,14 @@ case 12:
|
|
1248
1352
|
goto st3;
|
1249
1353
|
goto st12;
|
1250
1354
|
tr4:
|
1251
|
-
#line
|
1355
|
+
#line 408 "parser.rl"
|
1252
1356
|
{ p--; {p++; cs = 17; goto _out;} }
|
1253
1357
|
goto st17;
|
1254
1358
|
st17:
|
1255
1359
|
if ( ++p == pe )
|
1256
1360
|
goto _test_eof17;
|
1257
1361
|
case 17:
|
1258
|
-
#line
|
1362
|
+
#line 1363 "parser.c"
|
1259
1363
|
goto st0;
|
1260
1364
|
st13:
|
1261
1365
|
if ( ++p == pe )
|
@@ -1311,7 +1415,7 @@ case 16:
|
|
1311
1415
|
_out: {}
|
1312
1416
|
}
|
1313
1417
|
|
1314
|
-
#line
|
1418
|
+
#line 430 "parser.rl"
|
1315
1419
|
|
1316
1420
|
if(cs >= JSON_array_first_final) {
|
1317
1421
|
return p + 1;
|
@@ -1356,13 +1460,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
1356
1460
|
break;
|
1357
1461
|
case 'u':
|
1358
1462
|
if (pe > stringEnd - 4) {
|
1359
|
-
|
1463
|
+
rb_enc_raise(
|
1464
|
+
EXC_ENCODING eParserError,
|
1465
|
+
"%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
|
1466
|
+
);
|
1360
1467
|
} else {
|
1361
1468
|
UTF32 ch = unescape_unicode((unsigned char *) ++pe);
|
1362
1469
|
pe += 3;
|
1363
1470
|
if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
|
1364
1471
|
pe++;
|
1365
|
-
if (pe > stringEnd - 6)
|
1472
|
+
if (pe > stringEnd - 6) {
|
1473
|
+
rb_enc_raise(
|
1474
|
+
EXC_ENCODING eParserError,
|
1475
|
+
"%u: incomplete surrogate pair at '%s'", __LINE__, p
|
1476
|
+
);
|
1477
|
+
}
|
1366
1478
|
if (pe[0] == '\\' && pe[1] == 'u') {
|
1367
1479
|
UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
|
1368
1480
|
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
|
@@ -1392,15 +1504,15 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
1392
1504
|
}
|
1393
1505
|
|
1394
1506
|
|
1395
|
-
#line
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1507
|
+
#line 1508 "parser.c"
|
1508
|
+
enum {JSON_string_start = 1};
|
1509
|
+
enum {JSON_string_first_final = 8};
|
1510
|
+
enum {JSON_string_error = 0};
|
1399
1511
|
|
1400
|
-
|
1512
|
+
enum {JSON_string_en_main = 1};
|
1401
1513
|
|
1402
1514
|
|
1403
|
-
#line
|
1515
|
+
#line 537 "parser.rl"
|
1404
1516
|
|
1405
1517
|
|
1406
1518
|
static int
|
@@ -1422,15 +1534,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1422
1534
|
|
1423
1535
|
*result = rb_str_buf_new(0);
|
1424
1536
|
|
1425
|
-
#line
|
1537
|
+
#line 1538 "parser.c"
|
1426
1538
|
{
|
1427
1539
|
cs = JSON_string_start;
|
1428
1540
|
}
|
1429
1541
|
|
1430
|
-
#line
|
1542
|
+
#line 558 "parser.rl"
|
1431
1543
|
json->memo = p;
|
1432
1544
|
|
1433
|
-
#line
|
1545
|
+
#line 1546 "parser.c"
|
1434
1546
|
{
|
1435
1547
|
if ( p == pe )
|
1436
1548
|
goto _test_eof;
|
@@ -1455,7 +1567,7 @@ case 2:
|
|
1455
1567
|
goto st0;
|
1456
1568
|
goto st2;
|
1457
1569
|
tr2:
|
1458
|
-
#line
|
1570
|
+
#line 523 "parser.rl"
|
1459
1571
|
{
|
1460
1572
|
*result = json_string_unescape(*result, json->memo + 1, p);
|
1461
1573
|
if (NIL_P(*result)) {
|
@@ -1466,14 +1578,14 @@ tr2:
|
|
1466
1578
|
{p = (( p + 1))-1;}
|
1467
1579
|
}
|
1468
1580
|
}
|
1469
|
-
#line
|
1581
|
+
#line 534 "parser.rl"
|
1470
1582
|
{ p--; {p++; cs = 8; goto _out;} }
|
1471
1583
|
goto st8;
|
1472
1584
|
st8:
|
1473
1585
|
if ( ++p == pe )
|
1474
1586
|
goto _test_eof8;
|
1475
1587
|
case 8:
|
1476
|
-
#line
|
1588
|
+
#line 1589 "parser.c"
|
1477
1589
|
goto st0;
|
1478
1590
|
st3:
|
1479
1591
|
if ( ++p == pe )
|
@@ -1549,7 +1661,7 @@ case 7:
|
|
1549
1661
|
_out: {}
|
1550
1662
|
}
|
1551
1663
|
|
1552
|
-
#line
|
1664
|
+
#line 560 "parser.rl"
|
1553
1665
|
|
1554
1666
|
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
1555
1667
|
VALUE klass;
|
@@ -1564,6 +1676,8 @@ case 7:
|
|
1564
1676
|
|
1565
1677
|
if (json->symbolize_names && json->parsing_name) {
|
1566
1678
|
*result = rb_str_intern(*result);
|
1679
|
+
} else if (RB_TYPE_P(*result, T_STRING)) {
|
1680
|
+
rb_str_resize(*result, RSTRING_LEN(*result));
|
1567
1681
|
}
|
1568
1682
|
if (cs >= JSON_string_first_final) {
|
1569
1683
|
return p + 1;
|
@@ -1586,41 +1700,16 @@ case 7:
|
|
1586
1700
|
|
1587
1701
|
static VALUE convert_encoding(VALUE source)
|
1588
1702
|
{
|
1589
|
-
const char *ptr = RSTRING_PTR(source);
|
1590
|
-
long len = RSTRING_LEN(source);
|
1591
|
-
if (len < 2) {
|
1592
|
-
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
1593
|
-
}
|
1594
1703
|
#ifdef HAVE_RUBY_ENCODING_H
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
source = rb_str_conv_enc(source, UTF_32BE, rb_utf8_encoding());
|
1600
|
-
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
1601
|
-
source = rb_str_conv_enc(source, UTF_16BE, rb_utf8_encoding());
|
1602
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
1603
|
-
source = rb_str_conv_enc(source, UTF_32LE, rb_utf8_encoding());
|
1604
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
1605
|
-
source = rb_str_conv_enc(source, UTF_16LE, rb_utf8_encoding());
|
1606
|
-
} else {
|
1607
|
-
source = rb_str_dup(source);
|
1608
|
-
FORCE_UTF8(source);
|
1609
|
-
}
|
1610
|
-
} else {
|
1611
|
-
source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
|
1612
|
-
}
|
1613
|
-
}
|
1614
|
-
#else
|
1615
|
-
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
1616
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
|
1617
|
-
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
1618
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
|
1619
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
1620
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
|
1621
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
1622
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
|
1704
|
+
rb_encoding *enc = rb_enc_get(source);
|
1705
|
+
if (enc == rb_ascii8bit_encoding()) {
|
1706
|
+
if (OBJ_FROZEN(source)) {
|
1707
|
+
source = rb_str_dup(source);
|
1623
1708
|
}
|
1709
|
+
FORCE_UTF8(source);
|
1710
|
+
} else {
|
1711
|
+
source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
|
1712
|
+
}
|
1624
1713
|
#endif
|
1625
1714
|
return source;
|
1626
1715
|
}
|
@@ -1643,8 +1732,9 @@ static VALUE convert_encoding(VALUE source)
|
|
1643
1732
|
* defiance of RFC 4627 to be parsed by the Parser. This option defaults to
|
1644
1733
|
* false.
|
1645
1734
|
* * *symbolize_names*: If set to true, returns symbols for the names
|
1646
|
-
* (keys) in a JSON object. Otherwise strings are returned, which is
|
1647
|
-
* the default.
|
1735
|
+
* (keys) in a JSON object. Otherwise strings are returned, which is
|
1736
|
+
* also the default. It's not possible to use this option in
|
1737
|
+
* conjunction with the *create_additions* option.
|
1648
1738
|
* * *create_additions*: If set to false, the Parser doesn't create
|
1649
1739
|
* additions even if a matching class and create_id was found. This option
|
1650
1740
|
* defaults to false.
|
@@ -1695,19 +1785,17 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1695
1785
|
} else {
|
1696
1786
|
json->symbolize_names = 0;
|
1697
1787
|
}
|
1698
|
-
tmp = ID2SYM(i_quirks_mode);
|
1699
|
-
if (option_given_p(opts, tmp)) {
|
1700
|
-
VALUE quirks_mode = rb_hash_aref(opts, tmp);
|
1701
|
-
json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
|
1702
|
-
} else {
|
1703
|
-
json->quirks_mode = 0;
|
1704
|
-
}
|
1705
1788
|
tmp = ID2SYM(i_create_additions);
|
1706
1789
|
if (option_given_p(opts, tmp)) {
|
1707
1790
|
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
1708
1791
|
} else {
|
1709
1792
|
json->create_additions = 0;
|
1710
1793
|
}
|
1794
|
+
if (json->symbolize_names && json->create_additions) {
|
1795
|
+
rb_raise(rb_eArgError,
|
1796
|
+
"options :symbolize_names and :create_additions cannot be "
|
1797
|
+
" used in conjunction");
|
1798
|
+
}
|
1711
1799
|
tmp = ID2SYM(i_create_id);
|
1712
1800
|
if (option_given_p(opts, tmp)) {
|
1713
1801
|
json->create_id = rb_hash_aref(opts, tmp);
|
@@ -1726,6 +1814,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1726
1814
|
} else {
|
1727
1815
|
json->array_class = Qnil;
|
1728
1816
|
}
|
1817
|
+
tmp = ID2SYM(i_decimal_class);
|
1818
|
+
if (option_given_p(opts, tmp)) {
|
1819
|
+
json->decimal_class = rb_hash_aref(opts, tmp);
|
1820
|
+
} else {
|
1821
|
+
json->decimal_class = Qnil;
|
1822
|
+
}
|
1729
1823
|
tmp = ID2SYM(i_match_string);
|
1730
1824
|
if (option_given_p(opts, tmp)) {
|
1731
1825
|
VALUE match_string = rb_hash_aref(opts, tmp);
|
@@ -1739,16 +1833,14 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1739
1833
|
} else {
|
1740
1834
|
json->max_nesting = 100;
|
1741
1835
|
json->allow_nan = 0;
|
1742
|
-
json->create_additions =
|
1836
|
+
json->create_additions = 0;
|
1743
1837
|
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
1744
1838
|
json->object_class = Qnil;
|
1745
1839
|
json->array_class = Qnil;
|
1840
|
+
json->decimal_class = Qnil;
|
1746
1841
|
}
|
1842
|
+
source = convert_encoding(StringValue(source));
|
1747
1843
|
StringValue(source);
|
1748
|
-
if (!json->quirks_mode) {
|
1749
|
-
source = convert_encoding(source);
|
1750
|
-
}
|
1751
|
-
json->current_nesting = 0;
|
1752
1844
|
json->len = RSTRING_LEN(source);
|
1753
1845
|
json->source = RSTRING_PTR(source);;
|
1754
1846
|
json->Vsource = source;
|
@@ -1756,209 +1848,41 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1756
1848
|
}
|
1757
1849
|
|
1758
1850
|
|
1759
|
-
#line
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1851
|
+
#line 1852 "parser.c"
|
1852
|
+
enum {JSON_start = 1};
|
1853
|
+
enum {JSON_first_final = 10};
|
1854
|
+
enum {JSON_error = 0};
|
1763
1855
|
|
1764
|
-
|
1856
|
+
enum {JSON_en_main = 1};
|
1765
1857
|
|
1766
1858
|
|
1767
|
-
#line
|
1859
|
+
#line 760 "parser.rl"
|
1768
1860
|
|
1769
1861
|
|
1770
|
-
|
1862
|
+
/*
|
1863
|
+
* call-seq: parse()
|
1864
|
+
*
|
1865
|
+
* Parses the current JSON text _source_ and returns the complete data
|
1866
|
+
* structure as a result.
|
1867
|
+
*/
|
1868
|
+
static VALUE cParser_parse(VALUE self)
|
1771
1869
|
{
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1870
|
+
char *p, *pe;
|
1871
|
+
int cs = EVIL;
|
1872
|
+
VALUE result = Qnil;
|
1873
|
+
GET_PARSER;
|
1776
1874
|
|
1777
1875
|
|
1778
|
-
#line
|
1876
|
+
#line 1877 "parser.c"
|
1779
1877
|
{
|
1780
1878
|
cs = JSON_start;
|
1781
1879
|
}
|
1782
1880
|
|
1783
|
-
#line
|
1784
|
-
|
1785
|
-
|
1881
|
+
#line 776 "parser.rl"
|
1882
|
+
p = json->source;
|
1883
|
+
pe = p + json->len;
|
1786
1884
|
|
1787
|
-
#line
|
1788
|
-
{
|
1789
|
-
if ( p == pe )
|
1790
|
-
goto _test_eof;
|
1791
|
-
switch ( cs )
|
1792
|
-
{
|
1793
|
-
st1:
|
1794
|
-
if ( ++p == pe )
|
1795
|
-
goto _test_eof1;
|
1796
|
-
case 1:
|
1797
|
-
switch( (*p) ) {
|
1798
|
-
case 13: goto st1;
|
1799
|
-
case 32: goto st1;
|
1800
|
-
case 47: goto st2;
|
1801
|
-
case 91: goto tr3;
|
1802
|
-
case 123: goto tr4;
|
1803
|
-
}
|
1804
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
1805
|
-
goto st1;
|
1806
|
-
goto st0;
|
1807
|
-
st0:
|
1808
|
-
cs = 0;
|
1809
|
-
goto _out;
|
1810
|
-
st2:
|
1811
|
-
if ( ++p == pe )
|
1812
|
-
goto _test_eof2;
|
1813
|
-
case 2:
|
1814
|
-
switch( (*p) ) {
|
1815
|
-
case 42: goto st3;
|
1816
|
-
case 47: goto st5;
|
1817
|
-
}
|
1818
|
-
goto st0;
|
1819
|
-
st3:
|
1820
|
-
if ( ++p == pe )
|
1821
|
-
goto _test_eof3;
|
1822
|
-
case 3:
|
1823
|
-
if ( (*p) == 42 )
|
1824
|
-
goto st4;
|
1825
|
-
goto st3;
|
1826
|
-
st4:
|
1827
|
-
if ( ++p == pe )
|
1828
|
-
goto _test_eof4;
|
1829
|
-
case 4:
|
1830
|
-
switch( (*p) ) {
|
1831
|
-
case 42: goto st4;
|
1832
|
-
case 47: goto st1;
|
1833
|
-
}
|
1834
|
-
goto st3;
|
1835
|
-
st5:
|
1836
|
-
if ( ++p == pe )
|
1837
|
-
goto _test_eof5;
|
1838
|
-
case 5:
|
1839
|
-
if ( (*p) == 10 )
|
1840
|
-
goto st1;
|
1841
|
-
goto st5;
|
1842
|
-
tr3:
|
1843
|
-
#line 756 "parser.rl"
|
1844
|
-
{
|
1845
|
-
char *np;
|
1846
|
-
json->current_nesting = 1;
|
1847
|
-
np = JSON_parse_array(json, p, pe, &result);
|
1848
|
-
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
1849
|
-
}
|
1850
|
-
goto st10;
|
1851
|
-
tr4:
|
1852
|
-
#line 749 "parser.rl"
|
1853
|
-
{
|
1854
|
-
char *np;
|
1855
|
-
json->current_nesting = 1;
|
1856
|
-
np = JSON_parse_object(json, p, pe, &result);
|
1857
|
-
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
1858
|
-
}
|
1859
|
-
goto st10;
|
1860
|
-
st10:
|
1861
|
-
if ( ++p == pe )
|
1862
|
-
goto _test_eof10;
|
1863
|
-
case 10:
|
1864
|
-
#line 1865 "parser.c"
|
1865
|
-
switch( (*p) ) {
|
1866
|
-
case 13: goto st10;
|
1867
|
-
case 32: goto st10;
|
1868
|
-
case 47: goto st6;
|
1869
|
-
}
|
1870
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
1871
|
-
goto st10;
|
1872
|
-
goto st0;
|
1873
|
-
st6:
|
1874
|
-
if ( ++p == pe )
|
1875
|
-
goto _test_eof6;
|
1876
|
-
case 6:
|
1877
|
-
switch( (*p) ) {
|
1878
|
-
case 42: goto st7;
|
1879
|
-
case 47: goto st9;
|
1880
|
-
}
|
1881
|
-
goto st0;
|
1882
|
-
st7:
|
1883
|
-
if ( ++p == pe )
|
1884
|
-
goto _test_eof7;
|
1885
|
-
case 7:
|
1886
|
-
if ( (*p) == 42 )
|
1887
|
-
goto st8;
|
1888
|
-
goto st7;
|
1889
|
-
st8:
|
1890
|
-
if ( ++p == pe )
|
1891
|
-
goto _test_eof8;
|
1892
|
-
case 8:
|
1893
|
-
switch( (*p) ) {
|
1894
|
-
case 42: goto st8;
|
1895
|
-
case 47: goto st10;
|
1896
|
-
}
|
1897
|
-
goto st7;
|
1898
|
-
st9:
|
1899
|
-
if ( ++p == pe )
|
1900
|
-
goto _test_eof9;
|
1901
|
-
case 9:
|
1902
|
-
if ( (*p) == 10 )
|
1903
|
-
goto st10;
|
1904
|
-
goto st9;
|
1905
|
-
}
|
1906
|
-
_test_eof1: cs = 1; goto _test_eof;
|
1907
|
-
_test_eof2: cs = 2; goto _test_eof;
|
1908
|
-
_test_eof3: cs = 3; goto _test_eof;
|
1909
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1910
|
-
_test_eof5: cs = 5; goto _test_eof;
|
1911
|
-
_test_eof10: cs = 10; goto _test_eof;
|
1912
|
-
_test_eof6: cs = 6; goto _test_eof;
|
1913
|
-
_test_eof7: cs = 7; goto _test_eof;
|
1914
|
-
_test_eof8: cs = 8; goto _test_eof;
|
1915
|
-
_test_eof9: cs = 9; goto _test_eof;
|
1916
|
-
|
1917
|
-
_test_eof: {}
|
1918
|
-
_out: {}
|
1919
|
-
}
|
1920
|
-
|
1921
|
-
#line 780 "parser.rl"
|
1922
|
-
|
1923
|
-
if (cs >= JSON_first_final && p == pe) {
|
1924
|
-
return result;
|
1925
|
-
} else {
|
1926
|
-
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
1927
|
-
return Qnil;
|
1928
|
-
}
|
1929
|
-
}
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
#line 1934 "parser.c"
|
1934
|
-
static const int JSON_quirks_mode_start = 1;
|
1935
|
-
static const int JSON_quirks_mode_first_final = 10;
|
1936
|
-
static const int JSON_quirks_mode_error = 0;
|
1937
|
-
|
1938
|
-
static const int JSON_quirks_mode_en_main = 1;
|
1939
|
-
|
1940
|
-
|
1941
|
-
#line 805 "parser.rl"
|
1942
|
-
|
1943
|
-
|
1944
|
-
static VALUE cParser_parse_quirks_mode(VALUE self)
|
1945
|
-
{
|
1946
|
-
char *p, *pe;
|
1947
|
-
int cs = EVIL;
|
1948
|
-
VALUE result = Qnil;
|
1949
|
-
GET_PARSER;
|
1950
|
-
|
1951
|
-
|
1952
|
-
#line 1953 "parser.c"
|
1953
|
-
{
|
1954
|
-
cs = JSON_quirks_mode_start;
|
1955
|
-
}
|
1956
|
-
|
1957
|
-
#line 815 "parser.rl"
|
1958
|
-
p = json->source;
|
1959
|
-
pe = p + json->len;
|
1960
|
-
|
1961
|
-
#line 1962 "parser.c"
|
1885
|
+
#line 1886 "parser.c"
|
1962
1886
|
{
|
1963
1887
|
if ( p == pe )
|
1964
1888
|
goto _test_eof;
|
@@ -1992,9 +1916,9 @@ st0:
|
|
1992
1916
|
cs = 0;
|
1993
1917
|
goto _out;
|
1994
1918
|
tr2:
|
1995
|
-
#line
|
1919
|
+
#line 752 "parser.rl"
|
1996
1920
|
{
|
1997
|
-
char *np = JSON_parse_value(json, p, pe, &result);
|
1921
|
+
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
1998
1922
|
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
1999
1923
|
}
|
2000
1924
|
goto st10;
|
@@ -2002,7 +1926,7 @@ st10:
|
|
2002
1926
|
if ( ++p == pe )
|
2003
1927
|
goto _test_eof10;
|
2004
1928
|
case 10:
|
2005
|
-
#line
|
1929
|
+
#line 1930 "parser.c"
|
2006
1930
|
switch( (*p) ) {
|
2007
1931
|
case 13: goto st10;
|
2008
1932
|
case 32: goto st10;
|
@@ -2091,30 +2015,13 @@ case 9:
|
|
2091
2015
|
_out: {}
|
2092
2016
|
}
|
2093
2017
|
|
2094
|
-
#line
|
2018
|
+
#line 779 "parser.rl"
|
2095
2019
|
|
2096
|
-
|
2097
|
-
|
2098
|
-
} else {
|
2099
|
-
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
2100
|
-
return Qnil;
|
2101
|
-
}
|
2102
|
-
}
|
2103
|
-
|
2104
|
-
/*
|
2105
|
-
* call-seq: parse()
|
2106
|
-
*
|
2107
|
-
* Parses the current JSON text _source_ and returns the complete data
|
2108
|
-
* structure as a result.
|
2109
|
-
*/
|
2110
|
-
static VALUE cParser_parse(VALUE self)
|
2111
|
-
{
|
2112
|
-
GET_PARSER;
|
2113
|
-
|
2114
|
-
if (json->quirks_mode) {
|
2115
|
-
return cParser_parse_quirks_mode(self);
|
2020
|
+
if (cs >= JSON_first_final && p == pe) {
|
2021
|
+
return result;
|
2116
2022
|
} else {
|
2117
|
-
|
2023
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
2024
|
+
return Qnil;
|
2118
2025
|
}
|
2119
2026
|
}
|
2120
2027
|
|
@@ -2125,6 +2032,7 @@ static void JSON_mark(void *ptr)
|
|
2125
2032
|
rb_gc_mark_maybe(json->create_id);
|
2126
2033
|
rb_gc_mark_maybe(json->object_class);
|
2127
2034
|
rb_gc_mark_maybe(json->array_class);
|
2035
|
+
rb_gc_mark_maybe(json->decimal_class);
|
2128
2036
|
rb_gc_mark_maybe(json->match_string);
|
2129
2037
|
}
|
2130
2038
|
|
@@ -2172,35 +2080,30 @@ static VALUE cParser_source(VALUE self)
|
|
2172
2080
|
return rb_str_dup(json->Vsource);
|
2173
2081
|
}
|
2174
2082
|
|
2175
|
-
/*
|
2176
|
-
* call-seq: quirks_mode?()
|
2177
|
-
*
|
2178
|
-
* Returns a true, if this parser is in quirks_mode, false otherwise.
|
2179
|
-
*/
|
2180
|
-
static VALUE cParser_quirks_mode_p(VALUE self)
|
2181
|
-
{
|
2182
|
-
GET_PARSER;
|
2183
|
-
return json->quirks_mode ? Qtrue : Qfalse;
|
2184
|
-
}
|
2185
|
-
|
2186
|
-
|
2187
2083
|
void Init_parser(void)
|
2188
2084
|
{
|
2085
|
+
#undef rb_intern
|
2189
2086
|
rb_require("json/common");
|
2190
2087
|
mJSON = rb_define_module("JSON");
|
2191
2088
|
mExt = rb_define_module_under(mJSON, "Ext");
|
2192
2089
|
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
2193
2090
|
eParserError = rb_path2class("JSON::ParserError");
|
2194
2091
|
eNestingError = rb_path2class("JSON::NestingError");
|
2092
|
+
rb_gc_register_mark_object(eParserError);
|
2093
|
+
rb_gc_register_mark_object(eNestingError);
|
2195
2094
|
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
|
2196
2095
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
2197
2096
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
2198
2097
|
rb_define_method(cParser, "source", cParser_source, 0);
|
2199
|
-
rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
|
2200
2098
|
|
2201
2099
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
2100
|
+
rb_gc_register_mark_object(CNaN);
|
2101
|
+
|
2202
2102
|
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
|
2103
|
+
rb_gc_register_mark_object(CInfinity);
|
2104
|
+
|
2203
2105
|
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
|
2106
|
+
rb_gc_register_mark_object(CMinusInfinity);
|
2204
2107
|
|
2205
2108
|
i_json_creatable_p = rb_intern("json_creatable?");
|
2206
2109
|
i_json_create = rb_intern("json_create");
|
@@ -2210,9 +2113,9 @@ void Init_parser(void)
|
|
2210
2113
|
i_max_nesting = rb_intern("max_nesting");
|
2211
2114
|
i_allow_nan = rb_intern("allow_nan");
|
2212
2115
|
i_symbolize_names = rb_intern("symbolize_names");
|
2213
|
-
i_quirks_mode = rb_intern("quirks_mode");
|
2214
2116
|
i_object_class = rb_intern("object_class");
|
2215
2117
|
i_array_class = rb_intern("array_class");
|
2118
|
+
i_decimal_class = rb_intern("decimal_class");
|
2216
2119
|
i_match = rb_intern("match");
|
2217
2120
|
i_match_string = rb_intern("match_string");
|
2218
2121
|
i_key_p = rb_intern("key?");
|
@@ -2220,15 +2123,8 @@ void Init_parser(void)
|
|
2220
2123
|
i_aset = rb_intern("[]=");
|
2221
2124
|
i_aref = rb_intern("[]");
|
2222
2125
|
i_leftshift = rb_intern("<<");
|
2223
|
-
|
2224
|
-
|
2225
|
-
UTF_16BE = rb_enc_find("utf-16be");
|
2226
|
-
UTF_16LE = rb_enc_find("utf-16le");
|
2227
|
-
UTF_32BE = rb_enc_find("utf-32be");
|
2228
|
-
UTF_32LE = rb_enc_find("utf-32le");
|
2229
|
-
#else
|
2230
|
-
i_iconv = rb_intern("iconv");
|
2231
|
-
#endif
|
2126
|
+
i_new = rb_intern("new");
|
2127
|
+
i_BigDecimal = rb_intern("BigDecimal");
|
2232
2128
|
}
|
2233
2129
|
|
2234
2130
|
/*
|