json 1.8.0 → 2.6.2
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/{CHANGES → CHANGES.md} +262 -87
- data/{COPYING-json-jruby → LICENSE} +5 -6
- data/README.md +425 -0
- data/VERSION +1 -1
- data/ext/json/ext/fbuffer/fbuffer.h +10 -4
- data/ext/json/ext/generator/extconf.rb +0 -10
- data/ext/json/ext/generator/generator.c +308 -135
- data/ext/json/ext/generator/generator.h +35 -9
- data/ext/json/ext/parser/extconf.rb +25 -6
- data/ext/json/ext/parser/parser.c +3044 -1901
- data/ext/json/ext/parser/parser.h +29 -10
- data/ext/json/ext/parser/parser.rl +270 -211
- data/ext/json/extconf.rb +3 -0
- data/json.gemspec +57 -27
- data/lib/json/add/bigdecimal.rb +3 -2
- data/lib/json/add/complex.rb +9 -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 +8 -3
- 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 +2 -2
- data/lib/json/common.rb +383 -167
- data/lib/json/ext.rb +0 -6
- data/lib/json/generic_object.rb +5 -4
- data/lib/json/pure/generator.rb +83 -126
- data/lib/json/pure/parser.rb +63 -85
- data/lib/json/pure.rb +2 -8
- data/lib/json/version.rb +2 -1
- data/lib/json.rb +550 -29
- metadata +29 -136
- data/.gitignore +0 -12
- data/.travis.yml +0 -20
- data/COPYING +0 -58
- data/GPL +0 -340
- data/Gemfile +0 -11
- data/README-json-jruby.markdown +0 -33
- data/README.rdoc +0 -358
- data/Rakefile +0 -412
- data/TODO +0 -1
- data/data/example.json +0 -1
- data/data/index.html +0 -38
- data/data/prototype.js +0 -4184
- data/diagrams/.keep +0 -0
- data/install.rb +0 -23
- data/java/src/json/ext/ByteListTranscoder.java +0 -167
- data/java/src/json/ext/Generator.java +0 -444
- data/java/src/json/ext/GeneratorMethods.java +0 -232
- data/java/src/json/ext/GeneratorService.java +0 -43
- data/java/src/json/ext/GeneratorState.java +0 -543
- data/java/src/json/ext/OptionsReader.java +0 -114
- data/java/src/json/ext/Parser.java +0 -2644
- data/java/src/json/ext/Parser.rl +0 -968
- data/java/src/json/ext/ParserService.java +0 -35
- data/java/src/json/ext/RuntimeInfo.java +0 -121
- data/java/src/json/ext/StringDecoder.java +0 -167
- data/java/src/json/ext/StringEncoder.java +0 -106
- data/java/src/json/ext/Utils.java +0 -89
- data/json-java.gemspec +0 -23
- data/json_pure.gemspec +0 -39
- data/lib/json/ext/.keep +0 -0
- data/tests/fixtures/fail1.json +0 -1
- data/tests/fixtures/fail10.json +0 -1
- data/tests/fixtures/fail11.json +0 -1
- data/tests/fixtures/fail12.json +0 -1
- data/tests/fixtures/fail13.json +0 -1
- data/tests/fixtures/fail14.json +0 -1
- data/tests/fixtures/fail18.json +0 -1
- data/tests/fixtures/fail19.json +0 -1
- data/tests/fixtures/fail2.json +0 -1
- data/tests/fixtures/fail20.json +0 -1
- data/tests/fixtures/fail21.json +0 -1
- data/tests/fixtures/fail22.json +0 -1
- data/tests/fixtures/fail23.json +0 -1
- data/tests/fixtures/fail24.json +0 -1
- data/tests/fixtures/fail25.json +0 -1
- data/tests/fixtures/fail27.json +0 -2
- data/tests/fixtures/fail28.json +0 -2
- data/tests/fixtures/fail3.json +0 -1
- data/tests/fixtures/fail4.json +0 -1
- data/tests/fixtures/fail5.json +0 -1
- data/tests/fixtures/fail6.json +0 -1
- data/tests/fixtures/fail7.json +0 -1
- data/tests/fixtures/fail8.json +0 -1
- data/tests/fixtures/fail9.json +0 -1
- data/tests/fixtures/pass1.json +0 -56
- data/tests/fixtures/pass15.json +0 -1
- data/tests/fixtures/pass16.json +0 -1
- data/tests/fixtures/pass17.json +0 -1
- data/tests/fixtures/pass2.json +0 -1
- data/tests/fixtures/pass26.json +0 -1
- data/tests/fixtures/pass3.json +0 -6
- data/tests/setup_variant.rb +0 -11
- data/tests/test_json.rb +0 -545
- data/tests/test_json_addition.rb +0 -196
- data/tests/test_json_encoding.rb +0 -65
- data/tests/test_json_fixtures.rb +0 -35
- data/tests/test_json_generate.rb +0 -322
- data/tests/test_json_generic_object.rb +0 -75
- data/tests/test_json_string_matching.rb +0 -39
- data/tests/test_json_unicode.rb +0 -72
- data/tools/fuzz.rb +0 -139
- data/tools/server.rb +0 -62
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
#include "../fbuffer/fbuffer.h"
|
|
2
2
|
#include "parser.h"
|
|
3
3
|
|
|
4
|
+
#if defined HAVE_RUBY_ENCODING_H
|
|
5
|
+
# define EXC_ENCODING rb_utf8_encoding(),
|
|
6
|
+
# ifndef HAVE_RB_ENC_RAISE
|
|
7
|
+
static void
|
|
8
|
+
enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
|
|
9
|
+
{
|
|
10
|
+
va_list args;
|
|
11
|
+
VALUE mesg;
|
|
12
|
+
|
|
13
|
+
va_start(args, fmt);
|
|
14
|
+
mesg = rb_enc_vsprintf(enc, fmt, args);
|
|
15
|
+
va_end(args);
|
|
16
|
+
|
|
17
|
+
rb_exc_raise(rb_exc_new3(exc, mesg));
|
|
18
|
+
}
|
|
19
|
+
# define rb_enc_raise enc_raise
|
|
20
|
+
# endif
|
|
21
|
+
#else
|
|
22
|
+
# define EXC_ENCODING /* nothing */
|
|
23
|
+
# define rb_enc_raise rb_raise
|
|
24
|
+
#endif
|
|
25
|
+
|
|
4
26
|
/* unicode */
|
|
5
27
|
|
|
6
|
-
static const char digit_values[256] = {
|
|
28
|
+
static const signed char digit_values[256] = {
|
|
7
29
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
8
30
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
9
31
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
|
|
@@ -22,20 +44,20 @@ static const char digit_values[256] = {
|
|
|
22
44
|
|
|
23
45
|
static UTF32 unescape_unicode(const unsigned char *p)
|
|
24
46
|
{
|
|
25
|
-
char b;
|
|
47
|
+
signed char b;
|
|
26
48
|
UTF32 result = 0;
|
|
27
49
|
b = digit_values[p[0]];
|
|
28
50
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
|
29
|
-
result = (result << 4) | b;
|
|
51
|
+
result = (result << 4) | (unsigned char)b;
|
|
30
52
|
b = digit_values[p[1]];
|
|
31
|
-
result = (result << 4) | b;
|
|
32
53
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
|
54
|
+
result = (result << 4) | (unsigned char)b;
|
|
33
55
|
b = digit_values[p[2]];
|
|
34
|
-
result = (result << 4) | b;
|
|
35
56
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
|
57
|
+
result = (result << 4) | (unsigned char)b;
|
|
36
58
|
b = digit_values[p[3]];
|
|
37
|
-
result = (result << 4) | b;
|
|
38
59
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
|
60
|
+
result = (result << 4) | (unsigned char)b;
|
|
39
61
|
return result;
|
|
40
62
|
}
|
|
41
63
|
|
|
@@ -65,21 +87,14 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
|
65
87
|
return len;
|
|
66
88
|
}
|
|
67
89
|
|
|
68
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
|
69
|
-
static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
|
|
70
|
-
CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
|
|
71
|
-
static ID i_encoding, i_encode;
|
|
72
|
-
#else
|
|
73
|
-
static ID i_iconv;
|
|
74
|
-
#endif
|
|
75
|
-
|
|
76
90
|
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
|
77
91
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
|
78
92
|
|
|
79
93
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
|
80
|
-
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
|
81
|
-
i_object_class, i_array_class,
|
|
82
|
-
i_match_string, i_aset, i_aref,
|
|
94
|
+
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
|
95
|
+
i_object_class, i_array_class, i_decimal_class, i_key_p,
|
|
96
|
+
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
|
|
97
|
+
i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
|
|
83
98
|
|
|
84
99
|
%%{
|
|
85
100
|
machine JSON_common;
|
|
@@ -117,11 +132,12 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
|
|
117
132
|
|
|
118
133
|
action parse_value {
|
|
119
134
|
VALUE v = Qnil;
|
|
120
|
-
char *np = JSON_parse_value(json, fpc, pe, &v);
|
|
135
|
+
char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
|
|
121
136
|
if (np == NULL) {
|
|
122
137
|
fhold; fbreak;
|
|
123
138
|
} else {
|
|
124
139
|
if (NIL_P(json->object_class)) {
|
|
140
|
+
OBJ_FREEZE(last_name);
|
|
125
141
|
rb_hash_aset(*result, last_name, v);
|
|
126
142
|
} else {
|
|
127
143
|
rb_funcall(*result, i_aset, 2, last_name, v);
|
|
@@ -150,14 +166,14 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
|
|
150
166
|
) @exit;
|
|
151
167
|
}%%
|
|
152
168
|
|
|
153
|
-
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)
|
|
154
170
|
{
|
|
155
171
|
int cs = EVIL;
|
|
156
172
|
VALUE last_name = Qnil;
|
|
157
173
|
VALUE object_class = json->object_class;
|
|
158
174
|
|
|
159
|
-
if (json->max_nesting &&
|
|
160
|
-
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);
|
|
161
177
|
}
|
|
162
178
|
|
|
163
179
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
|
@@ -206,14 +222,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
|
206
222
|
if (json->allow_nan) {
|
|
207
223
|
*result = CNaN;
|
|
208
224
|
} else {
|
|
209
|
-
|
|
225
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
|
|
210
226
|
}
|
|
211
227
|
}
|
|
212
228
|
action parse_infinity {
|
|
213
229
|
if (json->allow_nan) {
|
|
214
230
|
*result = CInfinity;
|
|
215
231
|
} else {
|
|
216
|
-
|
|
232
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
|
|
217
233
|
}
|
|
218
234
|
}
|
|
219
235
|
action parse_string {
|
|
@@ -223,13 +239,13 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
|
223
239
|
|
|
224
240
|
action parse_number {
|
|
225
241
|
char *np;
|
|
226
|
-
if(pe > fpc +
|
|
242
|
+
if(pe > fpc + 8 && !strncmp(MinusInfinity, fpc, 9)) {
|
|
227
243
|
if (json->allow_nan) {
|
|
228
244
|
*result = CMinusInfinity;
|
|
229
245
|
fexec p + 10;
|
|
230
246
|
fhold; fbreak;
|
|
231
247
|
} else {
|
|
232
|
-
|
|
248
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
|
233
249
|
}
|
|
234
250
|
}
|
|
235
251
|
np = JSON_parse_float(json, fpc, pe, result);
|
|
@@ -241,23 +257,19 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
|
241
257
|
|
|
242
258
|
action parse_array {
|
|
243
259
|
char *np;
|
|
244
|
-
json
|
|
245
|
-
np = JSON_parse_array(json, fpc, pe, result);
|
|
246
|
-
json->current_nesting--;
|
|
260
|
+
np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1);
|
|
247
261
|
if (np == NULL) { fhold; fbreak; } else fexec np;
|
|
248
262
|
}
|
|
249
263
|
|
|
250
264
|
action parse_object {
|
|
251
265
|
char *np;
|
|
252
|
-
json
|
|
253
|
-
np = JSON_parse_object(json, fpc, pe, result);
|
|
254
|
-
json->current_nesting--;
|
|
266
|
+
np = JSON_parse_object(json, fpc, pe, result, current_nesting + 1);
|
|
255
267
|
if (np == NULL) { fhold; fbreak; } else fexec np;
|
|
256
268
|
}
|
|
257
269
|
|
|
258
270
|
action exit { fhold; fbreak; }
|
|
259
271
|
|
|
260
|
-
main := (
|
|
272
|
+
main := ignore* (
|
|
261
273
|
Vnull @parse_null |
|
|
262
274
|
Vfalse @parse_false |
|
|
263
275
|
Vtrue @parse_true |
|
|
@@ -267,16 +279,20 @@ main := (
|
|
|
267
279
|
begin_string >parse_string |
|
|
268
280
|
begin_array >parse_array |
|
|
269
281
|
begin_object >parse_object
|
|
270
|
-
) %*exit;
|
|
282
|
+
) ignore* %*exit;
|
|
271
283
|
}%%
|
|
272
284
|
|
|
273
|
-
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)
|
|
274
286
|
{
|
|
275
287
|
int cs = EVIL;
|
|
276
288
|
|
|
277
289
|
%% write init;
|
|
278
290
|
%% write exec;
|
|
279
291
|
|
|
292
|
+
if (json->freeze) {
|
|
293
|
+
OBJ_FREEZE(*result);
|
|
294
|
+
}
|
|
295
|
+
|
|
280
296
|
if (cs >= JSON_value_first_final) {
|
|
281
297
|
return p;
|
|
282
298
|
} else {
|
|
@@ -337,11 +353,46 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
|
337
353
|
%% write exec;
|
|
338
354
|
|
|
339
355
|
if (cs >= JSON_float_first_final) {
|
|
356
|
+
VALUE mod = Qnil;
|
|
357
|
+
ID method_id = 0;
|
|
358
|
+
if (rb_respond_to(json->decimal_class, i_try_convert)) {
|
|
359
|
+
mod = json->decimal_class;
|
|
360
|
+
method_id = i_try_convert;
|
|
361
|
+
} else if (rb_respond_to(json->decimal_class, i_new)) {
|
|
362
|
+
mod = json->decimal_class;
|
|
363
|
+
method_id = i_new;
|
|
364
|
+
} else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
|
|
365
|
+
VALUE name = rb_class_name(json->decimal_class);
|
|
366
|
+
const char *name_cstr = RSTRING_PTR(name);
|
|
367
|
+
const char *last_colon = strrchr(name_cstr, ':');
|
|
368
|
+
if (last_colon) {
|
|
369
|
+
const char *mod_path_end = last_colon - 1;
|
|
370
|
+
VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
|
|
371
|
+
mod = rb_path_to_class(mod_path);
|
|
372
|
+
|
|
373
|
+
const char *method_name_beg = last_colon + 1;
|
|
374
|
+
long before_len = method_name_beg - name_cstr;
|
|
375
|
+
long len = RSTRING_LEN(name) - before_len;
|
|
376
|
+
VALUE method_name = rb_str_substr(name, before_len, len);
|
|
377
|
+
method_id = SYM2ID(rb_str_intern(method_name));
|
|
378
|
+
} else {
|
|
379
|
+
mod = rb_mKernel;
|
|
380
|
+
method_id = SYM2ID(rb_str_intern(name));
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
340
384
|
long len = p - json->memo;
|
|
341
385
|
fbuffer_clear(json->fbuffer);
|
|
342
386
|
fbuffer_append(json->fbuffer, json->memo, len);
|
|
343
387
|
fbuffer_append_char(json->fbuffer, '\0');
|
|
344
|
-
|
|
388
|
+
|
|
389
|
+
if (method_id) {
|
|
390
|
+
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
|
391
|
+
*result = rb_funcallv(mod, method_id, 1, &text);
|
|
392
|
+
} else {
|
|
393
|
+
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
|
394
|
+
}
|
|
395
|
+
|
|
345
396
|
return p + 1;
|
|
346
397
|
} else {
|
|
347
398
|
return NULL;
|
|
@@ -357,7 +408,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
|
357
408
|
|
|
358
409
|
action parse_value {
|
|
359
410
|
VALUE v = Qnil;
|
|
360
|
-
char *np = JSON_parse_value(json, fpc, pe, &v);
|
|
411
|
+
char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
|
|
361
412
|
if (np == NULL) {
|
|
362
413
|
fhold; fbreak;
|
|
363
414
|
} else {
|
|
@@ -380,13 +431,13 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
|
380
431
|
end_array @exit;
|
|
381
432
|
}%%
|
|
382
433
|
|
|
383
|
-
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
|
434
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
|
384
435
|
{
|
|
385
436
|
int cs = EVIL;
|
|
386
437
|
VALUE array_class = json->array_class;
|
|
387
438
|
|
|
388
|
-
if (json->max_nesting &&
|
|
389
|
-
rb_raise(eNestingError, "nesting of %d is too deep",
|
|
439
|
+
if (json->max_nesting && current_nesting > json->max_nesting) {
|
|
440
|
+
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
|
390
441
|
}
|
|
391
442
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
|
392
443
|
|
|
@@ -396,22 +447,42 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
|
396
447
|
if(cs >= JSON_array_first_final) {
|
|
397
448
|
return p + 1;
|
|
398
449
|
} else {
|
|
399
|
-
|
|
450
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
|
400
451
|
return NULL;
|
|
401
452
|
}
|
|
402
453
|
}
|
|
403
454
|
|
|
404
|
-
static
|
|
455
|
+
static const size_t MAX_STACK_BUFFER_SIZE = 128;
|
|
456
|
+
static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
|
|
405
457
|
{
|
|
406
|
-
|
|
458
|
+
VALUE result = Qnil;
|
|
459
|
+
size_t bufferSize = stringEnd - string;
|
|
460
|
+
char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
|
|
407
461
|
int unescape_len;
|
|
408
462
|
char buf[4];
|
|
409
463
|
|
|
464
|
+
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
|
465
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
|
466
|
+
bufferStart = buffer = ALLOC_N(char, bufferSize ? bufferSize : 1);
|
|
467
|
+
# else
|
|
468
|
+
bufferStart = buffer = ALLOC_N(char, bufferSize);
|
|
469
|
+
# endif
|
|
470
|
+
} else {
|
|
471
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
|
472
|
+
bufferStart = buffer = ALLOCA_N(char, bufferSize ? bufferSize : 1);
|
|
473
|
+
# else
|
|
474
|
+
bufferStart = buffer = ALLOCA_N(char, bufferSize);
|
|
475
|
+
# endif
|
|
476
|
+
}
|
|
477
|
+
|
|
410
478
|
while (pe < stringEnd) {
|
|
411
479
|
if (*pe == '\\') {
|
|
412
480
|
unescape = (char *) "?";
|
|
413
481
|
unescape_len = 1;
|
|
414
|
-
if (pe > p)
|
|
482
|
+
if (pe > p) {
|
|
483
|
+
MEMCPY(buffer, p, char, pe - p);
|
|
484
|
+
buffer += pe - p;
|
|
485
|
+
}
|
|
415
486
|
switch (*++pe) {
|
|
416
487
|
case 'n':
|
|
417
488
|
unescape = (char *) "\n";
|
|
@@ -436,13 +507,27 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
|
436
507
|
break;
|
|
437
508
|
case 'u':
|
|
438
509
|
if (pe > stringEnd - 4) {
|
|
439
|
-
|
|
510
|
+
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
|
511
|
+
free(bufferStart);
|
|
512
|
+
}
|
|
513
|
+
rb_enc_raise(
|
|
514
|
+
EXC_ENCODING eParserError,
|
|
515
|
+
"%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
|
|
516
|
+
);
|
|
440
517
|
} else {
|
|
441
518
|
UTF32 ch = unescape_unicode((unsigned char *) ++pe);
|
|
442
519
|
pe += 3;
|
|
443
520
|
if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
|
|
444
521
|
pe++;
|
|
445
|
-
if (pe > stringEnd - 6)
|
|
522
|
+
if (pe > stringEnd - 6) {
|
|
523
|
+
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
|
524
|
+
free(bufferStart);
|
|
525
|
+
}
|
|
526
|
+
rb_enc_raise(
|
|
527
|
+
EXC_ENCODING eParserError,
|
|
528
|
+
"%u: incomplete surrogate pair at '%s'", __LINE__, p
|
|
529
|
+
);
|
|
530
|
+
}
|
|
446
531
|
if (pe[0] == '\\' && pe[1] == 'u') {
|
|
447
532
|
UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
|
|
448
533
|
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
|
|
@@ -461,13 +546,55 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
|
461
546
|
p = pe;
|
|
462
547
|
continue;
|
|
463
548
|
}
|
|
464
|
-
|
|
549
|
+
MEMCPY(buffer, unescape, char, unescape_len);
|
|
550
|
+
buffer += unescape_len;
|
|
465
551
|
p = ++pe;
|
|
466
552
|
} else {
|
|
467
553
|
pe++;
|
|
468
554
|
}
|
|
469
555
|
}
|
|
470
|
-
|
|
556
|
+
|
|
557
|
+
if (pe > p) {
|
|
558
|
+
MEMCPY(buffer, p, char, pe - p);
|
|
559
|
+
buffer += pe - p;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
|
563
|
+
if (intern) {
|
|
564
|
+
result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
|
|
565
|
+
} else {
|
|
566
|
+
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
|
|
567
|
+
}
|
|
568
|
+
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
|
569
|
+
free(bufferStart);
|
|
570
|
+
}
|
|
571
|
+
# else
|
|
572
|
+
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
|
|
573
|
+
|
|
574
|
+
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
|
575
|
+
free(bufferStart);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
if (intern) {
|
|
579
|
+
# if STR_UMINUS_DEDUPE_FROZEN
|
|
580
|
+
// Starting from MRI 2.8 it is preferable to freeze the string
|
|
581
|
+
// before deduplication so that it can be interned directly
|
|
582
|
+
// otherwise it would be duplicated first which is wasteful.
|
|
583
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
|
584
|
+
# elif STR_UMINUS_DEDUPE
|
|
585
|
+
// MRI 2.5 and older do not deduplicate strings that are already
|
|
586
|
+
// frozen.
|
|
587
|
+
result = rb_funcall(result, i_uminus, 0);
|
|
588
|
+
# else
|
|
589
|
+
result = rb_str_freeze(result);
|
|
590
|
+
# endif
|
|
591
|
+
}
|
|
592
|
+
# endif
|
|
593
|
+
|
|
594
|
+
if (symbolize) {
|
|
595
|
+
result = rb_str_intern(result);
|
|
596
|
+
}
|
|
597
|
+
|
|
471
598
|
return result;
|
|
472
599
|
}
|
|
473
600
|
|
|
@@ -478,12 +605,11 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
|
478
605
|
write data;
|
|
479
606
|
|
|
480
607
|
action parse_string {
|
|
481
|
-
*result = json_string_unescape(
|
|
608
|
+
*result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
|
482
609
|
if (NIL_P(*result)) {
|
|
483
610
|
fhold;
|
|
484
611
|
fbreak;
|
|
485
612
|
} else {
|
|
486
|
-
FORCE_UTF8(*result);
|
|
487
613
|
fexec p + 1;
|
|
488
614
|
}
|
|
489
615
|
}
|
|
@@ -510,7 +636,6 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
|
510
636
|
int cs = EVIL;
|
|
511
637
|
VALUE match_string;
|
|
512
638
|
|
|
513
|
-
*result = rb_str_buf_new(0);
|
|
514
639
|
%% write init;
|
|
515
640
|
json->memo = p;
|
|
516
641
|
%% write exec;
|
|
@@ -526,9 +651,6 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
|
526
651
|
}
|
|
527
652
|
}
|
|
528
653
|
|
|
529
|
-
if (json->symbolize_names && json->parsing_name) {
|
|
530
|
-
*result = rb_str_intern(*result);
|
|
531
|
-
}
|
|
532
654
|
if (cs >= JSON_string_first_final) {
|
|
533
655
|
return p + 1;
|
|
534
656
|
} else {
|
|
@@ -550,41 +672,16 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
|
550
672
|
|
|
551
673
|
static VALUE convert_encoding(VALUE source)
|
|
552
674
|
{
|
|
553
|
-
char *ptr = RSTRING_PTR(source);
|
|
554
|
-
long len = RSTRING_LEN(source);
|
|
555
|
-
if (len < 2) {
|
|
556
|
-
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
|
557
|
-
}
|
|
558
675
|
#ifdef HAVE_RUBY_ENCODING_H
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE);
|
|
564
|
-
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
|
565
|
-
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE);
|
|
566
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
|
567
|
-
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE);
|
|
568
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
|
569
|
-
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE);
|
|
570
|
-
} else {
|
|
571
|
-
source = rb_str_dup(source);
|
|
572
|
-
FORCE_UTF8(source);
|
|
573
|
-
}
|
|
574
|
-
} else {
|
|
575
|
-
source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
#else
|
|
579
|
-
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
|
580
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
|
|
581
|
-
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
|
582
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
|
|
583
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
|
584
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
|
|
585
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
|
586
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
|
|
676
|
+
rb_encoding *enc = rb_enc_get(source);
|
|
677
|
+
if (enc == rb_ascii8bit_encoding()) {
|
|
678
|
+
if (OBJ_FROZEN(source)) {
|
|
679
|
+
source = rb_str_dup(source);
|
|
587
680
|
}
|
|
681
|
+
FORCE_UTF8(source);
|
|
682
|
+
} else {
|
|
683
|
+
source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
|
|
684
|
+
}
|
|
588
685
|
#endif
|
|
589
686
|
return source;
|
|
590
687
|
}
|
|
@@ -607,11 +704,12 @@ static VALUE convert_encoding(VALUE source)
|
|
|
607
704
|
* defiance of RFC 4627 to be parsed by the Parser. This option defaults to
|
|
608
705
|
* false.
|
|
609
706
|
* * *symbolize_names*: If set to true, returns symbols for the names
|
|
610
|
-
* (keys) in a JSON object. Otherwise strings are returned, which is
|
|
611
|
-
* the default.
|
|
707
|
+
* (keys) in a JSON object. Otherwise strings are returned, which is
|
|
708
|
+
* also the default. It's not possible to use this option in
|
|
709
|
+
* conjunction with the *create_additions* option.
|
|
612
710
|
* * *create_additions*: If set to false, the Parser doesn't create
|
|
613
|
-
* additions even if a
|
|
614
|
-
* defaults to
|
|
711
|
+
* additions even if a matching class and create_id was found. This option
|
|
712
|
+
* defaults to false.
|
|
615
713
|
* * *object_class*: Defaults to Hash
|
|
616
714
|
* * *array_class*: Defaults to Array
|
|
617
715
|
*/
|
|
@@ -623,12 +721,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
623
721
|
if (json->Vsource) {
|
|
624
722
|
rb_raise(rb_eTypeError, "already initialized instance");
|
|
625
723
|
}
|
|
724
|
+
#ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
|
|
725
|
+
rb_scan_args(argc, argv, "1:", &source, &opts);
|
|
726
|
+
#else
|
|
626
727
|
rb_scan_args(argc, argv, "11", &source, &opts);
|
|
728
|
+
#endif
|
|
627
729
|
if (!NIL_P(opts)) {
|
|
730
|
+
#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
|
|
628
731
|
opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
|
|
629
732
|
if (NIL_P(opts)) {
|
|
630
733
|
rb_raise(rb_eArgError, "opts needs to be like a hash");
|
|
631
734
|
} else {
|
|
735
|
+
#endif
|
|
632
736
|
VALUE tmp = ID2SYM(i_max_nesting);
|
|
633
737
|
if (option_given_p(opts, tmp)) {
|
|
634
738
|
VALUE max_nesting = rb_hash_aref(opts, tmp);
|
|
@@ -653,12 +757,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
653
757
|
} else {
|
|
654
758
|
json->symbolize_names = 0;
|
|
655
759
|
}
|
|
656
|
-
tmp = ID2SYM(
|
|
760
|
+
tmp = ID2SYM(i_freeze);
|
|
657
761
|
if (option_given_p(opts, tmp)) {
|
|
658
|
-
|
|
659
|
-
json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
|
|
762
|
+
json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
|
660
763
|
} else {
|
|
661
|
-
json->
|
|
764
|
+
json->freeze = 0;
|
|
662
765
|
}
|
|
663
766
|
tmp = ID2SYM(i_create_additions);
|
|
664
767
|
if (option_given_p(opts, tmp)) {
|
|
@@ -666,6 +769,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
666
769
|
} else {
|
|
667
770
|
json->create_additions = 0;
|
|
668
771
|
}
|
|
772
|
+
if (json->symbolize_names && json->create_additions) {
|
|
773
|
+
rb_raise(rb_eArgError,
|
|
774
|
+
"options :symbolize_names and :create_additions cannot be "
|
|
775
|
+
" used in conjunction");
|
|
776
|
+
}
|
|
669
777
|
tmp = ID2SYM(i_create_id);
|
|
670
778
|
if (option_given_p(opts, tmp)) {
|
|
671
779
|
json->create_id = rb_hash_aref(opts, tmp);
|
|
@@ -684,6 +792,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
684
792
|
} else {
|
|
685
793
|
json->array_class = Qnil;
|
|
686
794
|
}
|
|
795
|
+
tmp = ID2SYM(i_decimal_class);
|
|
796
|
+
if (option_given_p(opts, tmp)) {
|
|
797
|
+
json->decimal_class = rb_hash_aref(opts, tmp);
|
|
798
|
+
} else {
|
|
799
|
+
json->decimal_class = Qnil;
|
|
800
|
+
}
|
|
687
801
|
tmp = ID2SYM(i_match_string);
|
|
688
802
|
if (option_given_p(opts, tmp)) {
|
|
689
803
|
VALUE match_string = rb_hash_aref(opts, tmp);
|
|
@@ -691,20 +805,19 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
691
805
|
} else {
|
|
692
806
|
json->match_string = Qnil;
|
|
693
807
|
}
|
|
808
|
+
#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
|
|
694
809
|
}
|
|
810
|
+
#endif
|
|
695
811
|
} else {
|
|
696
812
|
json->max_nesting = 100;
|
|
697
813
|
json->allow_nan = 0;
|
|
698
|
-
json->create_additions =
|
|
814
|
+
json->create_additions = 0;
|
|
699
815
|
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
|
700
816
|
json->object_class = Qnil;
|
|
701
817
|
json->array_class = Qnil;
|
|
818
|
+
json->decimal_class = Qnil;
|
|
702
819
|
}
|
|
703
|
-
source =
|
|
704
|
-
if (!json->quirks_mode) {
|
|
705
|
-
source = convert_encoding(StringValue(source));
|
|
706
|
-
}
|
|
707
|
-
json->current_nesting = 0;
|
|
820
|
+
source = convert_encoding(StringValue(source));
|
|
708
821
|
StringValue(source);
|
|
709
822
|
json->len = RSTRING_LEN(source);
|
|
710
823
|
json->source = RSTRING_PTR(source);;
|
|
@@ -719,56 +832,8 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
719
832
|
|
|
720
833
|
include JSON_common;
|
|
721
834
|
|
|
722
|
-
action parse_object {
|
|
723
|
-
char *np;
|
|
724
|
-
json->current_nesting = 1;
|
|
725
|
-
np = JSON_parse_object(json, fpc, pe, &result);
|
|
726
|
-
if (np == NULL) { fhold; fbreak; } else fexec np;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
action parse_array {
|
|
730
|
-
char *np;
|
|
731
|
-
json->current_nesting = 1;
|
|
732
|
-
np = JSON_parse_array(json, fpc, pe, &result);
|
|
733
|
-
if (np == NULL) { fhold; fbreak; } else fexec np;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
main := ignore* (
|
|
737
|
-
begin_object >parse_object |
|
|
738
|
-
begin_array >parse_array
|
|
739
|
-
) ignore*;
|
|
740
|
-
}%%
|
|
741
|
-
|
|
742
|
-
static VALUE cParser_parse_strict(VALUE self)
|
|
743
|
-
{
|
|
744
|
-
char *p, *pe;
|
|
745
|
-
int cs = EVIL;
|
|
746
|
-
VALUE result = Qnil;
|
|
747
|
-
GET_PARSER;
|
|
748
|
-
|
|
749
|
-
%% write init;
|
|
750
|
-
p = json->source;
|
|
751
|
-
pe = p + json->len;
|
|
752
|
-
%% write exec;
|
|
753
|
-
|
|
754
|
-
if (cs >= JSON_first_final && p == pe) {
|
|
755
|
-
return result;
|
|
756
|
-
} else {
|
|
757
|
-
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
|
758
|
-
return Qnil;
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
%%{
|
|
764
|
-
machine JSON_quirks_mode;
|
|
765
|
-
|
|
766
|
-
write data;
|
|
767
|
-
|
|
768
|
-
include JSON_common;
|
|
769
|
-
|
|
770
835
|
action parse_value {
|
|
771
|
-
char *np = JSON_parse_value(json, fpc, pe, &result);
|
|
836
|
+
char *np = JSON_parse_value(json, fpc, pe, &result, 0);
|
|
772
837
|
if (np == NULL) { fhold; fbreak; } else fexec np;
|
|
773
838
|
}
|
|
774
839
|
|
|
@@ -777,71 +842,74 @@ static VALUE cParser_parse_strict(VALUE self)
|
|
|
777
842
|
) ignore*;
|
|
778
843
|
}%%
|
|
779
844
|
|
|
780
|
-
static VALUE cParser_parse_quirks_mode(VALUE self)
|
|
781
|
-
{
|
|
782
|
-
char *p, *pe;
|
|
783
|
-
int cs = EVIL;
|
|
784
|
-
VALUE result = Qnil;
|
|
785
|
-
GET_PARSER;
|
|
786
|
-
|
|
787
|
-
%% write init;
|
|
788
|
-
p = json->source;
|
|
789
|
-
pe = p + json->len;
|
|
790
|
-
%% write exec;
|
|
791
|
-
|
|
792
|
-
if (cs >= JSON_quirks_mode_first_final && p == pe) {
|
|
793
|
-
return result;
|
|
794
|
-
} else {
|
|
795
|
-
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
|
796
|
-
return Qnil;
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
|
|
800
845
|
/*
|
|
801
846
|
* call-seq: parse()
|
|
802
847
|
*
|
|
803
848
|
* Parses the current JSON text _source_ and returns the complete data
|
|
804
849
|
* structure as a result.
|
|
850
|
+
* It raises JSON::ParseError if fail to parse.
|
|
805
851
|
*/
|
|
806
852
|
static VALUE cParser_parse(VALUE self)
|
|
807
853
|
{
|
|
854
|
+
char *p, *pe;
|
|
855
|
+
int cs = EVIL;
|
|
856
|
+
VALUE result = Qnil;
|
|
808
857
|
GET_PARSER;
|
|
809
858
|
|
|
810
|
-
|
|
811
|
-
|
|
859
|
+
%% write init;
|
|
860
|
+
p = json->source;
|
|
861
|
+
pe = p + json->len;
|
|
862
|
+
%% write exec;
|
|
863
|
+
|
|
864
|
+
if (cs >= JSON_first_final && p == pe) {
|
|
865
|
+
return result;
|
|
812
866
|
} else {
|
|
813
|
-
|
|
867
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
|
868
|
+
return Qnil;
|
|
814
869
|
}
|
|
815
870
|
}
|
|
816
871
|
|
|
817
|
-
|
|
818
|
-
static JSON_Parser *JSON_allocate()
|
|
819
|
-
{
|
|
820
|
-
JSON_Parser *json = ALLOC(JSON_Parser);
|
|
821
|
-
MEMZERO(json, JSON_Parser, 1);
|
|
822
|
-
json->fbuffer = fbuffer_alloc(0);
|
|
823
|
-
return json;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
static void JSON_mark(JSON_Parser *json)
|
|
872
|
+
static void JSON_mark(void *ptr)
|
|
827
873
|
{
|
|
874
|
+
JSON_Parser *json = ptr;
|
|
828
875
|
rb_gc_mark_maybe(json->Vsource);
|
|
829
876
|
rb_gc_mark_maybe(json->create_id);
|
|
830
877
|
rb_gc_mark_maybe(json->object_class);
|
|
831
878
|
rb_gc_mark_maybe(json->array_class);
|
|
879
|
+
rb_gc_mark_maybe(json->decimal_class);
|
|
832
880
|
rb_gc_mark_maybe(json->match_string);
|
|
833
881
|
}
|
|
834
882
|
|
|
835
|
-
static void JSON_free(
|
|
883
|
+
static void JSON_free(void *ptr)
|
|
836
884
|
{
|
|
885
|
+
JSON_Parser *json = ptr;
|
|
837
886
|
fbuffer_free(json->fbuffer);
|
|
838
887
|
ruby_xfree(json);
|
|
839
888
|
}
|
|
840
889
|
|
|
890
|
+
static size_t JSON_memsize(const void *ptr)
|
|
891
|
+
{
|
|
892
|
+
const JSON_Parser *json = ptr;
|
|
893
|
+
return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
#ifdef NEW_TYPEDDATA_WRAPPER
|
|
897
|
+
static const rb_data_type_t JSON_Parser_type = {
|
|
898
|
+
"JSON/Parser",
|
|
899
|
+
{JSON_mark, JSON_free, JSON_memsize,},
|
|
900
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
901
|
+
0, 0,
|
|
902
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
|
903
|
+
#endif
|
|
904
|
+
};
|
|
905
|
+
#endif
|
|
906
|
+
|
|
841
907
|
static VALUE cJSON_parser_s_allocate(VALUE klass)
|
|
842
908
|
{
|
|
843
|
-
JSON_Parser *json
|
|
844
|
-
|
|
909
|
+
JSON_Parser *json;
|
|
910
|
+
VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
|
|
911
|
+
json->fbuffer = fbuffer_alloc(0);
|
|
912
|
+
return obj;
|
|
845
913
|
}
|
|
846
914
|
|
|
847
915
|
/*
|
|
@@ -856,35 +924,34 @@ static VALUE cParser_source(VALUE self)
|
|
|
856
924
|
return rb_str_dup(json->Vsource);
|
|
857
925
|
}
|
|
858
926
|
|
|
859
|
-
|
|
860
|
-
* call-seq: quirks_mode?()
|
|
861
|
-
*
|
|
862
|
-
* Returns a true, if this parser is in quirks_mode, false otherwise.
|
|
863
|
-
*/
|
|
864
|
-
static VALUE cParser_quirks_mode_p(VALUE self)
|
|
927
|
+
void Init_parser(void)
|
|
865
928
|
{
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
929
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
|
930
|
+
rb_ext_ractor_safe(true);
|
|
931
|
+
#endif
|
|
870
932
|
|
|
871
|
-
|
|
872
|
-
{
|
|
933
|
+
#undef rb_intern
|
|
873
934
|
rb_require("json/common");
|
|
874
935
|
mJSON = rb_define_module("JSON");
|
|
875
936
|
mExt = rb_define_module_under(mJSON, "Ext");
|
|
876
937
|
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
|
877
938
|
eParserError = rb_path2class("JSON::ParserError");
|
|
878
939
|
eNestingError = rb_path2class("JSON::NestingError");
|
|
940
|
+
rb_gc_register_mark_object(eParserError);
|
|
941
|
+
rb_gc_register_mark_object(eNestingError);
|
|
879
942
|
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
|
|
880
943
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
|
881
944
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
|
882
945
|
rb_define_method(cParser, "source", cParser_source, 0);
|
|
883
|
-
rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
|
|
884
946
|
|
|
885
947
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
|
948
|
+
rb_gc_register_mark_object(CNaN);
|
|
949
|
+
|
|
886
950
|
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
|
|
951
|
+
rb_gc_register_mark_object(CInfinity);
|
|
952
|
+
|
|
887
953
|
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
|
|
954
|
+
rb_gc_register_mark_object(CMinusInfinity);
|
|
888
955
|
|
|
889
956
|
i_json_creatable_p = rb_intern("json_creatable?");
|
|
890
957
|
i_json_create = rb_intern("json_create");
|
|
@@ -894,9 +961,9 @@ void Init_parser()
|
|
|
894
961
|
i_max_nesting = rb_intern("max_nesting");
|
|
895
962
|
i_allow_nan = rb_intern("allow_nan");
|
|
896
963
|
i_symbolize_names = rb_intern("symbolize_names");
|
|
897
|
-
i_quirks_mode = rb_intern("quirks_mode");
|
|
898
964
|
i_object_class = rb_intern("object_class");
|
|
899
965
|
i_array_class = rb_intern("array_class");
|
|
966
|
+
i_decimal_class = rb_intern("decimal_class");
|
|
900
967
|
i_match = rb_intern("match");
|
|
901
968
|
i_match_string = rb_intern("match_string");
|
|
902
969
|
i_key_p = rb_intern("key?");
|
|
@@ -904,18 +971,10 @@ void Init_parser()
|
|
|
904
971
|
i_aset = rb_intern("[]=");
|
|
905
972
|
i_aref = rb_intern("[]");
|
|
906
973
|
i_leftshift = rb_intern("<<");
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
|
|
912
|
-
CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
|
|
913
|
-
CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
|
|
914
|
-
i_encoding = rb_intern("encoding");
|
|
915
|
-
i_encode = rb_intern("encode");
|
|
916
|
-
#else
|
|
917
|
-
i_iconv = rb_intern("iconv");
|
|
918
|
-
#endif
|
|
974
|
+
i_new = rb_intern("new");
|
|
975
|
+
i_try_convert = rb_intern("try_convert");
|
|
976
|
+
i_freeze = rb_intern("freeze");
|
|
977
|
+
i_uminus = rb_intern("-@");
|
|
919
978
|
}
|
|
920
979
|
|
|
921
980
|
/*
|