json 2.7.4 → 2.8.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.
- checksums.yaml +4 -4
- data/CHANGES.md +25 -0
- data/README.md +8 -77
- data/ext/json/ext/fbuffer/fbuffer.h +85 -47
- data/ext/json/ext/generator/generator.c +367 -216
- data/ext/json/ext/parser/extconf.rb +5 -27
- data/ext/json/ext/parser/parser.c +1536 -474
- data/ext/json/ext/parser/parser.rl +717 -243
- data/json.gemspec +4 -1
- data/lib/json/add/bigdecimal.rb +1 -1
- data/lib/json/common.rb +200 -54
- data/lib/json/ext/generator/state.rb +1 -31
- data/lib/json/ext.rb +2 -4
- data/lib/json/{pure → truffle_ruby}/generator.rb +165 -124
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +15 -20
- metadata +4 -8
- data/ext/json/ext/generator/generator.h +0 -129
- data/ext/json/ext/parser/parser.h +0 -60
- data/lib/json/pure/parser.rb +0 -331
- data/lib/json/pure.rb +0 -16
@@ -1,7 +1,321 @@
|
|
1
1
|
/* This file is automatically generated from parser.rl by using ragel */
|
2
2
|
#line 1 "parser.rl"
|
3
|
+
#include "ruby.h"
|
3
4
|
#include "../fbuffer/fbuffer.h"
|
4
|
-
|
5
|
+
|
6
|
+
static VALUE mJSON, mExt, cParser, eNestingError, Encoding_UTF_8;
|
7
|
+
static VALUE CNaN, CInfinity, CMinusInfinity;
|
8
|
+
|
9
|
+
static ID i_json_creatable_p, i_json_create, i_create_id,
|
10
|
+
i_chr, i_deep_const_get, i_match, i_aset, i_aref,
|
11
|
+
i_leftshift, i_new, i_try_convert, i_uminus, i_encode;
|
12
|
+
|
13
|
+
static VALUE sym_max_nesting, sym_allow_nan, sym_allow_trailing_comma, sym_symbolize_names, sym_freeze,
|
14
|
+
sym_create_additions, sym_create_id, sym_object_class, sym_array_class,
|
15
|
+
sym_decimal_class, sym_match_string;
|
16
|
+
|
17
|
+
static int binary_encindex;
|
18
|
+
static int utf8_encindex;
|
19
|
+
|
20
|
+
#ifdef HAVE_RB_CATEGORY_WARN
|
21
|
+
# define json_deprecated(message) rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, message)
|
22
|
+
#else
|
23
|
+
# define json_deprecated(message) rb_warn(message)
|
24
|
+
#endif
|
25
|
+
|
26
|
+
static const char deprecated_create_additions_warning[] =
|
27
|
+
"JSON.load implicit support for `create_additions: true` is deprecated "
|
28
|
+
"and will be removed in 3.0, use JSON.unsafe_load or explicitly "
|
29
|
+
"pass `create_additions: true`";
|
30
|
+
|
31
|
+
#ifndef HAVE_RB_GC_MARK_LOCATIONS
|
32
|
+
// For TruffleRuby
|
33
|
+
void rb_gc_mark_locations(const VALUE *start, const VALUE *end)
|
34
|
+
{
|
35
|
+
VALUE *value = start;
|
36
|
+
|
37
|
+
while (value < end) {
|
38
|
+
rb_gc_mark(*value);
|
39
|
+
value++;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
#endif
|
43
|
+
|
44
|
+
#ifndef HAVE_RB_HASH_BULK_INSERT
|
45
|
+
// For TruffleRuby
|
46
|
+
void rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash)
|
47
|
+
{
|
48
|
+
long index = 0;
|
49
|
+
while (index < count) {
|
50
|
+
VALUE name = pairs[index++];
|
51
|
+
VALUE value = pairs[index++];
|
52
|
+
rb_hash_aset(hash, name, value);
|
53
|
+
}
|
54
|
+
RB_GC_GUARD(hash);
|
55
|
+
}
|
56
|
+
#endif
|
57
|
+
|
58
|
+
/* name cache */
|
59
|
+
|
60
|
+
#include <string.h>
|
61
|
+
#include <ctype.h>
|
62
|
+
|
63
|
+
// Object names are likely to be repeated, and are frozen.
|
64
|
+
// As such we can re-use them if we keep a cache of the ones we've seen so far,
|
65
|
+
// and save much more expensive lookups into the global fstring table.
|
66
|
+
// This cache implementation is deliberately simple, as we're optimizing for compactness,
|
67
|
+
// to be able to fit safely on the stack.
|
68
|
+
// As such, binary search into a sorted array gives a good tradeoff between compactness and
|
69
|
+
// performance.
|
70
|
+
#define JSON_RVALUE_CACHE_CAPA 63
|
71
|
+
typedef struct rvalue_cache_struct {
|
72
|
+
int length;
|
73
|
+
VALUE entries[JSON_RVALUE_CACHE_CAPA];
|
74
|
+
} rvalue_cache;
|
75
|
+
|
76
|
+
static rb_encoding *enc_utf8;
|
77
|
+
|
78
|
+
#define JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH 55
|
79
|
+
|
80
|
+
static inline VALUE build_interned_string(const char *str, const long length)
|
81
|
+
{
|
82
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
83
|
+
return rb_enc_interned_str(str, length, enc_utf8);
|
84
|
+
# else
|
85
|
+
VALUE rstring = rb_utf8_str_new(str, length);
|
86
|
+
return rb_funcall(rb_str_freeze(rstring), i_uminus, 0);
|
87
|
+
# endif
|
88
|
+
}
|
89
|
+
|
90
|
+
static inline VALUE build_symbol(const char *str, const long length)
|
91
|
+
{
|
92
|
+
return rb_str_intern(build_interned_string(str, length));
|
93
|
+
}
|
94
|
+
|
95
|
+
static void rvalue_cache_insert_at(rvalue_cache *cache, int index, VALUE rstring)
|
96
|
+
{
|
97
|
+
MEMMOVE(&cache->entries[index + 1], &cache->entries[index], VALUE, cache->length - index);
|
98
|
+
cache->length++;
|
99
|
+
cache->entries[index] = rstring;
|
100
|
+
}
|
101
|
+
|
102
|
+
static inline int rstring_cache_cmp(const char *str, const long length, VALUE rstring)
|
103
|
+
{
|
104
|
+
long rstring_length = RSTRING_LEN(rstring);
|
105
|
+
if (length == rstring_length) {
|
106
|
+
return memcmp(str, RSTRING_PTR(rstring), length);
|
107
|
+
} else {
|
108
|
+
return (int)(length - rstring_length);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
static VALUE rstring_cache_fetch(rvalue_cache *cache, const char *str, const long length)
|
113
|
+
{
|
114
|
+
if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) {
|
115
|
+
// Common names aren't likely to be very long. So we just don't
|
116
|
+
// cache names above an arbitrary threshold.
|
117
|
+
return Qfalse;
|
118
|
+
}
|
119
|
+
|
120
|
+
if (RB_UNLIKELY(!isalpha(str[0]))) {
|
121
|
+
// Simple heuristic, if the first character isn't a letter,
|
122
|
+
// we're much less likely to see this string again.
|
123
|
+
// We mostly want to cache strings that are likely to be repeated.
|
124
|
+
return Qfalse;
|
125
|
+
}
|
126
|
+
|
127
|
+
int low = 0;
|
128
|
+
int high = cache->length - 1;
|
129
|
+
int mid = 0;
|
130
|
+
int last_cmp = 0;
|
131
|
+
|
132
|
+
while (low <= high) {
|
133
|
+
mid = (high + low) >> 1;
|
134
|
+
VALUE entry = cache->entries[mid];
|
135
|
+
last_cmp = rstring_cache_cmp(str, length, entry);
|
136
|
+
|
137
|
+
if (last_cmp == 0) {
|
138
|
+
return entry;
|
139
|
+
} else if (last_cmp > 0) {
|
140
|
+
low = mid + 1;
|
141
|
+
} else {
|
142
|
+
high = mid - 1;
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
if (RB_UNLIKELY(memchr(str, '\\', length))) {
|
147
|
+
// We assume the overwhelming majority of names don't need to be escaped.
|
148
|
+
// But if they do, we have to fallback to the slow path.
|
149
|
+
return Qfalse;
|
150
|
+
}
|
151
|
+
|
152
|
+
VALUE rstring = build_interned_string(str, length);
|
153
|
+
|
154
|
+
if (cache->length < JSON_RVALUE_CACHE_CAPA) {
|
155
|
+
if (last_cmp > 0) {
|
156
|
+
mid += 1;
|
157
|
+
}
|
158
|
+
|
159
|
+
rvalue_cache_insert_at(cache, mid, rstring);
|
160
|
+
}
|
161
|
+
return rstring;
|
162
|
+
}
|
163
|
+
|
164
|
+
static VALUE rsymbol_cache_fetch(rvalue_cache *cache, const char *str, const long length)
|
165
|
+
{
|
166
|
+
if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) {
|
167
|
+
// Common names aren't likely to be very long. So we just don't
|
168
|
+
// cache names above an arbitrary threshold.
|
169
|
+
return Qfalse;
|
170
|
+
}
|
171
|
+
|
172
|
+
if (RB_UNLIKELY(!isalpha(str[0]))) {
|
173
|
+
// Simple heuristic, if the first character isn't a letter,
|
174
|
+
// we're much less likely to see this string again.
|
175
|
+
// We mostly want to cache strings that are likely to be repeated.
|
176
|
+
return Qfalse;
|
177
|
+
}
|
178
|
+
|
179
|
+
int low = 0;
|
180
|
+
int high = cache->length - 1;
|
181
|
+
int mid = 0;
|
182
|
+
int last_cmp = 0;
|
183
|
+
|
184
|
+
while (low <= high) {
|
185
|
+
mid = (high + low) >> 1;
|
186
|
+
VALUE entry = cache->entries[mid];
|
187
|
+
last_cmp = rstring_cache_cmp(str, length, rb_sym2str(entry));
|
188
|
+
|
189
|
+
if (last_cmp == 0) {
|
190
|
+
return entry;
|
191
|
+
} else if (last_cmp > 0) {
|
192
|
+
low = mid + 1;
|
193
|
+
} else {
|
194
|
+
high = mid - 1;
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
if (RB_UNLIKELY(memchr(str, '\\', length))) {
|
199
|
+
// We assume the overwhelming majority of names don't need to be escaped.
|
200
|
+
// But if they do, we have to fallback to the slow path.
|
201
|
+
return Qfalse;
|
202
|
+
}
|
203
|
+
|
204
|
+
VALUE rsymbol = build_symbol(str, length);
|
205
|
+
|
206
|
+
if (cache->length < JSON_RVALUE_CACHE_CAPA) {
|
207
|
+
if (last_cmp > 0) {
|
208
|
+
mid += 1;
|
209
|
+
}
|
210
|
+
|
211
|
+
rvalue_cache_insert_at(cache, mid, rsymbol);
|
212
|
+
}
|
213
|
+
return rsymbol;
|
214
|
+
}
|
215
|
+
|
216
|
+
/* rvalue stack */
|
217
|
+
|
218
|
+
#define RVALUE_STACK_INITIAL_CAPA 128
|
219
|
+
|
220
|
+
enum rvalue_stack_type {
|
221
|
+
RVALUE_STACK_HEAP_ALLOCATED = 0,
|
222
|
+
RVALUE_STACK_STACK_ALLOCATED = 1,
|
223
|
+
};
|
224
|
+
|
225
|
+
typedef struct rvalue_stack_struct {
|
226
|
+
enum rvalue_stack_type type;
|
227
|
+
long capa;
|
228
|
+
long head;
|
229
|
+
VALUE *ptr;
|
230
|
+
} rvalue_stack;
|
231
|
+
|
232
|
+
static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref);
|
233
|
+
|
234
|
+
static rvalue_stack *rvalue_stack_grow(rvalue_stack *stack, VALUE *handle, rvalue_stack **stack_ref)
|
235
|
+
{
|
236
|
+
long required = stack->capa * 2;
|
237
|
+
|
238
|
+
if (stack->type == RVALUE_STACK_STACK_ALLOCATED) {
|
239
|
+
stack = rvalue_stack_spill(stack, handle, stack_ref);
|
240
|
+
} else {
|
241
|
+
REALLOC_N(stack->ptr, VALUE, required);
|
242
|
+
stack->capa = required;
|
243
|
+
}
|
244
|
+
return stack;
|
245
|
+
}
|
246
|
+
|
247
|
+
static void rvalue_stack_push(rvalue_stack *stack, VALUE value, VALUE *handle, rvalue_stack **stack_ref)
|
248
|
+
{
|
249
|
+
if (RB_UNLIKELY(stack->head >= stack->capa)) {
|
250
|
+
stack = rvalue_stack_grow(stack, handle, stack_ref);
|
251
|
+
}
|
252
|
+
stack->ptr[stack->head] = value;
|
253
|
+
stack->head++;
|
254
|
+
}
|
255
|
+
|
256
|
+
static inline VALUE *rvalue_stack_peek(rvalue_stack *stack, long count)
|
257
|
+
{
|
258
|
+
return stack->ptr + (stack->head - count);
|
259
|
+
}
|
260
|
+
|
261
|
+
static inline void rvalue_stack_pop(rvalue_stack *stack, long count)
|
262
|
+
{
|
263
|
+
stack->head -= count;
|
264
|
+
}
|
265
|
+
|
266
|
+
static void rvalue_stack_mark(void *ptr)
|
267
|
+
{
|
268
|
+
rvalue_stack *stack = (rvalue_stack *)ptr;
|
269
|
+
rb_gc_mark_locations(stack->ptr, stack->ptr + stack->head);
|
270
|
+
}
|
271
|
+
|
272
|
+
static void rvalue_stack_free(void *ptr)
|
273
|
+
{
|
274
|
+
rvalue_stack *stack = (rvalue_stack *)ptr;
|
275
|
+
if (stack) {
|
276
|
+
ruby_xfree(stack->ptr);
|
277
|
+
ruby_xfree(stack);
|
278
|
+
}
|
279
|
+
}
|
280
|
+
|
281
|
+
static size_t rvalue_stack_memsize(const void *ptr)
|
282
|
+
{
|
283
|
+
const rvalue_stack *stack = (const rvalue_stack *)ptr;
|
284
|
+
return sizeof(rvalue_stack) + sizeof(VALUE) * stack->capa;
|
285
|
+
}
|
286
|
+
|
287
|
+
static const rb_data_type_t JSON_Parser_rvalue_stack_type = {
|
288
|
+
"JSON::Ext::Parser/rvalue_stack",
|
289
|
+
{
|
290
|
+
.dmark = rvalue_stack_mark,
|
291
|
+
.dfree = rvalue_stack_free,
|
292
|
+
.dsize = rvalue_stack_memsize,
|
293
|
+
},
|
294
|
+
0, 0,
|
295
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
296
|
+
};
|
297
|
+
|
298
|
+
static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref)
|
299
|
+
{
|
300
|
+
rvalue_stack *stack;
|
301
|
+
*handle = TypedData_Make_Struct(0, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
|
302
|
+
*stack_ref = stack;
|
303
|
+
MEMCPY(stack, old_stack, rvalue_stack, 1);
|
304
|
+
|
305
|
+
stack->capa = old_stack->capa << 1;
|
306
|
+
stack->ptr = ALLOC_N(VALUE, stack->capa);
|
307
|
+
stack->type = RVALUE_STACK_HEAP_ALLOCATED;
|
308
|
+
MEMCPY(stack->ptr, old_stack->ptr, VALUE, old_stack->head);
|
309
|
+
return stack;
|
310
|
+
}
|
311
|
+
|
312
|
+
static void rvalue_stack_eagerly_release(VALUE handle)
|
313
|
+
{
|
314
|
+
rvalue_stack *stack;
|
315
|
+
TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
|
316
|
+
RTYPEDDATA_DATA(handle) = NULL;
|
317
|
+
rvalue_stack_free(stack);
|
318
|
+
}
|
5
319
|
|
6
320
|
/* unicode */
|
7
321
|
|
@@ -69,6 +383,50 @@ static int convert_UTF32_to_UTF8(char *buf, uint32_t ch)
|
|
69
383
|
return len;
|
70
384
|
}
|
71
385
|
|
386
|
+
typedef struct JSON_ParserStruct {
|
387
|
+
VALUE Vsource;
|
388
|
+
char *source;
|
389
|
+
long len;
|
390
|
+
char *memo;
|
391
|
+
VALUE create_id;
|
392
|
+
VALUE object_class;
|
393
|
+
VALUE array_class;
|
394
|
+
VALUE decimal_class;
|
395
|
+
VALUE match_string;
|
396
|
+
FBuffer fbuffer;
|
397
|
+
int max_nesting;
|
398
|
+
bool allow_nan;
|
399
|
+
bool allow_trailing_comma;
|
400
|
+
bool parsing_name;
|
401
|
+
bool symbolize_names;
|
402
|
+
bool freeze;
|
403
|
+
bool create_additions;
|
404
|
+
bool deprecated_create_additions;
|
405
|
+
rvalue_cache name_cache;
|
406
|
+
rvalue_stack *stack;
|
407
|
+
VALUE stack_handle;
|
408
|
+
} JSON_Parser;
|
409
|
+
|
410
|
+
#define GET_PARSER \
|
411
|
+
GET_PARSER_INIT; \
|
412
|
+
if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
|
413
|
+
|
414
|
+
#define GET_PARSER_INIT \
|
415
|
+
JSON_Parser *json; \
|
416
|
+
TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json)
|
417
|
+
|
418
|
+
#define MinusInfinity "-Infinity"
|
419
|
+
#define EVIL 0x666
|
420
|
+
|
421
|
+
static const rb_data_type_t JSON_Parser_type;
|
422
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
423
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
424
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
425
|
+
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
426
|
+
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
427
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
428
|
+
|
429
|
+
|
72
430
|
#define PARSE_ERROR_FRAGMENT_LEN 32
|
73
431
|
#ifdef RBIMPL_ATTR_NORETURN
|
74
432
|
RBIMPL_ATTR_NORETURN()
|
@@ -86,60 +444,49 @@ static void raise_parse_error(const char *format, const char *start)
|
|
86
444
|
ptr = buffer;
|
87
445
|
}
|
88
446
|
|
89
|
-
rb_enc_raise(
|
447
|
+
rb_enc_raise(enc_utf8, rb_path2class("JSON::ParserError"), format, ptr);
|
90
448
|
}
|
91
449
|
|
92
|
-
static VALUE mJSON, mExt, cParser, eNestingError;
|
93
|
-
static VALUE CNaN, CInfinity, CMinusInfinity;
|
94
|
-
|
95
|
-
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
96
|
-
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
97
|
-
i_object_class, i_array_class, i_decimal_class,
|
98
|
-
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
|
99
|
-
i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
|
100
450
|
|
101
|
-
static int binary_encindex;
|
102
|
-
static int utf8_encindex;
|
103
451
|
|
452
|
+
#line 475 "parser.rl"
|
104
453
|
|
105
454
|
|
106
|
-
#line 129 "parser.rl"
|
107
455
|
|
108
|
-
|
109
|
-
|
110
|
-
#line 111 "parser.c"
|
456
|
+
#line 457 "parser.c"
|
111
457
|
enum {JSON_object_start = 1};
|
112
|
-
enum {JSON_object_first_final =
|
458
|
+
enum {JSON_object_first_final = 32};
|
113
459
|
enum {JSON_object_error = 0};
|
114
460
|
|
115
461
|
enum {JSON_object_en_main = 1};
|
116
462
|
|
117
463
|
|
118
|
-
#line
|
464
|
+
#line 515 "parser.rl"
|
119
465
|
|
120
466
|
|
467
|
+
#define PUSH(result) rvalue_stack_push(json->stack, result, &json->stack_handle, &json->stack)
|
468
|
+
|
121
469
|
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
122
470
|
{
|
123
471
|
int cs = EVIL;
|
124
|
-
VALUE last_name = Qnil;
|
125
|
-
VALUE object_class = json->object_class;
|
126
472
|
|
127
473
|
if (json->max_nesting && current_nesting > json->max_nesting) {
|
128
474
|
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
129
475
|
}
|
130
476
|
|
131
|
-
|
477
|
+
long stack_head = json->stack->head;
|
132
478
|
|
133
479
|
|
134
|
-
#line
|
480
|
+
#line 481 "parser.c"
|
135
481
|
{
|
136
482
|
cs = JSON_object_start;
|
137
483
|
}
|
138
484
|
|
139
|
-
#line
|
485
|
+
#line 530 "parser.rl"
|
140
486
|
|
141
|
-
#line
|
487
|
+
#line 488 "parser.c"
|
142
488
|
{
|
489
|
+
short _widec;
|
143
490
|
if ( p == pe )
|
144
491
|
goto _test_eof;
|
145
492
|
switch ( cs )
|
@@ -159,27 +506,30 @@ case 2:
|
|
159
506
|
case 13: goto st2;
|
160
507
|
case 32: goto st2;
|
161
508
|
case 34: goto tr2;
|
162
|
-
case 47: goto
|
509
|
+
case 47: goto st28;
|
163
510
|
case 125: goto tr4;
|
164
511
|
}
|
165
512
|
if ( 9 <= (*p) && (*p) <= 10 )
|
166
513
|
goto st2;
|
167
514
|
goto st0;
|
168
515
|
tr2:
|
169
|
-
#line
|
516
|
+
#line 494 "parser.rl"
|
170
517
|
{
|
171
518
|
char *np;
|
172
|
-
json->parsing_name =
|
173
|
-
np = JSON_parse_string(json, p, pe,
|
174
|
-
json->parsing_name =
|
175
|
-
if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {
|
519
|
+
json->parsing_name = true;
|
520
|
+
np = JSON_parse_string(json, p, pe, result);
|
521
|
+
json->parsing_name = false;
|
522
|
+
if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {
|
523
|
+
PUSH(*result);
|
524
|
+
{p = (( np))-1;}
|
525
|
+
}
|
176
526
|
}
|
177
527
|
goto st3;
|
178
528
|
st3:
|
179
529
|
if ( ++p == pe )
|
180
530
|
goto _test_eof3;
|
181
531
|
case 3:
|
182
|
-
#line
|
532
|
+
#line 533 "parser.c"
|
183
533
|
switch( (*p) ) {
|
184
534
|
case 13: goto st3;
|
185
535
|
case 32: goto st3;
|
@@ -230,7 +580,7 @@ case 8:
|
|
230
580
|
case 32: goto st8;
|
231
581
|
case 34: goto tr11;
|
232
582
|
case 45: goto tr11;
|
233
|
-
case 47: goto
|
583
|
+
case 47: goto st24;
|
234
584
|
case 73: goto tr11;
|
235
585
|
case 78: goto tr11;
|
236
586
|
case 91: goto tr11;
|
@@ -246,19 +596,12 @@ case 8:
|
|
246
596
|
goto st8;
|
247
597
|
goto st0;
|
248
598
|
tr11:
|
249
|
-
#line
|
599
|
+
#line 483 "parser.rl"
|
250
600
|
{
|
251
|
-
|
252
|
-
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
601
|
+
char *np = JSON_parse_value(json, p, pe, result, current_nesting);
|
253
602
|
if (np == NULL) {
|
254
603
|
p--; {p++; cs = 9; goto _out;}
|
255
604
|
} else {
|
256
|
-
if (NIL_P(json->object_class)) {
|
257
|
-
OBJ_FREEZE(last_name);
|
258
|
-
rb_hash_aset(*result, last_name, v);
|
259
|
-
} else {
|
260
|
-
rb_funcall(*result, i_aset, 2, last_name, v);
|
261
|
-
}
|
262
605
|
{p = (( np))-1;}
|
263
606
|
}
|
264
607
|
}
|
@@ -267,16 +610,75 @@ st9:
|
|
267
610
|
if ( ++p == pe )
|
268
611
|
goto _test_eof9;
|
269
612
|
case 9:
|
270
|
-
#line
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
613
|
+
#line 614 "parser.c"
|
614
|
+
_widec = (*p);
|
615
|
+
if ( (*p) < 13 ) {
|
616
|
+
if ( (*p) > 9 ) {
|
617
|
+
if ( 10 <= (*p) && (*p) <= 10 ) {
|
618
|
+
_widec = (short)(128 + ((*p) - -128));
|
619
|
+
if (
|
620
|
+
#line 492 "parser.rl"
|
621
|
+
json->allow_trailing_comma ) _widec += 256;
|
622
|
+
}
|
623
|
+
} else if ( (*p) >= 9 ) {
|
624
|
+
_widec = (short)(128 + ((*p) - -128));
|
625
|
+
if (
|
626
|
+
#line 492 "parser.rl"
|
627
|
+
json->allow_trailing_comma ) _widec += 256;
|
628
|
+
}
|
629
|
+
} else if ( (*p) > 13 ) {
|
630
|
+
if ( (*p) < 44 ) {
|
631
|
+
if ( 32 <= (*p) && (*p) <= 32 ) {
|
632
|
+
_widec = (short)(128 + ((*p) - -128));
|
633
|
+
if (
|
634
|
+
#line 492 "parser.rl"
|
635
|
+
json->allow_trailing_comma ) _widec += 256;
|
636
|
+
}
|
637
|
+
} else if ( (*p) > 44 ) {
|
638
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
639
|
+
_widec = (short)(128 + ((*p) - -128));
|
640
|
+
if (
|
641
|
+
#line 492 "parser.rl"
|
642
|
+
json->allow_trailing_comma ) _widec += 256;
|
643
|
+
}
|
644
|
+
} else {
|
645
|
+
_widec = (short)(128 + ((*p) - -128));
|
646
|
+
if (
|
647
|
+
#line 492 "parser.rl"
|
648
|
+
json->allow_trailing_comma ) _widec += 256;
|
649
|
+
}
|
650
|
+
} else {
|
651
|
+
_widec = (short)(128 + ((*p) - -128));
|
652
|
+
if (
|
653
|
+
#line 492 "parser.rl"
|
654
|
+
json->allow_trailing_comma ) _widec += 256;
|
655
|
+
}
|
656
|
+
switch( _widec ) {
|
276
657
|
case 125: goto tr4;
|
277
|
-
|
278
|
-
|
279
|
-
goto
|
658
|
+
case 269: goto st10;
|
659
|
+
case 288: goto st10;
|
660
|
+
case 300: goto st11;
|
661
|
+
case 303: goto st16;
|
662
|
+
case 525: goto st9;
|
663
|
+
case 544: goto st9;
|
664
|
+
case 556: goto st2;
|
665
|
+
case 559: goto st20;
|
666
|
+
}
|
667
|
+
if ( _widec > 266 ) {
|
668
|
+
if ( 521 <= _widec && _widec <= 522 )
|
669
|
+
goto st9;
|
670
|
+
} else if ( _widec >= 265 )
|
671
|
+
goto st10;
|
672
|
+
goto st0;
|
673
|
+
tr4:
|
674
|
+
#line 505 "parser.rl"
|
675
|
+
{ p--; {p++; cs = 32; goto _out;} }
|
676
|
+
goto st32;
|
677
|
+
st32:
|
678
|
+
if ( ++p == pe )
|
679
|
+
goto _test_eof32;
|
680
|
+
case 32:
|
681
|
+
#line 682 "parser.c"
|
280
682
|
goto st0;
|
281
683
|
st10:
|
282
684
|
if ( ++p == pe )
|
@@ -285,8 +687,9 @@ case 10:
|
|
285
687
|
switch( (*p) ) {
|
286
688
|
case 13: goto st10;
|
287
689
|
case 32: goto st10;
|
288
|
-
case
|
289
|
-
case 47: goto
|
690
|
+
case 44: goto st11;
|
691
|
+
case 47: goto st16;
|
692
|
+
case 125: goto tr4;
|
290
693
|
}
|
291
694
|
if ( 9 <= (*p) && (*p) <= 10 )
|
292
695
|
goto st10;
|
@@ -296,139 +699,288 @@ st11:
|
|
296
699
|
goto _test_eof11;
|
297
700
|
case 11:
|
298
701
|
switch( (*p) ) {
|
299
|
-
case
|
300
|
-
case
|
702
|
+
case 13: goto st11;
|
703
|
+
case 32: goto st11;
|
704
|
+
case 34: goto tr2;
|
705
|
+
case 47: goto st12;
|
301
706
|
}
|
707
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
708
|
+
goto st11;
|
302
709
|
goto st0;
|
303
710
|
st12:
|
304
711
|
if ( ++p == pe )
|
305
712
|
goto _test_eof12;
|
306
713
|
case 12:
|
307
|
-
|
308
|
-
goto st13;
|
309
|
-
|
714
|
+
switch( (*p) ) {
|
715
|
+
case 42: goto st13;
|
716
|
+
case 47: goto st15;
|
717
|
+
}
|
718
|
+
goto st0;
|
310
719
|
st13:
|
311
720
|
if ( ++p == pe )
|
312
721
|
goto _test_eof13;
|
313
722
|
case 13:
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
}
|
318
|
-
goto st12;
|
723
|
+
if ( (*p) == 42 )
|
724
|
+
goto st14;
|
725
|
+
goto st13;
|
319
726
|
st14:
|
320
727
|
if ( ++p == pe )
|
321
728
|
goto _test_eof14;
|
322
729
|
case 14:
|
323
|
-
|
324
|
-
goto
|
325
|
-
|
730
|
+
switch( (*p) ) {
|
731
|
+
case 42: goto st14;
|
732
|
+
case 47: goto st11;
|
733
|
+
}
|
734
|
+
goto st13;
|
326
735
|
st15:
|
327
736
|
if ( ++p == pe )
|
328
737
|
goto _test_eof15;
|
329
738
|
case 15:
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
}
|
334
|
-
goto st0;
|
739
|
+
if ( (*p) == 10 )
|
740
|
+
goto st11;
|
741
|
+
goto st15;
|
335
742
|
st16:
|
336
743
|
if ( ++p == pe )
|
337
744
|
goto _test_eof16;
|
338
745
|
case 16:
|
339
|
-
|
340
|
-
goto st17;
|
341
|
-
|
746
|
+
switch( (*p) ) {
|
747
|
+
case 42: goto st17;
|
748
|
+
case 47: goto st19;
|
749
|
+
}
|
750
|
+
goto st0;
|
342
751
|
st17:
|
343
752
|
if ( ++p == pe )
|
344
753
|
goto _test_eof17;
|
345
754
|
case 17:
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
}
|
350
|
-
goto st16;
|
755
|
+
if ( (*p) == 42 )
|
756
|
+
goto st18;
|
757
|
+
goto st17;
|
351
758
|
st18:
|
352
759
|
if ( ++p == pe )
|
353
760
|
goto _test_eof18;
|
354
761
|
case 18:
|
355
|
-
|
356
|
-
goto
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
{ p--; {p++; cs = 27; goto _out;} }
|
361
|
-
goto st27;
|
362
|
-
st27:
|
363
|
-
if ( ++p == pe )
|
364
|
-
goto _test_eof27;
|
365
|
-
case 27:
|
366
|
-
#line 367 "parser.c"
|
367
|
-
goto st0;
|
762
|
+
switch( (*p) ) {
|
763
|
+
case 42: goto st18;
|
764
|
+
case 47: goto st10;
|
765
|
+
}
|
766
|
+
goto st17;
|
368
767
|
st19:
|
369
768
|
if ( ++p == pe )
|
370
769
|
goto _test_eof19;
|
371
770
|
case 19:
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
}
|
376
|
-
goto st0;
|
771
|
+
if ( (*p) == 10 )
|
772
|
+
goto st10;
|
773
|
+
goto st19;
|
377
774
|
st20:
|
378
775
|
if ( ++p == pe )
|
379
776
|
goto _test_eof20;
|
380
777
|
case 20:
|
381
|
-
|
382
|
-
|
383
|
-
|
778
|
+
_widec = (*p);
|
779
|
+
if ( (*p) > 42 ) {
|
780
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
781
|
+
_widec = (short)(128 + ((*p) - -128));
|
782
|
+
if (
|
783
|
+
#line 492 "parser.rl"
|
784
|
+
json->allow_trailing_comma ) _widec += 256;
|
785
|
+
}
|
786
|
+
} else if ( (*p) >= 42 ) {
|
787
|
+
_widec = (short)(128 + ((*p) - -128));
|
788
|
+
if (
|
789
|
+
#line 492 "parser.rl"
|
790
|
+
json->allow_trailing_comma ) _widec += 256;
|
791
|
+
}
|
792
|
+
switch( _widec ) {
|
793
|
+
case 298: goto st17;
|
794
|
+
case 303: goto st19;
|
795
|
+
case 554: goto st21;
|
796
|
+
case 559: goto st23;
|
797
|
+
}
|
798
|
+
goto st0;
|
384
799
|
st21:
|
385
800
|
if ( ++p == pe )
|
386
801
|
goto _test_eof21;
|
387
802
|
case 21:
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
803
|
+
_widec = (*p);
|
804
|
+
if ( (*p) < 42 ) {
|
805
|
+
if ( (*p) <= 41 ) {
|
806
|
+
_widec = (short)(128 + ((*p) - -128));
|
807
|
+
if (
|
808
|
+
#line 492 "parser.rl"
|
809
|
+
json->allow_trailing_comma ) _widec += 256;
|
810
|
+
}
|
811
|
+
} else if ( (*p) > 42 ) {
|
812
|
+
if ( 43 <= (*p) )
|
813
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
814
|
+
if (
|
815
|
+
#line 492 "parser.rl"
|
816
|
+
json->allow_trailing_comma ) _widec += 256;
|
817
|
+
}
|
818
|
+
} else {
|
819
|
+
_widec = (short)(128 + ((*p) - -128));
|
820
|
+
if (
|
821
|
+
#line 492 "parser.rl"
|
822
|
+
json->allow_trailing_comma ) _widec += 256;
|
823
|
+
}
|
824
|
+
switch( _widec ) {
|
825
|
+
case 298: goto st18;
|
826
|
+
case 554: goto st22;
|
827
|
+
}
|
828
|
+
if ( _widec > 383 ) {
|
829
|
+
if ( 384 <= _widec && _widec <= 639 )
|
830
|
+
goto st21;
|
831
|
+
} else if ( _widec >= 128 )
|
832
|
+
goto st17;
|
833
|
+
goto st0;
|
393
834
|
st22:
|
394
835
|
if ( ++p == pe )
|
395
836
|
goto _test_eof22;
|
396
837
|
case 22:
|
397
|
-
|
398
|
-
|
399
|
-
|
838
|
+
_widec = (*p);
|
839
|
+
if ( (*p) < 43 ) {
|
840
|
+
if ( (*p) > 41 ) {
|
841
|
+
if ( 42 <= (*p) && (*p) <= 42 ) {
|
842
|
+
_widec = (short)(128 + ((*p) - -128));
|
843
|
+
if (
|
844
|
+
#line 492 "parser.rl"
|
845
|
+
json->allow_trailing_comma ) _widec += 256;
|
846
|
+
}
|
847
|
+
} else {
|
848
|
+
_widec = (short)(128 + ((*p) - -128));
|
849
|
+
if (
|
850
|
+
#line 492 "parser.rl"
|
851
|
+
json->allow_trailing_comma ) _widec += 256;
|
852
|
+
}
|
853
|
+
} else if ( (*p) > 46 ) {
|
854
|
+
if ( (*p) > 47 ) {
|
855
|
+
if ( 48 <= (*p) )
|
856
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
857
|
+
if (
|
858
|
+
#line 492 "parser.rl"
|
859
|
+
json->allow_trailing_comma ) _widec += 256;
|
860
|
+
}
|
861
|
+
} else if ( (*p) >= 47 ) {
|
862
|
+
_widec = (short)(128 + ((*p) - -128));
|
863
|
+
if (
|
864
|
+
#line 492 "parser.rl"
|
865
|
+
json->allow_trailing_comma ) _widec += 256;
|
866
|
+
}
|
867
|
+
} else {
|
868
|
+
_widec = (short)(128 + ((*p) - -128));
|
869
|
+
if (
|
870
|
+
#line 492 "parser.rl"
|
871
|
+
json->allow_trailing_comma ) _widec += 256;
|
872
|
+
}
|
873
|
+
switch( _widec ) {
|
874
|
+
case 298: goto st18;
|
875
|
+
case 303: goto st10;
|
876
|
+
case 554: goto st22;
|
877
|
+
case 559: goto st9;
|
878
|
+
}
|
879
|
+
if ( _widec > 383 ) {
|
880
|
+
if ( 384 <= _widec && _widec <= 639 )
|
881
|
+
goto st21;
|
882
|
+
} else if ( _widec >= 128 )
|
883
|
+
goto st17;
|
884
|
+
goto st0;
|
400
885
|
st23:
|
401
886
|
if ( ++p == pe )
|
402
887
|
goto _test_eof23;
|
403
888
|
case 23:
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
889
|
+
_widec = (*p);
|
890
|
+
if ( (*p) < 10 ) {
|
891
|
+
if ( (*p) <= 9 ) {
|
892
|
+
_widec = (short)(128 + ((*p) - -128));
|
893
|
+
if (
|
894
|
+
#line 492 "parser.rl"
|
895
|
+
json->allow_trailing_comma ) _widec += 256;
|
896
|
+
}
|
897
|
+
} else if ( (*p) > 10 ) {
|
898
|
+
if ( 11 <= (*p) )
|
899
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
900
|
+
if (
|
901
|
+
#line 492 "parser.rl"
|
902
|
+
json->allow_trailing_comma ) _widec += 256;
|
903
|
+
}
|
904
|
+
} else {
|
905
|
+
_widec = (short)(128 + ((*p) - -128));
|
906
|
+
if (
|
907
|
+
#line 492 "parser.rl"
|
908
|
+
json->allow_trailing_comma ) _widec += 256;
|
909
|
+
}
|
910
|
+
switch( _widec ) {
|
911
|
+
case 266: goto st10;
|
912
|
+
case 522: goto st9;
|
913
|
+
}
|
914
|
+
if ( _widec > 383 ) {
|
915
|
+
if ( 384 <= _widec && _widec <= 639 )
|
916
|
+
goto st23;
|
917
|
+
} else if ( _widec >= 128 )
|
918
|
+
goto st19;
|
408
919
|
goto st0;
|
409
920
|
st24:
|
410
921
|
if ( ++p == pe )
|
411
922
|
goto _test_eof24;
|
412
923
|
case 24:
|
413
|
-
|
414
|
-
goto st25;
|
415
|
-
|
924
|
+
switch( (*p) ) {
|
925
|
+
case 42: goto st25;
|
926
|
+
case 47: goto st27;
|
927
|
+
}
|
928
|
+
goto st0;
|
416
929
|
st25:
|
417
930
|
if ( ++p == pe )
|
418
931
|
goto _test_eof25;
|
419
932
|
case 25:
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
}
|
424
|
-
goto st24;
|
933
|
+
if ( (*p) == 42 )
|
934
|
+
goto st26;
|
935
|
+
goto st25;
|
425
936
|
st26:
|
426
937
|
if ( ++p == pe )
|
427
938
|
goto _test_eof26;
|
428
939
|
case 26:
|
940
|
+
switch( (*p) ) {
|
941
|
+
case 42: goto st26;
|
942
|
+
case 47: goto st8;
|
943
|
+
}
|
944
|
+
goto st25;
|
945
|
+
st27:
|
946
|
+
if ( ++p == pe )
|
947
|
+
goto _test_eof27;
|
948
|
+
case 27:
|
949
|
+
if ( (*p) == 10 )
|
950
|
+
goto st8;
|
951
|
+
goto st27;
|
952
|
+
st28:
|
953
|
+
if ( ++p == pe )
|
954
|
+
goto _test_eof28;
|
955
|
+
case 28:
|
956
|
+
switch( (*p) ) {
|
957
|
+
case 42: goto st29;
|
958
|
+
case 47: goto st31;
|
959
|
+
}
|
960
|
+
goto st0;
|
961
|
+
st29:
|
962
|
+
if ( ++p == pe )
|
963
|
+
goto _test_eof29;
|
964
|
+
case 29:
|
965
|
+
if ( (*p) == 42 )
|
966
|
+
goto st30;
|
967
|
+
goto st29;
|
968
|
+
st30:
|
969
|
+
if ( ++p == pe )
|
970
|
+
goto _test_eof30;
|
971
|
+
case 30:
|
972
|
+
switch( (*p) ) {
|
973
|
+
case 42: goto st30;
|
974
|
+
case 47: goto st2;
|
975
|
+
}
|
976
|
+
goto st29;
|
977
|
+
st31:
|
978
|
+
if ( ++p == pe )
|
979
|
+
goto _test_eof31;
|
980
|
+
case 31:
|
429
981
|
if ( (*p) == 10 )
|
430
982
|
goto st2;
|
431
|
-
goto
|
983
|
+
goto st31;
|
432
984
|
}
|
433
985
|
_test_eof2: cs = 2; goto _test_eof;
|
434
986
|
_test_eof3: cs = 3; goto _test_eof;
|
@@ -438,6 +990,7 @@ case 26:
|
|
438
990
|
_test_eof7: cs = 7; goto _test_eof;
|
439
991
|
_test_eof8: cs = 8; goto _test_eof;
|
440
992
|
_test_eof9: cs = 9; goto _test_eof;
|
993
|
+
_test_eof32: cs = 32; goto _test_eof;
|
441
994
|
_test_eof10: cs = 10; goto _test_eof;
|
442
995
|
_test_eof11: cs = 11; goto _test_eof;
|
443
996
|
_test_eof12: cs = 12; goto _test_eof;
|
@@ -447,7 +1000,6 @@ case 26:
|
|
447
1000
|
_test_eof16: cs = 16; goto _test_eof;
|
448
1001
|
_test_eof17: cs = 17; goto _test_eof;
|
449
1002
|
_test_eof18: cs = 18; goto _test_eof;
|
450
|
-
_test_eof27: cs = 27; goto _test_eof;
|
451
1003
|
_test_eof19: cs = 19; goto _test_eof;
|
452
1004
|
_test_eof20: cs = 20; goto _test_eof;
|
453
1005
|
_test_eof21: cs = 21; goto _test_eof;
|
@@ -456,24 +1008,56 @@ case 26:
|
|
456
1008
|
_test_eof24: cs = 24; goto _test_eof;
|
457
1009
|
_test_eof25: cs = 25; goto _test_eof;
|
458
1010
|
_test_eof26: cs = 26; goto _test_eof;
|
1011
|
+
_test_eof27: cs = 27; goto _test_eof;
|
1012
|
+
_test_eof28: cs = 28; goto _test_eof;
|
1013
|
+
_test_eof29: cs = 29; goto _test_eof;
|
1014
|
+
_test_eof30: cs = 30; goto _test_eof;
|
1015
|
+
_test_eof31: cs = 31; goto _test_eof;
|
459
1016
|
|
460
1017
|
_test_eof: {}
|
461
1018
|
_out: {}
|
462
1019
|
}
|
463
1020
|
|
464
|
-
#line
|
1021
|
+
#line 531 "parser.rl"
|
465
1022
|
|
466
1023
|
if (cs >= JSON_object_first_final) {
|
467
|
-
|
1024
|
+
long count = json->stack->head - stack_head;
|
1025
|
+
|
1026
|
+
if (RB_UNLIKELY(json->object_class)) {
|
1027
|
+
VALUE object = rb_class_new_instance(0, 0, json->object_class);
|
1028
|
+
long index = 0;
|
1029
|
+
VALUE *items = rvalue_stack_peek(json->stack, count);
|
1030
|
+
while (index < count) {
|
1031
|
+
VALUE name = items[index++];
|
1032
|
+
VALUE value = items[index++];
|
1033
|
+
rb_funcall(object, i_aset, 2, name, value);
|
1034
|
+
}
|
1035
|
+
*result = object;
|
1036
|
+
} else {
|
1037
|
+
VALUE hash;
|
1038
|
+
#ifdef HAVE_RB_HASH_NEW_CAPA
|
1039
|
+
hash = rb_hash_new_capa(count >> 1);
|
1040
|
+
#else
|
1041
|
+
hash = rb_hash_new();
|
1042
|
+
#endif
|
1043
|
+
rb_hash_bulk_insert(count, rvalue_stack_peek(json->stack, count), hash);
|
1044
|
+
*result = hash;
|
1045
|
+
}
|
1046
|
+
rvalue_stack_pop(json->stack, count);
|
1047
|
+
|
1048
|
+
if (RB_UNLIKELY(json->create_additions)) {
|
468
1049
|
VALUE klassname;
|
469
|
-
if (
|
470
|
-
|
1050
|
+
if (json->object_class) {
|
1051
|
+
klassname = rb_funcall(*result, i_aref, 1, json->create_id);
|
471
1052
|
} else {
|
472
|
-
|
1053
|
+
klassname = rb_hash_aref(*result, json->create_id);
|
473
1054
|
}
|
474
1055
|
if (!NIL_P(klassname)) {
|
475
1056
|
VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
|
476
1057
|
if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
|
1058
|
+
if (json->deprecated_create_additions) {
|
1059
|
+
json_deprecated(deprecated_create_additions_warning);
|
1060
|
+
}
|
477
1061
|
*result = rb_funcall(klass, i_json_create, 1, *result);
|
478
1062
|
}
|
479
1063
|
}
|
@@ -485,8 +1069,7 @@ case 26:
|
|
485
1069
|
}
|
486
1070
|
|
487
1071
|
|
488
|
-
|
489
|
-
#line 490 "parser.c"
|
1072
|
+
#line 1073 "parser.c"
|
490
1073
|
enum {JSON_value_start = 1};
|
491
1074
|
enum {JSON_value_first_final = 29};
|
492
1075
|
enum {JSON_value_error = 0};
|
@@ -494,7 +1077,7 @@ enum {JSON_value_error = 0};
|
|
494
1077
|
enum {JSON_value_en_main = 1};
|
495
1078
|
|
496
1079
|
|
497
|
-
#line
|
1080
|
+
#line 666 "parser.rl"
|
498
1081
|
|
499
1082
|
|
500
1083
|
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -502,14 +1085,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
502
1085
|
int cs = EVIL;
|
503
1086
|
|
504
1087
|
|
505
|
-
#line
|
1088
|
+
#line 1089 "parser.c"
|
506
1089
|
{
|
507
1090
|
cs = JSON_value_start;
|
508
1091
|
}
|
509
1092
|
|
510
|
-
#line
|
1093
|
+
#line 673 "parser.rl"
|
511
1094
|
|
512
|
-
#line
|
1095
|
+
#line 1096 "parser.c"
|
513
1096
|
{
|
514
1097
|
if ( p == pe )
|
515
1098
|
goto _test_eof;
|
@@ -543,14 +1126,19 @@ st0:
|
|
543
1126
|
cs = 0;
|
544
1127
|
goto _out;
|
545
1128
|
tr2:
|
546
|
-
#line
|
1129
|
+
#line 609 "parser.rl"
|
547
1130
|
{
|
548
1131
|
char *np = JSON_parse_string(json, p, pe, result);
|
549
|
-
if (np == NULL) {
|
1132
|
+
if (np == NULL) {
|
1133
|
+
p--;
|
1134
|
+
{p++; cs = 29; goto _out;}
|
1135
|
+
} else {
|
1136
|
+
{p = (( np))-1;}
|
1137
|
+
}
|
550
1138
|
}
|
551
1139
|
goto st29;
|
552
1140
|
tr3:
|
553
|
-
#line
|
1141
|
+
#line 619 "parser.rl"
|
554
1142
|
{
|
555
1143
|
char *np;
|
556
1144
|
if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
|
@@ -563,14 +1151,18 @@ tr3:
|
|
563
1151
|
}
|
564
1152
|
}
|
565
1153
|
np = JSON_parse_float(json, p, pe, result);
|
566
|
-
if (np != NULL) {
|
1154
|
+
if (np != NULL) {
|
1155
|
+
{p = (( np))-1;}
|
1156
|
+
}
|
567
1157
|
np = JSON_parse_integer(json, p, pe, result);
|
568
|
-
if (np != NULL) {
|
1158
|
+
if (np != NULL) {
|
1159
|
+
{p = (( np))-1;}
|
1160
|
+
}
|
569
1161
|
p--; {p++; cs = 29; goto _out;}
|
570
1162
|
}
|
571
1163
|
goto st29;
|
572
1164
|
tr7:
|
573
|
-
#line
|
1165
|
+
#line 641 "parser.rl"
|
574
1166
|
{
|
575
1167
|
char *np;
|
576
1168
|
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
|
@@ -578,7 +1170,7 @@ tr7:
|
|
578
1170
|
}
|
579
1171
|
goto st29;
|
580
1172
|
tr11:
|
581
|
-
#line
|
1173
|
+
#line 647 "parser.rl"
|
582
1174
|
{
|
583
1175
|
char *np;
|
584
1176
|
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
|
@@ -586,7 +1178,7 @@ tr11:
|
|
586
1178
|
}
|
587
1179
|
goto st29;
|
588
1180
|
tr25:
|
589
|
-
#line
|
1181
|
+
#line 602 "parser.rl"
|
590
1182
|
{
|
591
1183
|
if (json->allow_nan) {
|
592
1184
|
*result = CInfinity;
|
@@ -596,7 +1188,7 @@ tr25:
|
|
596
1188
|
}
|
597
1189
|
goto st29;
|
598
1190
|
tr27:
|
599
|
-
#line
|
1191
|
+
#line 595 "parser.rl"
|
600
1192
|
{
|
601
1193
|
if (json->allow_nan) {
|
602
1194
|
*result = CNaN;
|
@@ -606,19 +1198,19 @@ tr27:
|
|
606
1198
|
}
|
607
1199
|
goto st29;
|
608
1200
|
tr31:
|
609
|
-
#line
|
1201
|
+
#line 589 "parser.rl"
|
610
1202
|
{
|
611
1203
|
*result = Qfalse;
|
612
1204
|
}
|
613
1205
|
goto st29;
|
614
1206
|
tr34:
|
615
|
-
#line
|
1207
|
+
#line 586 "parser.rl"
|
616
1208
|
{
|
617
1209
|
*result = Qnil;
|
618
1210
|
}
|
619
1211
|
goto st29;
|
620
1212
|
tr37:
|
621
|
-
#line
|
1213
|
+
#line 592 "parser.rl"
|
622
1214
|
{
|
623
1215
|
*result = Qtrue;
|
624
1216
|
}
|
@@ -627,9 +1219,9 @@ st29:
|
|
627
1219
|
if ( ++p == pe )
|
628
1220
|
goto _test_eof29;
|
629
1221
|
case 29:
|
630
|
-
#line
|
1222
|
+
#line 653 "parser.rl"
|
631
1223
|
{ p--; {p++; cs = 29; goto _out;} }
|
632
|
-
#line
|
1224
|
+
#line 1225 "parser.c"
|
633
1225
|
switch( (*p) ) {
|
634
1226
|
case 13: goto st29;
|
635
1227
|
case 32: goto st29;
|
@@ -870,13 +1462,14 @@ case 28:
|
|
870
1462
|
_out: {}
|
871
1463
|
}
|
872
1464
|
|
873
|
-
#line
|
1465
|
+
#line 674 "parser.rl"
|
874
1466
|
|
875
1467
|
if (json->freeze) {
|
876
1468
|
OBJ_FREEZE(*result);
|
877
1469
|
}
|
878
1470
|
|
879
1471
|
if (cs >= JSON_value_first_final) {
|
1472
|
+
PUSH(*result);
|
880
1473
|
return p;
|
881
1474
|
} else {
|
882
1475
|
return NULL;
|
@@ -884,7 +1477,7 @@ case 28:
|
|
884
1477
|
}
|
885
1478
|
|
886
1479
|
|
887
|
-
#line
|
1480
|
+
#line 1481 "parser.c"
|
888
1481
|
enum {JSON_integer_start = 1};
|
889
1482
|
enum {JSON_integer_first_final = 3};
|
890
1483
|
enum {JSON_integer_error = 0};
|
@@ -892,23 +1485,45 @@ enum {JSON_integer_error = 0};
|
|
892
1485
|
enum {JSON_integer_en_main = 1};
|
893
1486
|
|
894
1487
|
|
895
|
-
#line
|
1488
|
+
#line 695 "parser.rl"
|
896
1489
|
|
897
1490
|
|
1491
|
+
#define MAX_FAST_INTEGER_SIZE 18
|
1492
|
+
static inline VALUE fast_parse_integer(char *p, char *pe)
|
1493
|
+
{
|
1494
|
+
bool negative = false;
|
1495
|
+
if (*p == '-') {
|
1496
|
+
negative = true;
|
1497
|
+
p++;
|
1498
|
+
}
|
1499
|
+
|
1500
|
+
long long memo = 0;
|
1501
|
+
while (p < pe) {
|
1502
|
+
memo *= 10;
|
1503
|
+
memo += *p - '0';
|
1504
|
+
p++;
|
1505
|
+
}
|
1506
|
+
|
1507
|
+
if (negative) {
|
1508
|
+
memo = -memo;
|
1509
|
+
}
|
1510
|
+
return LL2NUM(memo);
|
1511
|
+
}
|
1512
|
+
|
898
1513
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
899
1514
|
{
|
900
1515
|
int cs = EVIL;
|
901
1516
|
|
902
1517
|
|
903
|
-
#line
|
1518
|
+
#line 1519 "parser.c"
|
904
1519
|
{
|
905
1520
|
cs = JSON_integer_start;
|
906
1521
|
}
|
907
1522
|
|
908
|
-
#line
|
1523
|
+
#line 724 "parser.rl"
|
909
1524
|
json->memo = p;
|
910
1525
|
|
911
|
-
#line
|
1526
|
+
#line 1527 "parser.c"
|
912
1527
|
{
|
913
1528
|
if ( p == pe )
|
914
1529
|
goto _test_eof;
|
@@ -942,14 +1557,14 @@ case 3:
|
|
942
1557
|
goto st0;
|
943
1558
|
goto tr4;
|
944
1559
|
tr4:
|
945
|
-
#line
|
1560
|
+
#line 692 "parser.rl"
|
946
1561
|
{ p--; {p++; cs = 4; goto _out;} }
|
947
1562
|
goto st4;
|
948
1563
|
st4:
|
949
1564
|
if ( ++p == pe )
|
950
1565
|
goto _test_eof4;
|
951
1566
|
case 4:
|
952
|
-
#line
|
1567
|
+
#line 1568 "parser.c"
|
953
1568
|
goto st0;
|
954
1569
|
st5:
|
955
1570
|
if ( ++p == pe )
|
@@ -968,14 +1583,18 @@ case 5:
|
|
968
1583
|
_out: {}
|
969
1584
|
}
|
970
1585
|
|
971
|
-
#line
|
1586
|
+
#line 726 "parser.rl"
|
972
1587
|
|
973
1588
|
if (cs >= JSON_integer_first_final) {
|
974
1589
|
long len = p - json->memo;
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
1590
|
+
if (RB_LIKELY(len < MAX_FAST_INTEGER_SIZE)) {
|
1591
|
+
*result = fast_parse_integer(json->memo, p);
|
1592
|
+
} else {
|
1593
|
+
fbuffer_clear(&json->fbuffer);
|
1594
|
+
fbuffer_append(&json->fbuffer, json->memo, len);
|
1595
|
+
fbuffer_append_char(&json->fbuffer, '\0');
|
1596
|
+
*result = rb_cstr2inum(FBUFFER_PTR(&json->fbuffer), 10);
|
1597
|
+
}
|
979
1598
|
return p + 1;
|
980
1599
|
} else {
|
981
1600
|
return NULL;
|
@@ -983,7 +1602,7 @@ case 5:
|
|
983
1602
|
}
|
984
1603
|
|
985
1604
|
|
986
|
-
#line
|
1605
|
+
#line 1606 "parser.c"
|
987
1606
|
enum {JSON_float_start = 1};
|
988
1607
|
enum {JSON_float_first_final = 8};
|
989
1608
|
enum {JSON_float_error = 0};
|
@@ -991,7 +1610,7 @@ enum {JSON_float_error = 0};
|
|
991
1610
|
enum {JSON_float_en_main = 1};
|
992
1611
|
|
993
1612
|
|
994
|
-
#line
|
1613
|
+
#line 755 "parser.rl"
|
995
1614
|
|
996
1615
|
|
997
1616
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -999,15 +1618,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
999
1618
|
int cs = EVIL;
|
1000
1619
|
|
1001
1620
|
|
1002
|
-
#line
|
1621
|
+
#line 1622 "parser.c"
|
1003
1622
|
{
|
1004
1623
|
cs = JSON_float_start;
|
1005
1624
|
}
|
1006
1625
|
|
1007
|
-
#line
|
1626
|
+
#line 762 "parser.rl"
|
1008
1627
|
json->memo = p;
|
1009
1628
|
|
1010
|
-
#line
|
1629
|
+
#line 1630 "parser.c"
|
1011
1630
|
{
|
1012
1631
|
if ( p == pe )
|
1013
1632
|
goto _test_eof;
|
@@ -1065,14 +1684,14 @@ case 8:
|
|
1065
1684
|
goto st0;
|
1066
1685
|
goto tr9;
|
1067
1686
|
tr9:
|
1068
|
-
#line
|
1687
|
+
#line 749 "parser.rl"
|
1069
1688
|
{ p--; {p++; cs = 9; goto _out;} }
|
1070
1689
|
goto st9;
|
1071
1690
|
st9:
|
1072
1691
|
if ( ++p == pe )
|
1073
1692
|
goto _test_eof9;
|
1074
1693
|
case 9:
|
1075
|
-
#line
|
1694
|
+
#line 1695 "parser.c"
|
1076
1695
|
goto st0;
|
1077
1696
|
st5:
|
1078
1697
|
if ( ++p == pe )
|
@@ -1133,12 +1752,12 @@ case 7:
|
|
1133
1752
|
_out: {}
|
1134
1753
|
}
|
1135
1754
|
|
1136
|
-
#line
|
1755
|
+
#line 764 "parser.rl"
|
1137
1756
|
|
1138
1757
|
if (cs >= JSON_float_first_final) {
|
1139
1758
|
VALUE mod = Qnil;
|
1140
1759
|
ID method_id = 0;
|
1141
|
-
if (
|
1760
|
+
if (json->decimal_class) {
|
1142
1761
|
if (rb_respond_to(json->decimal_class, i_try_convert)) {
|
1143
1762
|
mod = json->decimal_class;
|
1144
1763
|
method_id = i_try_convert;
|
@@ -1167,15 +1786,15 @@ case 7:
|
|
1167
1786
|
}
|
1168
1787
|
|
1169
1788
|
long len = p - json->memo;
|
1170
|
-
fbuffer_clear(json->fbuffer);
|
1171
|
-
fbuffer_append(json->fbuffer, json->memo, len);
|
1172
|
-
fbuffer_append_char(json->fbuffer, '\0');
|
1789
|
+
fbuffer_clear(&json->fbuffer);
|
1790
|
+
fbuffer_append(&json->fbuffer, json->memo, len);
|
1791
|
+
fbuffer_append_char(&json->fbuffer, '\0');
|
1173
1792
|
|
1174
1793
|
if (method_id) {
|
1175
|
-
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
1794
|
+
VALUE text = rb_str_new2(FBUFFER_PTR(&json->fbuffer));
|
1176
1795
|
*result = rb_funcallv(mod, method_id, 1, &text);
|
1177
1796
|
} else {
|
1178
|
-
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
1797
|
+
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(&json->fbuffer), 1));
|
1179
1798
|
}
|
1180
1799
|
|
1181
1800
|
return p + 1;
|
@@ -1186,37 +1805,37 @@ case 7:
|
|
1186
1805
|
|
1187
1806
|
|
1188
1807
|
|
1189
|
-
#line
|
1808
|
+
#line 1809 "parser.c"
|
1190
1809
|
enum {JSON_array_start = 1};
|
1191
|
-
enum {JSON_array_first_final =
|
1810
|
+
enum {JSON_array_first_final = 22};
|
1192
1811
|
enum {JSON_array_error = 0};
|
1193
1812
|
|
1194
1813
|
enum {JSON_array_en_main = 1};
|
1195
1814
|
|
1196
1815
|
|
1197
|
-
#line
|
1816
|
+
#line 841 "parser.rl"
|
1198
1817
|
|
1199
1818
|
|
1200
1819
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
1201
1820
|
{
|
1202
1821
|
int cs = EVIL;
|
1203
|
-
VALUE array_class = json->array_class;
|
1204
1822
|
|
1205
1823
|
if (json->max_nesting && current_nesting > json->max_nesting) {
|
1206
1824
|
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
1207
1825
|
}
|
1208
|
-
|
1826
|
+
long stack_head = json->stack->head;
|
1209
1827
|
|
1210
1828
|
|
1211
|
-
#line
|
1829
|
+
#line 1830 "parser.c"
|
1212
1830
|
{
|
1213
1831
|
cs = JSON_array_start;
|
1214
1832
|
}
|
1215
1833
|
|
1216
|
-
#line
|
1834
|
+
#line 853 "parser.rl"
|
1217
1835
|
|
1218
|
-
#line
|
1836
|
+
#line 1837 "parser.c"
|
1219
1837
|
{
|
1838
|
+
short _widec;
|
1220
1839
|
if ( p == pe )
|
1221
1840
|
goto _test_eof;
|
1222
1841
|
switch ( cs )
|
@@ -1237,7 +1856,7 @@ case 2:
|
|
1237
1856
|
case 32: goto st2;
|
1238
1857
|
case 34: goto tr2;
|
1239
1858
|
case 45: goto tr2;
|
1240
|
-
case 47: goto
|
1859
|
+
case 47: goto st18;
|
1241
1860
|
case 73: goto tr2;
|
1242
1861
|
case 78: goto tr2;
|
1243
1862
|
case 91: goto tr2;
|
@@ -1254,18 +1873,13 @@ case 2:
|
|
1254
1873
|
goto st2;
|
1255
1874
|
goto st0;
|
1256
1875
|
tr2:
|
1257
|
-
#line
|
1876
|
+
#line 821 "parser.rl"
|
1258
1877
|
{
|
1259
1878
|
VALUE v = Qnil;
|
1260
1879
|
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
1261
1880
|
if (np == NULL) {
|
1262
1881
|
p--; {p++; cs = 3; goto _out;}
|
1263
1882
|
} else {
|
1264
|
-
if (NIL_P(json->array_class)) {
|
1265
|
-
rb_ary_push(*result, v);
|
1266
|
-
} else {
|
1267
|
-
rb_funcall(*result, i_leftshift, 1, v);
|
1268
|
-
}
|
1269
1883
|
{p = (( np))-1;}
|
1270
1884
|
}
|
1271
1885
|
}
|
@@ -1274,15 +1888,23 @@ st3:
|
|
1274
1888
|
if ( ++p == pe )
|
1275
1889
|
goto _test_eof3;
|
1276
1890
|
case 3:
|
1277
|
-
#line
|
1278
|
-
|
1891
|
+
#line 1892 "parser.c"
|
1892
|
+
_widec = (*p);
|
1893
|
+
if ( 44 <= (*p) && (*p) <= 44 ) {
|
1894
|
+
_widec = (short)(128 + ((*p) - -128));
|
1895
|
+
if (
|
1896
|
+
#line 831 "parser.rl"
|
1897
|
+
json->allow_trailing_comma ) _widec += 256;
|
1898
|
+
}
|
1899
|
+
switch( _widec ) {
|
1279
1900
|
case 13: goto st3;
|
1280
1901
|
case 32: goto st3;
|
1281
|
-
case
|
1282
|
-
case 47: goto st9;
|
1902
|
+
case 47: goto st4;
|
1283
1903
|
case 93: goto tr4;
|
1904
|
+
case 300: goto st8;
|
1905
|
+
case 556: goto st13;
|
1284
1906
|
}
|
1285
|
-
if ( 9 <=
|
1907
|
+
if ( 9 <= _widec && _widec <= 10 )
|
1286
1908
|
goto st3;
|
1287
1909
|
goto st0;
|
1288
1910
|
st4:
|
@@ -1290,57 +1912,67 @@ st4:
|
|
1290
1912
|
goto _test_eof4;
|
1291
1913
|
case 4:
|
1292
1914
|
switch( (*p) ) {
|
1293
|
-
case
|
1294
|
-
case
|
1295
|
-
case 34: goto tr2;
|
1296
|
-
case 45: goto tr2;
|
1297
|
-
case 47: goto st5;
|
1298
|
-
case 73: goto tr2;
|
1299
|
-
case 78: goto tr2;
|
1300
|
-
case 91: goto tr2;
|
1301
|
-
case 102: goto tr2;
|
1302
|
-
case 110: goto tr2;
|
1303
|
-
case 116: goto tr2;
|
1304
|
-
case 123: goto tr2;
|
1915
|
+
case 42: goto st5;
|
1916
|
+
case 47: goto st7;
|
1305
1917
|
}
|
1306
|
-
if ( (*p) > 10 ) {
|
1307
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1308
|
-
goto tr2;
|
1309
|
-
} else if ( (*p) >= 9 )
|
1310
|
-
goto st4;
|
1311
1918
|
goto st0;
|
1312
1919
|
st5:
|
1313
1920
|
if ( ++p == pe )
|
1314
1921
|
goto _test_eof5;
|
1315
1922
|
case 5:
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
}
|
1320
|
-
goto st0;
|
1923
|
+
if ( (*p) == 42 )
|
1924
|
+
goto st6;
|
1925
|
+
goto st5;
|
1321
1926
|
st6:
|
1322
1927
|
if ( ++p == pe )
|
1323
1928
|
goto _test_eof6;
|
1324
1929
|
case 6:
|
1325
|
-
|
1326
|
-
goto
|
1327
|
-
|
1930
|
+
switch( (*p) ) {
|
1931
|
+
case 42: goto st6;
|
1932
|
+
case 47: goto st3;
|
1933
|
+
}
|
1934
|
+
goto st5;
|
1328
1935
|
st7:
|
1329
1936
|
if ( ++p == pe )
|
1330
1937
|
goto _test_eof7;
|
1331
1938
|
case 7:
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1939
|
+
if ( (*p) == 10 )
|
1940
|
+
goto st3;
|
1941
|
+
goto st7;
|
1942
|
+
tr4:
|
1943
|
+
#line 833 "parser.rl"
|
1944
|
+
{ p--; {p++; cs = 22; goto _out;} }
|
1945
|
+
goto st22;
|
1946
|
+
st22:
|
1947
|
+
if ( ++p == pe )
|
1948
|
+
goto _test_eof22;
|
1949
|
+
case 22:
|
1950
|
+
#line 1951 "parser.c"
|
1951
|
+
goto st0;
|
1337
1952
|
st8:
|
1338
1953
|
if ( ++p == pe )
|
1339
1954
|
goto _test_eof8;
|
1340
1955
|
case 8:
|
1341
|
-
|
1342
|
-
goto
|
1343
|
-
|
1956
|
+
switch( (*p) ) {
|
1957
|
+
case 13: goto st8;
|
1958
|
+
case 32: goto st8;
|
1959
|
+
case 34: goto tr2;
|
1960
|
+
case 45: goto tr2;
|
1961
|
+
case 47: goto st9;
|
1962
|
+
case 73: goto tr2;
|
1963
|
+
case 78: goto tr2;
|
1964
|
+
case 91: goto tr2;
|
1965
|
+
case 102: goto tr2;
|
1966
|
+
case 110: goto tr2;
|
1967
|
+
case 116: goto tr2;
|
1968
|
+
case 123: goto tr2;
|
1969
|
+
}
|
1970
|
+
if ( (*p) > 10 ) {
|
1971
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1972
|
+
goto tr2;
|
1973
|
+
} else if ( (*p) >= 9 )
|
1974
|
+
goto st8;
|
1975
|
+
goto st0;
|
1344
1976
|
st9:
|
1345
1977
|
if ( ++p == pe )
|
1346
1978
|
goto _test_eof9;
|
@@ -1363,7 +1995,7 @@ st11:
|
|
1363
1995
|
case 11:
|
1364
1996
|
switch( (*p) ) {
|
1365
1997
|
case 42: goto st11;
|
1366
|
-
case 47: goto
|
1998
|
+
case 47: goto st8;
|
1367
1999
|
}
|
1368
2000
|
goto st10;
|
1369
2001
|
st12:
|
@@ -1371,50 +2003,252 @@ st12:
|
|
1371
2003
|
goto _test_eof12;
|
1372
2004
|
case 12:
|
1373
2005
|
if ( (*p) == 10 )
|
1374
|
-
goto
|
2006
|
+
goto st8;
|
1375
2007
|
goto st12;
|
1376
|
-
tr4:
|
1377
|
-
#line 430 "parser.rl"
|
1378
|
-
{ p--; {p++; cs = 17; goto _out;} }
|
1379
|
-
goto st17;
|
1380
|
-
st17:
|
1381
|
-
if ( ++p == pe )
|
1382
|
-
goto _test_eof17;
|
1383
|
-
case 17:
|
1384
|
-
#line 1385 "parser.c"
|
1385
|
-
goto st0;
|
1386
2008
|
st13:
|
1387
2009
|
if ( ++p == pe )
|
1388
2010
|
goto _test_eof13;
|
1389
2011
|
case 13:
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
2012
|
+
_widec = (*p);
|
2013
|
+
if ( (*p) < 13 ) {
|
2014
|
+
if ( (*p) > 9 ) {
|
2015
|
+
if ( 10 <= (*p) && (*p) <= 10 ) {
|
2016
|
+
_widec = (short)(128 + ((*p) - -128));
|
2017
|
+
if (
|
2018
|
+
#line 831 "parser.rl"
|
2019
|
+
json->allow_trailing_comma ) _widec += 256;
|
2020
|
+
}
|
2021
|
+
} else if ( (*p) >= 9 ) {
|
2022
|
+
_widec = (short)(128 + ((*p) - -128));
|
2023
|
+
if (
|
2024
|
+
#line 831 "parser.rl"
|
2025
|
+
json->allow_trailing_comma ) _widec += 256;
|
2026
|
+
}
|
2027
|
+
} else if ( (*p) > 13 ) {
|
2028
|
+
if ( (*p) > 32 ) {
|
2029
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
2030
|
+
_widec = (short)(128 + ((*p) - -128));
|
2031
|
+
if (
|
2032
|
+
#line 831 "parser.rl"
|
2033
|
+
json->allow_trailing_comma ) _widec += 256;
|
2034
|
+
}
|
2035
|
+
} else if ( (*p) >= 32 ) {
|
2036
|
+
_widec = (short)(128 + ((*p) - -128));
|
2037
|
+
if (
|
2038
|
+
#line 831 "parser.rl"
|
2039
|
+
json->allow_trailing_comma ) _widec += 256;
|
2040
|
+
}
|
2041
|
+
} else {
|
2042
|
+
_widec = (short)(128 + ((*p) - -128));
|
2043
|
+
if (
|
2044
|
+
#line 831 "parser.rl"
|
2045
|
+
json->allow_trailing_comma ) _widec += 256;
|
2046
|
+
}
|
2047
|
+
switch( _widec ) {
|
2048
|
+
case 34: goto tr2;
|
2049
|
+
case 45: goto tr2;
|
2050
|
+
case 73: goto tr2;
|
2051
|
+
case 78: goto tr2;
|
2052
|
+
case 91: goto tr2;
|
2053
|
+
case 93: goto tr4;
|
2054
|
+
case 102: goto tr2;
|
2055
|
+
case 110: goto tr2;
|
2056
|
+
case 116: goto tr2;
|
2057
|
+
case 123: goto tr2;
|
2058
|
+
case 269: goto st8;
|
2059
|
+
case 288: goto st8;
|
2060
|
+
case 303: goto st9;
|
2061
|
+
case 525: goto st13;
|
2062
|
+
case 544: goto st13;
|
2063
|
+
case 559: goto st14;
|
2064
|
+
}
|
2065
|
+
if ( _widec < 265 ) {
|
2066
|
+
if ( 48 <= _widec && _widec <= 57 )
|
2067
|
+
goto tr2;
|
2068
|
+
} else if ( _widec > 266 ) {
|
2069
|
+
if ( 521 <= _widec && _widec <= 522 )
|
2070
|
+
goto st13;
|
2071
|
+
} else
|
2072
|
+
goto st8;
|
1394
2073
|
goto st0;
|
1395
2074
|
st14:
|
1396
2075
|
if ( ++p == pe )
|
1397
2076
|
goto _test_eof14;
|
1398
2077
|
case 14:
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
2078
|
+
_widec = (*p);
|
2079
|
+
if ( (*p) > 42 ) {
|
2080
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
2081
|
+
_widec = (short)(128 + ((*p) - -128));
|
2082
|
+
if (
|
2083
|
+
#line 831 "parser.rl"
|
2084
|
+
json->allow_trailing_comma ) _widec += 256;
|
2085
|
+
}
|
2086
|
+
} else if ( (*p) >= 42 ) {
|
2087
|
+
_widec = (short)(128 + ((*p) - -128));
|
2088
|
+
if (
|
2089
|
+
#line 831 "parser.rl"
|
2090
|
+
json->allow_trailing_comma ) _widec += 256;
|
2091
|
+
}
|
2092
|
+
switch( _widec ) {
|
2093
|
+
case 298: goto st10;
|
2094
|
+
case 303: goto st12;
|
2095
|
+
case 554: goto st15;
|
2096
|
+
case 559: goto st17;
|
2097
|
+
}
|
2098
|
+
goto st0;
|
1402
2099
|
st15:
|
1403
2100
|
if ( ++p == pe )
|
1404
2101
|
goto _test_eof15;
|
1405
2102
|
case 15:
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
2103
|
+
_widec = (*p);
|
2104
|
+
if ( (*p) < 42 ) {
|
2105
|
+
if ( (*p) <= 41 ) {
|
2106
|
+
_widec = (short)(128 + ((*p) - -128));
|
2107
|
+
if (
|
2108
|
+
#line 831 "parser.rl"
|
2109
|
+
json->allow_trailing_comma ) _widec += 256;
|
2110
|
+
}
|
2111
|
+
} else if ( (*p) > 42 ) {
|
2112
|
+
if ( 43 <= (*p) )
|
2113
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2114
|
+
if (
|
2115
|
+
#line 831 "parser.rl"
|
2116
|
+
json->allow_trailing_comma ) _widec += 256;
|
2117
|
+
}
|
2118
|
+
} else {
|
2119
|
+
_widec = (short)(128 + ((*p) - -128));
|
2120
|
+
if (
|
2121
|
+
#line 831 "parser.rl"
|
2122
|
+
json->allow_trailing_comma ) _widec += 256;
|
2123
|
+
}
|
2124
|
+
switch( _widec ) {
|
2125
|
+
case 298: goto st11;
|
2126
|
+
case 554: goto st16;
|
2127
|
+
}
|
2128
|
+
if ( _widec > 383 ) {
|
2129
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2130
|
+
goto st15;
|
2131
|
+
} else if ( _widec >= 128 )
|
2132
|
+
goto st10;
|
2133
|
+
goto st0;
|
1411
2134
|
st16:
|
1412
2135
|
if ( ++p == pe )
|
1413
2136
|
goto _test_eof16;
|
1414
2137
|
case 16:
|
2138
|
+
_widec = (*p);
|
2139
|
+
if ( (*p) < 43 ) {
|
2140
|
+
if ( (*p) > 41 ) {
|
2141
|
+
if ( 42 <= (*p) && (*p) <= 42 ) {
|
2142
|
+
_widec = (short)(128 + ((*p) - -128));
|
2143
|
+
if (
|
2144
|
+
#line 831 "parser.rl"
|
2145
|
+
json->allow_trailing_comma ) _widec += 256;
|
2146
|
+
}
|
2147
|
+
} else {
|
2148
|
+
_widec = (short)(128 + ((*p) - -128));
|
2149
|
+
if (
|
2150
|
+
#line 831 "parser.rl"
|
2151
|
+
json->allow_trailing_comma ) _widec += 256;
|
2152
|
+
}
|
2153
|
+
} else if ( (*p) > 46 ) {
|
2154
|
+
if ( (*p) > 47 ) {
|
2155
|
+
if ( 48 <= (*p) )
|
2156
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2157
|
+
if (
|
2158
|
+
#line 831 "parser.rl"
|
2159
|
+
json->allow_trailing_comma ) _widec += 256;
|
2160
|
+
}
|
2161
|
+
} else if ( (*p) >= 47 ) {
|
2162
|
+
_widec = (short)(128 + ((*p) - -128));
|
2163
|
+
if (
|
2164
|
+
#line 831 "parser.rl"
|
2165
|
+
json->allow_trailing_comma ) _widec += 256;
|
2166
|
+
}
|
2167
|
+
} else {
|
2168
|
+
_widec = (short)(128 + ((*p) - -128));
|
2169
|
+
if (
|
2170
|
+
#line 831 "parser.rl"
|
2171
|
+
json->allow_trailing_comma ) _widec += 256;
|
2172
|
+
}
|
2173
|
+
switch( _widec ) {
|
2174
|
+
case 298: goto st11;
|
2175
|
+
case 303: goto st8;
|
2176
|
+
case 554: goto st16;
|
2177
|
+
case 559: goto st13;
|
2178
|
+
}
|
2179
|
+
if ( _widec > 383 ) {
|
2180
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2181
|
+
goto st15;
|
2182
|
+
} else if ( _widec >= 128 )
|
2183
|
+
goto st10;
|
2184
|
+
goto st0;
|
2185
|
+
st17:
|
2186
|
+
if ( ++p == pe )
|
2187
|
+
goto _test_eof17;
|
2188
|
+
case 17:
|
2189
|
+
_widec = (*p);
|
2190
|
+
if ( (*p) < 10 ) {
|
2191
|
+
if ( (*p) <= 9 ) {
|
2192
|
+
_widec = (short)(128 + ((*p) - -128));
|
2193
|
+
if (
|
2194
|
+
#line 831 "parser.rl"
|
2195
|
+
json->allow_trailing_comma ) _widec += 256;
|
2196
|
+
}
|
2197
|
+
} else if ( (*p) > 10 ) {
|
2198
|
+
if ( 11 <= (*p) )
|
2199
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2200
|
+
if (
|
2201
|
+
#line 831 "parser.rl"
|
2202
|
+
json->allow_trailing_comma ) _widec += 256;
|
2203
|
+
}
|
2204
|
+
} else {
|
2205
|
+
_widec = (short)(128 + ((*p) - -128));
|
2206
|
+
if (
|
2207
|
+
#line 831 "parser.rl"
|
2208
|
+
json->allow_trailing_comma ) _widec += 256;
|
2209
|
+
}
|
2210
|
+
switch( _widec ) {
|
2211
|
+
case 266: goto st8;
|
2212
|
+
case 522: goto st13;
|
2213
|
+
}
|
2214
|
+
if ( _widec > 383 ) {
|
2215
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2216
|
+
goto st17;
|
2217
|
+
} else if ( _widec >= 128 )
|
2218
|
+
goto st12;
|
2219
|
+
goto st0;
|
2220
|
+
st18:
|
2221
|
+
if ( ++p == pe )
|
2222
|
+
goto _test_eof18;
|
2223
|
+
case 18:
|
2224
|
+
switch( (*p) ) {
|
2225
|
+
case 42: goto st19;
|
2226
|
+
case 47: goto st21;
|
2227
|
+
}
|
2228
|
+
goto st0;
|
2229
|
+
st19:
|
2230
|
+
if ( ++p == pe )
|
2231
|
+
goto _test_eof19;
|
2232
|
+
case 19:
|
2233
|
+
if ( (*p) == 42 )
|
2234
|
+
goto st20;
|
2235
|
+
goto st19;
|
2236
|
+
st20:
|
2237
|
+
if ( ++p == pe )
|
2238
|
+
goto _test_eof20;
|
2239
|
+
case 20:
|
2240
|
+
switch( (*p) ) {
|
2241
|
+
case 42: goto st20;
|
2242
|
+
case 47: goto st2;
|
2243
|
+
}
|
2244
|
+
goto st19;
|
2245
|
+
st21:
|
2246
|
+
if ( ++p == pe )
|
2247
|
+
goto _test_eof21;
|
2248
|
+
case 21:
|
1415
2249
|
if ( (*p) == 10 )
|
1416
2250
|
goto st2;
|
1417
|
-
goto
|
2251
|
+
goto st21;
|
1418
2252
|
}
|
1419
2253
|
_test_eof2: cs = 2; goto _test_eof;
|
1420
2254
|
_test_eof3: cs = 3; goto _test_eof;
|
@@ -1422,24 +2256,45 @@ case 16:
|
|
1422
2256
|
_test_eof5: cs = 5; goto _test_eof;
|
1423
2257
|
_test_eof6: cs = 6; goto _test_eof;
|
1424
2258
|
_test_eof7: cs = 7; goto _test_eof;
|
2259
|
+
_test_eof22: cs = 22; goto _test_eof;
|
1425
2260
|
_test_eof8: cs = 8; goto _test_eof;
|
1426
2261
|
_test_eof9: cs = 9; goto _test_eof;
|
1427
2262
|
_test_eof10: cs = 10; goto _test_eof;
|
1428
2263
|
_test_eof11: cs = 11; goto _test_eof;
|
1429
2264
|
_test_eof12: cs = 12; goto _test_eof;
|
1430
|
-
_test_eof17: cs = 17; goto _test_eof;
|
1431
2265
|
_test_eof13: cs = 13; goto _test_eof;
|
1432
2266
|
_test_eof14: cs = 14; goto _test_eof;
|
1433
2267
|
_test_eof15: cs = 15; goto _test_eof;
|
1434
2268
|
_test_eof16: cs = 16; goto _test_eof;
|
2269
|
+
_test_eof17: cs = 17; goto _test_eof;
|
2270
|
+
_test_eof18: cs = 18; goto _test_eof;
|
2271
|
+
_test_eof19: cs = 19; goto _test_eof;
|
2272
|
+
_test_eof20: cs = 20; goto _test_eof;
|
2273
|
+
_test_eof21: cs = 21; goto _test_eof;
|
1435
2274
|
|
1436
2275
|
_test_eof: {}
|
1437
2276
|
_out: {}
|
1438
2277
|
}
|
1439
2278
|
|
1440
|
-
#line
|
2279
|
+
#line 854 "parser.rl"
|
1441
2280
|
|
1442
2281
|
if(cs >= JSON_array_first_final) {
|
2282
|
+
long count = json->stack->head - stack_head;
|
2283
|
+
|
2284
|
+
if (RB_UNLIKELY(json->array_class)) {
|
2285
|
+
VALUE array = rb_class_new_instance(0, 0, json->array_class);
|
2286
|
+
VALUE *items = rvalue_stack_peek(json->stack, count);
|
2287
|
+
long index;
|
2288
|
+
for (index = 0; index < count; index++) {
|
2289
|
+
rb_funcall(array, i_leftshift, 1, items[index]);
|
2290
|
+
}
|
2291
|
+
*result = array;
|
2292
|
+
} else {
|
2293
|
+
VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(json->stack, count));
|
2294
|
+
*result = array;
|
2295
|
+
}
|
2296
|
+
rvalue_stack_pop(json->stack, count);
|
2297
|
+
|
1443
2298
|
return p + 1;
|
1444
2299
|
} else {
|
1445
2300
|
raise_parse_error("unexpected token at '%s'", p);
|
@@ -1447,29 +2302,81 @@ case 16:
|
|
1447
2302
|
}
|
1448
2303
|
}
|
1449
2304
|
|
1450
|
-
static const
|
1451
|
-
|
2305
|
+
static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize)
|
2306
|
+
{
|
2307
|
+
if (symbolize) {
|
2308
|
+
intern = true;
|
2309
|
+
}
|
2310
|
+
VALUE result;
|
2311
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
2312
|
+
if (intern) {
|
2313
|
+
result = rb_enc_interned_str(start, (long)(end - start), enc_utf8);
|
2314
|
+
} else {
|
2315
|
+
result = rb_utf8_str_new(start, (long)(end - start));
|
2316
|
+
}
|
2317
|
+
# else
|
2318
|
+
result = rb_utf8_str_new(start, (long)(end - start));
|
2319
|
+
if (intern) {
|
2320
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
2321
|
+
}
|
2322
|
+
# endif
|
2323
|
+
|
2324
|
+
if (symbolize) {
|
2325
|
+
result = rb_str_intern(result);
|
2326
|
+
}
|
2327
|
+
|
2328
|
+
return result;
|
2329
|
+
}
|
2330
|
+
|
2331
|
+
static VALUE json_string_fastpath(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
|
2332
|
+
{
|
2333
|
+
size_t bufferSize = stringEnd - string;
|
2334
|
+
|
2335
|
+
if (is_name) {
|
2336
|
+
VALUE cached_key;
|
2337
|
+
if (RB_UNLIKELY(symbolize)) {
|
2338
|
+
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
|
2339
|
+
} else {
|
2340
|
+
cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
|
2341
|
+
}
|
2342
|
+
|
2343
|
+
if (RB_LIKELY(cached_key)) {
|
2344
|
+
return cached_key;
|
2345
|
+
}
|
2346
|
+
}
|
2347
|
+
|
2348
|
+
return build_string(string, stringEnd, intern, symbolize);
|
2349
|
+
}
|
2350
|
+
|
2351
|
+
static VALUE json_string_unescape(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
|
1452
2352
|
{
|
1453
|
-
VALUE result = Qnil;
|
1454
2353
|
size_t bufferSize = stringEnd - string;
|
1455
2354
|
char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
|
1456
2355
|
int unescape_len;
|
1457
2356
|
char buf[4];
|
1458
2357
|
|
1459
|
-
if (
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
2358
|
+
if (is_name) {
|
2359
|
+
VALUE cached_key;
|
2360
|
+
if (RB_UNLIKELY(symbolize)) {
|
2361
|
+
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
|
2362
|
+
} else {
|
2363
|
+
cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
|
2364
|
+
}
|
2365
|
+
|
2366
|
+
if (RB_LIKELY(cached_key)) {
|
2367
|
+
return cached_key;
|
2368
|
+
}
|
2369
|
+
}
|
2370
|
+
|
2371
|
+
pe = memchr(p, '\\', bufferSize);
|
2372
|
+
if (RB_UNLIKELY(pe == NULL)) {
|
2373
|
+
return build_string(string, stringEnd, intern, symbolize);
|
1471
2374
|
}
|
1472
2375
|
|
2376
|
+
VALUE result = rb_str_buf_new(bufferSize);
|
2377
|
+
rb_enc_associate_index(result, utf8_encindex);
|
2378
|
+
buffer = bufferStart = RSTRING_PTR(result);
|
2379
|
+
|
1473
2380
|
while (pe < stringEnd) {
|
1474
2381
|
if (*pe == '\\') {
|
1475
2382
|
unescape = (char *) "?";
|
@@ -1502,9 +2409,6 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1502
2409
|
break;
|
1503
2410
|
case 'u':
|
1504
2411
|
if (pe > stringEnd - 4) {
|
1505
|
-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
1506
|
-
ruby_xfree(bufferStart);
|
1507
|
-
}
|
1508
2412
|
raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
|
1509
2413
|
} else {
|
1510
2414
|
uint32_t ch = unescape_unicode((unsigned char *) ++pe);
|
@@ -1522,9 +2426,6 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1522
2426
|
if ((ch & 0xFC00) == 0xD800) {
|
1523
2427
|
pe++;
|
1524
2428
|
if (pe > stringEnd - 6) {
|
1525
|
-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
1526
|
-
ruby_xfree(bufferStart);
|
1527
|
-
}
|
1528
2429
|
raise_parse_error("incomplete surrogate pair at '%s'", p);
|
1529
2430
|
}
|
1530
2431
|
if (pe[0] == '\\' && pe[1] == 'u') {
|
@@ -1557,56 +2458,27 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1557
2458
|
MEMCPY(buffer, p, char, pe - p);
|
1558
2459
|
buffer += pe - p;
|
1559
2460
|
}
|
1560
|
-
|
1561
|
-
# ifdef HAVE_RB_ENC_INTERNED_STR
|
1562
|
-
if (intern) {
|
1563
|
-
result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
|
1564
|
-
} else {
|
1565
|
-
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
|
1566
|
-
}
|
1567
|
-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
1568
|
-
ruby_xfree(bufferStart);
|
1569
|
-
}
|
1570
|
-
# else
|
1571
|
-
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
|
1572
|
-
|
1573
|
-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
1574
|
-
ruby_xfree(bufferStart);
|
1575
|
-
}
|
1576
|
-
|
1577
|
-
if (intern) {
|
1578
|
-
# if STR_UMINUS_DEDUPE_FROZEN
|
1579
|
-
// Starting from MRI 2.8 it is preferable to freeze the string
|
1580
|
-
// before deduplication so that it can be interned directly
|
1581
|
-
// otherwise it would be duplicated first which is wasteful.
|
1582
|
-
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
1583
|
-
# elif STR_UMINUS_DEDUPE
|
1584
|
-
// MRI 2.5 and older do not deduplicate strings that are already
|
1585
|
-
// frozen.
|
1586
|
-
result = rb_funcall(result, i_uminus, 0);
|
1587
|
-
# else
|
1588
|
-
result = rb_str_freeze(result);
|
1589
|
-
# endif
|
1590
|
-
}
|
1591
|
-
# endif
|
2461
|
+
rb_str_set_len(result, buffer - bufferStart);
|
1592
2462
|
|
1593
2463
|
if (symbolize) {
|
1594
|
-
|
2464
|
+
result = rb_str_intern(result);
|
2465
|
+
} else if (intern) {
|
2466
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
1595
2467
|
}
|
1596
2468
|
|
1597
2469
|
return result;
|
1598
2470
|
}
|
1599
2471
|
|
1600
2472
|
|
1601
|
-
#line
|
2473
|
+
#line 2474 "parser.c"
|
1602
2474
|
enum {JSON_string_start = 1};
|
1603
|
-
enum {JSON_string_first_final =
|
2475
|
+
enum {JSON_string_first_final = 9};
|
1604
2476
|
enum {JSON_string_error = 0};
|
1605
2477
|
|
1606
2478
|
enum {JSON_string_en_main = 1};
|
1607
2479
|
|
1608
2480
|
|
1609
|
-
#line
|
2481
|
+
#line 1077 "parser.rl"
|
1610
2482
|
|
1611
2483
|
|
1612
2484
|
static int
|
@@ -1627,15 +2499,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1627
2499
|
VALUE match_string;
|
1628
2500
|
|
1629
2501
|
|
1630
|
-
#line
|
2502
|
+
#line 2503 "parser.c"
|
1631
2503
|
{
|
1632
2504
|
cs = JSON_string_start;
|
1633
2505
|
}
|
1634
2506
|
|
1635
|
-
#line
|
2507
|
+
#line 1097 "parser.rl"
|
1636
2508
|
json->memo = p;
|
1637
2509
|
|
1638
|
-
#line
|
2510
|
+
#line 2511 "parser.c"
|
1639
2511
|
{
|
1640
2512
|
if ( p == pe )
|
1641
2513
|
goto _test_eof;
|
@@ -1660,47 +2532,56 @@ case 2:
|
|
1660
2532
|
goto st0;
|
1661
2533
|
goto st2;
|
1662
2534
|
tr2:
|
1663
|
-
#line
|
2535
|
+
#line 1059 "parser.rl"
|
1664
2536
|
{
|
1665
|
-
*result =
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
} else {
|
1670
|
-
{p = (( p + 1))-1;}
|
1671
|
-
}
|
2537
|
+
*result = json_string_fastpath(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2538
|
+
{p = (( p + 1))-1;}
|
2539
|
+
p--;
|
2540
|
+
{p++; cs = 9; goto _out;}
|
1672
2541
|
}
|
1673
|
-
#line
|
1674
|
-
{
|
1675
|
-
|
1676
|
-
|
2542
|
+
#line 1052 "parser.rl"
|
2543
|
+
{
|
2544
|
+
*result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2545
|
+
{p = (( p + 1))-1;}
|
2546
|
+
p--;
|
2547
|
+
{p++; cs = 9; goto _out;}
|
2548
|
+
}
|
2549
|
+
goto st9;
|
2550
|
+
tr6:
|
2551
|
+
#line 1052 "parser.rl"
|
2552
|
+
{
|
2553
|
+
*result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2554
|
+
{p = (( p + 1))-1;}
|
2555
|
+
p--;
|
2556
|
+
{p++; cs = 9; goto _out;}
|
2557
|
+
}
|
2558
|
+
goto st9;
|
2559
|
+
st9:
|
1677
2560
|
if ( ++p == pe )
|
1678
|
-
goto
|
1679
|
-
case
|
1680
|
-
#line
|
2561
|
+
goto _test_eof9;
|
2562
|
+
case 9:
|
2563
|
+
#line 2564 "parser.c"
|
1681
2564
|
goto st0;
|
1682
2565
|
st3:
|
1683
2566
|
if ( ++p == pe )
|
1684
2567
|
goto _test_eof3;
|
1685
2568
|
case 3:
|
1686
2569
|
if ( (*p) == 117 )
|
1687
|
-
goto
|
2570
|
+
goto st5;
|
1688
2571
|
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
1689
2572
|
goto st0;
|
1690
|
-
goto
|
2573
|
+
goto st4;
|
1691
2574
|
st4:
|
1692
|
-
if ( ++p == pe )
|
1693
|
-
goto _test_eof4;
|
1694
|
-
case 4:
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
}
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
goto st5;
|
1703
|
-
goto st0;
|
2575
|
+
if ( ++p == pe )
|
2576
|
+
goto _test_eof4;
|
2577
|
+
case 4:
|
2578
|
+
switch( (*p) ) {
|
2579
|
+
case 34: goto tr6;
|
2580
|
+
case 92: goto st3;
|
2581
|
+
}
|
2582
|
+
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
2583
|
+
goto st0;
|
2584
|
+
goto st4;
|
1704
2585
|
st5:
|
1705
2586
|
if ( ++p == pe )
|
1706
2587
|
goto _test_eof5;
|
@@ -1733,27 +2614,41 @@ st7:
|
|
1733
2614
|
case 7:
|
1734
2615
|
if ( (*p) < 65 ) {
|
1735
2616
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1736
|
-
goto
|
2617
|
+
goto st8;
|
1737
2618
|
} else if ( (*p) > 70 ) {
|
1738
2619
|
if ( 97 <= (*p) && (*p) <= 102 )
|
1739
|
-
goto
|
2620
|
+
goto st8;
|
1740
2621
|
} else
|
1741
|
-
goto
|
2622
|
+
goto st8;
|
2623
|
+
goto st0;
|
2624
|
+
st8:
|
2625
|
+
if ( ++p == pe )
|
2626
|
+
goto _test_eof8;
|
2627
|
+
case 8:
|
2628
|
+
if ( (*p) < 65 ) {
|
2629
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
2630
|
+
goto st4;
|
2631
|
+
} else if ( (*p) > 70 ) {
|
2632
|
+
if ( 97 <= (*p) && (*p) <= 102 )
|
2633
|
+
goto st4;
|
2634
|
+
} else
|
2635
|
+
goto st4;
|
1742
2636
|
goto st0;
|
1743
2637
|
}
|
1744
2638
|
_test_eof2: cs = 2; goto _test_eof;
|
1745
|
-
|
2639
|
+
_test_eof9: cs = 9; goto _test_eof;
|
1746
2640
|
_test_eof3: cs = 3; goto _test_eof;
|
1747
2641
|
_test_eof4: cs = 4; goto _test_eof;
|
1748
2642
|
_test_eof5: cs = 5; goto _test_eof;
|
1749
2643
|
_test_eof6: cs = 6; goto _test_eof;
|
1750
2644
|
_test_eof7: cs = 7; goto _test_eof;
|
2645
|
+
_test_eof8: cs = 8; goto _test_eof;
|
1751
2646
|
|
1752
2647
|
_test_eof: {}
|
1753
2648
|
_out: {}
|
1754
2649
|
}
|
1755
2650
|
|
1756
|
-
#line
|
2651
|
+
#line 1099 "parser.rl"
|
1757
2652
|
|
1758
2653
|
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
1759
2654
|
VALUE klass;
|
@@ -1789,18 +2684,78 @@ static VALUE convert_encoding(VALUE source)
|
|
1789
2684
|
{
|
1790
2685
|
int encindex = RB_ENCODING_GET(source);
|
1791
2686
|
|
1792
|
-
if (encindex == utf8_encindex) {
|
2687
|
+
if (RB_LIKELY(encindex == utf8_encindex)) {
|
1793
2688
|
return source;
|
1794
2689
|
}
|
1795
2690
|
|
1796
2691
|
if (encindex == binary_encindex) {
|
1797
|
-
// For historical reason, we silently reinterpret binary strings as UTF-8
|
1798
|
-
// TODO: Deprecate in 2.8.0
|
1799
|
-
// TODO: Remove in 3.0.0
|
2692
|
+
// For historical reason, we silently reinterpret binary strings as UTF-8
|
1800
2693
|
return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
|
1801
2694
|
}
|
1802
2695
|
|
1803
|
-
return
|
2696
|
+
return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
|
2697
|
+
}
|
2698
|
+
|
2699
|
+
static int configure_parser_i(VALUE key, VALUE val, VALUE data)
|
2700
|
+
{
|
2701
|
+
JSON_Parser *json = (JSON_Parser *)data;
|
2702
|
+
|
2703
|
+
if (key == sym_max_nesting) { json->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
|
2704
|
+
else if (key == sym_allow_nan) { json->allow_nan = RTEST(val); }
|
2705
|
+
else if (key == sym_allow_trailing_comma) { json->allow_trailing_comma = RTEST(val); }
|
2706
|
+
else if (key == sym_symbolize_names) { json->symbolize_names = RTEST(val); }
|
2707
|
+
else if (key == sym_freeze) { json->freeze = RTEST(val); }
|
2708
|
+
else if (key == sym_create_id) { json->create_id = RTEST(val) ? val : Qfalse; }
|
2709
|
+
else if (key == sym_object_class) { json->object_class = RTEST(val) ? val : Qfalse; }
|
2710
|
+
else if (key == sym_array_class) { json->array_class = RTEST(val) ? val : Qfalse; }
|
2711
|
+
else if (key == sym_decimal_class) { json->decimal_class = RTEST(val) ? val : Qfalse; }
|
2712
|
+
else if (key == sym_match_string) { json->match_string = RTEST(val) ? val : Qfalse; }
|
2713
|
+
else if (key == sym_create_additions) {
|
2714
|
+
if (NIL_P(val)) {
|
2715
|
+
json->create_additions = true;
|
2716
|
+
json->deprecated_create_additions = true;
|
2717
|
+
} else {
|
2718
|
+
json->create_additions = RTEST(val);
|
2719
|
+
json->deprecated_create_additions = false;
|
2720
|
+
}
|
2721
|
+
}
|
2722
|
+
|
2723
|
+
return ST_CONTINUE;
|
2724
|
+
}
|
2725
|
+
|
2726
|
+
static void parser_init(JSON_Parser *json, VALUE source, VALUE opts)
|
2727
|
+
{
|
2728
|
+
if (json->Vsource) {
|
2729
|
+
rb_raise(rb_eTypeError, "already initialized instance");
|
2730
|
+
}
|
2731
|
+
|
2732
|
+
json->fbuffer.initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
|
2733
|
+
json->max_nesting = 100;
|
2734
|
+
|
2735
|
+
if (!NIL_P(opts)) {
|
2736
|
+
Check_Type(opts, T_HASH);
|
2737
|
+
if (RHASH_SIZE(opts) > 0) {
|
2738
|
+
// We assume in most cases few keys are set so it's faster to go over
|
2739
|
+
// the provided keys than to check all possible keys.
|
2740
|
+
rb_hash_foreach(opts, configure_parser_i, (VALUE)json);
|
2741
|
+
|
2742
|
+
if (json->symbolize_names && json->create_additions) {
|
2743
|
+
rb_raise(rb_eArgError,
|
2744
|
+
"options :symbolize_names and :create_additions cannot be "
|
2745
|
+
" used in conjunction");
|
2746
|
+
}
|
2747
|
+
|
2748
|
+
if (json->create_additions && !json->create_id) {
|
2749
|
+
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
2750
|
+
}
|
2751
|
+
}
|
2752
|
+
|
2753
|
+
}
|
2754
|
+
source = convert_encoding(StringValue(source));
|
2755
|
+
StringValue(source);
|
2756
|
+
json->len = RSTRING_LEN(source);
|
2757
|
+
json->source = RSTRING_PTR(source);
|
2758
|
+
json->Vsource = source;
|
1804
2759
|
}
|
1805
2760
|
|
1806
2761
|
/*
|
@@ -1837,116 +2792,16 @@ static VALUE convert_encoding(VALUE source)
|
|
1837
2792
|
*/
|
1838
2793
|
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
1839
2794
|
{
|
1840
|
-
VALUE source, opts;
|
1841
2795
|
GET_PARSER_INIT;
|
1842
2796
|
|
1843
|
-
if (json->Vsource) {
|
1844
|
-
rb_raise(rb_eTypeError, "already initialized instance");
|
1845
|
-
}
|
1846
|
-
|
1847
2797
|
rb_check_arity(argc, 1, 2);
|
1848
|
-
source = argv[0];
|
1849
|
-
opts = Qnil;
|
1850
|
-
if (argc == 2) {
|
1851
|
-
opts = argv[1];
|
1852
|
-
Check_Type(argv[1], T_HASH);
|
1853
|
-
if (RHASH_SIZE(argv[1]) > 0) {
|
1854
|
-
opts = argv[1];
|
1855
|
-
}
|
1856
|
-
}
|
1857
2798
|
|
1858
|
-
|
1859
|
-
VALUE tmp = ID2SYM(i_max_nesting);
|
1860
|
-
if (option_given_p(opts, tmp)) {
|
1861
|
-
VALUE max_nesting = rb_hash_aref(opts, tmp);
|
1862
|
-
if (RTEST(max_nesting)) {
|
1863
|
-
Check_Type(max_nesting, T_FIXNUM);
|
1864
|
-
json->max_nesting = FIX2INT(max_nesting);
|
1865
|
-
} else {
|
1866
|
-
json->max_nesting = 0;
|
1867
|
-
}
|
1868
|
-
} else {
|
1869
|
-
json->max_nesting = 100;
|
1870
|
-
}
|
1871
|
-
tmp = ID2SYM(i_allow_nan);
|
1872
|
-
if (option_given_p(opts, tmp)) {
|
1873
|
-
json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
1874
|
-
} else {
|
1875
|
-
json->allow_nan = 0;
|
1876
|
-
}
|
1877
|
-
tmp = ID2SYM(i_symbolize_names);
|
1878
|
-
if (option_given_p(opts, tmp)) {
|
1879
|
-
json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
1880
|
-
} else {
|
1881
|
-
json->symbolize_names = 0;
|
1882
|
-
}
|
1883
|
-
tmp = ID2SYM(i_freeze);
|
1884
|
-
if (option_given_p(opts, tmp)) {
|
1885
|
-
json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
1886
|
-
} else {
|
1887
|
-
json->freeze = 0;
|
1888
|
-
}
|
1889
|
-
tmp = ID2SYM(i_create_additions);
|
1890
|
-
if (option_given_p(opts, tmp)) {
|
1891
|
-
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
1892
|
-
} else {
|
1893
|
-
json->create_additions = 0;
|
1894
|
-
}
|
1895
|
-
if (json->symbolize_names && json->create_additions) {
|
1896
|
-
rb_raise(rb_eArgError,
|
1897
|
-
"options :symbolize_names and :create_additions cannot be "
|
1898
|
-
" used in conjunction");
|
1899
|
-
}
|
1900
|
-
tmp = ID2SYM(i_create_id);
|
1901
|
-
if (option_given_p(opts, tmp)) {
|
1902
|
-
json->create_id = rb_hash_aref(opts, tmp);
|
1903
|
-
} else {
|
1904
|
-
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
1905
|
-
}
|
1906
|
-
tmp = ID2SYM(i_object_class);
|
1907
|
-
if (option_given_p(opts, tmp)) {
|
1908
|
-
json->object_class = rb_hash_aref(opts, tmp);
|
1909
|
-
} else {
|
1910
|
-
json->object_class = Qnil;
|
1911
|
-
}
|
1912
|
-
tmp = ID2SYM(i_array_class);
|
1913
|
-
if (option_given_p(opts, tmp)) {
|
1914
|
-
json->array_class = rb_hash_aref(opts, tmp);
|
1915
|
-
} else {
|
1916
|
-
json->array_class = Qnil;
|
1917
|
-
}
|
1918
|
-
tmp = ID2SYM(i_decimal_class);
|
1919
|
-
if (option_given_p(opts, tmp)) {
|
1920
|
-
json->decimal_class = rb_hash_aref(opts, tmp);
|
1921
|
-
} else {
|
1922
|
-
json->decimal_class = Qnil;
|
1923
|
-
}
|
1924
|
-
tmp = ID2SYM(i_match_string);
|
1925
|
-
if (option_given_p(opts, tmp)) {
|
1926
|
-
VALUE match_string = rb_hash_aref(opts, tmp);
|
1927
|
-
json->match_string = RTEST(match_string) ? match_string : Qnil;
|
1928
|
-
} else {
|
1929
|
-
json->match_string = Qnil;
|
1930
|
-
}
|
1931
|
-
} else {
|
1932
|
-
json->max_nesting = 100;
|
1933
|
-
json->allow_nan = 0;
|
1934
|
-
json->create_additions = 0;
|
1935
|
-
json->create_id = Qnil;
|
1936
|
-
json->object_class = Qnil;
|
1937
|
-
json->array_class = Qnil;
|
1938
|
-
json->decimal_class = Qnil;
|
1939
|
-
}
|
1940
|
-
source = convert_encoding(StringValue(source));
|
1941
|
-
StringValue(source);
|
1942
|
-
json->len = RSTRING_LEN(source);
|
1943
|
-
json->source = RSTRING_PTR(source);;
|
1944
|
-
json->Vsource = source;
|
2799
|
+
parser_init(json, argv[0], argc == 2 ? argv[1] : Qnil);
|
1945
2800
|
return self;
|
1946
2801
|
}
|
1947
2802
|
|
1948
2803
|
|
1949
|
-
#line
|
2804
|
+
#line 2805 "parser.c"
|
1950
2805
|
enum {JSON_start = 1};
|
1951
2806
|
enum {JSON_first_final = 10};
|
1952
2807
|
enum {JSON_error = 0};
|
@@ -1954,7 +2809,7 @@ enum {JSON_error = 0};
|
|
1954
2809
|
enum {JSON_en_main = 1};
|
1955
2810
|
|
1956
2811
|
|
1957
|
-
#line
|
2812
|
+
#line 1265 "parser.rl"
|
1958
2813
|
|
1959
2814
|
|
1960
2815
|
/*
|
@@ -1971,17 +2826,206 @@ static VALUE cParser_parse(VALUE self)
|
|
1971
2826
|
VALUE result = Qnil;
|
1972
2827
|
GET_PARSER;
|
1973
2828
|
|
2829
|
+
char stack_buffer[FBUFFER_STACK_SIZE];
|
2830
|
+
fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
|
2831
|
+
|
2832
|
+
VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
|
2833
|
+
rvalue_stack stack = {
|
2834
|
+
.type = RVALUE_STACK_STACK_ALLOCATED,
|
2835
|
+
.ptr = rvalue_stack_buffer,
|
2836
|
+
.capa = RVALUE_STACK_INITIAL_CAPA,
|
2837
|
+
};
|
2838
|
+
json->stack = &stack;
|
2839
|
+
|
2840
|
+
|
2841
|
+
#line 2842 "parser.c"
|
2842
|
+
{
|
2843
|
+
cs = JSON_start;
|
2844
|
+
}
|
2845
|
+
|
2846
|
+
#line 1293 "parser.rl"
|
2847
|
+
p = json->source;
|
2848
|
+
pe = p + json->len;
|
2849
|
+
|
2850
|
+
#line 2851 "parser.c"
|
2851
|
+
{
|
2852
|
+
if ( p == pe )
|
2853
|
+
goto _test_eof;
|
2854
|
+
switch ( cs )
|
2855
|
+
{
|
2856
|
+
st1:
|
2857
|
+
if ( ++p == pe )
|
2858
|
+
goto _test_eof1;
|
2859
|
+
case 1:
|
2860
|
+
switch( (*p) ) {
|
2861
|
+
case 13: goto st1;
|
2862
|
+
case 32: goto st1;
|
2863
|
+
case 34: goto tr2;
|
2864
|
+
case 45: goto tr2;
|
2865
|
+
case 47: goto st6;
|
2866
|
+
case 73: goto tr2;
|
2867
|
+
case 78: goto tr2;
|
2868
|
+
case 91: goto tr2;
|
2869
|
+
case 102: goto tr2;
|
2870
|
+
case 110: goto tr2;
|
2871
|
+
case 116: goto tr2;
|
2872
|
+
case 123: goto tr2;
|
2873
|
+
}
|
2874
|
+
if ( (*p) > 10 ) {
|
2875
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
2876
|
+
goto tr2;
|
2877
|
+
} else if ( (*p) >= 9 )
|
2878
|
+
goto st1;
|
2879
|
+
goto st0;
|
2880
|
+
st0:
|
2881
|
+
cs = 0;
|
2882
|
+
goto _out;
|
2883
|
+
tr2:
|
2884
|
+
#line 1257 "parser.rl"
|
2885
|
+
{
|
2886
|
+
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
2887
|
+
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
2888
|
+
}
|
2889
|
+
goto st10;
|
2890
|
+
st10:
|
2891
|
+
if ( ++p == pe )
|
2892
|
+
goto _test_eof10;
|
2893
|
+
case 10:
|
2894
|
+
#line 2895 "parser.c"
|
2895
|
+
switch( (*p) ) {
|
2896
|
+
case 13: goto st10;
|
2897
|
+
case 32: goto st10;
|
2898
|
+
case 47: goto st2;
|
2899
|
+
}
|
2900
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
2901
|
+
goto st10;
|
2902
|
+
goto st0;
|
2903
|
+
st2:
|
2904
|
+
if ( ++p == pe )
|
2905
|
+
goto _test_eof2;
|
2906
|
+
case 2:
|
2907
|
+
switch( (*p) ) {
|
2908
|
+
case 42: goto st3;
|
2909
|
+
case 47: goto st5;
|
2910
|
+
}
|
2911
|
+
goto st0;
|
2912
|
+
st3:
|
2913
|
+
if ( ++p == pe )
|
2914
|
+
goto _test_eof3;
|
2915
|
+
case 3:
|
2916
|
+
if ( (*p) == 42 )
|
2917
|
+
goto st4;
|
2918
|
+
goto st3;
|
2919
|
+
st4:
|
2920
|
+
if ( ++p == pe )
|
2921
|
+
goto _test_eof4;
|
2922
|
+
case 4:
|
2923
|
+
switch( (*p) ) {
|
2924
|
+
case 42: goto st4;
|
2925
|
+
case 47: goto st10;
|
2926
|
+
}
|
2927
|
+
goto st3;
|
2928
|
+
st5:
|
2929
|
+
if ( ++p == pe )
|
2930
|
+
goto _test_eof5;
|
2931
|
+
case 5:
|
2932
|
+
if ( (*p) == 10 )
|
2933
|
+
goto st10;
|
2934
|
+
goto st5;
|
2935
|
+
st6:
|
2936
|
+
if ( ++p == pe )
|
2937
|
+
goto _test_eof6;
|
2938
|
+
case 6:
|
2939
|
+
switch( (*p) ) {
|
2940
|
+
case 42: goto st7;
|
2941
|
+
case 47: goto st9;
|
2942
|
+
}
|
2943
|
+
goto st0;
|
2944
|
+
st7:
|
2945
|
+
if ( ++p == pe )
|
2946
|
+
goto _test_eof7;
|
2947
|
+
case 7:
|
2948
|
+
if ( (*p) == 42 )
|
2949
|
+
goto st8;
|
2950
|
+
goto st7;
|
2951
|
+
st8:
|
2952
|
+
if ( ++p == pe )
|
2953
|
+
goto _test_eof8;
|
2954
|
+
case 8:
|
2955
|
+
switch( (*p) ) {
|
2956
|
+
case 42: goto st8;
|
2957
|
+
case 47: goto st1;
|
2958
|
+
}
|
2959
|
+
goto st7;
|
2960
|
+
st9:
|
2961
|
+
if ( ++p == pe )
|
2962
|
+
goto _test_eof9;
|
2963
|
+
case 9:
|
2964
|
+
if ( (*p) == 10 )
|
2965
|
+
goto st1;
|
2966
|
+
goto st9;
|
2967
|
+
}
|
2968
|
+
_test_eof1: cs = 1; goto _test_eof;
|
2969
|
+
_test_eof10: cs = 10; goto _test_eof;
|
2970
|
+
_test_eof2: cs = 2; goto _test_eof;
|
2971
|
+
_test_eof3: cs = 3; goto _test_eof;
|
2972
|
+
_test_eof4: cs = 4; goto _test_eof;
|
2973
|
+
_test_eof5: cs = 5; goto _test_eof;
|
2974
|
+
_test_eof6: cs = 6; goto _test_eof;
|
2975
|
+
_test_eof7: cs = 7; goto _test_eof;
|
2976
|
+
_test_eof8: cs = 8; goto _test_eof;
|
2977
|
+
_test_eof9: cs = 9; goto _test_eof;
|
2978
|
+
|
2979
|
+
_test_eof: {}
|
2980
|
+
_out: {}
|
2981
|
+
}
|
2982
|
+
|
2983
|
+
#line 1296 "parser.rl"
|
2984
|
+
|
2985
|
+
if (json->stack_handle) {
|
2986
|
+
rvalue_stack_eagerly_release(json->stack_handle);
|
2987
|
+
}
|
2988
|
+
|
2989
|
+
if (cs >= JSON_first_final && p == pe) {
|
2990
|
+
return result;
|
2991
|
+
} else {
|
2992
|
+
raise_parse_error("unexpected token at '%s'", p);
|
2993
|
+
return Qnil;
|
2994
|
+
}
|
2995
|
+
}
|
2996
|
+
|
2997
|
+
static VALUE cParser_m_parse(VALUE klass, VALUE source, VALUE opts)
|
2998
|
+
{
|
2999
|
+
char *p, *pe;
|
3000
|
+
int cs = EVIL;
|
3001
|
+
VALUE result = Qnil;
|
3002
|
+
|
3003
|
+
JSON_Parser _parser = {0};
|
3004
|
+
JSON_Parser *json = &_parser;
|
3005
|
+
parser_init(json, source, opts);
|
3006
|
+
|
3007
|
+
char stack_buffer[FBUFFER_STACK_SIZE];
|
3008
|
+
fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
|
3009
|
+
|
3010
|
+
VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
|
3011
|
+
rvalue_stack stack = {
|
3012
|
+
.type = RVALUE_STACK_STACK_ALLOCATED,
|
3013
|
+
.ptr = rvalue_stack_buffer,
|
3014
|
+
.capa = RVALUE_STACK_INITIAL_CAPA,
|
3015
|
+
};
|
3016
|
+
json->stack = &stack;
|
1974
3017
|
|
1975
|
-
|
3018
|
+
|
3019
|
+
#line 3020 "parser.c"
|
1976
3020
|
{
|
1977
3021
|
cs = JSON_start;
|
1978
3022
|
}
|
1979
3023
|
|
1980
|
-
#line
|
3024
|
+
#line 1331 "parser.rl"
|
1981
3025
|
p = json->source;
|
1982
3026
|
pe = p + json->len;
|
1983
3027
|
|
1984
|
-
#line
|
3028
|
+
#line 3029 "parser.c"
|
1985
3029
|
{
|
1986
3030
|
if ( p == pe )
|
1987
3031
|
goto _test_eof;
|
@@ -2015,7 +3059,7 @@ st0:
|
|
2015
3059
|
cs = 0;
|
2016
3060
|
goto _out;
|
2017
3061
|
tr2:
|
2018
|
-
#line
|
3062
|
+
#line 1257 "parser.rl"
|
2019
3063
|
{
|
2020
3064
|
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
2021
3065
|
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
@@ -2025,7 +3069,7 @@ st10:
|
|
2025
3069
|
if ( ++p == pe )
|
2026
3070
|
goto _test_eof10;
|
2027
3071
|
case 10:
|
2028
|
-
#line
|
3072
|
+
#line 3073 "parser.c"
|
2029
3073
|
switch( (*p) ) {
|
2030
3074
|
case 13: goto st10;
|
2031
3075
|
case 32: goto st10;
|
@@ -2114,7 +3158,11 @@ case 9:
|
|
2114
3158
|
_out: {}
|
2115
3159
|
}
|
2116
3160
|
|
2117
|
-
#line
|
3161
|
+
#line 1334 "parser.rl"
|
3162
|
+
|
3163
|
+
if (json->stack_handle) {
|
3164
|
+
rvalue_stack_eagerly_release(json->stack_handle);
|
3165
|
+
}
|
2118
3166
|
|
2119
3167
|
if (cs >= JSON_first_final && p == pe) {
|
2120
3168
|
return result;
|
@@ -2133,19 +3181,23 @@ static void JSON_mark(void *ptr)
|
|
2133
3181
|
rb_gc_mark(json->array_class);
|
2134
3182
|
rb_gc_mark(json->decimal_class);
|
2135
3183
|
rb_gc_mark(json->match_string);
|
3184
|
+
rb_gc_mark(json->stack_handle);
|
3185
|
+
|
3186
|
+
const VALUE *name_cache_entries = &json->name_cache.entries[0];
|
3187
|
+
rb_gc_mark_locations(name_cache_entries, name_cache_entries + json->name_cache.length);
|
2136
3188
|
}
|
2137
3189
|
|
2138
3190
|
static void JSON_free(void *ptr)
|
2139
3191
|
{
|
2140
3192
|
JSON_Parser *json = ptr;
|
2141
|
-
fbuffer_free(json->fbuffer);
|
3193
|
+
fbuffer_free(&json->fbuffer);
|
2142
3194
|
ruby_xfree(json);
|
2143
3195
|
}
|
2144
3196
|
|
2145
3197
|
static size_t JSON_memsize(const void *ptr)
|
2146
3198
|
{
|
2147
3199
|
const JSON_Parser *json = ptr;
|
2148
|
-
return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
|
3200
|
+
return sizeof(*json) + FBUFFER_CAPA(&json->fbuffer);
|
2149
3201
|
}
|
2150
3202
|
|
2151
3203
|
static const rb_data_type_t JSON_Parser_type = {
|
@@ -2159,7 +3211,7 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
|
|
2159
3211
|
{
|
2160
3212
|
JSON_Parser *json;
|
2161
3213
|
VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
|
2162
|
-
json->fbuffer
|
3214
|
+
fbuffer_stack_init(&json->fbuffer, 0, NULL, 0);
|
2163
3215
|
return obj;
|
2164
3216
|
}
|
2165
3217
|
|
@@ -2193,6 +3245,8 @@ void Init_parser(void)
|
|
2193
3245
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
2194
3246
|
rb_define_method(cParser, "source", cParser_source, 0);
|
2195
3247
|
|
3248
|
+
rb_define_singleton_method(cParser, "parse", cParser_m_parse, 2);
|
3249
|
+
|
2196
3250
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
2197
3251
|
rb_gc_register_mark_object(CNaN);
|
2198
3252
|
|
@@ -2202,30 +3256,38 @@ void Init_parser(void)
|
|
2202
3256
|
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
|
2203
3257
|
rb_gc_register_mark_object(CMinusInfinity);
|
2204
3258
|
|
3259
|
+
rb_global_variable(&Encoding_UTF_8);
|
3260
|
+
Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8"));
|
3261
|
+
|
3262
|
+
sym_max_nesting = ID2SYM(rb_intern("max_nesting"));
|
3263
|
+
sym_allow_nan = ID2SYM(rb_intern("allow_nan"));
|
3264
|
+
sym_allow_trailing_comma = ID2SYM(rb_intern("allow_trailing_comma"));
|
3265
|
+
sym_symbolize_names = ID2SYM(rb_intern("symbolize_names"));
|
3266
|
+
sym_freeze = ID2SYM(rb_intern("freeze"));
|
3267
|
+
sym_create_additions = ID2SYM(rb_intern("create_additions"));
|
3268
|
+
sym_create_id = ID2SYM(rb_intern("create_id"));
|
3269
|
+
sym_object_class = ID2SYM(rb_intern("object_class"));
|
3270
|
+
sym_array_class = ID2SYM(rb_intern("array_class"));
|
3271
|
+
sym_decimal_class = ID2SYM(rb_intern("decimal_class"));
|
3272
|
+
sym_match_string = ID2SYM(rb_intern("match_string"));
|
3273
|
+
|
3274
|
+
i_create_id = rb_intern("create_id");
|
2205
3275
|
i_json_creatable_p = rb_intern("json_creatable?");
|
2206
3276
|
i_json_create = rb_intern("json_create");
|
2207
|
-
i_create_id = rb_intern("create_id");
|
2208
|
-
i_create_additions = rb_intern("create_additions");
|
2209
3277
|
i_chr = rb_intern("chr");
|
2210
|
-
i_max_nesting = rb_intern("max_nesting");
|
2211
|
-
i_allow_nan = rb_intern("allow_nan");
|
2212
|
-
i_symbolize_names = rb_intern("symbolize_names");
|
2213
|
-
i_object_class = rb_intern("object_class");
|
2214
|
-
i_array_class = rb_intern("array_class");
|
2215
|
-
i_decimal_class = rb_intern("decimal_class");
|
2216
3278
|
i_match = rb_intern("match");
|
2217
|
-
i_match_string = rb_intern("match_string");
|
2218
3279
|
i_deep_const_get = rb_intern("deep_const_get");
|
2219
3280
|
i_aset = rb_intern("[]=");
|
2220
3281
|
i_aref = rb_intern("[]");
|
2221
3282
|
i_leftshift = rb_intern("<<");
|
2222
3283
|
i_new = rb_intern("new");
|
2223
3284
|
i_try_convert = rb_intern("try_convert");
|
2224
|
-
i_freeze = rb_intern("freeze");
|
2225
3285
|
i_uminus = rb_intern("-@");
|
3286
|
+
i_encode = rb_intern("encode");
|
2226
3287
|
|
2227
3288
|
binary_encindex = rb_ascii8bit_encindex();
|
2228
3289
|
utf8_encindex = rb_utf8_encindex();
|
3290
|
+
enc_utf8 = rb_utf8_encoding();
|
2229
3291
|
}
|
2230
3292
|
|
2231
3293
|
/*
|