json 2.6.2 → 2.10.1

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/BSDL +22 -0
  3. data/CHANGES.md +144 -17
  4. data/LEGAL +8 -0
  5. data/README.md +67 -224
  6. data/ext/json/ext/fbuffer/fbuffer.h +110 -92
  7. data/ext/json/ext/generator/extconf.rb +8 -2
  8. data/ext/json/ext/generator/generator.c +1020 -806
  9. data/ext/json/ext/parser/extconf.rb +7 -27
  10. data/ext/json/ext/parser/parser.c +1343 -3212
  11. data/json.gemspec +48 -52
  12. data/lib/json/add/bigdecimal.rb +39 -10
  13. data/lib/json/add/complex.rb +29 -6
  14. data/lib/json/add/core.rb +1 -1
  15. data/lib/json/add/date.rb +27 -7
  16. data/lib/json/add/date_time.rb +26 -9
  17. data/lib/json/add/exception.rb +25 -7
  18. data/lib/json/add/ostruct.rb +32 -9
  19. data/lib/json/add/range.rb +33 -8
  20. data/lib/json/add/rational.rb +28 -6
  21. data/lib/json/add/regexp.rb +26 -8
  22. data/lib/json/add/set.rb +25 -6
  23. data/lib/json/add/struct.rb +29 -7
  24. data/lib/json/add/symbol.rb +34 -7
  25. data/lib/json/add/time.rb +29 -15
  26. data/lib/json/common.rb +418 -128
  27. data/lib/json/ext/generator/state.rb +106 -0
  28. data/lib/json/ext.rb +34 -4
  29. data/lib/json/generic_object.rb +7 -3
  30. data/lib/json/truffle_ruby/generator.rb +690 -0
  31. data/lib/json/version.rb +3 -7
  32. data/lib/json.rb +25 -21
  33. metadata +15 -26
  34. data/VERSION +0 -1
  35. data/ext/json/ext/generator/depend +0 -1
  36. data/ext/json/ext/generator/generator.h +0 -174
  37. data/ext/json/ext/parser/depend +0 -1
  38. data/ext/json/ext/parser/parser.h +0 -96
  39. data/ext/json/ext/parser/parser.rl +0 -986
  40. data/ext/json/extconf.rb +0 -3
  41. data/lib/json/pure/generator.rb +0 -479
  42. data/lib/json/pure/parser.rb +0 -337
  43. data/lib/json/pure.rb +0 -15
  44. /data/{LICENSE → COPYING} +0 -0
@@ -1,986 +0,0 @@
1
- #include "../fbuffer/fbuffer.h"
2
- #include "parser.h"
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
-
26
- /* unicode */
27
-
28
- static const signed char digit_values[256] = {
29
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
30
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
31
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
32
- -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
33
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
34
- 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
35
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
38
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
39
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
40
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
41
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
42
- -1, -1, -1, -1, -1, -1, -1
43
- };
44
-
45
- static UTF32 unescape_unicode(const unsigned char *p)
46
- {
47
- signed char b;
48
- UTF32 result = 0;
49
- b = digit_values[p[0]];
50
- if (b < 0) return UNI_REPLACEMENT_CHAR;
51
- result = (result << 4) | (unsigned char)b;
52
- b = digit_values[p[1]];
53
- if (b < 0) return UNI_REPLACEMENT_CHAR;
54
- result = (result << 4) | (unsigned char)b;
55
- b = digit_values[p[2]];
56
- if (b < 0) return UNI_REPLACEMENT_CHAR;
57
- result = (result << 4) | (unsigned char)b;
58
- b = digit_values[p[3]];
59
- if (b < 0) return UNI_REPLACEMENT_CHAR;
60
- result = (result << 4) | (unsigned char)b;
61
- return result;
62
- }
63
-
64
- static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
65
- {
66
- int len = 1;
67
- if (ch <= 0x7F) {
68
- buf[0] = (char) ch;
69
- } else if (ch <= 0x07FF) {
70
- buf[0] = (char) ((ch >> 6) | 0xC0);
71
- buf[1] = (char) ((ch & 0x3F) | 0x80);
72
- len++;
73
- } else if (ch <= 0xFFFF) {
74
- buf[0] = (char) ((ch >> 12) | 0xE0);
75
- buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
76
- buf[2] = (char) ((ch & 0x3F) | 0x80);
77
- len += 2;
78
- } else if (ch <= 0x1fffff) {
79
- buf[0] =(char) ((ch >> 18) | 0xF0);
80
- buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
81
- buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
82
- buf[3] =(char) ((ch & 0x3F) | 0x80);
83
- len += 3;
84
- } else {
85
- buf[0] = '?';
86
- }
87
- return len;
88
- }
89
-
90
- static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
91
- static VALUE CNaN, CInfinity, CMinusInfinity;
92
-
93
- static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
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;
98
-
99
- %%{
100
- machine JSON_common;
101
-
102
- cr = '\n';
103
- cr_neg = [^\n];
104
- ws = [ \t\r\n];
105
- c_comment = '/*' ( any* - (any* '*/' any* ) ) '*/';
106
- cpp_comment = '//' cr_neg* cr;
107
- comment = c_comment | cpp_comment;
108
- ignore = ws | comment;
109
- name_separator = ':';
110
- value_separator = ',';
111
- Vnull = 'null';
112
- Vfalse = 'false';
113
- Vtrue = 'true';
114
- VNaN = 'NaN';
115
- VInfinity = 'Infinity';
116
- VMinusInfinity = '-Infinity';
117
- begin_value = [nft\"\-\[\{NI] | digit;
118
- begin_object = '{';
119
- end_object = '}';
120
- begin_array = '[';
121
- end_array = ']';
122
- begin_string = '"';
123
- begin_name = begin_string;
124
- begin_number = digit | '-';
125
- }%%
126
-
127
- %%{
128
- machine JSON_object;
129
- include JSON_common;
130
-
131
- write data;
132
-
133
- action parse_value {
134
- VALUE v = Qnil;
135
- char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
136
- if (np == NULL) {
137
- fhold; fbreak;
138
- } else {
139
- if (NIL_P(json->object_class)) {
140
- OBJ_FREEZE(last_name);
141
- rb_hash_aset(*result, last_name, v);
142
- } else {
143
- rb_funcall(*result, i_aset, 2, last_name, v);
144
- }
145
- fexec np;
146
- }
147
- }
148
-
149
- action parse_name {
150
- char *np;
151
- json->parsing_name = 1;
152
- np = JSON_parse_string(json, fpc, pe, &last_name);
153
- json->parsing_name = 0;
154
- if (np == NULL) { fhold; fbreak; } else fexec np;
155
- }
156
-
157
- action exit { fhold; fbreak; }
158
-
159
- pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value;
160
- next_pair = ignore* value_separator pair;
161
-
162
- main := (
163
- begin_object
164
- (pair (next_pair)*)? ignore*
165
- end_object
166
- ) @exit;
167
- }%%
168
-
169
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
170
- {
171
- int cs = EVIL;
172
- VALUE last_name = Qnil;
173
- VALUE object_class = json->object_class;
174
-
175
- if (json->max_nesting && current_nesting > json->max_nesting) {
176
- rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
177
- }
178
-
179
- *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
180
-
181
- %% write init;
182
- %% write exec;
183
-
184
- if (cs >= JSON_object_first_final) {
185
- if (json->create_additions) {
186
- VALUE klassname;
187
- if (NIL_P(json->object_class)) {
188
- klassname = rb_hash_aref(*result, json->create_id);
189
- } else {
190
- klassname = rb_funcall(*result, i_aref, 1, json->create_id);
191
- }
192
- if (!NIL_P(klassname)) {
193
- VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
194
- if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
195
- *result = rb_funcall(klass, i_json_create, 1, *result);
196
- }
197
- }
198
- }
199
- return p + 1;
200
- } else {
201
- return NULL;
202
- }
203
- }
204
-
205
-
206
- %%{
207
- machine JSON_value;
208
- include JSON_common;
209
-
210
- write data;
211
-
212
- action parse_null {
213
- *result = Qnil;
214
- }
215
- action parse_false {
216
- *result = Qfalse;
217
- }
218
- action parse_true {
219
- *result = Qtrue;
220
- }
221
- action parse_nan {
222
- if (json->allow_nan) {
223
- *result = CNaN;
224
- } else {
225
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
226
- }
227
- }
228
- action parse_infinity {
229
- if (json->allow_nan) {
230
- *result = CInfinity;
231
- } else {
232
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
233
- }
234
- }
235
- action parse_string {
236
- char *np = JSON_parse_string(json, fpc, pe, result);
237
- if (np == NULL) { fhold; fbreak; } else fexec np;
238
- }
239
-
240
- action parse_number {
241
- char *np;
242
- if(pe > fpc + 8 && !strncmp(MinusInfinity, fpc, 9)) {
243
- if (json->allow_nan) {
244
- *result = CMinusInfinity;
245
- fexec p + 10;
246
- fhold; fbreak;
247
- } else {
248
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
249
- }
250
- }
251
- np = JSON_parse_float(json, fpc, pe, result);
252
- if (np != NULL) fexec np;
253
- np = JSON_parse_integer(json, fpc, pe, result);
254
- if (np != NULL) fexec np;
255
- fhold; fbreak;
256
- }
257
-
258
- action parse_array {
259
- char *np;
260
- np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1);
261
- if (np == NULL) { fhold; fbreak; } else fexec np;
262
- }
263
-
264
- action parse_object {
265
- char *np;
266
- np = JSON_parse_object(json, fpc, pe, result, current_nesting + 1);
267
- if (np == NULL) { fhold; fbreak; } else fexec np;
268
- }
269
-
270
- action exit { fhold; fbreak; }
271
-
272
- main := ignore* (
273
- Vnull @parse_null |
274
- Vfalse @parse_false |
275
- Vtrue @parse_true |
276
- VNaN @parse_nan |
277
- VInfinity @parse_infinity |
278
- begin_number >parse_number |
279
- begin_string >parse_string |
280
- begin_array >parse_array |
281
- begin_object >parse_object
282
- ) ignore* %*exit;
283
- }%%
284
-
285
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
286
- {
287
- int cs = EVIL;
288
-
289
- %% write init;
290
- %% write exec;
291
-
292
- if (json->freeze) {
293
- OBJ_FREEZE(*result);
294
- }
295
-
296
- if (cs >= JSON_value_first_final) {
297
- return p;
298
- } else {
299
- return NULL;
300
- }
301
- }
302
-
303
- %%{
304
- machine JSON_integer;
305
-
306
- write data;
307
-
308
- action exit { fhold; fbreak; }
309
-
310
- main := '-'? ('0' | [1-9][0-9]*) (^[0-9]? @exit);
311
- }%%
312
-
313
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
314
- {
315
- int cs = EVIL;
316
-
317
- %% write init;
318
- json->memo = p;
319
- %% write exec;
320
-
321
- if (cs >= JSON_integer_first_final) {
322
- long len = p - json->memo;
323
- fbuffer_clear(json->fbuffer);
324
- fbuffer_append(json->fbuffer, json->memo, len);
325
- fbuffer_append_char(json->fbuffer, '\0');
326
- *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
327
- return p + 1;
328
- } else {
329
- return NULL;
330
- }
331
- }
332
-
333
- %%{
334
- machine JSON_float;
335
- include JSON_common;
336
-
337
- write data;
338
-
339
- action exit { fhold; fbreak; }
340
-
341
- main := '-'? (
342
- (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
343
- | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
344
- ) (^[0-9Ee.\-]? @exit );
345
- }%%
346
-
347
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
348
- {
349
- int cs = EVIL;
350
-
351
- %% write init;
352
- json->memo = p;
353
- %% write exec;
354
-
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
-
384
- long len = p - json->memo;
385
- fbuffer_clear(json->fbuffer);
386
- fbuffer_append(json->fbuffer, json->memo, len);
387
- fbuffer_append_char(json->fbuffer, '\0');
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
-
396
- return p + 1;
397
- } else {
398
- return NULL;
399
- }
400
- }
401
-
402
-
403
- %%{
404
- machine JSON_array;
405
- include JSON_common;
406
-
407
- write data;
408
-
409
- action parse_value {
410
- VALUE v = Qnil;
411
- char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
412
- if (np == NULL) {
413
- fhold; fbreak;
414
- } else {
415
- if (NIL_P(json->array_class)) {
416
- rb_ary_push(*result, v);
417
- } else {
418
- rb_funcall(*result, i_leftshift, 1, v);
419
- }
420
- fexec np;
421
- }
422
- }
423
-
424
- action exit { fhold; fbreak; }
425
-
426
- next_element = value_separator ignore* begin_value >parse_value;
427
-
428
- main := begin_array ignore*
429
- ((begin_value >parse_value ignore*)
430
- (ignore* next_element ignore*)*)?
431
- end_array @exit;
432
- }%%
433
-
434
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
435
- {
436
- int cs = EVIL;
437
- VALUE array_class = json->array_class;
438
-
439
- if (json->max_nesting && current_nesting > json->max_nesting) {
440
- rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
441
- }
442
- *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
443
-
444
- %% write init;
445
- %% write exec;
446
-
447
- if(cs >= JSON_array_first_final) {
448
- return p + 1;
449
- } else {
450
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
451
- return NULL;
452
- }
453
- }
454
-
455
- static const size_t MAX_STACK_BUFFER_SIZE = 128;
456
- static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
457
- {
458
- VALUE result = Qnil;
459
- size_t bufferSize = stringEnd - string;
460
- char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
461
- int unescape_len;
462
- char buf[4];
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
-
478
- while (pe < stringEnd) {
479
- if (*pe == '\\') {
480
- unescape = (char *) "?";
481
- unescape_len = 1;
482
- if (pe > p) {
483
- MEMCPY(buffer, p, char, pe - p);
484
- buffer += pe - p;
485
- }
486
- switch (*++pe) {
487
- case 'n':
488
- unescape = (char *) "\n";
489
- break;
490
- case 'r':
491
- unescape = (char *) "\r";
492
- break;
493
- case 't':
494
- unescape = (char *) "\t";
495
- break;
496
- case '"':
497
- unescape = (char *) "\"";
498
- break;
499
- case '\\':
500
- unescape = (char *) "\\";
501
- break;
502
- case 'b':
503
- unescape = (char *) "\b";
504
- break;
505
- case 'f':
506
- unescape = (char *) "\f";
507
- break;
508
- case 'u':
509
- if (pe > stringEnd - 4) {
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
- );
517
- } else {
518
- UTF32 ch = unescape_unicode((unsigned char *) ++pe);
519
- pe += 3;
520
- if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
521
- pe++;
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
- }
531
- if (pe[0] == '\\' && pe[1] == 'u') {
532
- UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
533
- ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
534
- | (sur & 0x3FF));
535
- pe += 5;
536
- } else {
537
- unescape = (char *) "?";
538
- break;
539
- }
540
- }
541
- unescape_len = convert_UTF32_to_UTF8(buf, ch);
542
- unescape = buf;
543
- }
544
- break;
545
- default:
546
- p = pe;
547
- continue;
548
- }
549
- MEMCPY(buffer, unescape, char, unescape_len);
550
- buffer += unescape_len;
551
- p = ++pe;
552
- } else {
553
- pe++;
554
- }
555
- }
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
-
598
- return result;
599
- }
600
-
601
- %%{
602
- machine JSON_string;
603
- include JSON_common;
604
-
605
- write data;
606
-
607
- action parse_string {
608
- *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
609
- if (NIL_P(*result)) {
610
- fhold;
611
- fbreak;
612
- } else {
613
- fexec p + 1;
614
- }
615
- }
616
-
617
- action exit { fhold; fbreak; }
618
-
619
- main := '"' ((^([\"\\] | 0..0x1f) | '\\'[\"\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^([\"\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
620
- }%%
621
-
622
- static int
623
- match_i(VALUE regexp, VALUE klass, VALUE memo)
624
- {
625
- if (regexp == Qundef) return ST_STOP;
626
- if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
627
- RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
628
- rb_ary_push(memo, klass);
629
- return ST_STOP;
630
- }
631
- return ST_CONTINUE;
632
- }
633
-
634
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
635
- {
636
- int cs = EVIL;
637
- VALUE match_string;
638
-
639
- %% write init;
640
- json->memo = p;
641
- %% write exec;
642
-
643
- if (json->create_additions && RTEST(match_string = json->match_string)) {
644
- VALUE klass;
645
- VALUE memo = rb_ary_new2(2);
646
- rb_ary_push(memo, *result);
647
- rb_hash_foreach(match_string, match_i, memo);
648
- klass = rb_ary_entry(memo, 1);
649
- if (RTEST(klass)) {
650
- *result = rb_funcall(klass, i_json_create, 1, *result);
651
- }
652
- }
653
-
654
- if (cs >= JSON_string_first_final) {
655
- return p + 1;
656
- } else {
657
- return NULL;
658
- }
659
- }
660
-
661
- /*
662
- * Document-class: JSON::Ext::Parser
663
- *
664
- * This is the JSON parser implemented as a C extension. It can be configured
665
- * to be used by setting
666
- *
667
- * JSON.parser = JSON::Ext::Parser
668
- *
669
- * with the method parser= in JSON.
670
- *
671
- */
672
-
673
- static VALUE convert_encoding(VALUE source)
674
- {
675
- #ifdef HAVE_RUBY_ENCODING_H
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);
680
- }
681
- FORCE_UTF8(source);
682
- } else {
683
- source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
684
- }
685
- #endif
686
- return source;
687
- }
688
-
689
- /*
690
- * call-seq: new(source, opts => {})
691
- *
692
- * Creates a new JSON::Ext::Parser instance for the string _source_.
693
- *
694
- * Creates a new JSON::Ext::Parser instance for the string _source_.
695
- *
696
- * It will be configured by the _opts_ hash. _opts_ can have the following
697
- * keys:
698
- *
699
- * _opts_ can have the following keys:
700
- * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
701
- * structures. Disable depth checking with :max_nesting => false|nil|0, it
702
- * defaults to 100.
703
- * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
704
- * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
705
- * false.
706
- * * *symbolize_names*: If set to true, returns symbols for the names
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.
710
- * * *create_additions*: If set to false, the Parser doesn't create
711
- * additions even if a matching class and create_id was found. This option
712
- * defaults to false.
713
- * * *object_class*: Defaults to Hash
714
- * * *array_class*: Defaults to Array
715
- */
716
- static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
717
- {
718
- VALUE source, opts;
719
- GET_PARSER_INIT;
720
-
721
- if (json->Vsource) {
722
- rb_raise(rb_eTypeError, "already initialized instance");
723
- }
724
- #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
725
- rb_scan_args(argc, argv, "1:", &source, &opts);
726
- #else
727
- rb_scan_args(argc, argv, "11", &source, &opts);
728
- #endif
729
- if (!NIL_P(opts)) {
730
- #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
731
- opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
732
- if (NIL_P(opts)) {
733
- rb_raise(rb_eArgError, "opts needs to be like a hash");
734
- } else {
735
- #endif
736
- VALUE tmp = ID2SYM(i_max_nesting);
737
- if (option_given_p(opts, tmp)) {
738
- VALUE max_nesting = rb_hash_aref(opts, tmp);
739
- if (RTEST(max_nesting)) {
740
- Check_Type(max_nesting, T_FIXNUM);
741
- json->max_nesting = FIX2INT(max_nesting);
742
- } else {
743
- json->max_nesting = 0;
744
- }
745
- } else {
746
- json->max_nesting = 100;
747
- }
748
- tmp = ID2SYM(i_allow_nan);
749
- if (option_given_p(opts, tmp)) {
750
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
751
- } else {
752
- json->allow_nan = 0;
753
- }
754
- tmp = ID2SYM(i_symbolize_names);
755
- if (option_given_p(opts, tmp)) {
756
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
757
- } else {
758
- json->symbolize_names = 0;
759
- }
760
- tmp = ID2SYM(i_freeze);
761
- if (option_given_p(opts, tmp)) {
762
- json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
763
- } else {
764
- json->freeze = 0;
765
- }
766
- tmp = ID2SYM(i_create_additions);
767
- if (option_given_p(opts, tmp)) {
768
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
769
- } else {
770
- json->create_additions = 0;
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
- }
777
- tmp = ID2SYM(i_create_id);
778
- if (option_given_p(opts, tmp)) {
779
- json->create_id = rb_hash_aref(opts, tmp);
780
- } else {
781
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
782
- }
783
- tmp = ID2SYM(i_object_class);
784
- if (option_given_p(opts, tmp)) {
785
- json->object_class = rb_hash_aref(opts, tmp);
786
- } else {
787
- json->object_class = Qnil;
788
- }
789
- tmp = ID2SYM(i_array_class);
790
- if (option_given_p(opts, tmp)) {
791
- json->array_class = rb_hash_aref(opts, tmp);
792
- } else {
793
- json->array_class = Qnil;
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
- }
801
- tmp = ID2SYM(i_match_string);
802
- if (option_given_p(opts, tmp)) {
803
- VALUE match_string = rb_hash_aref(opts, tmp);
804
- json->match_string = RTEST(match_string) ? match_string : Qnil;
805
- } else {
806
- json->match_string = Qnil;
807
- }
808
- #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
809
- }
810
- #endif
811
- } else {
812
- json->max_nesting = 100;
813
- json->allow_nan = 0;
814
- json->create_additions = 0;
815
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
816
- json->object_class = Qnil;
817
- json->array_class = Qnil;
818
- json->decimal_class = Qnil;
819
- }
820
- source = convert_encoding(StringValue(source));
821
- StringValue(source);
822
- json->len = RSTRING_LEN(source);
823
- json->source = RSTRING_PTR(source);;
824
- json->Vsource = source;
825
- return self;
826
- }
827
-
828
- %%{
829
- machine JSON;
830
-
831
- write data;
832
-
833
- include JSON_common;
834
-
835
- action parse_value {
836
- char *np = JSON_parse_value(json, fpc, pe, &result, 0);
837
- if (np == NULL) { fhold; fbreak; } else fexec np;
838
- }
839
-
840
- main := ignore* (
841
- begin_value >parse_value
842
- ) ignore*;
843
- }%%
844
-
845
- /*
846
- * call-seq: parse()
847
- *
848
- * Parses the current JSON text _source_ and returns the complete data
849
- * structure as a result.
850
- * It raises JSON::ParseError if fail to parse.
851
- */
852
- static VALUE cParser_parse(VALUE self)
853
- {
854
- char *p, *pe;
855
- int cs = EVIL;
856
- VALUE result = Qnil;
857
- GET_PARSER;
858
-
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;
866
- } else {
867
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
868
- return Qnil;
869
- }
870
- }
871
-
872
- static void JSON_mark(void *ptr)
873
- {
874
- JSON_Parser *json = ptr;
875
- rb_gc_mark_maybe(json->Vsource);
876
- rb_gc_mark_maybe(json->create_id);
877
- rb_gc_mark_maybe(json->object_class);
878
- rb_gc_mark_maybe(json->array_class);
879
- rb_gc_mark_maybe(json->decimal_class);
880
- rb_gc_mark_maybe(json->match_string);
881
- }
882
-
883
- static void JSON_free(void *ptr)
884
- {
885
- JSON_Parser *json = ptr;
886
- fbuffer_free(json->fbuffer);
887
- ruby_xfree(json);
888
- }
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
-
907
- static VALUE cJSON_parser_s_allocate(VALUE klass)
908
- {
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;
913
- }
914
-
915
- /*
916
- * call-seq: source()
917
- *
918
- * Returns a copy of the current _source_ string, that was used to construct
919
- * this Parser.
920
- */
921
- static VALUE cParser_source(VALUE self)
922
- {
923
- GET_PARSER;
924
- return rb_str_dup(json->Vsource);
925
- }
926
-
927
- void Init_parser(void)
928
- {
929
- #ifdef HAVE_RB_EXT_RACTOR_SAFE
930
- rb_ext_ractor_safe(true);
931
- #endif
932
-
933
- #undef rb_intern
934
- rb_require("json/common");
935
- mJSON = rb_define_module("JSON");
936
- mExt = rb_define_module_under(mJSON, "Ext");
937
- cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
938
- eParserError = rb_path2class("JSON::ParserError");
939
- eNestingError = rb_path2class("JSON::NestingError");
940
- rb_gc_register_mark_object(eParserError);
941
- rb_gc_register_mark_object(eNestingError);
942
- rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
943
- rb_define_method(cParser, "initialize", cParser_initialize, -1);
944
- rb_define_method(cParser, "parse", cParser_parse, 0);
945
- rb_define_method(cParser, "source", cParser_source, 0);
946
-
947
- CNaN = rb_const_get(mJSON, rb_intern("NaN"));
948
- rb_gc_register_mark_object(CNaN);
949
-
950
- CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
951
- rb_gc_register_mark_object(CInfinity);
952
-
953
- CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
954
- rb_gc_register_mark_object(CMinusInfinity);
955
-
956
- i_json_creatable_p = rb_intern("json_creatable?");
957
- i_json_create = rb_intern("json_create");
958
- i_create_id = rb_intern("create_id");
959
- i_create_additions = rb_intern("create_additions");
960
- i_chr = rb_intern("chr");
961
- i_max_nesting = rb_intern("max_nesting");
962
- i_allow_nan = rb_intern("allow_nan");
963
- i_symbolize_names = rb_intern("symbolize_names");
964
- i_object_class = rb_intern("object_class");
965
- i_array_class = rb_intern("array_class");
966
- i_decimal_class = rb_intern("decimal_class");
967
- i_match = rb_intern("match");
968
- i_match_string = rb_intern("match_string");
969
- i_key_p = rb_intern("key?");
970
- i_deep_const_get = rb_intern("deep_const_get");
971
- i_aset = rb_intern("[]=");
972
- i_aref = rb_intern("[]");
973
- i_leftshift = rb_intern("<<");
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("-@");
978
- }
979
-
980
- /*
981
- * Local variables:
982
- * mode: c
983
- * c-file-style: ruby
984
- * indent-tabs-mode: nil
985
- * End:
986
- */