json 2.7.5 → 2.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +23 -0
- data/README.md +8 -77
- data/ext/json/ext/fbuffer/fbuffer.h +85 -47
- data/ext/json/ext/generator/generator.c +335 -204
- data/ext/json/ext/parser/extconf.rb +5 -27
- data/ext/json/ext/parser/parser.c +1598 -597
- data/ext/json/ext/parser/parser.rl +726 -258
- data/json.gemspec +4 -1
- data/lib/json/add/bigdecimal.rb +1 -1
- data/lib/json/common.rb +206 -64
- data/lib/json/ext/generator/state.rb +1 -31
- data/lib/json/ext.rb +2 -4
- data/lib/json/{pure → truffle_ruby}/generator.rb +158 -117
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +15 -20
- metadata +4 -8
- data/ext/json/ext/generator/generator.h +0 -118
- 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 in_array;
|
398
|
+
int max_nesting;
|
399
|
+
bool allow_nan;
|
400
|
+
bool allow_trailing_comma;
|
401
|
+
bool parsing_name;
|
402
|
+
bool symbolize_names;
|
403
|
+
bool freeze;
|
404
|
+
bool create_additions;
|
405
|
+
bool deprecated_create_additions;
|
406
|
+
rvalue_cache name_cache;
|
407
|
+
rvalue_stack *stack;
|
408
|
+
VALUE stack_handle;
|
409
|
+
} JSON_Parser;
|
410
|
+
|
411
|
+
#define GET_PARSER \
|
412
|
+
GET_PARSER_INIT; \
|
413
|
+
if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
|
414
|
+
|
415
|
+
#define GET_PARSER_INIT \
|
416
|
+
JSON_Parser *json; \
|
417
|
+
TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json)
|
418
|
+
|
419
|
+
#define MinusInfinity "-Infinity"
|
420
|
+
#define EVIL 0x666
|
421
|
+
|
422
|
+
static const rb_data_type_t JSON_Parser_type;
|
423
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
424
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
425
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
426
|
+
static char *JSON_parse_number(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
|
-
|
101
|
-
static int binary_encindex;
|
102
|
-
static int utf8_encindex;
|
103
|
-
|
104
450
|
|
105
451
|
|
106
|
-
#line
|
452
|
+
#line 475 "parser.rl"
|
107
453
|
|
108
454
|
|
109
455
|
|
110
|
-
#line
|
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 664 "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 671 "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)) {
|
@@ -562,23 +1150,25 @@ tr3:
|
|
562
1150
|
raise_parse_error("unexpected token at '%s'", p);
|
563
1151
|
}
|
564
1152
|
}
|
565
|
-
np =
|
566
|
-
if (np != NULL) {
|
567
|
-
|
568
|
-
|
1153
|
+
np = JSON_parse_number(json, p, pe, result);
|
1154
|
+
if (np != NULL) {
|
1155
|
+
{p = (( np))-1;}
|
1156
|
+
}
|
569
1157
|
p--; {p++; cs = 29; goto _out;}
|
570
1158
|
}
|
571
1159
|
goto st29;
|
572
1160
|
tr7:
|
573
|
-
#line
|
1161
|
+
#line 637 "parser.rl"
|
574
1162
|
{
|
575
1163
|
char *np;
|
1164
|
+
json->in_array++;
|
576
1165
|
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
|
1166
|
+
json->in_array--;
|
577
1167
|
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
578
1168
|
}
|
579
1169
|
goto st29;
|
580
1170
|
tr11:
|
581
|
-
#line
|
1171
|
+
#line 645 "parser.rl"
|
582
1172
|
{
|
583
1173
|
char *np;
|
584
1174
|
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
|
@@ -586,7 +1176,7 @@ tr11:
|
|
586
1176
|
}
|
587
1177
|
goto st29;
|
588
1178
|
tr25:
|
589
|
-
#line
|
1179
|
+
#line 602 "parser.rl"
|
590
1180
|
{
|
591
1181
|
if (json->allow_nan) {
|
592
1182
|
*result = CInfinity;
|
@@ -596,7 +1186,7 @@ tr25:
|
|
596
1186
|
}
|
597
1187
|
goto st29;
|
598
1188
|
tr27:
|
599
|
-
#line
|
1189
|
+
#line 595 "parser.rl"
|
600
1190
|
{
|
601
1191
|
if (json->allow_nan) {
|
602
1192
|
*result = CNaN;
|
@@ -606,19 +1196,19 @@ tr27:
|
|
606
1196
|
}
|
607
1197
|
goto st29;
|
608
1198
|
tr31:
|
609
|
-
#line
|
1199
|
+
#line 589 "parser.rl"
|
610
1200
|
{
|
611
1201
|
*result = Qfalse;
|
612
1202
|
}
|
613
1203
|
goto st29;
|
614
1204
|
tr34:
|
615
|
-
#line
|
1205
|
+
#line 586 "parser.rl"
|
616
1206
|
{
|
617
1207
|
*result = Qnil;
|
618
1208
|
}
|
619
1209
|
goto st29;
|
620
1210
|
tr37:
|
621
|
-
#line
|
1211
|
+
#line 592 "parser.rl"
|
622
1212
|
{
|
623
1213
|
*result = Qtrue;
|
624
1214
|
}
|
@@ -627,9 +1217,9 @@ st29:
|
|
627
1217
|
if ( ++p == pe )
|
628
1218
|
goto _test_eof29;
|
629
1219
|
case 29:
|
630
|
-
#line
|
1220
|
+
#line 651 "parser.rl"
|
631
1221
|
{ p--; {p++; cs = 29; goto _out;} }
|
632
|
-
#line
|
1222
|
+
#line 1223 "parser.c"
|
633
1223
|
switch( (*p) ) {
|
634
1224
|
case 13: goto st29;
|
635
1225
|
case 32: goto st29;
|
@@ -870,13 +1460,14 @@ case 28:
|
|
870
1460
|
_out: {}
|
871
1461
|
}
|
872
1462
|
|
873
|
-
#line
|
1463
|
+
#line 672 "parser.rl"
|
874
1464
|
|
875
1465
|
if (json->freeze) {
|
876
1466
|
OBJ_FREEZE(*result);
|
877
1467
|
}
|
878
1468
|
|
879
1469
|
if (cs >= JSON_value_first_final) {
|
1470
|
+
PUSH(*result);
|
880
1471
|
return p;
|
881
1472
|
} else {
|
882
1473
|
return NULL;
|
@@ -884,7 +1475,7 @@ case 28:
|
|
884
1475
|
}
|
885
1476
|
|
886
1477
|
|
887
|
-
#line
|
1478
|
+
#line 1479 "parser.c"
|
888
1479
|
enum {JSON_integer_start = 1};
|
889
1480
|
enum {JSON_integer_first_final = 3};
|
890
1481
|
enum {JSON_integer_error = 0};
|
@@ -892,122 +1483,72 @@ enum {JSON_integer_error = 0};
|
|
892
1483
|
enum {JSON_integer_en_main = 1};
|
893
1484
|
|
894
1485
|
|
895
|
-
#line
|
1486
|
+
#line 693 "parser.rl"
|
896
1487
|
|
897
1488
|
|
898
|
-
|
1489
|
+
#define MAX_FAST_INTEGER_SIZE 18
|
1490
|
+
static inline VALUE fast_parse_integer(char *p, char *pe)
|
899
1491
|
{
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
cs = JSON_integer_start;
|
906
|
-
}
|
907
|
-
|
908
|
-
#line 322 "parser.rl"
|
909
|
-
json->memo = p;
|
910
|
-
|
911
|
-
#line 912 "parser.c"
|
912
|
-
{
|
913
|
-
if ( p == pe )
|
914
|
-
goto _test_eof;
|
915
|
-
switch ( cs )
|
916
|
-
{
|
917
|
-
case 1:
|
918
|
-
switch( (*p) ) {
|
919
|
-
case 45: goto st2;
|
920
|
-
case 48: goto st3;
|
921
|
-
}
|
922
|
-
if ( 49 <= (*p) && (*p) <= 57 )
|
923
|
-
goto st5;
|
924
|
-
goto st0;
|
925
|
-
st0:
|
926
|
-
cs = 0;
|
927
|
-
goto _out;
|
928
|
-
st2:
|
929
|
-
if ( ++p == pe )
|
930
|
-
goto _test_eof2;
|
931
|
-
case 2:
|
932
|
-
if ( (*p) == 48 )
|
933
|
-
goto st3;
|
934
|
-
if ( 49 <= (*p) && (*p) <= 57 )
|
935
|
-
goto st5;
|
936
|
-
goto st0;
|
937
|
-
st3:
|
938
|
-
if ( ++p == pe )
|
939
|
-
goto _test_eof3;
|
940
|
-
case 3:
|
941
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
942
|
-
goto st0;
|
943
|
-
goto tr4;
|
944
|
-
tr4:
|
945
|
-
#line 312 "parser.rl"
|
946
|
-
{ p--; {p++; cs = 4; goto _out;} }
|
947
|
-
goto st4;
|
948
|
-
st4:
|
949
|
-
if ( ++p == pe )
|
950
|
-
goto _test_eof4;
|
951
|
-
case 4:
|
952
|
-
#line 953 "parser.c"
|
953
|
-
goto st0;
|
954
|
-
st5:
|
955
|
-
if ( ++p == pe )
|
956
|
-
goto _test_eof5;
|
957
|
-
case 5:
|
958
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
959
|
-
goto st5;
|
960
|
-
goto tr4;
|
961
|
-
}
|
962
|
-
_test_eof2: cs = 2; goto _test_eof;
|
963
|
-
_test_eof3: cs = 3; goto _test_eof;
|
964
|
-
_test_eof4: cs = 4; goto _test_eof;
|
965
|
-
_test_eof5: cs = 5; goto _test_eof;
|
1492
|
+
bool negative = false;
|
1493
|
+
if (*p == '-') {
|
1494
|
+
negative = true;
|
1495
|
+
p++;
|
1496
|
+
}
|
966
1497
|
|
967
|
-
|
968
|
-
|
969
|
-
|
1498
|
+
long long memo = 0;
|
1499
|
+
while (p < pe) {
|
1500
|
+
memo *= 10;
|
1501
|
+
memo += *p - '0';
|
1502
|
+
p++;
|
1503
|
+
}
|
970
1504
|
|
971
|
-
|
1505
|
+
if (negative) {
|
1506
|
+
memo = -memo;
|
1507
|
+
}
|
1508
|
+
return LL2NUM(memo);
|
1509
|
+
}
|
972
1510
|
|
973
|
-
|
1511
|
+
static char *JSON_decode_integer(JSON_Parser *json, char *p, VALUE *result)
|
1512
|
+
{
|
974
1513
|
long len = p - json->memo;
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
1514
|
+
if (RB_LIKELY(len < MAX_FAST_INTEGER_SIZE)) {
|
1515
|
+
*result = fast_parse_integer(json->memo, p);
|
1516
|
+
} else {
|
1517
|
+
fbuffer_clear(&json->fbuffer);
|
1518
|
+
fbuffer_append(&json->fbuffer, json->memo, len);
|
1519
|
+
fbuffer_append_char(&json->fbuffer, '\0');
|
1520
|
+
*result = rb_cstr2inum(FBUFFER_PTR(&json->fbuffer), 10);
|
1521
|
+
}
|
979
1522
|
return p + 1;
|
980
|
-
} else {
|
981
|
-
return NULL;
|
982
|
-
}
|
983
1523
|
}
|
984
1524
|
|
985
1525
|
|
986
|
-
#line
|
1526
|
+
#line 1527 "parser.c"
|
987
1527
|
enum {JSON_float_start = 1};
|
988
|
-
enum {JSON_float_first_final =
|
1528
|
+
enum {JSON_float_first_final = 6};
|
989
1529
|
enum {JSON_float_error = 0};
|
990
1530
|
|
991
1531
|
enum {JSON_float_en_main = 1};
|
992
1532
|
|
993
1533
|
|
994
|
-
#line
|
1534
|
+
#line 745 "parser.rl"
|
995
1535
|
|
996
1536
|
|
997
|
-
static char *
|
1537
|
+
static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
998
1538
|
{
|
999
1539
|
int cs = EVIL;
|
1540
|
+
bool is_float = false;
|
1000
1541
|
|
1001
1542
|
|
1002
|
-
#line
|
1543
|
+
#line 1544 "parser.c"
|
1003
1544
|
{
|
1004
1545
|
cs = JSON_float_start;
|
1005
1546
|
}
|
1006
1547
|
|
1007
|
-
#line
|
1548
|
+
#line 753 "parser.rl"
|
1008
1549
|
json->memo = p;
|
1009
1550
|
|
1010
|
-
#line
|
1551
|
+
#line 1552 "parser.c"
|
1011
1552
|
{
|
1012
1553
|
if ( p == pe )
|
1013
1554
|
goto _test_eof;
|
@@ -1016,10 +1557,10 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
1016
1557
|
case 1:
|
1017
1558
|
switch( (*p) ) {
|
1018
1559
|
case 45: goto st2;
|
1019
|
-
case 48: goto
|
1560
|
+
case 48: goto st6;
|
1020
1561
|
}
|
1021
1562
|
if ( 49 <= (*p) && (*p) <= 57 )
|
1022
|
-
goto
|
1563
|
+
goto st10;
|
1023
1564
|
goto st0;
|
1024
1565
|
st0:
|
1025
1566
|
cs = 0;
|
@@ -1029,24 +1570,42 @@ st2:
|
|
1029
1570
|
goto _test_eof2;
|
1030
1571
|
case 2:
|
1031
1572
|
if ( (*p) == 48 )
|
1032
|
-
goto
|
1573
|
+
goto st6;
|
1033
1574
|
if ( 49 <= (*p) && (*p) <= 57 )
|
1034
|
-
goto
|
1575
|
+
goto st10;
|
1035
1576
|
goto st0;
|
1036
|
-
|
1577
|
+
st6:
|
1037
1578
|
if ( ++p == pe )
|
1038
|
-
goto
|
1039
|
-
case
|
1579
|
+
goto _test_eof6;
|
1580
|
+
case 6:
|
1040
1581
|
switch( (*p) ) {
|
1041
|
-
case
|
1042
|
-
case
|
1043
|
-
case
|
1582
|
+
case 45: goto st0;
|
1583
|
+
case 46: goto tr8;
|
1584
|
+
case 69: goto tr9;
|
1585
|
+
case 101: goto tr9;
|
1044
1586
|
}
|
1587
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1588
|
+
goto st0;
|
1589
|
+
goto tr7;
|
1590
|
+
tr7:
|
1591
|
+
#line 737 "parser.rl"
|
1592
|
+
{ p--; {p++; cs = 7; goto _out;} }
|
1593
|
+
goto st7;
|
1594
|
+
st7:
|
1595
|
+
if ( ++p == pe )
|
1596
|
+
goto _test_eof7;
|
1597
|
+
case 7:
|
1598
|
+
#line 1599 "parser.c"
|
1045
1599
|
goto st0;
|
1046
|
-
|
1600
|
+
tr8:
|
1601
|
+
#line 738 "parser.rl"
|
1602
|
+
{ is_float = true; }
|
1603
|
+
goto st3;
|
1604
|
+
st3:
|
1047
1605
|
if ( ++p == pe )
|
1048
|
-
goto
|
1049
|
-
case
|
1606
|
+
goto _test_eof3;
|
1607
|
+
case 3:
|
1608
|
+
#line 1609 "parser.c"
|
1050
1609
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1051
1610
|
goto st8;
|
1052
1611
|
goto st0;
|
@@ -1055,90 +1614,89 @@ st8:
|
|
1055
1614
|
goto _test_eof8;
|
1056
1615
|
case 8:
|
1057
1616
|
switch( (*p) ) {
|
1058
|
-
case 69: goto
|
1059
|
-
case 101: goto
|
1617
|
+
case 69: goto st4;
|
1618
|
+
case 101: goto st4;
|
1060
1619
|
}
|
1061
1620
|
if ( (*p) > 46 ) {
|
1062
1621
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1063
1622
|
goto st8;
|
1064
1623
|
} else if ( (*p) >= 45 )
|
1065
1624
|
goto st0;
|
1066
|
-
goto
|
1625
|
+
goto tr7;
|
1067
1626
|
tr9:
|
1068
|
-
#line
|
1069
|
-
{
|
1070
|
-
goto
|
1071
|
-
|
1072
|
-
if ( ++p == pe )
|
1073
|
-
goto _test_eof9;
|
1074
|
-
case 9:
|
1075
|
-
#line 1076 "parser.c"
|
1076
|
-
goto st0;
|
1077
|
-
st5:
|
1627
|
+
#line 738 "parser.rl"
|
1628
|
+
{ is_float = true; }
|
1629
|
+
goto st4;
|
1630
|
+
st4:
|
1078
1631
|
if ( ++p == pe )
|
1079
|
-
goto
|
1080
|
-
case
|
1632
|
+
goto _test_eof4;
|
1633
|
+
case 4:
|
1634
|
+
#line 1635 "parser.c"
|
1081
1635
|
switch( (*p) ) {
|
1082
|
-
case 43: goto
|
1083
|
-
case 45: goto
|
1636
|
+
case 43: goto st5;
|
1637
|
+
case 45: goto st5;
|
1084
1638
|
}
|
1085
1639
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1086
|
-
goto
|
1640
|
+
goto st9;
|
1087
1641
|
goto st0;
|
1088
|
-
|
1642
|
+
st5:
|
1089
1643
|
if ( ++p == pe )
|
1090
|
-
goto
|
1091
|
-
case
|
1644
|
+
goto _test_eof5;
|
1645
|
+
case 5:
|
1092
1646
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1093
|
-
goto
|
1647
|
+
goto st9;
|
1094
1648
|
goto st0;
|
1095
|
-
|
1649
|
+
st9:
|
1096
1650
|
if ( ++p == pe )
|
1097
|
-
goto
|
1098
|
-
case
|
1651
|
+
goto _test_eof9;
|
1652
|
+
case 9:
|
1099
1653
|
switch( (*p) ) {
|
1100
1654
|
case 69: goto st0;
|
1101
1655
|
case 101: goto st0;
|
1102
1656
|
}
|
1103
1657
|
if ( (*p) > 46 ) {
|
1104
1658
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1105
|
-
goto
|
1659
|
+
goto st9;
|
1106
1660
|
} else if ( (*p) >= 45 )
|
1107
1661
|
goto st0;
|
1108
|
-
goto
|
1109
|
-
|
1662
|
+
goto tr7;
|
1663
|
+
st10:
|
1110
1664
|
if ( ++p == pe )
|
1111
|
-
goto
|
1112
|
-
case
|
1665
|
+
goto _test_eof10;
|
1666
|
+
case 10:
|
1113
1667
|
switch( (*p) ) {
|
1114
|
-
case
|
1115
|
-
case
|
1116
|
-
case
|
1668
|
+
case 45: goto st0;
|
1669
|
+
case 46: goto tr8;
|
1670
|
+
case 69: goto tr9;
|
1671
|
+
case 101: goto tr9;
|
1117
1672
|
}
|
1118
1673
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1119
|
-
goto
|
1120
|
-
goto
|
1674
|
+
goto st10;
|
1675
|
+
goto tr7;
|
1121
1676
|
}
|
1122
1677
|
_test_eof2: cs = 2; goto _test_eof;
|
1678
|
+
_test_eof6: cs = 6; goto _test_eof;
|
1679
|
+
_test_eof7: cs = 7; goto _test_eof;
|
1123
1680
|
_test_eof3: cs = 3; goto _test_eof;
|
1124
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1125
1681
|
_test_eof8: cs = 8; goto _test_eof;
|
1126
|
-
|
1682
|
+
_test_eof4: cs = 4; goto _test_eof;
|
1127
1683
|
_test_eof5: cs = 5; goto _test_eof;
|
1128
|
-
|
1684
|
+
_test_eof9: cs = 9; goto _test_eof;
|
1129
1685
|
_test_eof10: cs = 10; goto _test_eof;
|
1130
|
-
_test_eof7: cs = 7; goto _test_eof;
|
1131
1686
|
|
1132
1687
|
_test_eof: {}
|
1133
1688
|
_out: {}
|
1134
1689
|
}
|
1135
1690
|
|
1136
|
-
#line
|
1691
|
+
#line 755 "parser.rl"
|
1137
1692
|
|
1138
1693
|
if (cs >= JSON_float_first_final) {
|
1694
|
+
if (!is_float) {
|
1695
|
+
return JSON_decode_integer(json, p, result);
|
1696
|
+
}
|
1139
1697
|
VALUE mod = Qnil;
|
1140
1698
|
ID method_id = 0;
|
1141
|
-
if (
|
1699
|
+
if (json->decimal_class) {
|
1142
1700
|
if (rb_respond_to(json->decimal_class, i_try_convert)) {
|
1143
1701
|
mod = json->decimal_class;
|
1144
1702
|
method_id = i_try_convert;
|
@@ -1167,15 +1725,15 @@ case 7:
|
|
1167
1725
|
}
|
1168
1726
|
|
1169
1727
|
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');
|
1728
|
+
fbuffer_clear(&json->fbuffer);
|
1729
|
+
fbuffer_append(&json->fbuffer, json->memo, len);
|
1730
|
+
fbuffer_append_char(&json->fbuffer, '\0');
|
1173
1731
|
|
1174
1732
|
if (method_id) {
|
1175
|
-
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
1733
|
+
VALUE text = rb_str_new2(FBUFFER_PTR(&json->fbuffer));
|
1176
1734
|
*result = rb_funcallv(mod, method_id, 1, &text);
|
1177
1735
|
} else {
|
1178
|
-
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
1736
|
+
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(&json->fbuffer), 1));
|
1179
1737
|
}
|
1180
1738
|
|
1181
1739
|
return p + 1;
|
@@ -1186,37 +1744,37 @@ case 7:
|
|
1186
1744
|
|
1187
1745
|
|
1188
1746
|
|
1189
|
-
#line
|
1747
|
+
#line 1748 "parser.c"
|
1190
1748
|
enum {JSON_array_start = 1};
|
1191
|
-
enum {JSON_array_first_final =
|
1749
|
+
enum {JSON_array_first_final = 22};
|
1192
1750
|
enum {JSON_array_error = 0};
|
1193
1751
|
|
1194
1752
|
enum {JSON_array_en_main = 1};
|
1195
1753
|
|
1196
1754
|
|
1197
|
-
#line
|
1755
|
+
#line 835 "parser.rl"
|
1198
1756
|
|
1199
1757
|
|
1200
1758
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
1201
1759
|
{
|
1202
1760
|
int cs = EVIL;
|
1203
|
-
VALUE array_class = json->array_class;
|
1204
1761
|
|
1205
1762
|
if (json->max_nesting && current_nesting > json->max_nesting) {
|
1206
1763
|
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
1207
1764
|
}
|
1208
|
-
|
1765
|
+
long stack_head = json->stack->head;
|
1209
1766
|
|
1210
1767
|
|
1211
|
-
#line
|
1768
|
+
#line 1769 "parser.c"
|
1212
1769
|
{
|
1213
1770
|
cs = JSON_array_start;
|
1214
1771
|
}
|
1215
1772
|
|
1216
|
-
#line
|
1773
|
+
#line 847 "parser.rl"
|
1217
1774
|
|
1218
|
-
#line
|
1775
|
+
#line 1776 "parser.c"
|
1219
1776
|
{
|
1777
|
+
short _widec;
|
1220
1778
|
if ( p == pe )
|
1221
1779
|
goto _test_eof;
|
1222
1780
|
switch ( cs )
|
@@ -1237,7 +1795,7 @@ case 2:
|
|
1237
1795
|
case 32: goto st2;
|
1238
1796
|
case 34: goto tr2;
|
1239
1797
|
case 45: goto tr2;
|
1240
|
-
case 47: goto
|
1798
|
+
case 47: goto st18;
|
1241
1799
|
case 73: goto tr2;
|
1242
1800
|
case 78: goto tr2;
|
1243
1801
|
case 91: goto tr2;
|
@@ -1254,18 +1812,13 @@ case 2:
|
|
1254
1812
|
goto st2;
|
1255
1813
|
goto st0;
|
1256
1814
|
tr2:
|
1257
|
-
#line
|
1815
|
+
#line 815 "parser.rl"
|
1258
1816
|
{
|
1259
1817
|
VALUE v = Qnil;
|
1260
1818
|
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
1261
1819
|
if (np == NULL) {
|
1262
1820
|
p--; {p++; cs = 3; goto _out;}
|
1263
1821
|
} 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
1822
|
{p = (( np))-1;}
|
1270
1823
|
}
|
1271
1824
|
}
|
@@ -1274,15 +1827,23 @@ st3:
|
|
1274
1827
|
if ( ++p == pe )
|
1275
1828
|
goto _test_eof3;
|
1276
1829
|
case 3:
|
1277
|
-
#line
|
1278
|
-
|
1830
|
+
#line 1831 "parser.c"
|
1831
|
+
_widec = (*p);
|
1832
|
+
if ( 44 <= (*p) && (*p) <= 44 ) {
|
1833
|
+
_widec = (short)(128 + ((*p) - -128));
|
1834
|
+
if (
|
1835
|
+
#line 825 "parser.rl"
|
1836
|
+
json->allow_trailing_comma ) _widec += 256;
|
1837
|
+
}
|
1838
|
+
switch( _widec ) {
|
1279
1839
|
case 13: goto st3;
|
1280
1840
|
case 32: goto st3;
|
1281
|
-
case
|
1282
|
-
case 47: goto st9;
|
1841
|
+
case 47: goto st4;
|
1283
1842
|
case 93: goto tr4;
|
1843
|
+
case 300: goto st8;
|
1844
|
+
case 556: goto st13;
|
1284
1845
|
}
|
1285
|
-
if ( 9 <=
|
1846
|
+
if ( 9 <= _widec && _widec <= 10 )
|
1286
1847
|
goto st3;
|
1287
1848
|
goto st0;
|
1288
1849
|
st4:
|
@@ -1290,57 +1851,67 @@ st4:
|
|
1290
1851
|
goto _test_eof4;
|
1291
1852
|
case 4:
|
1292
1853
|
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;
|
1854
|
+
case 42: goto st5;
|
1855
|
+
case 47: goto st7;
|
1305
1856
|
}
|
1306
|
-
if ( (*p) > 10 ) {
|
1307
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1308
|
-
goto tr2;
|
1309
|
-
} else if ( (*p) >= 9 )
|
1310
|
-
goto st4;
|
1311
1857
|
goto st0;
|
1312
1858
|
st5:
|
1313
1859
|
if ( ++p == pe )
|
1314
1860
|
goto _test_eof5;
|
1315
1861
|
case 5:
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
}
|
1320
|
-
goto st0;
|
1862
|
+
if ( (*p) == 42 )
|
1863
|
+
goto st6;
|
1864
|
+
goto st5;
|
1321
1865
|
st6:
|
1322
1866
|
if ( ++p == pe )
|
1323
1867
|
goto _test_eof6;
|
1324
1868
|
case 6:
|
1325
|
-
|
1326
|
-
goto
|
1327
|
-
|
1869
|
+
switch( (*p) ) {
|
1870
|
+
case 42: goto st6;
|
1871
|
+
case 47: goto st3;
|
1872
|
+
}
|
1873
|
+
goto st5;
|
1328
1874
|
st7:
|
1329
1875
|
if ( ++p == pe )
|
1330
1876
|
goto _test_eof7;
|
1331
1877
|
case 7:
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1878
|
+
if ( (*p) == 10 )
|
1879
|
+
goto st3;
|
1880
|
+
goto st7;
|
1881
|
+
tr4:
|
1882
|
+
#line 827 "parser.rl"
|
1883
|
+
{ p--; {p++; cs = 22; goto _out;} }
|
1884
|
+
goto st22;
|
1885
|
+
st22:
|
1886
|
+
if ( ++p == pe )
|
1887
|
+
goto _test_eof22;
|
1888
|
+
case 22:
|
1889
|
+
#line 1890 "parser.c"
|
1890
|
+
goto st0;
|
1337
1891
|
st8:
|
1338
1892
|
if ( ++p == pe )
|
1339
1893
|
goto _test_eof8;
|
1340
1894
|
case 8:
|
1341
|
-
|
1342
|
-
goto
|
1343
|
-
|
1895
|
+
switch( (*p) ) {
|
1896
|
+
case 13: goto st8;
|
1897
|
+
case 32: goto st8;
|
1898
|
+
case 34: goto tr2;
|
1899
|
+
case 45: goto tr2;
|
1900
|
+
case 47: goto st9;
|
1901
|
+
case 73: goto tr2;
|
1902
|
+
case 78: goto tr2;
|
1903
|
+
case 91: goto tr2;
|
1904
|
+
case 102: goto tr2;
|
1905
|
+
case 110: goto tr2;
|
1906
|
+
case 116: goto tr2;
|
1907
|
+
case 123: goto tr2;
|
1908
|
+
}
|
1909
|
+
if ( (*p) > 10 ) {
|
1910
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1911
|
+
goto tr2;
|
1912
|
+
} else if ( (*p) >= 9 )
|
1913
|
+
goto st8;
|
1914
|
+
goto st0;
|
1344
1915
|
st9:
|
1345
1916
|
if ( ++p == pe )
|
1346
1917
|
goto _test_eof9;
|
@@ -1363,7 +1934,7 @@ st11:
|
|
1363
1934
|
case 11:
|
1364
1935
|
switch( (*p) ) {
|
1365
1936
|
case 42: goto st11;
|
1366
|
-
case 47: goto
|
1937
|
+
case 47: goto st8;
|
1367
1938
|
}
|
1368
1939
|
goto st10;
|
1369
1940
|
st12:
|
@@ -1371,50 +1942,252 @@ st12:
|
|
1371
1942
|
goto _test_eof12;
|
1372
1943
|
case 12:
|
1373
1944
|
if ( (*p) == 10 )
|
1374
|
-
goto
|
1945
|
+
goto st8;
|
1375
1946
|
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
1947
|
st13:
|
1387
1948
|
if ( ++p == pe )
|
1388
1949
|
goto _test_eof13;
|
1389
1950
|
case 13:
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1951
|
+
_widec = (*p);
|
1952
|
+
if ( (*p) < 13 ) {
|
1953
|
+
if ( (*p) > 9 ) {
|
1954
|
+
if ( 10 <= (*p) && (*p) <= 10 ) {
|
1955
|
+
_widec = (short)(128 + ((*p) - -128));
|
1956
|
+
if (
|
1957
|
+
#line 825 "parser.rl"
|
1958
|
+
json->allow_trailing_comma ) _widec += 256;
|
1959
|
+
}
|
1960
|
+
} else if ( (*p) >= 9 ) {
|
1961
|
+
_widec = (short)(128 + ((*p) - -128));
|
1962
|
+
if (
|
1963
|
+
#line 825 "parser.rl"
|
1964
|
+
json->allow_trailing_comma ) _widec += 256;
|
1965
|
+
}
|
1966
|
+
} else if ( (*p) > 13 ) {
|
1967
|
+
if ( (*p) > 32 ) {
|
1968
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
1969
|
+
_widec = (short)(128 + ((*p) - -128));
|
1970
|
+
if (
|
1971
|
+
#line 825 "parser.rl"
|
1972
|
+
json->allow_trailing_comma ) _widec += 256;
|
1973
|
+
}
|
1974
|
+
} else if ( (*p) >= 32 ) {
|
1975
|
+
_widec = (short)(128 + ((*p) - -128));
|
1976
|
+
if (
|
1977
|
+
#line 825 "parser.rl"
|
1978
|
+
json->allow_trailing_comma ) _widec += 256;
|
1979
|
+
}
|
1980
|
+
} else {
|
1981
|
+
_widec = (short)(128 + ((*p) - -128));
|
1982
|
+
if (
|
1983
|
+
#line 825 "parser.rl"
|
1984
|
+
json->allow_trailing_comma ) _widec += 256;
|
1985
|
+
}
|
1986
|
+
switch( _widec ) {
|
1987
|
+
case 34: goto tr2;
|
1988
|
+
case 45: goto tr2;
|
1989
|
+
case 73: goto tr2;
|
1990
|
+
case 78: goto tr2;
|
1991
|
+
case 91: goto tr2;
|
1992
|
+
case 93: goto tr4;
|
1993
|
+
case 102: goto tr2;
|
1994
|
+
case 110: goto tr2;
|
1995
|
+
case 116: goto tr2;
|
1996
|
+
case 123: goto tr2;
|
1997
|
+
case 269: goto st8;
|
1998
|
+
case 288: goto st8;
|
1999
|
+
case 303: goto st9;
|
2000
|
+
case 525: goto st13;
|
2001
|
+
case 544: goto st13;
|
2002
|
+
case 559: goto st14;
|
2003
|
+
}
|
2004
|
+
if ( _widec < 265 ) {
|
2005
|
+
if ( 48 <= _widec && _widec <= 57 )
|
2006
|
+
goto tr2;
|
2007
|
+
} else if ( _widec > 266 ) {
|
2008
|
+
if ( 521 <= _widec && _widec <= 522 )
|
2009
|
+
goto st13;
|
2010
|
+
} else
|
2011
|
+
goto st8;
|
1394
2012
|
goto st0;
|
1395
2013
|
st14:
|
1396
2014
|
if ( ++p == pe )
|
1397
2015
|
goto _test_eof14;
|
1398
2016
|
case 14:
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
2017
|
+
_widec = (*p);
|
2018
|
+
if ( (*p) > 42 ) {
|
2019
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
2020
|
+
_widec = (short)(128 + ((*p) - -128));
|
2021
|
+
if (
|
2022
|
+
#line 825 "parser.rl"
|
2023
|
+
json->allow_trailing_comma ) _widec += 256;
|
2024
|
+
}
|
2025
|
+
} else if ( (*p) >= 42 ) {
|
2026
|
+
_widec = (short)(128 + ((*p) - -128));
|
2027
|
+
if (
|
2028
|
+
#line 825 "parser.rl"
|
2029
|
+
json->allow_trailing_comma ) _widec += 256;
|
2030
|
+
}
|
2031
|
+
switch( _widec ) {
|
2032
|
+
case 298: goto st10;
|
2033
|
+
case 303: goto st12;
|
2034
|
+
case 554: goto st15;
|
2035
|
+
case 559: goto st17;
|
2036
|
+
}
|
2037
|
+
goto st0;
|
1402
2038
|
st15:
|
1403
2039
|
if ( ++p == pe )
|
1404
2040
|
goto _test_eof15;
|
1405
2041
|
case 15:
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
2042
|
+
_widec = (*p);
|
2043
|
+
if ( (*p) < 42 ) {
|
2044
|
+
if ( (*p) <= 41 ) {
|
2045
|
+
_widec = (short)(128 + ((*p) - -128));
|
2046
|
+
if (
|
2047
|
+
#line 825 "parser.rl"
|
2048
|
+
json->allow_trailing_comma ) _widec += 256;
|
2049
|
+
}
|
2050
|
+
} else if ( (*p) > 42 ) {
|
2051
|
+
if ( 43 <= (*p) )
|
2052
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2053
|
+
if (
|
2054
|
+
#line 825 "parser.rl"
|
2055
|
+
json->allow_trailing_comma ) _widec += 256;
|
2056
|
+
}
|
2057
|
+
} else {
|
2058
|
+
_widec = (short)(128 + ((*p) - -128));
|
2059
|
+
if (
|
2060
|
+
#line 825 "parser.rl"
|
2061
|
+
json->allow_trailing_comma ) _widec += 256;
|
2062
|
+
}
|
2063
|
+
switch( _widec ) {
|
2064
|
+
case 298: goto st11;
|
2065
|
+
case 554: goto st16;
|
2066
|
+
}
|
2067
|
+
if ( _widec > 383 ) {
|
2068
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2069
|
+
goto st15;
|
2070
|
+
} else if ( _widec >= 128 )
|
2071
|
+
goto st10;
|
2072
|
+
goto st0;
|
1411
2073
|
st16:
|
1412
2074
|
if ( ++p == pe )
|
1413
2075
|
goto _test_eof16;
|
1414
2076
|
case 16:
|
2077
|
+
_widec = (*p);
|
2078
|
+
if ( (*p) < 43 ) {
|
2079
|
+
if ( (*p) > 41 ) {
|
2080
|
+
if ( 42 <= (*p) && (*p) <= 42 ) {
|
2081
|
+
_widec = (short)(128 + ((*p) - -128));
|
2082
|
+
if (
|
2083
|
+
#line 825 "parser.rl"
|
2084
|
+
json->allow_trailing_comma ) _widec += 256;
|
2085
|
+
}
|
2086
|
+
} else {
|
2087
|
+
_widec = (short)(128 + ((*p) - -128));
|
2088
|
+
if (
|
2089
|
+
#line 825 "parser.rl"
|
2090
|
+
json->allow_trailing_comma ) _widec += 256;
|
2091
|
+
}
|
2092
|
+
} else if ( (*p) > 46 ) {
|
2093
|
+
if ( (*p) > 47 ) {
|
2094
|
+
if ( 48 <= (*p) )
|
2095
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2096
|
+
if (
|
2097
|
+
#line 825 "parser.rl"
|
2098
|
+
json->allow_trailing_comma ) _widec += 256;
|
2099
|
+
}
|
2100
|
+
} else if ( (*p) >= 47 ) {
|
2101
|
+
_widec = (short)(128 + ((*p) - -128));
|
2102
|
+
if (
|
2103
|
+
#line 825 "parser.rl"
|
2104
|
+
json->allow_trailing_comma ) _widec += 256;
|
2105
|
+
}
|
2106
|
+
} else {
|
2107
|
+
_widec = (short)(128 + ((*p) - -128));
|
2108
|
+
if (
|
2109
|
+
#line 825 "parser.rl"
|
2110
|
+
json->allow_trailing_comma ) _widec += 256;
|
2111
|
+
}
|
2112
|
+
switch( _widec ) {
|
2113
|
+
case 298: goto st11;
|
2114
|
+
case 303: goto st8;
|
2115
|
+
case 554: goto st16;
|
2116
|
+
case 559: goto st13;
|
2117
|
+
}
|
2118
|
+
if ( _widec > 383 ) {
|
2119
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2120
|
+
goto st15;
|
2121
|
+
} else if ( _widec >= 128 )
|
2122
|
+
goto st10;
|
2123
|
+
goto st0;
|
2124
|
+
st17:
|
2125
|
+
if ( ++p == pe )
|
2126
|
+
goto _test_eof17;
|
2127
|
+
case 17:
|
2128
|
+
_widec = (*p);
|
2129
|
+
if ( (*p) < 10 ) {
|
2130
|
+
if ( (*p) <= 9 ) {
|
2131
|
+
_widec = (short)(128 + ((*p) - -128));
|
2132
|
+
if (
|
2133
|
+
#line 825 "parser.rl"
|
2134
|
+
json->allow_trailing_comma ) _widec += 256;
|
2135
|
+
}
|
2136
|
+
} else if ( (*p) > 10 ) {
|
2137
|
+
if ( 11 <= (*p) )
|
2138
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2139
|
+
if (
|
2140
|
+
#line 825 "parser.rl"
|
2141
|
+
json->allow_trailing_comma ) _widec += 256;
|
2142
|
+
}
|
2143
|
+
} else {
|
2144
|
+
_widec = (short)(128 + ((*p) - -128));
|
2145
|
+
if (
|
2146
|
+
#line 825 "parser.rl"
|
2147
|
+
json->allow_trailing_comma ) _widec += 256;
|
2148
|
+
}
|
2149
|
+
switch( _widec ) {
|
2150
|
+
case 266: goto st8;
|
2151
|
+
case 522: goto st13;
|
2152
|
+
}
|
2153
|
+
if ( _widec > 383 ) {
|
2154
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2155
|
+
goto st17;
|
2156
|
+
} else if ( _widec >= 128 )
|
2157
|
+
goto st12;
|
2158
|
+
goto st0;
|
2159
|
+
st18:
|
2160
|
+
if ( ++p == pe )
|
2161
|
+
goto _test_eof18;
|
2162
|
+
case 18:
|
2163
|
+
switch( (*p) ) {
|
2164
|
+
case 42: goto st19;
|
2165
|
+
case 47: goto st21;
|
2166
|
+
}
|
2167
|
+
goto st0;
|
2168
|
+
st19:
|
2169
|
+
if ( ++p == pe )
|
2170
|
+
goto _test_eof19;
|
2171
|
+
case 19:
|
2172
|
+
if ( (*p) == 42 )
|
2173
|
+
goto st20;
|
2174
|
+
goto st19;
|
2175
|
+
st20:
|
2176
|
+
if ( ++p == pe )
|
2177
|
+
goto _test_eof20;
|
2178
|
+
case 20:
|
2179
|
+
switch( (*p) ) {
|
2180
|
+
case 42: goto st20;
|
2181
|
+
case 47: goto st2;
|
2182
|
+
}
|
2183
|
+
goto st19;
|
2184
|
+
st21:
|
2185
|
+
if ( ++p == pe )
|
2186
|
+
goto _test_eof21;
|
2187
|
+
case 21:
|
1415
2188
|
if ( (*p) == 10 )
|
1416
2189
|
goto st2;
|
1417
|
-
goto
|
2190
|
+
goto st21;
|
1418
2191
|
}
|
1419
2192
|
_test_eof2: cs = 2; goto _test_eof;
|
1420
2193
|
_test_eof3: cs = 3; goto _test_eof;
|
@@ -1422,24 +2195,45 @@ case 16:
|
|
1422
2195
|
_test_eof5: cs = 5; goto _test_eof;
|
1423
2196
|
_test_eof6: cs = 6; goto _test_eof;
|
1424
2197
|
_test_eof7: cs = 7; goto _test_eof;
|
2198
|
+
_test_eof22: cs = 22; goto _test_eof;
|
1425
2199
|
_test_eof8: cs = 8; goto _test_eof;
|
1426
2200
|
_test_eof9: cs = 9; goto _test_eof;
|
1427
2201
|
_test_eof10: cs = 10; goto _test_eof;
|
1428
2202
|
_test_eof11: cs = 11; goto _test_eof;
|
1429
2203
|
_test_eof12: cs = 12; goto _test_eof;
|
1430
|
-
_test_eof17: cs = 17; goto _test_eof;
|
1431
2204
|
_test_eof13: cs = 13; goto _test_eof;
|
1432
2205
|
_test_eof14: cs = 14; goto _test_eof;
|
1433
2206
|
_test_eof15: cs = 15; goto _test_eof;
|
1434
2207
|
_test_eof16: cs = 16; goto _test_eof;
|
2208
|
+
_test_eof17: cs = 17; goto _test_eof;
|
2209
|
+
_test_eof18: cs = 18; goto _test_eof;
|
2210
|
+
_test_eof19: cs = 19; goto _test_eof;
|
2211
|
+
_test_eof20: cs = 20; goto _test_eof;
|
2212
|
+
_test_eof21: cs = 21; goto _test_eof;
|
1435
2213
|
|
1436
2214
|
_test_eof: {}
|
1437
2215
|
_out: {}
|
1438
2216
|
}
|
1439
2217
|
|
1440
|
-
#line
|
2218
|
+
#line 848 "parser.rl"
|
1441
2219
|
|
1442
2220
|
if(cs >= JSON_array_first_final) {
|
2221
|
+
long count = json->stack->head - stack_head;
|
2222
|
+
|
2223
|
+
if (RB_UNLIKELY(json->array_class)) {
|
2224
|
+
VALUE array = rb_class_new_instance(0, 0, json->array_class);
|
2225
|
+
VALUE *items = rvalue_stack_peek(json->stack, count);
|
2226
|
+
long index;
|
2227
|
+
for (index = 0; index < count; index++) {
|
2228
|
+
rb_funcall(array, i_leftshift, 1, items[index]);
|
2229
|
+
}
|
2230
|
+
*result = array;
|
2231
|
+
} else {
|
2232
|
+
VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(json->stack, count));
|
2233
|
+
*result = array;
|
2234
|
+
}
|
2235
|
+
rvalue_stack_pop(json->stack, count);
|
2236
|
+
|
1443
2237
|
return p + 1;
|
1444
2238
|
} else {
|
1445
2239
|
raise_parse_error("unexpected token at '%s'", p);
|
@@ -1447,29 +2241,81 @@ case 16:
|
|
1447
2241
|
}
|
1448
2242
|
}
|
1449
2243
|
|
1450
|
-
static const
|
1451
|
-
|
2244
|
+
static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize)
|
2245
|
+
{
|
2246
|
+
if (symbolize) {
|
2247
|
+
intern = true;
|
2248
|
+
}
|
2249
|
+
VALUE result;
|
2250
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
2251
|
+
if (intern) {
|
2252
|
+
result = rb_enc_interned_str(start, (long)(end - start), enc_utf8);
|
2253
|
+
} else {
|
2254
|
+
result = rb_utf8_str_new(start, (long)(end - start));
|
2255
|
+
}
|
2256
|
+
# else
|
2257
|
+
result = rb_utf8_str_new(start, (long)(end - start));
|
2258
|
+
if (intern) {
|
2259
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
2260
|
+
}
|
2261
|
+
# endif
|
2262
|
+
|
2263
|
+
if (symbolize) {
|
2264
|
+
result = rb_str_intern(result);
|
2265
|
+
}
|
2266
|
+
|
2267
|
+
return result;
|
2268
|
+
}
|
2269
|
+
|
2270
|
+
static VALUE json_string_fastpath(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
|
2271
|
+
{
|
2272
|
+
size_t bufferSize = stringEnd - string;
|
2273
|
+
|
2274
|
+
if (is_name && json->in_array) {
|
2275
|
+
VALUE cached_key;
|
2276
|
+
if (RB_UNLIKELY(symbolize)) {
|
2277
|
+
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
|
2278
|
+
} else {
|
2279
|
+
cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
|
2280
|
+
}
|
2281
|
+
|
2282
|
+
if (RB_LIKELY(cached_key)) {
|
2283
|
+
return cached_key;
|
2284
|
+
}
|
2285
|
+
}
|
2286
|
+
|
2287
|
+
return build_string(string, stringEnd, intern, symbolize);
|
2288
|
+
}
|
2289
|
+
|
2290
|
+
static VALUE json_string_unescape(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
|
1452
2291
|
{
|
1453
|
-
VALUE result = Qnil;
|
1454
2292
|
size_t bufferSize = stringEnd - string;
|
1455
2293
|
char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
|
1456
2294
|
int unescape_len;
|
1457
2295
|
char buf[4];
|
1458
2296
|
|
1459
|
-
if (
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
2297
|
+
if (is_name && json->in_array) {
|
2298
|
+
VALUE cached_key;
|
2299
|
+
if (RB_UNLIKELY(symbolize)) {
|
2300
|
+
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
|
2301
|
+
} else {
|
2302
|
+
cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
|
2303
|
+
}
|
2304
|
+
|
2305
|
+
if (RB_LIKELY(cached_key)) {
|
2306
|
+
return cached_key;
|
2307
|
+
}
|
2308
|
+
}
|
2309
|
+
|
2310
|
+
pe = memchr(p, '\\', bufferSize);
|
2311
|
+
if (RB_UNLIKELY(pe == NULL)) {
|
2312
|
+
return build_string(string, stringEnd, intern, symbolize);
|
1471
2313
|
}
|
1472
2314
|
|
2315
|
+
VALUE result = rb_str_buf_new(bufferSize);
|
2316
|
+
rb_enc_associate_index(result, utf8_encindex);
|
2317
|
+
buffer = bufferStart = RSTRING_PTR(result);
|
2318
|
+
|
1473
2319
|
while (pe < stringEnd) {
|
1474
2320
|
if (*pe == '\\') {
|
1475
2321
|
unescape = (char *) "?";
|
@@ -1502,9 +2348,6 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1502
2348
|
break;
|
1503
2349
|
case 'u':
|
1504
2350
|
if (pe > stringEnd - 4) {
|
1505
|
-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
1506
|
-
ruby_xfree(bufferStart);
|
1507
|
-
}
|
1508
2351
|
raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
|
1509
2352
|
} else {
|
1510
2353
|
uint32_t ch = unescape_unicode((unsigned char *) ++pe);
|
@@ -1522,9 +2365,6 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1522
2365
|
if ((ch & 0xFC00) == 0xD800) {
|
1523
2366
|
pe++;
|
1524
2367
|
if (pe > stringEnd - 6) {
|
1525
|
-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
1526
|
-
ruby_xfree(bufferStart);
|
1527
|
-
}
|
1528
2368
|
raise_parse_error("incomplete surrogate pair at '%s'", p);
|
1529
2369
|
}
|
1530
2370
|
if (pe[0] == '\\' && pe[1] == 'u') {
|
@@ -1557,56 +2397,27 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1557
2397
|
MEMCPY(buffer, p, char, pe - p);
|
1558
2398
|
buffer += pe - p;
|
1559
2399
|
}
|
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
|
2400
|
+
rb_str_set_len(result, buffer - bufferStart);
|
1592
2401
|
|
1593
2402
|
if (symbolize) {
|
1594
|
-
|
2403
|
+
result = rb_str_intern(result);
|
2404
|
+
} else if (intern) {
|
2405
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
1595
2406
|
}
|
1596
2407
|
|
1597
2408
|
return result;
|
1598
2409
|
}
|
1599
2410
|
|
1600
2411
|
|
1601
|
-
#line
|
2412
|
+
#line 2413 "parser.c"
|
1602
2413
|
enum {JSON_string_start = 1};
|
1603
|
-
enum {JSON_string_first_final =
|
2414
|
+
enum {JSON_string_first_final = 9};
|
1604
2415
|
enum {JSON_string_error = 0};
|
1605
2416
|
|
1606
2417
|
enum {JSON_string_en_main = 1};
|
1607
2418
|
|
1608
2419
|
|
1609
|
-
#line
|
2420
|
+
#line 1071 "parser.rl"
|
1610
2421
|
|
1611
2422
|
|
1612
2423
|
static int
|
@@ -1627,15 +2438,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1627
2438
|
VALUE match_string;
|
1628
2439
|
|
1629
2440
|
|
1630
|
-
#line
|
2441
|
+
#line 2442 "parser.c"
|
1631
2442
|
{
|
1632
2443
|
cs = JSON_string_start;
|
1633
2444
|
}
|
1634
2445
|
|
1635
|
-
#line
|
2446
|
+
#line 1091 "parser.rl"
|
1636
2447
|
json->memo = p;
|
1637
2448
|
|
1638
|
-
#line
|
2449
|
+
#line 2450 "parser.c"
|
1639
2450
|
{
|
1640
2451
|
if ( p == pe )
|
1641
2452
|
goto _test_eof;
|
@@ -1660,47 +2471,56 @@ case 2:
|
|
1660
2471
|
goto st0;
|
1661
2472
|
goto st2;
|
1662
2473
|
tr2:
|
1663
|
-
#line
|
2474
|
+
#line 1053 "parser.rl"
|
1664
2475
|
{
|
1665
|
-
*result =
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
} else {
|
1670
|
-
{p = (( p + 1))-1;}
|
1671
|
-
}
|
2476
|
+
*result = json_string_fastpath(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2477
|
+
{p = (( p + 1))-1;}
|
2478
|
+
p--;
|
2479
|
+
{p++; cs = 9; goto _out;}
|
1672
2480
|
}
|
1673
|
-
#line
|
1674
|
-
{
|
1675
|
-
|
1676
|
-
|
2481
|
+
#line 1046 "parser.rl"
|
2482
|
+
{
|
2483
|
+
*result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2484
|
+
{p = (( p + 1))-1;}
|
2485
|
+
p--;
|
2486
|
+
{p++; cs = 9; goto _out;}
|
2487
|
+
}
|
2488
|
+
goto st9;
|
2489
|
+
tr6:
|
2490
|
+
#line 1046 "parser.rl"
|
2491
|
+
{
|
2492
|
+
*result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2493
|
+
{p = (( p + 1))-1;}
|
2494
|
+
p--;
|
2495
|
+
{p++; cs = 9; goto _out;}
|
2496
|
+
}
|
2497
|
+
goto st9;
|
2498
|
+
st9:
|
1677
2499
|
if ( ++p == pe )
|
1678
|
-
goto
|
1679
|
-
case
|
1680
|
-
#line
|
2500
|
+
goto _test_eof9;
|
2501
|
+
case 9:
|
2502
|
+
#line 2503 "parser.c"
|
1681
2503
|
goto st0;
|
1682
2504
|
st3:
|
1683
2505
|
if ( ++p == pe )
|
1684
2506
|
goto _test_eof3;
|
1685
2507
|
case 3:
|
1686
2508
|
if ( (*p) == 117 )
|
1687
|
-
goto
|
2509
|
+
goto st5;
|
1688
2510
|
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
1689
2511
|
goto st0;
|
1690
|
-
goto
|
2512
|
+
goto st4;
|
1691
2513
|
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;
|
2514
|
+
if ( ++p == pe )
|
2515
|
+
goto _test_eof4;
|
2516
|
+
case 4:
|
2517
|
+
switch( (*p) ) {
|
2518
|
+
case 34: goto tr6;
|
2519
|
+
case 92: goto st3;
|
2520
|
+
}
|
2521
|
+
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
2522
|
+
goto st0;
|
2523
|
+
goto st4;
|
1704
2524
|
st5:
|
1705
2525
|
if ( ++p == pe )
|
1706
2526
|
goto _test_eof5;
|
@@ -1733,27 +2553,41 @@ st7:
|
|
1733
2553
|
case 7:
|
1734
2554
|
if ( (*p) < 65 ) {
|
1735
2555
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1736
|
-
goto
|
2556
|
+
goto st8;
|
1737
2557
|
} else if ( (*p) > 70 ) {
|
1738
2558
|
if ( 97 <= (*p) && (*p) <= 102 )
|
1739
|
-
goto
|
2559
|
+
goto st8;
|
1740
2560
|
} else
|
1741
|
-
goto
|
2561
|
+
goto st8;
|
2562
|
+
goto st0;
|
2563
|
+
st8:
|
2564
|
+
if ( ++p == pe )
|
2565
|
+
goto _test_eof8;
|
2566
|
+
case 8:
|
2567
|
+
if ( (*p) < 65 ) {
|
2568
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
2569
|
+
goto st4;
|
2570
|
+
} else if ( (*p) > 70 ) {
|
2571
|
+
if ( 97 <= (*p) && (*p) <= 102 )
|
2572
|
+
goto st4;
|
2573
|
+
} else
|
2574
|
+
goto st4;
|
1742
2575
|
goto st0;
|
1743
2576
|
}
|
1744
2577
|
_test_eof2: cs = 2; goto _test_eof;
|
1745
|
-
|
2578
|
+
_test_eof9: cs = 9; goto _test_eof;
|
1746
2579
|
_test_eof3: cs = 3; goto _test_eof;
|
1747
2580
|
_test_eof4: cs = 4; goto _test_eof;
|
1748
2581
|
_test_eof5: cs = 5; goto _test_eof;
|
1749
2582
|
_test_eof6: cs = 6; goto _test_eof;
|
1750
2583
|
_test_eof7: cs = 7; goto _test_eof;
|
2584
|
+
_test_eof8: cs = 8; goto _test_eof;
|
1751
2585
|
|
1752
2586
|
_test_eof: {}
|
1753
2587
|
_out: {}
|
1754
2588
|
}
|
1755
2589
|
|
1756
|
-
#line
|
2590
|
+
#line 1093 "parser.rl"
|
1757
2591
|
|
1758
2592
|
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
1759
2593
|
VALUE klass;
|
@@ -1789,18 +2623,78 @@ static VALUE convert_encoding(VALUE source)
|
|
1789
2623
|
{
|
1790
2624
|
int encindex = RB_ENCODING_GET(source);
|
1791
2625
|
|
1792
|
-
if (encindex == utf8_encindex) {
|
2626
|
+
if (RB_LIKELY(encindex == utf8_encindex)) {
|
1793
2627
|
return source;
|
1794
2628
|
}
|
1795
2629
|
|
1796
2630
|
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
|
2631
|
+
// For historical reason, we silently reinterpret binary strings as UTF-8
|
1800
2632
|
return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
|
1801
2633
|
}
|
1802
2634
|
|
1803
|
-
return
|
2635
|
+
return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
|
2636
|
+
}
|
2637
|
+
|
2638
|
+
static int configure_parser_i(VALUE key, VALUE val, VALUE data)
|
2639
|
+
{
|
2640
|
+
JSON_Parser *json = (JSON_Parser *)data;
|
2641
|
+
|
2642
|
+
if (key == sym_max_nesting) { json->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
|
2643
|
+
else if (key == sym_allow_nan) { json->allow_nan = RTEST(val); }
|
2644
|
+
else if (key == sym_allow_trailing_comma) { json->allow_trailing_comma = RTEST(val); }
|
2645
|
+
else if (key == sym_symbolize_names) { json->symbolize_names = RTEST(val); }
|
2646
|
+
else if (key == sym_freeze) { json->freeze = RTEST(val); }
|
2647
|
+
else if (key == sym_create_id) { json->create_id = RTEST(val) ? val : Qfalse; }
|
2648
|
+
else if (key == sym_object_class) { json->object_class = RTEST(val) ? val : Qfalse; }
|
2649
|
+
else if (key == sym_array_class) { json->array_class = RTEST(val) ? val : Qfalse; }
|
2650
|
+
else if (key == sym_decimal_class) { json->decimal_class = RTEST(val) ? val : Qfalse; }
|
2651
|
+
else if (key == sym_match_string) { json->match_string = RTEST(val) ? val : Qfalse; }
|
2652
|
+
else if (key == sym_create_additions) {
|
2653
|
+
if (NIL_P(val)) {
|
2654
|
+
json->create_additions = true;
|
2655
|
+
json->deprecated_create_additions = true;
|
2656
|
+
} else {
|
2657
|
+
json->create_additions = RTEST(val);
|
2658
|
+
json->deprecated_create_additions = false;
|
2659
|
+
}
|
2660
|
+
}
|
2661
|
+
|
2662
|
+
return ST_CONTINUE;
|
2663
|
+
}
|
2664
|
+
|
2665
|
+
static void parser_init(JSON_Parser *json, VALUE source, VALUE opts)
|
2666
|
+
{
|
2667
|
+
if (json->Vsource) {
|
2668
|
+
rb_raise(rb_eTypeError, "already initialized instance");
|
2669
|
+
}
|
2670
|
+
|
2671
|
+
json->fbuffer.initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
|
2672
|
+
json->max_nesting = 100;
|
2673
|
+
|
2674
|
+
if (!NIL_P(opts)) {
|
2675
|
+
Check_Type(opts, T_HASH);
|
2676
|
+
if (RHASH_SIZE(opts) > 0) {
|
2677
|
+
// We assume in most cases few keys are set so it's faster to go over
|
2678
|
+
// the provided keys than to check all possible keys.
|
2679
|
+
rb_hash_foreach(opts, configure_parser_i, (VALUE)json);
|
2680
|
+
|
2681
|
+
if (json->symbolize_names && json->create_additions) {
|
2682
|
+
rb_raise(rb_eArgError,
|
2683
|
+
"options :symbolize_names and :create_additions cannot be "
|
2684
|
+
" used in conjunction");
|
2685
|
+
}
|
2686
|
+
|
2687
|
+
if (json->create_additions && !json->create_id) {
|
2688
|
+
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
2689
|
+
}
|
2690
|
+
}
|
2691
|
+
|
2692
|
+
}
|
2693
|
+
source = convert_encoding(StringValue(source));
|
2694
|
+
StringValue(source);
|
2695
|
+
json->len = RSTRING_LEN(source);
|
2696
|
+
json->source = RSTRING_PTR(source);
|
2697
|
+
json->Vsource = source;
|
1804
2698
|
}
|
1805
2699
|
|
1806
2700
|
/*
|
@@ -1837,116 +2731,16 @@ static VALUE convert_encoding(VALUE source)
|
|
1837
2731
|
*/
|
1838
2732
|
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
1839
2733
|
{
|
1840
|
-
VALUE source, opts;
|
1841
2734
|
GET_PARSER_INIT;
|
1842
2735
|
|
1843
|
-
if (json->Vsource) {
|
1844
|
-
rb_raise(rb_eTypeError, "already initialized instance");
|
1845
|
-
}
|
1846
|
-
|
1847
2736
|
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
2737
|
|
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;
|
2738
|
+
parser_init(json, argv[0], argc == 2 ? argv[1] : Qnil);
|
1945
2739
|
return self;
|
1946
2740
|
}
|
1947
2741
|
|
1948
2742
|
|
1949
|
-
#line
|
2743
|
+
#line 2744 "parser.c"
|
1950
2744
|
enum {JSON_start = 1};
|
1951
2745
|
enum {JSON_first_final = 10};
|
1952
2746
|
enum {JSON_error = 0};
|
@@ -1954,7 +2748,7 @@ enum {JSON_error = 0};
|
|
1954
2748
|
enum {JSON_en_main = 1};
|
1955
2749
|
|
1956
2750
|
|
1957
|
-
#line
|
2751
|
+
#line 1259 "parser.rl"
|
1958
2752
|
|
1959
2753
|
|
1960
2754
|
/*
|
@@ -1971,17 +2765,206 @@ static VALUE cParser_parse(VALUE self)
|
|
1971
2765
|
VALUE result = Qnil;
|
1972
2766
|
GET_PARSER;
|
1973
2767
|
|
2768
|
+
char stack_buffer[FBUFFER_STACK_SIZE];
|
2769
|
+
fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
|
2770
|
+
|
2771
|
+
VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
|
2772
|
+
rvalue_stack stack = {
|
2773
|
+
.type = RVALUE_STACK_STACK_ALLOCATED,
|
2774
|
+
.ptr = rvalue_stack_buffer,
|
2775
|
+
.capa = RVALUE_STACK_INITIAL_CAPA,
|
2776
|
+
};
|
2777
|
+
json->stack = &stack;
|
2778
|
+
|
2779
|
+
|
2780
|
+
#line 2781 "parser.c"
|
2781
|
+
{
|
2782
|
+
cs = JSON_start;
|
2783
|
+
}
|
2784
|
+
|
2785
|
+
#line 1287 "parser.rl"
|
2786
|
+
p = json->source;
|
2787
|
+
pe = p + json->len;
|
2788
|
+
|
2789
|
+
#line 2790 "parser.c"
|
2790
|
+
{
|
2791
|
+
if ( p == pe )
|
2792
|
+
goto _test_eof;
|
2793
|
+
switch ( cs )
|
2794
|
+
{
|
2795
|
+
st1:
|
2796
|
+
if ( ++p == pe )
|
2797
|
+
goto _test_eof1;
|
2798
|
+
case 1:
|
2799
|
+
switch( (*p) ) {
|
2800
|
+
case 13: goto st1;
|
2801
|
+
case 32: goto st1;
|
2802
|
+
case 34: goto tr2;
|
2803
|
+
case 45: goto tr2;
|
2804
|
+
case 47: goto st6;
|
2805
|
+
case 73: goto tr2;
|
2806
|
+
case 78: goto tr2;
|
2807
|
+
case 91: goto tr2;
|
2808
|
+
case 102: goto tr2;
|
2809
|
+
case 110: goto tr2;
|
2810
|
+
case 116: goto tr2;
|
2811
|
+
case 123: goto tr2;
|
2812
|
+
}
|
2813
|
+
if ( (*p) > 10 ) {
|
2814
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
2815
|
+
goto tr2;
|
2816
|
+
} else if ( (*p) >= 9 )
|
2817
|
+
goto st1;
|
2818
|
+
goto st0;
|
2819
|
+
st0:
|
2820
|
+
cs = 0;
|
2821
|
+
goto _out;
|
2822
|
+
tr2:
|
2823
|
+
#line 1251 "parser.rl"
|
2824
|
+
{
|
2825
|
+
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
2826
|
+
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
2827
|
+
}
|
2828
|
+
goto st10;
|
2829
|
+
st10:
|
2830
|
+
if ( ++p == pe )
|
2831
|
+
goto _test_eof10;
|
2832
|
+
case 10:
|
2833
|
+
#line 2834 "parser.c"
|
2834
|
+
switch( (*p) ) {
|
2835
|
+
case 13: goto st10;
|
2836
|
+
case 32: goto st10;
|
2837
|
+
case 47: goto st2;
|
2838
|
+
}
|
2839
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
2840
|
+
goto st10;
|
2841
|
+
goto st0;
|
2842
|
+
st2:
|
2843
|
+
if ( ++p == pe )
|
2844
|
+
goto _test_eof2;
|
2845
|
+
case 2:
|
2846
|
+
switch( (*p) ) {
|
2847
|
+
case 42: goto st3;
|
2848
|
+
case 47: goto st5;
|
2849
|
+
}
|
2850
|
+
goto st0;
|
2851
|
+
st3:
|
2852
|
+
if ( ++p == pe )
|
2853
|
+
goto _test_eof3;
|
2854
|
+
case 3:
|
2855
|
+
if ( (*p) == 42 )
|
2856
|
+
goto st4;
|
2857
|
+
goto st3;
|
2858
|
+
st4:
|
2859
|
+
if ( ++p == pe )
|
2860
|
+
goto _test_eof4;
|
2861
|
+
case 4:
|
2862
|
+
switch( (*p) ) {
|
2863
|
+
case 42: goto st4;
|
2864
|
+
case 47: goto st10;
|
2865
|
+
}
|
2866
|
+
goto st3;
|
2867
|
+
st5:
|
2868
|
+
if ( ++p == pe )
|
2869
|
+
goto _test_eof5;
|
2870
|
+
case 5:
|
2871
|
+
if ( (*p) == 10 )
|
2872
|
+
goto st10;
|
2873
|
+
goto st5;
|
2874
|
+
st6:
|
2875
|
+
if ( ++p == pe )
|
2876
|
+
goto _test_eof6;
|
2877
|
+
case 6:
|
2878
|
+
switch( (*p) ) {
|
2879
|
+
case 42: goto st7;
|
2880
|
+
case 47: goto st9;
|
2881
|
+
}
|
2882
|
+
goto st0;
|
2883
|
+
st7:
|
2884
|
+
if ( ++p == pe )
|
2885
|
+
goto _test_eof7;
|
2886
|
+
case 7:
|
2887
|
+
if ( (*p) == 42 )
|
2888
|
+
goto st8;
|
2889
|
+
goto st7;
|
2890
|
+
st8:
|
2891
|
+
if ( ++p == pe )
|
2892
|
+
goto _test_eof8;
|
2893
|
+
case 8:
|
2894
|
+
switch( (*p) ) {
|
2895
|
+
case 42: goto st8;
|
2896
|
+
case 47: goto st1;
|
2897
|
+
}
|
2898
|
+
goto st7;
|
2899
|
+
st9:
|
2900
|
+
if ( ++p == pe )
|
2901
|
+
goto _test_eof9;
|
2902
|
+
case 9:
|
2903
|
+
if ( (*p) == 10 )
|
2904
|
+
goto st1;
|
2905
|
+
goto st9;
|
2906
|
+
}
|
2907
|
+
_test_eof1: cs = 1; goto _test_eof;
|
2908
|
+
_test_eof10: cs = 10; goto _test_eof;
|
2909
|
+
_test_eof2: cs = 2; goto _test_eof;
|
2910
|
+
_test_eof3: cs = 3; goto _test_eof;
|
2911
|
+
_test_eof4: cs = 4; goto _test_eof;
|
2912
|
+
_test_eof5: cs = 5; goto _test_eof;
|
2913
|
+
_test_eof6: cs = 6; goto _test_eof;
|
2914
|
+
_test_eof7: cs = 7; goto _test_eof;
|
2915
|
+
_test_eof8: cs = 8; goto _test_eof;
|
2916
|
+
_test_eof9: cs = 9; goto _test_eof;
|
2917
|
+
|
2918
|
+
_test_eof: {}
|
2919
|
+
_out: {}
|
2920
|
+
}
|
2921
|
+
|
2922
|
+
#line 1290 "parser.rl"
|
2923
|
+
|
2924
|
+
if (json->stack_handle) {
|
2925
|
+
rvalue_stack_eagerly_release(json->stack_handle);
|
2926
|
+
}
|
2927
|
+
|
2928
|
+
if (cs >= JSON_first_final && p == pe) {
|
2929
|
+
return result;
|
2930
|
+
} else {
|
2931
|
+
raise_parse_error("unexpected token at '%s'", p);
|
2932
|
+
return Qnil;
|
2933
|
+
}
|
2934
|
+
}
|
2935
|
+
|
2936
|
+
static VALUE cParser_m_parse(VALUE klass, VALUE source, VALUE opts)
|
2937
|
+
{
|
2938
|
+
char *p, *pe;
|
2939
|
+
int cs = EVIL;
|
2940
|
+
VALUE result = Qnil;
|
2941
|
+
|
2942
|
+
JSON_Parser _parser = {0};
|
2943
|
+
JSON_Parser *json = &_parser;
|
2944
|
+
parser_init(json, source, opts);
|
2945
|
+
|
2946
|
+
char stack_buffer[FBUFFER_STACK_SIZE];
|
2947
|
+
fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
|
2948
|
+
|
2949
|
+
VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
|
2950
|
+
rvalue_stack stack = {
|
2951
|
+
.type = RVALUE_STACK_STACK_ALLOCATED,
|
2952
|
+
.ptr = rvalue_stack_buffer,
|
2953
|
+
.capa = RVALUE_STACK_INITIAL_CAPA,
|
2954
|
+
};
|
2955
|
+
json->stack = &stack;
|
1974
2956
|
|
1975
|
-
|
2957
|
+
|
2958
|
+
#line 2959 "parser.c"
|
1976
2959
|
{
|
1977
2960
|
cs = JSON_start;
|
1978
2961
|
}
|
1979
2962
|
|
1980
|
-
#line
|
2963
|
+
#line 1325 "parser.rl"
|
1981
2964
|
p = json->source;
|
1982
2965
|
pe = p + json->len;
|
1983
2966
|
|
1984
|
-
#line
|
2967
|
+
#line 2968 "parser.c"
|
1985
2968
|
{
|
1986
2969
|
if ( p == pe )
|
1987
2970
|
goto _test_eof;
|
@@ -2015,7 +2998,7 @@ st0:
|
|
2015
2998
|
cs = 0;
|
2016
2999
|
goto _out;
|
2017
3000
|
tr2:
|
2018
|
-
#line
|
3001
|
+
#line 1251 "parser.rl"
|
2019
3002
|
{
|
2020
3003
|
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
2021
3004
|
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
@@ -2025,7 +3008,7 @@ st10:
|
|
2025
3008
|
if ( ++p == pe )
|
2026
3009
|
goto _test_eof10;
|
2027
3010
|
case 10:
|
2028
|
-
#line
|
3011
|
+
#line 3012 "parser.c"
|
2029
3012
|
switch( (*p) ) {
|
2030
3013
|
case 13: goto st10;
|
2031
3014
|
case 32: goto st10;
|
@@ -2114,7 +3097,11 @@ case 9:
|
|
2114
3097
|
_out: {}
|
2115
3098
|
}
|
2116
3099
|
|
2117
|
-
#line
|
3100
|
+
#line 1328 "parser.rl"
|
3101
|
+
|
3102
|
+
if (json->stack_handle) {
|
3103
|
+
rvalue_stack_eagerly_release(json->stack_handle);
|
3104
|
+
}
|
2118
3105
|
|
2119
3106
|
if (cs >= JSON_first_final && p == pe) {
|
2120
3107
|
return result;
|
@@ -2133,19 +3120,23 @@ static void JSON_mark(void *ptr)
|
|
2133
3120
|
rb_gc_mark(json->array_class);
|
2134
3121
|
rb_gc_mark(json->decimal_class);
|
2135
3122
|
rb_gc_mark(json->match_string);
|
3123
|
+
rb_gc_mark(json->stack_handle);
|
3124
|
+
|
3125
|
+
const VALUE *name_cache_entries = &json->name_cache.entries[0];
|
3126
|
+
rb_gc_mark_locations(name_cache_entries, name_cache_entries + json->name_cache.length);
|
2136
3127
|
}
|
2137
3128
|
|
2138
3129
|
static void JSON_free(void *ptr)
|
2139
3130
|
{
|
2140
3131
|
JSON_Parser *json = ptr;
|
2141
|
-
fbuffer_free(json->fbuffer);
|
3132
|
+
fbuffer_free(&json->fbuffer);
|
2142
3133
|
ruby_xfree(json);
|
2143
3134
|
}
|
2144
3135
|
|
2145
3136
|
static size_t JSON_memsize(const void *ptr)
|
2146
3137
|
{
|
2147
3138
|
const JSON_Parser *json = ptr;
|
2148
|
-
return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
|
3139
|
+
return sizeof(*json) + FBUFFER_CAPA(&json->fbuffer);
|
2149
3140
|
}
|
2150
3141
|
|
2151
3142
|
static const rb_data_type_t JSON_Parser_type = {
|
@@ -2159,7 +3150,7 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
|
|
2159
3150
|
{
|
2160
3151
|
JSON_Parser *json;
|
2161
3152
|
VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
|
2162
|
-
json->fbuffer
|
3153
|
+
fbuffer_stack_init(&json->fbuffer, 0, NULL, 0);
|
2163
3154
|
return obj;
|
2164
3155
|
}
|
2165
3156
|
|
@@ -2193,6 +3184,8 @@ void Init_parser(void)
|
|
2193
3184
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
2194
3185
|
rb_define_method(cParser, "source", cParser_source, 0);
|
2195
3186
|
|
3187
|
+
rb_define_singleton_method(cParser, "parse", cParser_m_parse, 2);
|
3188
|
+
|
2196
3189
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
2197
3190
|
rb_gc_register_mark_object(CNaN);
|
2198
3191
|
|
@@ -2202,30 +3195,38 @@ void Init_parser(void)
|
|
2202
3195
|
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
|
2203
3196
|
rb_gc_register_mark_object(CMinusInfinity);
|
2204
3197
|
|
3198
|
+
rb_global_variable(&Encoding_UTF_8);
|
3199
|
+
Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8"));
|
3200
|
+
|
3201
|
+
sym_max_nesting = ID2SYM(rb_intern("max_nesting"));
|
3202
|
+
sym_allow_nan = ID2SYM(rb_intern("allow_nan"));
|
3203
|
+
sym_allow_trailing_comma = ID2SYM(rb_intern("allow_trailing_comma"));
|
3204
|
+
sym_symbolize_names = ID2SYM(rb_intern("symbolize_names"));
|
3205
|
+
sym_freeze = ID2SYM(rb_intern("freeze"));
|
3206
|
+
sym_create_additions = ID2SYM(rb_intern("create_additions"));
|
3207
|
+
sym_create_id = ID2SYM(rb_intern("create_id"));
|
3208
|
+
sym_object_class = ID2SYM(rb_intern("object_class"));
|
3209
|
+
sym_array_class = ID2SYM(rb_intern("array_class"));
|
3210
|
+
sym_decimal_class = ID2SYM(rb_intern("decimal_class"));
|
3211
|
+
sym_match_string = ID2SYM(rb_intern("match_string"));
|
3212
|
+
|
3213
|
+
i_create_id = rb_intern("create_id");
|
2205
3214
|
i_json_creatable_p = rb_intern("json_creatable?");
|
2206
3215
|
i_json_create = rb_intern("json_create");
|
2207
|
-
i_create_id = rb_intern("create_id");
|
2208
|
-
i_create_additions = rb_intern("create_additions");
|
2209
3216
|
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
3217
|
i_match = rb_intern("match");
|
2217
|
-
i_match_string = rb_intern("match_string");
|
2218
3218
|
i_deep_const_get = rb_intern("deep_const_get");
|
2219
3219
|
i_aset = rb_intern("[]=");
|
2220
3220
|
i_aref = rb_intern("[]");
|
2221
3221
|
i_leftshift = rb_intern("<<");
|
2222
3222
|
i_new = rb_intern("new");
|
2223
3223
|
i_try_convert = rb_intern("try_convert");
|
2224
|
-
i_freeze = rb_intern("freeze");
|
2225
3224
|
i_uminus = rb_intern("-@");
|
3225
|
+
i_encode = rb_intern("encode");
|
2226
3226
|
|
2227
3227
|
binary_encindex = rb_ascii8bit_encindex();
|
2228
3228
|
utf8_encindex = rb_utf8_encindex();
|
3229
|
+
enc_utf8 = rb_utf8_encoding();
|
2229
3230
|
}
|
2230
3231
|
|
2231
3232
|
/*
|