json 2.7.4 → 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.
@@ -1,997 +0,0 @@
1
- #include "../fbuffer/fbuffer.h"
2
- #include "parser.h"
3
-
4
- /* unicode */
5
-
6
- static const signed char digit_values[256] = {
7
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
8
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
9
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
10
- -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
11
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
12
- 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
13
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
14
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
15
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
16
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
17
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
18
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
19
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
20
- -1, -1, -1, -1, -1, -1, -1
21
- };
22
-
23
- static uint32_t unescape_unicode(const unsigned char *p)
24
- {
25
- const uint32_t replacement_char = 0xFFFD;
26
-
27
- signed char b;
28
- uint32_t result = 0;
29
- b = digit_values[p[0]];
30
- if (b < 0) return replacement_char;
31
- result = (result << 4) | (unsigned char)b;
32
- b = digit_values[p[1]];
33
- if (b < 0) return replacement_char;
34
- result = (result << 4) | (unsigned char)b;
35
- b = digit_values[p[2]];
36
- if (b < 0) return replacement_char;
37
- result = (result << 4) | (unsigned char)b;
38
- b = digit_values[p[3]];
39
- if (b < 0) return replacement_char;
40
- result = (result << 4) | (unsigned char)b;
41
- return result;
42
- }
43
-
44
- static int convert_UTF32_to_UTF8(char *buf, uint32_t ch)
45
- {
46
- int len = 1;
47
- if (ch <= 0x7F) {
48
- buf[0] = (char) ch;
49
- } else if (ch <= 0x07FF) {
50
- buf[0] = (char) ((ch >> 6) | 0xC0);
51
- buf[1] = (char) ((ch & 0x3F) | 0x80);
52
- len++;
53
- } else if (ch <= 0xFFFF) {
54
- buf[0] = (char) ((ch >> 12) | 0xE0);
55
- buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
56
- buf[2] = (char) ((ch & 0x3F) | 0x80);
57
- len += 2;
58
- } else if (ch <= 0x1fffff) {
59
- buf[0] =(char) ((ch >> 18) | 0xF0);
60
- buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
61
- buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
62
- buf[3] =(char) ((ch & 0x3F) | 0x80);
63
- len += 3;
64
- } else {
65
- buf[0] = '?';
66
- }
67
- return len;
68
- }
69
-
70
- #define PARSE_ERROR_FRAGMENT_LEN 32
71
- #ifdef RBIMPL_ATTR_NORETURN
72
- RBIMPL_ATTR_NORETURN()
73
- #endif
74
- static void raise_parse_error(const char *format, const char *start)
75
- {
76
- char buffer[PARSE_ERROR_FRAGMENT_LEN + 1];
77
-
78
- size_t len = strnlen(start, PARSE_ERROR_FRAGMENT_LEN);
79
- const char *ptr = start;
80
-
81
- if (len == PARSE_ERROR_FRAGMENT_LEN) {
82
- MEMCPY(buffer, start, char, PARSE_ERROR_FRAGMENT_LEN);
83
- buffer[PARSE_ERROR_FRAGMENT_LEN] = '\0';
84
- ptr = buffer;
85
- }
86
-
87
- rb_enc_raise(rb_utf8_encoding(), rb_path2class("JSON::ParserError"), format, ptr);
88
- }
89
-
90
- static VALUE mJSON, mExt, cParser, 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,
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
- static int binary_encindex;
100
- static int utf8_encindex;
101
-
102
-
103
- %%{
104
- machine JSON_common;
105
-
106
- cr = '\n';
107
- cr_neg = [^\n];
108
- ws = [ \t\r\n];
109
- c_comment = '/*' ( any* - (any* '*/' any* ) ) '*/';
110
- cpp_comment = '//' cr_neg* cr;
111
- comment = c_comment | cpp_comment;
112
- ignore = ws | comment;
113
- name_separator = ':';
114
- value_separator = ',';
115
- Vnull = 'null';
116
- Vfalse = 'false';
117
- Vtrue = 'true';
118
- VNaN = 'NaN';
119
- VInfinity = 'Infinity';
120
- VMinusInfinity = '-Infinity';
121
- begin_value = [nft\"\-\[\{NI] | digit;
122
- begin_object = '{';
123
- end_object = '}';
124
- begin_array = '[';
125
- end_array = ']';
126
- begin_string = '"';
127
- begin_name = begin_string;
128
- begin_number = digit | '-';
129
- }%%
130
-
131
- %%{
132
- machine JSON_object;
133
- include JSON_common;
134
-
135
- write data;
136
-
137
- action parse_value {
138
- VALUE v = Qnil;
139
- char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
140
- if (np == NULL) {
141
- fhold; fbreak;
142
- } else {
143
- if (NIL_P(json->object_class)) {
144
- OBJ_FREEZE(last_name);
145
- rb_hash_aset(*result, last_name, v);
146
- } else {
147
- rb_funcall(*result, i_aset, 2, last_name, v);
148
- }
149
- fexec np;
150
- }
151
- }
152
-
153
- action parse_name {
154
- char *np;
155
- json->parsing_name = 1;
156
- np = JSON_parse_string(json, fpc, pe, &last_name);
157
- json->parsing_name = 0;
158
- if (np == NULL) { fhold; fbreak; } else fexec np;
159
- }
160
-
161
- action exit { fhold; fbreak; }
162
-
163
- pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value;
164
- next_pair = ignore* value_separator pair;
165
-
166
- main := (
167
- begin_object
168
- (pair (next_pair)*)? ignore*
169
- end_object
170
- ) @exit;
171
- }%%
172
-
173
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
174
- {
175
- int cs = EVIL;
176
- VALUE last_name = Qnil;
177
- VALUE object_class = json->object_class;
178
-
179
- if (json->max_nesting && current_nesting > json->max_nesting) {
180
- rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
181
- }
182
-
183
- *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
184
-
185
- %% write init;
186
- %% write exec;
187
-
188
- if (cs >= JSON_object_first_final) {
189
- if (json->create_additions) {
190
- VALUE klassname;
191
- if (NIL_P(json->object_class)) {
192
- klassname = rb_hash_aref(*result, json->create_id);
193
- } else {
194
- klassname = rb_funcall(*result, i_aref, 1, json->create_id);
195
- }
196
- if (!NIL_P(klassname)) {
197
- VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
198
- if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
199
- *result = rb_funcall(klass, i_json_create, 1, *result);
200
- }
201
- }
202
- }
203
- return p + 1;
204
- } else {
205
- return NULL;
206
- }
207
- }
208
-
209
-
210
- %%{
211
- machine JSON_value;
212
- include JSON_common;
213
-
214
- write data;
215
-
216
- action parse_null {
217
- *result = Qnil;
218
- }
219
- action parse_false {
220
- *result = Qfalse;
221
- }
222
- action parse_true {
223
- *result = Qtrue;
224
- }
225
- action parse_nan {
226
- if (json->allow_nan) {
227
- *result = CNaN;
228
- } else {
229
- raise_parse_error("unexpected token at '%s'", p - 2);
230
- }
231
- }
232
- action parse_infinity {
233
- if (json->allow_nan) {
234
- *result = CInfinity;
235
- } else {
236
- raise_parse_error("unexpected token at '%s'", p - 7);
237
- }
238
- }
239
- action parse_string {
240
- char *np = JSON_parse_string(json, fpc, pe, result);
241
- if (np == NULL) { fhold; fbreak; } else fexec np;
242
- }
243
-
244
- action parse_number {
245
- char *np;
246
- if(pe > fpc + 8 && !strncmp(MinusInfinity, fpc, 9)) {
247
- if (json->allow_nan) {
248
- *result = CMinusInfinity;
249
- fexec p + 10;
250
- fhold; fbreak;
251
- } else {
252
- raise_parse_error("unexpected token at '%s'", p);
253
- }
254
- }
255
- np = JSON_parse_float(json, fpc, pe, result);
256
- if (np != NULL) fexec np;
257
- np = JSON_parse_integer(json, fpc, pe, result);
258
- if (np != NULL) fexec np;
259
- fhold; fbreak;
260
- }
261
-
262
- action parse_array {
263
- char *np;
264
- np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1);
265
- if (np == NULL) { fhold; fbreak; } else fexec np;
266
- }
267
-
268
- action parse_object {
269
- char *np;
270
- np = JSON_parse_object(json, fpc, pe, result, current_nesting + 1);
271
- if (np == NULL) { fhold; fbreak; } else fexec np;
272
- }
273
-
274
- action exit { fhold; fbreak; }
275
-
276
- main := ignore* (
277
- Vnull @parse_null |
278
- Vfalse @parse_false |
279
- Vtrue @parse_true |
280
- VNaN @parse_nan |
281
- VInfinity @parse_infinity |
282
- begin_number >parse_number |
283
- begin_string >parse_string |
284
- begin_array >parse_array |
285
- begin_object >parse_object
286
- ) ignore* %*exit;
287
- }%%
288
-
289
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
290
- {
291
- int cs = EVIL;
292
-
293
- %% write init;
294
- %% write exec;
295
-
296
- if (json->freeze) {
297
- OBJ_FREEZE(*result);
298
- }
299
-
300
- if (cs >= JSON_value_first_final) {
301
- return p;
302
- } else {
303
- return NULL;
304
- }
305
- }
306
-
307
- %%{
308
- machine JSON_integer;
309
-
310
- write data;
311
-
312
- action exit { fhold; fbreak; }
313
-
314
- main := '-'? ('0' | [1-9][0-9]*) (^[0-9]? @exit);
315
- }%%
316
-
317
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
318
- {
319
- int cs = EVIL;
320
-
321
- %% write init;
322
- json->memo = p;
323
- %% write exec;
324
-
325
- if (cs >= JSON_integer_first_final) {
326
- long len = p - json->memo;
327
- fbuffer_clear(json->fbuffer);
328
- fbuffer_append(json->fbuffer, json->memo, len);
329
- fbuffer_append_char(json->fbuffer, '\0');
330
- *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
331
- return p + 1;
332
- } else {
333
- return NULL;
334
- }
335
- }
336
-
337
- %%{
338
- machine JSON_float;
339
- include JSON_common;
340
-
341
- write data;
342
-
343
- action exit { fhold; fbreak; }
344
-
345
- main := '-'? (
346
- (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
347
- | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
348
- ) (^[0-9Ee.\-]? @exit );
349
- }%%
350
-
351
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
352
- {
353
- int cs = EVIL;
354
-
355
- %% write init;
356
- json->memo = p;
357
- %% write exec;
358
-
359
- if (cs >= JSON_float_first_final) {
360
- VALUE mod = Qnil;
361
- ID method_id = 0;
362
- if (!NIL_P(json->decimal_class)) {
363
- if (rb_respond_to(json->decimal_class, i_try_convert)) {
364
- mod = json->decimal_class;
365
- method_id = i_try_convert;
366
- } else if (rb_respond_to(json->decimal_class, i_new)) {
367
- mod = json->decimal_class;
368
- method_id = i_new;
369
- } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
370
- VALUE name = rb_class_name(json->decimal_class);
371
- const char *name_cstr = RSTRING_PTR(name);
372
- const char *last_colon = strrchr(name_cstr, ':');
373
- if (last_colon) {
374
- const char *mod_path_end = last_colon - 1;
375
- VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
376
- mod = rb_path_to_class(mod_path);
377
-
378
- const char *method_name_beg = last_colon + 1;
379
- long before_len = method_name_beg - name_cstr;
380
- long len = RSTRING_LEN(name) - before_len;
381
- VALUE method_name = rb_str_substr(name, before_len, len);
382
- method_id = SYM2ID(rb_str_intern(method_name));
383
- } else {
384
- mod = rb_mKernel;
385
- method_id = SYM2ID(rb_str_intern(name));
386
- }
387
- }
388
- }
389
-
390
- long len = p - json->memo;
391
- fbuffer_clear(json->fbuffer);
392
- fbuffer_append(json->fbuffer, json->memo, len);
393
- fbuffer_append_char(json->fbuffer, '\0');
394
-
395
- if (method_id) {
396
- VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
397
- *result = rb_funcallv(mod, method_id, 1, &text);
398
- } else {
399
- *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
400
- }
401
-
402
- return p + 1;
403
- } else {
404
- return NULL;
405
- }
406
- }
407
-
408
-
409
- %%{
410
- machine JSON_array;
411
- include JSON_common;
412
-
413
- write data;
414
-
415
- action parse_value {
416
- VALUE v = Qnil;
417
- char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
418
- if (np == NULL) {
419
- fhold; fbreak;
420
- } else {
421
- if (NIL_P(json->array_class)) {
422
- rb_ary_push(*result, v);
423
- } else {
424
- rb_funcall(*result, i_leftshift, 1, v);
425
- }
426
- fexec np;
427
- }
428
- }
429
-
430
- action exit { fhold; fbreak; }
431
-
432
- next_element = value_separator ignore* begin_value >parse_value;
433
-
434
- main := begin_array ignore*
435
- ((begin_value >parse_value ignore*)
436
- (ignore* next_element ignore*)*)?
437
- end_array @exit;
438
- }%%
439
-
440
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
441
- {
442
- int cs = EVIL;
443
- VALUE array_class = json->array_class;
444
-
445
- if (json->max_nesting && current_nesting > json->max_nesting) {
446
- rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
447
- }
448
- *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
449
-
450
- %% write init;
451
- %% write exec;
452
-
453
- if(cs >= JSON_array_first_final) {
454
- return p + 1;
455
- } else {
456
- raise_parse_error("unexpected token at '%s'", p);
457
- return NULL;
458
- }
459
- }
460
-
461
- static const size_t MAX_STACK_BUFFER_SIZE = 128;
462
- static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
463
- {
464
- VALUE result = Qnil;
465
- size_t bufferSize = stringEnd - string;
466
- char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
467
- int unescape_len;
468
- char buf[4];
469
-
470
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
471
- # ifdef HAVE_RB_ENC_INTERNED_STR
472
- bufferStart = buffer = ALLOC_N(char, bufferSize ? bufferSize : 1);
473
- # else
474
- bufferStart = buffer = ALLOC_N(char, bufferSize);
475
- # endif
476
- } else {
477
- # ifdef HAVE_RB_ENC_INTERNED_STR
478
- bufferStart = buffer = ALLOCA_N(char, bufferSize ? bufferSize : 1);
479
- # else
480
- bufferStart = buffer = ALLOCA_N(char, bufferSize);
481
- # endif
482
- }
483
-
484
- while (pe < stringEnd) {
485
- if (*pe == '\\') {
486
- unescape = (char *) "?";
487
- unescape_len = 1;
488
- if (pe > p) {
489
- MEMCPY(buffer, p, char, pe - p);
490
- buffer += pe - p;
491
- }
492
- switch (*++pe) {
493
- case 'n':
494
- unescape = (char *) "\n";
495
- break;
496
- case 'r':
497
- unescape = (char *) "\r";
498
- break;
499
- case 't':
500
- unescape = (char *) "\t";
501
- break;
502
- case '"':
503
- unescape = (char *) "\"";
504
- break;
505
- case '\\':
506
- unescape = (char *) "\\";
507
- break;
508
- case 'b':
509
- unescape = (char *) "\b";
510
- break;
511
- case 'f':
512
- unescape = (char *) "\f";
513
- break;
514
- case 'u':
515
- if (pe > stringEnd - 4) {
516
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
517
- ruby_xfree(bufferStart);
518
- }
519
- raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
520
- } else {
521
- uint32_t ch = unescape_unicode((unsigned char *) ++pe);
522
- pe += 3;
523
- /* To handle values above U+FFFF, we take a sequence of
524
- * \uXXXX escapes in the U+D800..U+DBFF then
525
- * U+DC00..U+DFFF ranges, take the low 10 bits from each
526
- * to make a 20-bit number, then add 0x10000 to get the
527
- * final codepoint.
528
- *
529
- * See Unicode 15: 3.8 "Surrogates", 5.3 "Handling
530
- * Surrogate Pairs in UTF-16", and 23.6 "Surrogates
531
- * Area".
532
- */
533
- if ((ch & 0xFC00) == 0xD800) {
534
- pe++;
535
- if (pe > stringEnd - 6) {
536
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
537
- ruby_xfree(bufferStart);
538
- }
539
- raise_parse_error("incomplete surrogate pair at '%s'", p);
540
- }
541
- if (pe[0] == '\\' && pe[1] == 'u') {
542
- uint32_t sur = unescape_unicode((unsigned char *) pe + 2);
543
- ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
544
- | (sur & 0x3FF));
545
- pe += 5;
546
- } else {
547
- unescape = (char *) "?";
548
- break;
549
- }
550
- }
551
- unescape_len = convert_UTF32_to_UTF8(buf, ch);
552
- unescape = buf;
553
- }
554
- break;
555
- default:
556
- p = pe;
557
- continue;
558
- }
559
- MEMCPY(buffer, unescape, char, unescape_len);
560
- buffer += unescape_len;
561
- p = ++pe;
562
- } else {
563
- pe++;
564
- }
565
- }
566
-
567
- if (pe > p) {
568
- MEMCPY(buffer, p, char, pe - p);
569
- buffer += pe - p;
570
- }
571
-
572
- # ifdef HAVE_RB_ENC_INTERNED_STR
573
- if (intern) {
574
- result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
575
- } else {
576
- result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
577
- }
578
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
579
- ruby_xfree(bufferStart);
580
- }
581
- # else
582
- result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
583
-
584
- if (bufferSize > MAX_STACK_BUFFER_SIZE) {
585
- ruby_xfree(bufferStart);
586
- }
587
-
588
- if (intern) {
589
- # if STR_UMINUS_DEDUPE_FROZEN
590
- // Starting from MRI 2.8 it is preferable to freeze the string
591
- // before deduplication so that it can be interned directly
592
- // otherwise it would be duplicated first which is wasteful.
593
- result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
594
- # elif STR_UMINUS_DEDUPE
595
- // MRI 2.5 and older do not deduplicate strings that are already
596
- // frozen.
597
- result = rb_funcall(result, i_uminus, 0);
598
- # else
599
- result = rb_str_freeze(result);
600
- # endif
601
- }
602
- # endif
603
-
604
- if (symbolize) {
605
- result = rb_str_intern(result);
606
- }
607
-
608
- return result;
609
- }
610
-
611
- %%{
612
- machine JSON_string;
613
- include JSON_common;
614
-
615
- write data;
616
-
617
- action parse_string {
618
- *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
619
- if (NIL_P(*result)) {
620
- fhold;
621
- fbreak;
622
- } else {
623
- fexec p + 1;
624
- }
625
- }
626
-
627
- action exit { fhold; fbreak; }
628
-
629
- main := '"' ((^([\"\\] | 0..0x1f) | '\\'[\"\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^([\"\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
630
- }%%
631
-
632
- static int
633
- match_i(VALUE regexp, VALUE klass, VALUE memo)
634
- {
635
- if (regexp == Qundef) return ST_STOP;
636
- if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
637
- RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
638
- rb_ary_push(memo, klass);
639
- return ST_STOP;
640
- }
641
- return ST_CONTINUE;
642
- }
643
-
644
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
645
- {
646
- int cs = EVIL;
647
- VALUE match_string;
648
-
649
- %% write init;
650
- json->memo = p;
651
- %% write exec;
652
-
653
- if (json->create_additions && RTEST(match_string = json->match_string)) {
654
- VALUE klass;
655
- VALUE memo = rb_ary_new2(2);
656
- rb_ary_push(memo, *result);
657
- rb_hash_foreach(match_string, match_i, memo);
658
- klass = rb_ary_entry(memo, 1);
659
- if (RTEST(klass)) {
660
- *result = rb_funcall(klass, i_json_create, 1, *result);
661
- }
662
- }
663
-
664
- if (cs >= JSON_string_first_final) {
665
- return p + 1;
666
- } else {
667
- return NULL;
668
- }
669
- }
670
-
671
- /*
672
- * Document-class: JSON::Ext::Parser
673
- *
674
- * This is the JSON parser implemented as a C extension. It can be configured
675
- * to be used by setting
676
- *
677
- * JSON.parser = JSON::Ext::Parser
678
- *
679
- * with the method parser= in JSON.
680
- *
681
- */
682
-
683
- static VALUE convert_encoding(VALUE source)
684
- {
685
- int encindex = RB_ENCODING_GET(source);
686
-
687
- if (encindex == utf8_encindex) {
688
- return source;
689
- }
690
-
691
- if (encindex == binary_encindex) {
692
- // For historical reason, we silently reinterpret binary strings as UTF-8 if it would work.
693
- // TODO: Deprecate in 2.8.0
694
- // TODO: Remove in 3.0.0
695
- return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
696
- }
697
-
698
- return rb_str_conv_enc(source, rb_enc_from_index(encindex), rb_utf8_encoding());
699
- }
700
-
701
- /*
702
- * call-seq: new(source, opts => {})
703
- *
704
- * Creates a new JSON::Ext::Parser instance for the string _source_.
705
- *
706
- * It will be configured by the _opts_ hash. _opts_ can have the following
707
- * keys:
708
- *
709
- * _opts_ can have the following keys:
710
- * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
711
- * structures. Disable depth checking with :max_nesting => false|nil|0, it
712
- * defaults to 100.
713
- * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
714
- * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
715
- * false.
716
- * * *symbolize_names*: If set to true, returns symbols for the names
717
- * (keys) in a JSON object. Otherwise strings are returned, which is
718
- * also the default. It's not possible to use this option in
719
- * conjunction with the *create_additions* option.
720
- * * *create_additions*: If set to false, the Parser doesn't create
721
- * additions even if a matching class and create_id was found. This option
722
- * defaults to false.
723
- * * *object_class*: Defaults to Hash. If another type is provided, it will be used
724
- * instead of Hash to represent JSON objects. The type must respond to
725
- * +new+ without arguments, and return an object that respond to +[]=+.
726
- * * *array_class*: Defaults to Array If another type is provided, it will be used
727
- * instead of Hash to represent JSON arrays. The type must respond to
728
- * +new+ without arguments, and return an object that respond to +<<+.
729
- * * *decimal_class*: Specifies which class to use instead of the default
730
- * (Float) when parsing decimal numbers. This class must accept a single
731
- * string argument in its constructor.
732
- */
733
- static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
734
- {
735
- VALUE source, opts;
736
- GET_PARSER_INIT;
737
-
738
- if (json->Vsource) {
739
- rb_raise(rb_eTypeError, "already initialized instance");
740
- }
741
-
742
- rb_check_arity(argc, 1, 2);
743
- source = argv[0];
744
- opts = Qnil;
745
- if (argc == 2) {
746
- opts = argv[1];
747
- Check_Type(argv[1], T_HASH);
748
- if (RHASH_SIZE(argv[1]) > 0) {
749
- opts = argv[1];
750
- }
751
- }
752
-
753
- if (!NIL_P(opts)) {
754
- VALUE tmp = ID2SYM(i_max_nesting);
755
- if (option_given_p(opts, tmp)) {
756
- VALUE max_nesting = rb_hash_aref(opts, tmp);
757
- if (RTEST(max_nesting)) {
758
- Check_Type(max_nesting, T_FIXNUM);
759
- json->max_nesting = FIX2INT(max_nesting);
760
- } else {
761
- json->max_nesting = 0;
762
- }
763
- } else {
764
- json->max_nesting = 100;
765
- }
766
- tmp = ID2SYM(i_allow_nan);
767
- if (option_given_p(opts, tmp)) {
768
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
769
- } else {
770
- json->allow_nan = 0;
771
- }
772
- tmp = ID2SYM(i_symbolize_names);
773
- if (option_given_p(opts, tmp)) {
774
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
775
- } else {
776
- json->symbolize_names = 0;
777
- }
778
- tmp = ID2SYM(i_freeze);
779
- if (option_given_p(opts, tmp)) {
780
- json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
781
- } else {
782
- json->freeze = 0;
783
- }
784
- tmp = ID2SYM(i_create_additions);
785
- if (option_given_p(opts, tmp)) {
786
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
787
- } else {
788
- json->create_additions = 0;
789
- }
790
- if (json->symbolize_names && json->create_additions) {
791
- rb_raise(rb_eArgError,
792
- "options :symbolize_names and :create_additions cannot be "
793
- " used in conjunction");
794
- }
795
- tmp = ID2SYM(i_create_id);
796
- if (option_given_p(opts, tmp)) {
797
- json->create_id = rb_hash_aref(opts, tmp);
798
- } else {
799
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
800
- }
801
- tmp = ID2SYM(i_object_class);
802
- if (option_given_p(opts, tmp)) {
803
- json->object_class = rb_hash_aref(opts, tmp);
804
- } else {
805
- json->object_class = Qnil;
806
- }
807
- tmp = ID2SYM(i_array_class);
808
- if (option_given_p(opts, tmp)) {
809
- json->array_class = rb_hash_aref(opts, tmp);
810
- } else {
811
- json->array_class = Qnil;
812
- }
813
- tmp = ID2SYM(i_decimal_class);
814
- if (option_given_p(opts, tmp)) {
815
- json->decimal_class = rb_hash_aref(opts, tmp);
816
- } else {
817
- json->decimal_class = Qnil;
818
- }
819
- tmp = ID2SYM(i_match_string);
820
- if (option_given_p(opts, tmp)) {
821
- VALUE match_string = rb_hash_aref(opts, tmp);
822
- json->match_string = RTEST(match_string) ? match_string : Qnil;
823
- } else {
824
- json->match_string = Qnil;
825
- }
826
- } else {
827
- json->max_nesting = 100;
828
- json->allow_nan = 0;
829
- json->create_additions = 0;
830
- json->create_id = Qnil;
831
- json->object_class = Qnil;
832
- json->array_class = Qnil;
833
- json->decimal_class = Qnil;
834
- }
835
- source = convert_encoding(StringValue(source));
836
- StringValue(source);
837
- json->len = RSTRING_LEN(source);
838
- json->source = RSTRING_PTR(source);;
839
- json->Vsource = source;
840
- return self;
841
- }
842
-
843
- %%{
844
- machine JSON;
845
-
846
- write data;
847
-
848
- include JSON_common;
849
-
850
- action parse_value {
851
- char *np = JSON_parse_value(json, fpc, pe, &result, 0);
852
- if (np == NULL) { fhold; fbreak; } else fexec np;
853
- }
854
-
855
- main := ignore* (
856
- begin_value >parse_value
857
- ) ignore*;
858
- }%%
859
-
860
- /*
861
- * call-seq: parse()
862
- *
863
- * Parses the current JSON text _source_ and returns the complete data
864
- * structure as a result.
865
- * It raises JSON::ParserError if fail to parse.
866
- */
867
- static VALUE cParser_parse(VALUE self)
868
- {
869
- char *p, *pe;
870
- int cs = EVIL;
871
- VALUE result = Qnil;
872
- GET_PARSER;
873
-
874
- %% write init;
875
- p = json->source;
876
- pe = p + json->len;
877
- %% write exec;
878
-
879
- if (cs >= JSON_first_final && p == pe) {
880
- return result;
881
- } else {
882
- raise_parse_error("unexpected token at '%s'", p);
883
- return Qnil;
884
- }
885
- }
886
-
887
- static void JSON_mark(void *ptr)
888
- {
889
- JSON_Parser *json = ptr;
890
- rb_gc_mark(json->Vsource);
891
- rb_gc_mark(json->create_id);
892
- rb_gc_mark(json->object_class);
893
- rb_gc_mark(json->array_class);
894
- rb_gc_mark(json->decimal_class);
895
- rb_gc_mark(json->match_string);
896
- }
897
-
898
- static void JSON_free(void *ptr)
899
- {
900
- JSON_Parser *json = ptr;
901
- fbuffer_free(json->fbuffer);
902
- ruby_xfree(json);
903
- }
904
-
905
- static size_t JSON_memsize(const void *ptr)
906
- {
907
- const JSON_Parser *json = ptr;
908
- return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
909
- }
910
-
911
- static const rb_data_type_t JSON_Parser_type = {
912
- "JSON/Parser",
913
- {JSON_mark, JSON_free, JSON_memsize,},
914
- 0, 0,
915
- RUBY_TYPED_FREE_IMMEDIATELY,
916
- };
917
-
918
- static VALUE cJSON_parser_s_allocate(VALUE klass)
919
- {
920
- JSON_Parser *json;
921
- VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
922
- json->fbuffer = fbuffer_alloc(0);
923
- return obj;
924
- }
925
-
926
- /*
927
- * call-seq: source()
928
- *
929
- * Returns a copy of the current _source_ string, that was used to construct
930
- * this Parser.
931
- */
932
- static VALUE cParser_source(VALUE self)
933
- {
934
- GET_PARSER;
935
- return rb_str_dup(json->Vsource);
936
- }
937
-
938
- void Init_parser(void)
939
- {
940
- #ifdef HAVE_RB_EXT_RACTOR_SAFE
941
- rb_ext_ractor_safe(true);
942
- #endif
943
-
944
- #undef rb_intern
945
- rb_require("json/common");
946
- mJSON = rb_define_module("JSON");
947
- mExt = rb_define_module_under(mJSON, "Ext");
948
- cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
949
- eNestingError = rb_path2class("JSON::NestingError");
950
- rb_gc_register_mark_object(eNestingError);
951
- rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
952
- rb_define_method(cParser, "initialize", cParser_initialize, -1);
953
- rb_define_method(cParser, "parse", cParser_parse, 0);
954
- rb_define_method(cParser, "source", cParser_source, 0);
955
-
956
- CNaN = rb_const_get(mJSON, rb_intern("NaN"));
957
- rb_gc_register_mark_object(CNaN);
958
-
959
- CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
960
- rb_gc_register_mark_object(CInfinity);
961
-
962
- CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
963
- rb_gc_register_mark_object(CMinusInfinity);
964
-
965
- i_json_creatable_p = rb_intern("json_creatable?");
966
- i_json_create = rb_intern("json_create");
967
- i_create_id = rb_intern("create_id");
968
- i_create_additions = rb_intern("create_additions");
969
- i_chr = rb_intern("chr");
970
- i_max_nesting = rb_intern("max_nesting");
971
- i_allow_nan = rb_intern("allow_nan");
972
- i_symbolize_names = rb_intern("symbolize_names");
973
- i_object_class = rb_intern("object_class");
974
- i_array_class = rb_intern("array_class");
975
- i_decimal_class = rb_intern("decimal_class");
976
- i_match = rb_intern("match");
977
- i_match_string = rb_intern("match_string");
978
- i_deep_const_get = rb_intern("deep_const_get");
979
- i_aset = rb_intern("[]=");
980
- i_aref = rb_intern("[]");
981
- i_leftshift = rb_intern("<<");
982
- i_new = rb_intern("new");
983
- i_try_convert = rb_intern("try_convert");
984
- i_freeze = rb_intern("freeze");
985
- i_uminus = rb_intern("-@");
986
-
987
- binary_encindex = rb_ascii8bit_encindex();
988
- utf8_encindex = rb_utf8_encindex();
989
- }
990
-
991
- /*
992
- * Local variables:
993
- * mode: c
994
- * c-file-style: ruby
995
- * indent-tabs-mode: nil
996
- * End:
997
- */