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
@@ -34,13 +34,12 @@ typedef struct JSON_ParserStruct {
|
|
34
34
|
char *memo;
|
35
35
|
VALUE create_id;
|
36
36
|
int max_nesting;
|
37
|
-
int current_nesting;
|
38
37
|
int allow_nan;
|
39
38
|
int parsing_name;
|
40
39
|
int symbolize_names;
|
41
|
-
int quirks_mode;
|
42
40
|
VALUE object_class;
|
43
41
|
VALUE array_class;
|
42
|
+
VALUE decimal_class;
|
44
43
|
int create_additions;
|
45
44
|
VALUE match_string;
|
46
45
|
FBuffer *fbuffer;
|
@@ -58,11 +57,11 @@ typedef struct JSON_ParserStruct {
|
|
58
57
|
|
59
58
|
static UTF32 unescape_unicode(const unsigned char *p);
|
60
59
|
static int convert_UTF32_to_UTF8(char *buf, UTF32 ch);
|
61
|
-
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
62
|
-
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
60
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
61
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
63
62
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
64
63
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
65
|
-
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
64
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
66
65
|
static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd);
|
67
66
|
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
68
67
|
static VALUE convert_encoding(VALUE source);
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#include "parser.h"
|
3
3
|
|
4
4
|
#if defined HAVE_RUBY_ENCODING_H
|
5
|
-
# define EXC_ENCODING
|
5
|
+
# define EXC_ENCODING rb_utf8_encoding(),
|
6
6
|
# ifndef HAVE_RB_ENC_RAISE
|
7
7
|
static void
|
8
8
|
enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
|
@@ -25,7 +25,7 @@ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
|
|
25
25
|
|
26
26
|
/* unicode */
|
27
27
|
|
28
|
-
static const char digit_values[256] = {
|
28
|
+
static const signed char digit_values[256] = {
|
29
29
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
30
30
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
31
31
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
|
@@ -44,7 +44,7 @@ static const char digit_values[256] = {
|
|
44
44
|
|
45
45
|
static UTF32 unescape_unicode(const unsigned char *p)
|
46
46
|
{
|
47
|
-
char b;
|
47
|
+
signed char b;
|
48
48
|
UTF32 result = 0;
|
49
49
|
b = digit_values[p[0]];
|
50
50
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
@@ -87,19 +87,15 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
87
87
|
return len;
|
88
88
|
}
|
89
89
|
|
90
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
91
|
-
static rb_encoding *UTF_8, *UTF_16BE, *UTF_16LE, *UTF_32BE, *UTF_32LE;
|
92
|
-
#else
|
93
|
-
static ID i_iconv;
|
94
|
-
#endif
|
95
|
-
|
96
90
|
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
97
91
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
92
|
+
static VALUE cBigDecimal = Qundef;
|
98
93
|
|
99
94
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
100
|
-
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
101
|
-
i_object_class, i_array_class,
|
102
|
-
i_match_string, i_aset, i_aref,
|
95
|
+
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
96
|
+
i_object_class, i_array_class, i_decimal_class, i_key_p,
|
97
|
+
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
|
98
|
+
i_leftshift, i_new, i_BigDecimal;
|
103
99
|
|
104
100
|
%%{
|
105
101
|
machine JSON_common;
|
@@ -137,7 +133,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
|
137
133
|
|
138
134
|
action parse_value {
|
139
135
|
VALUE v = Qnil;
|
140
|
-
char *np = JSON_parse_value(json, fpc, pe, &v);
|
136
|
+
char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
|
141
137
|
if (np == NULL) {
|
142
138
|
fhold; fbreak;
|
143
139
|
} else {
|
@@ -170,14 +166,14 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
|
170
166
|
) @exit;
|
171
167
|
}%%
|
172
168
|
|
173
|
-
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
169
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
174
170
|
{
|
175
171
|
int cs = EVIL;
|
176
172
|
VALUE last_name = Qnil;
|
177
173
|
VALUE object_class = json->object_class;
|
178
174
|
|
179
|
-
if (json->max_nesting &&
|
180
|
-
rb_raise(eNestingError, "nesting of %d is too deep",
|
175
|
+
if (json->max_nesting && current_nesting > json->max_nesting) {
|
176
|
+
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
181
177
|
}
|
182
178
|
|
183
179
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
@@ -243,7 +239,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
243
239
|
|
244
240
|
action parse_number {
|
245
241
|
char *np;
|
246
|
-
if(pe > fpc +
|
242
|
+
if(pe > fpc + 8 && !strncmp(MinusInfinity, fpc, 9)) {
|
247
243
|
if (json->allow_nan) {
|
248
244
|
*result = CMinusInfinity;
|
249
245
|
fexec p + 10;
|
@@ -261,23 +257,19 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
261
257
|
|
262
258
|
action parse_array {
|
263
259
|
char *np;
|
264
|
-
json
|
265
|
-
np = JSON_parse_array(json, fpc, pe, result);
|
266
|
-
json->current_nesting--;
|
260
|
+
np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1);
|
267
261
|
if (np == NULL) { fhold; fbreak; } else fexec np;
|
268
262
|
}
|
269
263
|
|
270
264
|
action parse_object {
|
271
265
|
char *np;
|
272
|
-
json
|
273
|
-
np = JSON_parse_object(json, fpc, pe, result);
|
274
|
-
json->current_nesting--;
|
266
|
+
np = JSON_parse_object(json, fpc, pe, result, current_nesting + 1);
|
275
267
|
if (np == NULL) { fhold; fbreak; } else fexec np;
|
276
268
|
}
|
277
269
|
|
278
270
|
action exit { fhold; fbreak; }
|
279
271
|
|
280
|
-
main := (
|
272
|
+
main := ignore* (
|
281
273
|
Vnull @parse_null |
|
282
274
|
Vfalse @parse_false |
|
283
275
|
Vtrue @parse_true |
|
@@ -287,10 +279,10 @@ main := (
|
|
287
279
|
begin_string >parse_string |
|
288
280
|
begin_array >parse_array |
|
289
281
|
begin_object >parse_object
|
290
|
-
) %*exit;
|
282
|
+
) ignore* %*exit;
|
291
283
|
}%%
|
292
284
|
|
293
|
-
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
285
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
294
286
|
{
|
295
287
|
int cs = EVIL;
|
296
288
|
|
@@ -348,6 +340,19 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|
348
340
|
) (^[0-9Ee.\-]? @exit );
|
349
341
|
}%%
|
350
342
|
|
343
|
+
static int is_bigdecimal_class(VALUE obj)
|
344
|
+
{
|
345
|
+
if (cBigDecimal == Qundef) {
|
346
|
+
if (rb_const_defined(rb_cObject, i_BigDecimal)) {
|
347
|
+
cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
|
348
|
+
}
|
349
|
+
else {
|
350
|
+
return 0;
|
351
|
+
}
|
352
|
+
}
|
353
|
+
return obj == cBigDecimal;
|
354
|
+
}
|
355
|
+
|
351
356
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
352
357
|
{
|
353
358
|
int cs = EVIL;
|
@@ -361,7 +366,17 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
361
366
|
fbuffer_clear(json->fbuffer);
|
362
367
|
fbuffer_append(json->fbuffer, json->memo, len);
|
363
368
|
fbuffer_append_char(json->fbuffer, '\0');
|
364
|
-
|
369
|
+
if (NIL_P(json->decimal_class)) {
|
370
|
+
*result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
371
|
+
} else {
|
372
|
+
VALUE text;
|
373
|
+
text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
374
|
+
if (is_bigdecimal_class(json->decimal_class)) {
|
375
|
+
*result = rb_funcall(Qnil, i_BigDecimal, 1, text);
|
376
|
+
} else {
|
377
|
+
*result = rb_funcall(json->decimal_class, i_new, 1, text);
|
378
|
+
}
|
379
|
+
}
|
365
380
|
return p + 1;
|
366
381
|
} else {
|
367
382
|
return NULL;
|
@@ -377,7 +392,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
377
392
|
|
378
393
|
action parse_value {
|
379
394
|
VALUE v = Qnil;
|
380
|
-
char *np = JSON_parse_value(json, fpc, pe, &v);
|
395
|
+
char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
|
381
396
|
if (np == NULL) {
|
382
397
|
fhold; fbreak;
|
383
398
|
} else {
|
@@ -400,13 +415,13 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
400
415
|
end_array @exit;
|
401
416
|
}%%
|
402
417
|
|
403
|
-
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
418
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
404
419
|
{
|
405
420
|
int cs = EVIL;
|
406
421
|
VALUE array_class = json->array_class;
|
407
422
|
|
408
|
-
if (json->max_nesting &&
|
409
|
-
rb_raise(eNestingError, "nesting of %d is too deep",
|
423
|
+
if (json->max_nesting && current_nesting > json->max_nesting) {
|
424
|
+
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
410
425
|
}
|
411
426
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
412
427
|
|
@@ -456,13 +471,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
456
471
|
break;
|
457
472
|
case 'u':
|
458
473
|
if (pe > stringEnd - 4) {
|
459
|
-
|
474
|
+
rb_enc_raise(
|
475
|
+
EXC_ENCODING eParserError,
|
476
|
+
"%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
|
477
|
+
);
|
460
478
|
} else {
|
461
479
|
UTF32 ch = unescape_unicode((unsigned char *) ++pe);
|
462
480
|
pe += 3;
|
463
481
|
if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
|
464
482
|
pe++;
|
465
|
-
if (pe > stringEnd - 6)
|
483
|
+
if (pe > stringEnd - 6) {
|
484
|
+
rb_enc_raise(
|
485
|
+
EXC_ENCODING eParserError,
|
486
|
+
"%u: incomplete surrogate pair at '%s'", __LINE__, p
|
487
|
+
);
|
488
|
+
}
|
466
489
|
if (pe[0] == '\\' && pe[1] == 'u') {
|
467
490
|
UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
|
468
491
|
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
|
@@ -548,6 +571,8 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
548
571
|
|
549
572
|
if (json->symbolize_names && json->parsing_name) {
|
550
573
|
*result = rb_str_intern(*result);
|
574
|
+
} else if (RB_TYPE_P(*result, T_STRING)) {
|
575
|
+
rb_str_resize(*result, RSTRING_LEN(*result));
|
551
576
|
}
|
552
577
|
if (cs >= JSON_string_first_final) {
|
553
578
|
return p + 1;
|
@@ -570,41 +595,16 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
570
595
|
|
571
596
|
static VALUE convert_encoding(VALUE source)
|
572
597
|
{
|
573
|
-
const char *ptr = RSTRING_PTR(source);
|
574
|
-
long len = RSTRING_LEN(source);
|
575
|
-
if (len < 2) {
|
576
|
-
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
577
|
-
}
|
578
598
|
#ifdef HAVE_RUBY_ENCODING_H
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
source = rb_str_conv_enc(source, UTF_32BE, rb_utf8_encoding());
|
584
|
-
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
585
|
-
source = rb_str_conv_enc(source, UTF_16BE, rb_utf8_encoding());
|
586
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
587
|
-
source = rb_str_conv_enc(source, UTF_32LE, rb_utf8_encoding());
|
588
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
589
|
-
source = rb_str_conv_enc(source, UTF_16LE, rb_utf8_encoding());
|
590
|
-
} else {
|
591
|
-
source = rb_str_dup(source);
|
592
|
-
FORCE_UTF8(source);
|
593
|
-
}
|
594
|
-
} else {
|
595
|
-
source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
|
596
|
-
}
|
597
|
-
}
|
598
|
-
#else
|
599
|
-
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
600
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
|
601
|
-
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
602
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
|
603
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
604
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
|
605
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
606
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
|
599
|
+
rb_encoding *enc = rb_enc_get(source);
|
600
|
+
if (enc == rb_ascii8bit_encoding()) {
|
601
|
+
if (OBJ_FROZEN(source)) {
|
602
|
+
source = rb_str_dup(source);
|
607
603
|
}
|
604
|
+
FORCE_UTF8(source);
|
605
|
+
} else {
|
606
|
+
source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
|
607
|
+
}
|
608
608
|
#endif
|
609
609
|
return source;
|
610
610
|
}
|
@@ -627,8 +627,9 @@ static VALUE convert_encoding(VALUE source)
|
|
627
627
|
* defiance of RFC 4627 to be parsed by the Parser. This option defaults to
|
628
628
|
* false.
|
629
629
|
* * *symbolize_names*: If set to true, returns symbols for the names
|
630
|
-
* (keys) in a JSON object. Otherwise strings are returned, which is
|
631
|
-
* the default.
|
630
|
+
* (keys) in a JSON object. Otherwise strings are returned, which is
|
631
|
+
* also the default. It's not possible to use this option in
|
632
|
+
* conjunction with the *create_additions* option.
|
632
633
|
* * *create_additions*: If set to false, the Parser doesn't create
|
633
634
|
* additions even if a matching class and create_id was found. This option
|
634
635
|
* defaults to false.
|
@@ -679,19 +680,17 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
679
680
|
} else {
|
680
681
|
json->symbolize_names = 0;
|
681
682
|
}
|
682
|
-
tmp = ID2SYM(i_quirks_mode);
|
683
|
-
if (option_given_p(opts, tmp)) {
|
684
|
-
VALUE quirks_mode = rb_hash_aref(opts, tmp);
|
685
|
-
json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
|
686
|
-
} else {
|
687
|
-
json->quirks_mode = 0;
|
688
|
-
}
|
689
683
|
tmp = ID2SYM(i_create_additions);
|
690
684
|
if (option_given_p(opts, tmp)) {
|
691
685
|
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
692
686
|
} else {
|
693
687
|
json->create_additions = 0;
|
694
688
|
}
|
689
|
+
if (json->symbolize_names && json->create_additions) {
|
690
|
+
rb_raise(rb_eArgError,
|
691
|
+
"options :symbolize_names and :create_additions cannot be "
|
692
|
+
" used in conjunction");
|
693
|
+
}
|
695
694
|
tmp = ID2SYM(i_create_id);
|
696
695
|
if (option_given_p(opts, tmp)) {
|
697
696
|
json->create_id = rb_hash_aref(opts, tmp);
|
@@ -710,6 +709,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
710
709
|
} else {
|
711
710
|
json->array_class = Qnil;
|
712
711
|
}
|
712
|
+
tmp = ID2SYM(i_decimal_class);
|
713
|
+
if (option_given_p(opts, tmp)) {
|
714
|
+
json->decimal_class = rb_hash_aref(opts, tmp);
|
715
|
+
} else {
|
716
|
+
json->decimal_class = Qnil;
|
717
|
+
}
|
713
718
|
tmp = ID2SYM(i_match_string);
|
714
719
|
if (option_given_p(opts, tmp)) {
|
715
720
|
VALUE match_string = rb_hash_aref(opts, tmp);
|
@@ -723,16 +728,14 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
723
728
|
} else {
|
724
729
|
json->max_nesting = 100;
|
725
730
|
json->allow_nan = 0;
|
726
|
-
json->create_additions =
|
731
|
+
json->create_additions = 0;
|
727
732
|
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
728
733
|
json->object_class = Qnil;
|
729
734
|
json->array_class = Qnil;
|
735
|
+
json->decimal_class = Qnil;
|
730
736
|
}
|
737
|
+
source = convert_encoding(StringValue(source));
|
731
738
|
StringValue(source);
|
732
|
-
if (!json->quirks_mode) {
|
733
|
-
source = convert_encoding(source);
|
734
|
-
}
|
735
|
-
json->current_nesting = 0;
|
736
739
|
json->len = RSTRING_LEN(source);
|
737
740
|
json->source = RSTRING_PTR(source);;
|
738
741
|
json->Vsource = source;
|
@@ -746,56 +749,8 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
746
749
|
|
747
750
|
include JSON_common;
|
748
751
|
|
749
|
-
action parse_object {
|
750
|
-
char *np;
|
751
|
-
json->current_nesting = 1;
|
752
|
-
np = JSON_parse_object(json, fpc, pe, &result);
|
753
|
-
if (np == NULL) { fhold; fbreak; } else fexec np;
|
754
|
-
}
|
755
|
-
|
756
|
-
action parse_array {
|
757
|
-
char *np;
|
758
|
-
json->current_nesting = 1;
|
759
|
-
np = JSON_parse_array(json, fpc, pe, &result);
|
760
|
-
if (np == NULL) { fhold; fbreak; } else fexec np;
|
761
|
-
}
|
762
|
-
|
763
|
-
main := ignore* (
|
764
|
-
begin_object >parse_object |
|
765
|
-
begin_array >parse_array
|
766
|
-
) ignore*;
|
767
|
-
}%%
|
768
|
-
|
769
|
-
static VALUE cParser_parse_strict(VALUE self)
|
770
|
-
{
|
771
|
-
char *p, *pe;
|
772
|
-
int cs = EVIL;
|
773
|
-
VALUE result = Qnil;
|
774
|
-
GET_PARSER;
|
775
|
-
|
776
|
-
%% write init;
|
777
|
-
p = json->source;
|
778
|
-
pe = p + json->len;
|
779
|
-
%% write exec;
|
780
|
-
|
781
|
-
if (cs >= JSON_first_final && p == pe) {
|
782
|
-
return result;
|
783
|
-
} else {
|
784
|
-
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
785
|
-
return Qnil;
|
786
|
-
}
|
787
|
-
}
|
788
|
-
|
789
|
-
|
790
|
-
%%{
|
791
|
-
machine JSON_quirks_mode;
|
792
|
-
|
793
|
-
write data;
|
794
|
-
|
795
|
-
include JSON_common;
|
796
|
-
|
797
752
|
action parse_value {
|
798
|
-
char *np = JSON_parse_value(json, fpc, pe, &result);
|
753
|
+
char *np = JSON_parse_value(json, fpc, pe, &result, 0);
|
799
754
|
if (np == NULL) { fhold; fbreak; } else fexec np;
|
800
755
|
}
|
801
756
|
|
@@ -804,26 +759,6 @@ static VALUE cParser_parse_strict(VALUE self)
|
|
804
759
|
) ignore*;
|
805
760
|
}%%
|
806
761
|
|
807
|
-
static VALUE cParser_parse_quirks_mode(VALUE self)
|
808
|
-
{
|
809
|
-
char *p, *pe;
|
810
|
-
int cs = EVIL;
|
811
|
-
VALUE result = Qnil;
|
812
|
-
GET_PARSER;
|
813
|
-
|
814
|
-
%% write init;
|
815
|
-
p = json->source;
|
816
|
-
pe = p + json->len;
|
817
|
-
%% write exec;
|
818
|
-
|
819
|
-
if (cs >= JSON_quirks_mode_first_final && p == pe) {
|
820
|
-
return result;
|
821
|
-
} else {
|
822
|
-
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
823
|
-
return Qnil;
|
824
|
-
}
|
825
|
-
}
|
826
|
-
|
827
762
|
/*
|
828
763
|
* call-seq: parse()
|
829
764
|
*
|
@@ -832,12 +767,21 @@ static VALUE cParser_parse_quirks_mode(VALUE self)
|
|
832
767
|
*/
|
833
768
|
static VALUE cParser_parse(VALUE self)
|
834
769
|
{
|
770
|
+
char *p, *pe;
|
771
|
+
int cs = EVIL;
|
772
|
+
VALUE result = Qnil;
|
835
773
|
GET_PARSER;
|
836
774
|
|
837
|
-
|
838
|
-
|
775
|
+
%% write init;
|
776
|
+
p = json->source;
|
777
|
+
pe = p + json->len;
|
778
|
+
%% write exec;
|
779
|
+
|
780
|
+
if (cs >= JSON_first_final && p == pe) {
|
781
|
+
return result;
|
839
782
|
} else {
|
840
|
-
|
783
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
784
|
+
return Qnil;
|
841
785
|
}
|
842
786
|
}
|
843
787
|
|
@@ -848,6 +792,7 @@ static void JSON_mark(void *ptr)
|
|
848
792
|
rb_gc_mark_maybe(json->create_id);
|
849
793
|
rb_gc_mark_maybe(json->object_class);
|
850
794
|
rb_gc_mark_maybe(json->array_class);
|
795
|
+
rb_gc_mark_maybe(json->decimal_class);
|
851
796
|
rb_gc_mark_maybe(json->match_string);
|
852
797
|
}
|
853
798
|
|
@@ -895,35 +840,30 @@ static VALUE cParser_source(VALUE self)
|
|
895
840
|
return rb_str_dup(json->Vsource);
|
896
841
|
}
|
897
842
|
|
898
|
-
/*
|
899
|
-
* call-seq: quirks_mode?()
|
900
|
-
*
|
901
|
-
* Returns a true, if this parser is in quirks_mode, false otherwise.
|
902
|
-
*/
|
903
|
-
static VALUE cParser_quirks_mode_p(VALUE self)
|
904
|
-
{
|
905
|
-
GET_PARSER;
|
906
|
-
return json->quirks_mode ? Qtrue : Qfalse;
|
907
|
-
}
|
908
|
-
|
909
|
-
|
910
843
|
void Init_parser(void)
|
911
844
|
{
|
845
|
+
#undef rb_intern
|
912
846
|
rb_require("json/common");
|
913
847
|
mJSON = rb_define_module("JSON");
|
914
848
|
mExt = rb_define_module_under(mJSON, "Ext");
|
915
849
|
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
916
850
|
eParserError = rb_path2class("JSON::ParserError");
|
917
851
|
eNestingError = rb_path2class("JSON::NestingError");
|
852
|
+
rb_gc_register_mark_object(eParserError);
|
853
|
+
rb_gc_register_mark_object(eNestingError);
|
918
854
|
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
|
919
855
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
920
856
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
921
857
|
rb_define_method(cParser, "source", cParser_source, 0);
|
922
|
-
rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
|
923
858
|
|
924
859
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
860
|
+
rb_gc_register_mark_object(CNaN);
|
861
|
+
|
925
862
|
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
|
863
|
+
rb_gc_register_mark_object(CInfinity);
|
864
|
+
|
926
865
|
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
|
866
|
+
rb_gc_register_mark_object(CMinusInfinity);
|
927
867
|
|
928
868
|
i_json_creatable_p = rb_intern("json_creatable?");
|
929
869
|
i_json_create = rb_intern("json_create");
|
@@ -933,9 +873,9 @@ void Init_parser(void)
|
|
933
873
|
i_max_nesting = rb_intern("max_nesting");
|
934
874
|
i_allow_nan = rb_intern("allow_nan");
|
935
875
|
i_symbolize_names = rb_intern("symbolize_names");
|
936
|
-
i_quirks_mode = rb_intern("quirks_mode");
|
937
876
|
i_object_class = rb_intern("object_class");
|
938
877
|
i_array_class = rb_intern("array_class");
|
878
|
+
i_decimal_class = rb_intern("decimal_class");
|
939
879
|
i_match = rb_intern("match");
|
940
880
|
i_match_string = rb_intern("match_string");
|
941
881
|
i_key_p = rb_intern("key?");
|
@@ -943,15 +883,8 @@ void Init_parser(void)
|
|
943
883
|
i_aset = rb_intern("[]=");
|
944
884
|
i_aref = rb_intern("[]");
|
945
885
|
i_leftshift = rb_intern("<<");
|
946
|
-
|
947
|
-
|
948
|
-
UTF_16BE = rb_enc_find("utf-16be");
|
949
|
-
UTF_16LE = rb_enc_find("utf-16le");
|
950
|
-
UTF_32BE = rb_enc_find("utf-32be");
|
951
|
-
UTF_32LE = rb_enc_find("utf-32le");
|
952
|
-
#else
|
953
|
-
i_iconv = rb_intern("iconv");
|
954
|
-
#endif
|
886
|
+
i_new = rb_intern("new");
|
887
|
+
i_BigDecimal = rb_intern("BigDecimal");
|
955
888
|
}
|
956
889
|
|
957
890
|
/*
|