json 2.7.5 → 2.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +36 -0
- data/README.md +8 -77
- data/ext/json/ext/fbuffer/fbuffer.h +122 -54
- data/ext/json/ext/generator/generator.c +391 -232
- data/ext/json/ext/parser/extconf.rb +5 -27
- data/ext/json/ext/parser/parser.c +1597 -596
- 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 +239 -77
- data/lib/json/ext/generator/state.rb +12 -31
- data/lib/json/ext.rb +2 -4
- data/lib/json/{pure → truffle_ruby}/generator.rb +173 -124
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +15 -20
- metadata +4 -8
- data/ext/json/ext/generator/generator.h +0 -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,311 @@
|
|
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_HASH_BULK_INSERT
|
32
|
+
// For TruffleRuby
|
33
|
+
void rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash)
|
34
|
+
{
|
35
|
+
long index = 0;
|
36
|
+
while (index < count) {
|
37
|
+
VALUE name = pairs[index++];
|
38
|
+
VALUE value = pairs[index++];
|
39
|
+
rb_hash_aset(hash, name, value);
|
40
|
+
}
|
41
|
+
RB_GC_GUARD(hash);
|
42
|
+
}
|
43
|
+
#endif
|
44
|
+
|
45
|
+
/* name cache */
|
46
|
+
|
47
|
+
#include <string.h>
|
48
|
+
#include <ctype.h>
|
49
|
+
|
50
|
+
// Object names are likely to be repeated, and are frozen.
|
51
|
+
// As such we can re-use them if we keep a cache of the ones we've seen so far,
|
52
|
+
// and save much more expensive lookups into the global fstring table.
|
53
|
+
// This cache implementation is deliberately simple, as we're optimizing for compactness,
|
54
|
+
// to be able to fit safely on the stack.
|
55
|
+
// As such, binary search into a sorted array gives a good tradeoff between compactness and
|
56
|
+
// performance.
|
57
|
+
#define JSON_RVALUE_CACHE_CAPA 63
|
58
|
+
typedef struct rvalue_cache_struct {
|
59
|
+
int length;
|
60
|
+
VALUE entries[JSON_RVALUE_CACHE_CAPA];
|
61
|
+
} rvalue_cache;
|
62
|
+
|
63
|
+
static rb_encoding *enc_utf8;
|
64
|
+
|
65
|
+
#define JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH 55
|
66
|
+
|
67
|
+
static inline VALUE build_interned_string(const char *str, const long length)
|
68
|
+
{
|
69
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
70
|
+
return rb_enc_interned_str(str, length, enc_utf8);
|
71
|
+
# else
|
72
|
+
VALUE rstring = rb_utf8_str_new(str, length);
|
73
|
+
return rb_funcall(rb_str_freeze(rstring), i_uminus, 0);
|
74
|
+
# endif
|
75
|
+
}
|
76
|
+
|
77
|
+
static inline VALUE build_symbol(const char *str, const long length)
|
78
|
+
{
|
79
|
+
return rb_str_intern(build_interned_string(str, length));
|
80
|
+
}
|
81
|
+
|
82
|
+
static void rvalue_cache_insert_at(rvalue_cache *cache, int index, VALUE rstring)
|
83
|
+
{
|
84
|
+
MEMMOVE(&cache->entries[index + 1], &cache->entries[index], VALUE, cache->length - index);
|
85
|
+
cache->length++;
|
86
|
+
cache->entries[index] = rstring;
|
87
|
+
}
|
88
|
+
|
89
|
+
static inline int rstring_cache_cmp(const char *str, const long length, VALUE rstring)
|
90
|
+
{
|
91
|
+
long rstring_length = RSTRING_LEN(rstring);
|
92
|
+
if (length == rstring_length) {
|
93
|
+
return memcmp(str, RSTRING_PTR(rstring), length);
|
94
|
+
} else {
|
95
|
+
return (int)(length - rstring_length);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
static VALUE rstring_cache_fetch(rvalue_cache *cache, const char *str, const long length)
|
100
|
+
{
|
101
|
+
if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) {
|
102
|
+
// Common names aren't likely to be very long. So we just don't
|
103
|
+
// cache names above an arbitrary threshold.
|
104
|
+
return Qfalse;
|
105
|
+
}
|
106
|
+
|
107
|
+
if (RB_UNLIKELY(!isalpha(str[0]))) {
|
108
|
+
// Simple heuristic, if the first character isn't a letter,
|
109
|
+
// we're much less likely to see this string again.
|
110
|
+
// We mostly want to cache strings that are likely to be repeated.
|
111
|
+
return Qfalse;
|
112
|
+
}
|
113
|
+
|
114
|
+
int low = 0;
|
115
|
+
int high = cache->length - 1;
|
116
|
+
int mid = 0;
|
117
|
+
int last_cmp = 0;
|
118
|
+
|
119
|
+
while (low <= high) {
|
120
|
+
mid = (high + low) >> 1;
|
121
|
+
VALUE entry = cache->entries[mid];
|
122
|
+
last_cmp = rstring_cache_cmp(str, length, entry);
|
123
|
+
|
124
|
+
if (last_cmp == 0) {
|
125
|
+
return entry;
|
126
|
+
} else if (last_cmp > 0) {
|
127
|
+
low = mid + 1;
|
128
|
+
} else {
|
129
|
+
high = mid - 1;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
if (RB_UNLIKELY(memchr(str, '\\', length))) {
|
134
|
+
// We assume the overwhelming majority of names don't need to be escaped.
|
135
|
+
// But if they do, we have to fallback to the slow path.
|
136
|
+
return Qfalse;
|
137
|
+
}
|
138
|
+
|
139
|
+
VALUE rstring = build_interned_string(str, length);
|
140
|
+
|
141
|
+
if (cache->length < JSON_RVALUE_CACHE_CAPA) {
|
142
|
+
if (last_cmp > 0) {
|
143
|
+
mid += 1;
|
144
|
+
}
|
145
|
+
|
146
|
+
rvalue_cache_insert_at(cache, mid, rstring);
|
147
|
+
}
|
148
|
+
return rstring;
|
149
|
+
}
|
150
|
+
|
151
|
+
static VALUE rsymbol_cache_fetch(rvalue_cache *cache, const char *str, const long length)
|
152
|
+
{
|
153
|
+
if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) {
|
154
|
+
// Common names aren't likely to be very long. So we just don't
|
155
|
+
// cache names above an arbitrary threshold.
|
156
|
+
return Qfalse;
|
157
|
+
}
|
158
|
+
|
159
|
+
if (RB_UNLIKELY(!isalpha(str[0]))) {
|
160
|
+
// Simple heuristic, if the first character isn't a letter,
|
161
|
+
// we're much less likely to see this string again.
|
162
|
+
// We mostly want to cache strings that are likely to be repeated.
|
163
|
+
return Qfalse;
|
164
|
+
}
|
165
|
+
|
166
|
+
int low = 0;
|
167
|
+
int high = cache->length - 1;
|
168
|
+
int mid = 0;
|
169
|
+
int last_cmp = 0;
|
170
|
+
|
171
|
+
while (low <= high) {
|
172
|
+
mid = (high + low) >> 1;
|
173
|
+
VALUE entry = cache->entries[mid];
|
174
|
+
last_cmp = rstring_cache_cmp(str, length, rb_sym2str(entry));
|
175
|
+
|
176
|
+
if (last_cmp == 0) {
|
177
|
+
return entry;
|
178
|
+
} else if (last_cmp > 0) {
|
179
|
+
low = mid + 1;
|
180
|
+
} else {
|
181
|
+
high = mid - 1;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
if (RB_UNLIKELY(memchr(str, '\\', length))) {
|
186
|
+
// We assume the overwhelming majority of names don't need to be escaped.
|
187
|
+
// But if they do, we have to fallback to the slow path.
|
188
|
+
return Qfalse;
|
189
|
+
}
|
190
|
+
|
191
|
+
VALUE rsymbol = build_symbol(str, length);
|
192
|
+
|
193
|
+
if (cache->length < JSON_RVALUE_CACHE_CAPA) {
|
194
|
+
if (last_cmp > 0) {
|
195
|
+
mid += 1;
|
196
|
+
}
|
197
|
+
|
198
|
+
rvalue_cache_insert_at(cache, mid, rsymbol);
|
199
|
+
}
|
200
|
+
return rsymbol;
|
201
|
+
}
|
202
|
+
|
203
|
+
/* rvalue stack */
|
204
|
+
|
205
|
+
#define RVALUE_STACK_INITIAL_CAPA 128
|
206
|
+
|
207
|
+
enum rvalue_stack_type {
|
208
|
+
RVALUE_STACK_HEAP_ALLOCATED = 0,
|
209
|
+
RVALUE_STACK_STACK_ALLOCATED = 1,
|
210
|
+
};
|
211
|
+
|
212
|
+
typedef struct rvalue_stack_struct {
|
213
|
+
enum rvalue_stack_type type;
|
214
|
+
long capa;
|
215
|
+
long head;
|
216
|
+
VALUE *ptr;
|
217
|
+
} rvalue_stack;
|
218
|
+
|
219
|
+
static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref);
|
220
|
+
|
221
|
+
static rvalue_stack *rvalue_stack_grow(rvalue_stack *stack, VALUE *handle, rvalue_stack **stack_ref)
|
222
|
+
{
|
223
|
+
long required = stack->capa * 2;
|
224
|
+
|
225
|
+
if (stack->type == RVALUE_STACK_STACK_ALLOCATED) {
|
226
|
+
stack = rvalue_stack_spill(stack, handle, stack_ref);
|
227
|
+
} else {
|
228
|
+
REALLOC_N(stack->ptr, VALUE, required);
|
229
|
+
stack->capa = required;
|
230
|
+
}
|
231
|
+
return stack;
|
232
|
+
}
|
233
|
+
|
234
|
+
static void rvalue_stack_push(rvalue_stack *stack, VALUE value, VALUE *handle, rvalue_stack **stack_ref)
|
235
|
+
{
|
236
|
+
if (RB_UNLIKELY(stack->head >= stack->capa)) {
|
237
|
+
stack = rvalue_stack_grow(stack, handle, stack_ref);
|
238
|
+
}
|
239
|
+
stack->ptr[stack->head] = value;
|
240
|
+
stack->head++;
|
241
|
+
}
|
242
|
+
|
243
|
+
static inline VALUE *rvalue_stack_peek(rvalue_stack *stack, long count)
|
244
|
+
{
|
245
|
+
return stack->ptr + (stack->head - count);
|
246
|
+
}
|
247
|
+
|
248
|
+
static inline void rvalue_stack_pop(rvalue_stack *stack, long count)
|
249
|
+
{
|
250
|
+
stack->head -= count;
|
251
|
+
}
|
252
|
+
|
253
|
+
static void rvalue_stack_mark(void *ptr)
|
254
|
+
{
|
255
|
+
rvalue_stack *stack = (rvalue_stack *)ptr;
|
256
|
+
long index;
|
257
|
+
for (index = 0; index < stack->head; index++) {
|
258
|
+
rb_gc_mark(stack->ptr[index]);
|
259
|
+
}
|
260
|
+
}
|
261
|
+
|
262
|
+
static void rvalue_stack_free(void *ptr)
|
263
|
+
{
|
264
|
+
rvalue_stack *stack = (rvalue_stack *)ptr;
|
265
|
+
if (stack) {
|
266
|
+
ruby_xfree(stack->ptr);
|
267
|
+
ruby_xfree(stack);
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
static size_t rvalue_stack_memsize(const void *ptr)
|
272
|
+
{
|
273
|
+
const rvalue_stack *stack = (const rvalue_stack *)ptr;
|
274
|
+
return sizeof(rvalue_stack) + sizeof(VALUE) * stack->capa;
|
275
|
+
}
|
276
|
+
|
277
|
+
static const rb_data_type_t JSON_Parser_rvalue_stack_type = {
|
278
|
+
"JSON::Ext::Parser/rvalue_stack",
|
279
|
+
{
|
280
|
+
.dmark = rvalue_stack_mark,
|
281
|
+
.dfree = rvalue_stack_free,
|
282
|
+
.dsize = rvalue_stack_memsize,
|
283
|
+
},
|
284
|
+
0, 0,
|
285
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
286
|
+
};
|
287
|
+
|
288
|
+
static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref)
|
289
|
+
{
|
290
|
+
rvalue_stack *stack;
|
291
|
+
*handle = TypedData_Make_Struct(0, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
|
292
|
+
*stack_ref = stack;
|
293
|
+
MEMCPY(stack, old_stack, rvalue_stack, 1);
|
294
|
+
|
295
|
+
stack->capa = old_stack->capa << 1;
|
296
|
+
stack->ptr = ALLOC_N(VALUE, stack->capa);
|
297
|
+
stack->type = RVALUE_STACK_HEAP_ALLOCATED;
|
298
|
+
MEMCPY(stack->ptr, old_stack->ptr, VALUE, old_stack->head);
|
299
|
+
return stack;
|
300
|
+
}
|
301
|
+
|
302
|
+
static void rvalue_stack_eagerly_release(VALUE handle)
|
303
|
+
{
|
304
|
+
rvalue_stack *stack;
|
305
|
+
TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
|
306
|
+
RTYPEDDATA_DATA(handle) = NULL;
|
307
|
+
rvalue_stack_free(stack);
|
308
|
+
}
|
5
309
|
|
6
310
|
/* unicode */
|
7
311
|
|
@@ -69,6 +373,58 @@ static int convert_UTF32_to_UTF8(char *buf, uint32_t ch)
|
|
69
373
|
return len;
|
70
374
|
}
|
71
375
|
|
376
|
+
typedef struct JSON_ParserStruct {
|
377
|
+
VALUE Vsource;
|
378
|
+
char *source;
|
379
|
+
long len;
|
380
|
+
char *memo;
|
381
|
+
VALUE create_id;
|
382
|
+
VALUE object_class;
|
383
|
+
VALUE array_class;
|
384
|
+
VALUE decimal_class;
|
385
|
+
VALUE match_string;
|
386
|
+
FBuffer fbuffer;
|
387
|
+
int in_array;
|
388
|
+
int max_nesting;
|
389
|
+
bool allow_nan;
|
390
|
+
bool allow_trailing_comma;
|
391
|
+
bool parsing_name;
|
392
|
+
bool symbolize_names;
|
393
|
+
bool freeze;
|
394
|
+
bool create_additions;
|
395
|
+
bool deprecated_create_additions;
|
396
|
+
rvalue_cache name_cache;
|
397
|
+
rvalue_stack *stack;
|
398
|
+
VALUE stack_handle;
|
399
|
+
} JSON_Parser;
|
400
|
+
|
401
|
+
#define GET_PARSER \
|
402
|
+
GET_PARSER_INIT; \
|
403
|
+
if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
|
404
|
+
|
405
|
+
#define GET_PARSER_INIT \
|
406
|
+
JSON_Parser *json; \
|
407
|
+
TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json)
|
408
|
+
|
409
|
+
#define MinusInfinity "-Infinity"
|
410
|
+
#define EVIL 0x666
|
411
|
+
|
412
|
+
static const rb_data_type_t JSON_Parser_type;
|
413
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
414
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
415
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
416
|
+
static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
417
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
418
|
+
|
419
|
+
|
420
|
+
#ifndef HAVE_STRNLEN
|
421
|
+
static size_t strnlen(const char *s, size_t maxlen)
|
422
|
+
{
|
423
|
+
char *p;
|
424
|
+
return ((p = memchr(s, '\0', maxlen)) ? p - s : maxlen);
|
425
|
+
}
|
426
|
+
#endif
|
427
|
+
|
72
428
|
#define PARSE_ERROR_FRAGMENT_LEN 32
|
73
429
|
#ifdef RBIMPL_ATTR_NORETURN
|
74
430
|
RBIMPL_ATTR_NORETURN()
|
@@ -86,60 +442,49 @@ static void raise_parse_error(const char *format, const char *start)
|
|
86
442
|
ptr = buffer;
|
87
443
|
}
|
88
444
|
|
89
|
-
rb_enc_raise(
|
445
|
+
rb_enc_raise(enc_utf8, rb_path2class("JSON::ParserError"), format, ptr);
|
90
446
|
}
|
91
447
|
|
92
|
-
static VALUE mJSON, mExt, cParser, eNestingError;
|
93
|
-
static VALUE CNaN, CInfinity, CMinusInfinity;
|
94
448
|
|
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
449
|
|
450
|
+
#line 473 "parser.rl"
|
104
451
|
|
105
452
|
|
106
|
-
#line 129 "parser.rl"
|
107
453
|
|
108
|
-
|
109
|
-
|
110
|
-
#line 111 "parser.c"
|
454
|
+
#line 455 "parser.c"
|
111
455
|
enum {JSON_object_start = 1};
|
112
|
-
enum {JSON_object_first_final =
|
456
|
+
enum {JSON_object_first_final = 32};
|
113
457
|
enum {JSON_object_error = 0};
|
114
458
|
|
115
459
|
enum {JSON_object_en_main = 1};
|
116
460
|
|
117
461
|
|
118
|
-
#line
|
462
|
+
#line 513 "parser.rl"
|
463
|
+
|
119
464
|
|
465
|
+
#define PUSH(result) rvalue_stack_push(json->stack, result, &json->stack_handle, &json->stack)
|
120
466
|
|
121
467
|
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
122
468
|
{
|
123
469
|
int cs = EVIL;
|
124
|
-
VALUE last_name = Qnil;
|
125
|
-
VALUE object_class = json->object_class;
|
126
470
|
|
127
471
|
if (json->max_nesting && current_nesting > json->max_nesting) {
|
128
472
|
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
129
473
|
}
|
130
474
|
|
131
|
-
|
475
|
+
long stack_head = json->stack->head;
|
132
476
|
|
133
477
|
|
134
|
-
#line
|
478
|
+
#line 479 "parser.c"
|
135
479
|
{
|
136
480
|
cs = JSON_object_start;
|
137
481
|
}
|
138
482
|
|
139
|
-
#line
|
483
|
+
#line 528 "parser.rl"
|
140
484
|
|
141
|
-
#line
|
485
|
+
#line 486 "parser.c"
|
142
486
|
{
|
487
|
+
short _widec;
|
143
488
|
if ( p == pe )
|
144
489
|
goto _test_eof;
|
145
490
|
switch ( cs )
|
@@ -159,27 +504,30 @@ case 2:
|
|
159
504
|
case 13: goto st2;
|
160
505
|
case 32: goto st2;
|
161
506
|
case 34: goto tr2;
|
162
|
-
case 47: goto
|
507
|
+
case 47: goto st28;
|
163
508
|
case 125: goto tr4;
|
164
509
|
}
|
165
510
|
if ( 9 <= (*p) && (*p) <= 10 )
|
166
511
|
goto st2;
|
167
512
|
goto st0;
|
168
513
|
tr2:
|
169
|
-
#line
|
514
|
+
#line 492 "parser.rl"
|
170
515
|
{
|
171
516
|
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 {
|
517
|
+
json->parsing_name = true;
|
518
|
+
np = JSON_parse_string(json, p, pe, result);
|
519
|
+
json->parsing_name = false;
|
520
|
+
if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {
|
521
|
+
PUSH(*result);
|
522
|
+
{p = (( np))-1;}
|
523
|
+
}
|
176
524
|
}
|
177
525
|
goto st3;
|
178
526
|
st3:
|
179
527
|
if ( ++p == pe )
|
180
528
|
goto _test_eof3;
|
181
529
|
case 3:
|
182
|
-
#line
|
530
|
+
#line 531 "parser.c"
|
183
531
|
switch( (*p) ) {
|
184
532
|
case 13: goto st3;
|
185
533
|
case 32: goto st3;
|
@@ -230,7 +578,7 @@ case 8:
|
|
230
578
|
case 32: goto st8;
|
231
579
|
case 34: goto tr11;
|
232
580
|
case 45: goto tr11;
|
233
|
-
case 47: goto
|
581
|
+
case 47: goto st24;
|
234
582
|
case 73: goto tr11;
|
235
583
|
case 78: goto tr11;
|
236
584
|
case 91: goto tr11;
|
@@ -246,19 +594,12 @@ case 8:
|
|
246
594
|
goto st8;
|
247
595
|
goto st0;
|
248
596
|
tr11:
|
249
|
-
#line
|
597
|
+
#line 481 "parser.rl"
|
250
598
|
{
|
251
|
-
|
252
|
-
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
599
|
+
char *np = JSON_parse_value(json, p, pe, result, current_nesting);
|
253
600
|
if (np == NULL) {
|
254
601
|
p--; {p++; cs = 9; goto _out;}
|
255
602
|
} 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
603
|
{p = (( np))-1;}
|
263
604
|
}
|
264
605
|
}
|
@@ -267,16 +608,75 @@ st9:
|
|
267
608
|
if ( ++p == pe )
|
268
609
|
goto _test_eof9;
|
269
610
|
case 9:
|
270
|
-
#line
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
611
|
+
#line 612 "parser.c"
|
612
|
+
_widec = (*p);
|
613
|
+
if ( (*p) < 13 ) {
|
614
|
+
if ( (*p) > 9 ) {
|
615
|
+
if ( 10 <= (*p) && (*p) <= 10 ) {
|
616
|
+
_widec = (short)(128 + ((*p) - -128));
|
617
|
+
if (
|
618
|
+
#line 490 "parser.rl"
|
619
|
+
json->allow_trailing_comma ) _widec += 256;
|
620
|
+
}
|
621
|
+
} else if ( (*p) >= 9 ) {
|
622
|
+
_widec = (short)(128 + ((*p) - -128));
|
623
|
+
if (
|
624
|
+
#line 490 "parser.rl"
|
625
|
+
json->allow_trailing_comma ) _widec += 256;
|
626
|
+
}
|
627
|
+
} else if ( (*p) > 13 ) {
|
628
|
+
if ( (*p) < 44 ) {
|
629
|
+
if ( 32 <= (*p) && (*p) <= 32 ) {
|
630
|
+
_widec = (short)(128 + ((*p) - -128));
|
631
|
+
if (
|
632
|
+
#line 490 "parser.rl"
|
633
|
+
json->allow_trailing_comma ) _widec += 256;
|
634
|
+
}
|
635
|
+
} else if ( (*p) > 44 ) {
|
636
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
637
|
+
_widec = (short)(128 + ((*p) - -128));
|
638
|
+
if (
|
639
|
+
#line 490 "parser.rl"
|
640
|
+
json->allow_trailing_comma ) _widec += 256;
|
641
|
+
}
|
642
|
+
} else {
|
643
|
+
_widec = (short)(128 + ((*p) - -128));
|
644
|
+
if (
|
645
|
+
#line 490 "parser.rl"
|
646
|
+
json->allow_trailing_comma ) _widec += 256;
|
647
|
+
}
|
648
|
+
} else {
|
649
|
+
_widec = (short)(128 + ((*p) - -128));
|
650
|
+
if (
|
651
|
+
#line 490 "parser.rl"
|
652
|
+
json->allow_trailing_comma ) _widec += 256;
|
653
|
+
}
|
654
|
+
switch( _widec ) {
|
276
655
|
case 125: goto tr4;
|
277
|
-
|
278
|
-
|
279
|
-
goto
|
656
|
+
case 269: goto st10;
|
657
|
+
case 288: goto st10;
|
658
|
+
case 300: goto st11;
|
659
|
+
case 303: goto st16;
|
660
|
+
case 525: goto st9;
|
661
|
+
case 544: goto st9;
|
662
|
+
case 556: goto st2;
|
663
|
+
case 559: goto st20;
|
664
|
+
}
|
665
|
+
if ( _widec > 266 ) {
|
666
|
+
if ( 521 <= _widec && _widec <= 522 )
|
667
|
+
goto st9;
|
668
|
+
} else if ( _widec >= 265 )
|
669
|
+
goto st10;
|
670
|
+
goto st0;
|
671
|
+
tr4:
|
672
|
+
#line 503 "parser.rl"
|
673
|
+
{ p--; {p++; cs = 32; goto _out;} }
|
674
|
+
goto st32;
|
675
|
+
st32:
|
676
|
+
if ( ++p == pe )
|
677
|
+
goto _test_eof32;
|
678
|
+
case 32:
|
679
|
+
#line 680 "parser.c"
|
280
680
|
goto st0;
|
281
681
|
st10:
|
282
682
|
if ( ++p == pe )
|
@@ -285,8 +685,9 @@ case 10:
|
|
285
685
|
switch( (*p) ) {
|
286
686
|
case 13: goto st10;
|
287
687
|
case 32: goto st10;
|
288
|
-
case
|
289
|
-
case 47: goto
|
688
|
+
case 44: goto st11;
|
689
|
+
case 47: goto st16;
|
690
|
+
case 125: goto tr4;
|
290
691
|
}
|
291
692
|
if ( 9 <= (*p) && (*p) <= 10 )
|
292
693
|
goto st10;
|
@@ -296,139 +697,288 @@ st11:
|
|
296
697
|
goto _test_eof11;
|
297
698
|
case 11:
|
298
699
|
switch( (*p) ) {
|
299
|
-
case
|
300
|
-
case
|
700
|
+
case 13: goto st11;
|
701
|
+
case 32: goto st11;
|
702
|
+
case 34: goto tr2;
|
703
|
+
case 47: goto st12;
|
301
704
|
}
|
705
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
706
|
+
goto st11;
|
302
707
|
goto st0;
|
303
708
|
st12:
|
304
709
|
if ( ++p == pe )
|
305
710
|
goto _test_eof12;
|
306
711
|
case 12:
|
307
|
-
|
308
|
-
goto st13;
|
309
|
-
|
712
|
+
switch( (*p) ) {
|
713
|
+
case 42: goto st13;
|
714
|
+
case 47: goto st15;
|
715
|
+
}
|
716
|
+
goto st0;
|
310
717
|
st13:
|
311
718
|
if ( ++p == pe )
|
312
719
|
goto _test_eof13;
|
313
720
|
case 13:
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
}
|
318
|
-
goto st12;
|
721
|
+
if ( (*p) == 42 )
|
722
|
+
goto st14;
|
723
|
+
goto st13;
|
319
724
|
st14:
|
320
725
|
if ( ++p == pe )
|
321
726
|
goto _test_eof14;
|
322
727
|
case 14:
|
323
|
-
|
324
|
-
goto
|
325
|
-
|
728
|
+
switch( (*p) ) {
|
729
|
+
case 42: goto st14;
|
730
|
+
case 47: goto st11;
|
731
|
+
}
|
732
|
+
goto st13;
|
326
733
|
st15:
|
327
734
|
if ( ++p == pe )
|
328
735
|
goto _test_eof15;
|
329
736
|
case 15:
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
}
|
334
|
-
goto st0;
|
737
|
+
if ( (*p) == 10 )
|
738
|
+
goto st11;
|
739
|
+
goto st15;
|
335
740
|
st16:
|
336
741
|
if ( ++p == pe )
|
337
742
|
goto _test_eof16;
|
338
743
|
case 16:
|
339
|
-
|
340
|
-
goto st17;
|
341
|
-
|
744
|
+
switch( (*p) ) {
|
745
|
+
case 42: goto st17;
|
746
|
+
case 47: goto st19;
|
747
|
+
}
|
748
|
+
goto st0;
|
342
749
|
st17:
|
343
750
|
if ( ++p == pe )
|
344
751
|
goto _test_eof17;
|
345
752
|
case 17:
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
}
|
350
|
-
goto st16;
|
753
|
+
if ( (*p) == 42 )
|
754
|
+
goto st18;
|
755
|
+
goto st17;
|
351
756
|
st18:
|
352
757
|
if ( ++p == pe )
|
353
758
|
goto _test_eof18;
|
354
759
|
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;
|
760
|
+
switch( (*p) ) {
|
761
|
+
case 42: goto st18;
|
762
|
+
case 47: goto st10;
|
763
|
+
}
|
764
|
+
goto st17;
|
368
765
|
st19:
|
369
766
|
if ( ++p == pe )
|
370
767
|
goto _test_eof19;
|
371
768
|
case 19:
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
}
|
376
|
-
goto st0;
|
769
|
+
if ( (*p) == 10 )
|
770
|
+
goto st10;
|
771
|
+
goto st19;
|
377
772
|
st20:
|
378
773
|
if ( ++p == pe )
|
379
774
|
goto _test_eof20;
|
380
775
|
case 20:
|
381
|
-
|
382
|
-
|
383
|
-
|
776
|
+
_widec = (*p);
|
777
|
+
if ( (*p) > 42 ) {
|
778
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
779
|
+
_widec = (short)(128 + ((*p) - -128));
|
780
|
+
if (
|
781
|
+
#line 490 "parser.rl"
|
782
|
+
json->allow_trailing_comma ) _widec += 256;
|
783
|
+
}
|
784
|
+
} else if ( (*p) >= 42 ) {
|
785
|
+
_widec = (short)(128 + ((*p) - -128));
|
786
|
+
if (
|
787
|
+
#line 490 "parser.rl"
|
788
|
+
json->allow_trailing_comma ) _widec += 256;
|
789
|
+
}
|
790
|
+
switch( _widec ) {
|
791
|
+
case 298: goto st17;
|
792
|
+
case 303: goto st19;
|
793
|
+
case 554: goto st21;
|
794
|
+
case 559: goto st23;
|
795
|
+
}
|
796
|
+
goto st0;
|
384
797
|
st21:
|
385
798
|
if ( ++p == pe )
|
386
799
|
goto _test_eof21;
|
387
800
|
case 21:
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
801
|
+
_widec = (*p);
|
802
|
+
if ( (*p) < 42 ) {
|
803
|
+
if ( (*p) <= 41 ) {
|
804
|
+
_widec = (short)(128 + ((*p) - -128));
|
805
|
+
if (
|
806
|
+
#line 490 "parser.rl"
|
807
|
+
json->allow_trailing_comma ) _widec += 256;
|
808
|
+
}
|
809
|
+
} else if ( (*p) > 42 ) {
|
810
|
+
if ( 43 <= (*p) )
|
811
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
812
|
+
if (
|
813
|
+
#line 490 "parser.rl"
|
814
|
+
json->allow_trailing_comma ) _widec += 256;
|
815
|
+
}
|
816
|
+
} else {
|
817
|
+
_widec = (short)(128 + ((*p) - -128));
|
818
|
+
if (
|
819
|
+
#line 490 "parser.rl"
|
820
|
+
json->allow_trailing_comma ) _widec += 256;
|
821
|
+
}
|
822
|
+
switch( _widec ) {
|
823
|
+
case 298: goto st18;
|
824
|
+
case 554: goto st22;
|
825
|
+
}
|
826
|
+
if ( _widec > 383 ) {
|
827
|
+
if ( 384 <= _widec && _widec <= 639 )
|
828
|
+
goto st21;
|
829
|
+
} else if ( _widec >= 128 )
|
830
|
+
goto st17;
|
831
|
+
goto st0;
|
393
832
|
st22:
|
394
833
|
if ( ++p == pe )
|
395
834
|
goto _test_eof22;
|
396
835
|
case 22:
|
397
|
-
|
398
|
-
|
399
|
-
|
836
|
+
_widec = (*p);
|
837
|
+
if ( (*p) < 43 ) {
|
838
|
+
if ( (*p) > 41 ) {
|
839
|
+
if ( 42 <= (*p) && (*p) <= 42 ) {
|
840
|
+
_widec = (short)(128 + ((*p) - -128));
|
841
|
+
if (
|
842
|
+
#line 490 "parser.rl"
|
843
|
+
json->allow_trailing_comma ) _widec += 256;
|
844
|
+
}
|
845
|
+
} else {
|
846
|
+
_widec = (short)(128 + ((*p) - -128));
|
847
|
+
if (
|
848
|
+
#line 490 "parser.rl"
|
849
|
+
json->allow_trailing_comma ) _widec += 256;
|
850
|
+
}
|
851
|
+
} else if ( (*p) > 46 ) {
|
852
|
+
if ( (*p) > 47 ) {
|
853
|
+
if ( 48 <= (*p) )
|
854
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
855
|
+
if (
|
856
|
+
#line 490 "parser.rl"
|
857
|
+
json->allow_trailing_comma ) _widec += 256;
|
858
|
+
}
|
859
|
+
} else if ( (*p) >= 47 ) {
|
860
|
+
_widec = (short)(128 + ((*p) - -128));
|
861
|
+
if (
|
862
|
+
#line 490 "parser.rl"
|
863
|
+
json->allow_trailing_comma ) _widec += 256;
|
864
|
+
}
|
865
|
+
} else {
|
866
|
+
_widec = (short)(128 + ((*p) - -128));
|
867
|
+
if (
|
868
|
+
#line 490 "parser.rl"
|
869
|
+
json->allow_trailing_comma ) _widec += 256;
|
870
|
+
}
|
871
|
+
switch( _widec ) {
|
872
|
+
case 298: goto st18;
|
873
|
+
case 303: goto st10;
|
874
|
+
case 554: goto st22;
|
875
|
+
case 559: goto st9;
|
876
|
+
}
|
877
|
+
if ( _widec > 383 ) {
|
878
|
+
if ( 384 <= _widec && _widec <= 639 )
|
879
|
+
goto st21;
|
880
|
+
} else if ( _widec >= 128 )
|
881
|
+
goto st17;
|
882
|
+
goto st0;
|
400
883
|
st23:
|
401
884
|
if ( ++p == pe )
|
402
885
|
goto _test_eof23;
|
403
886
|
case 23:
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
887
|
+
_widec = (*p);
|
888
|
+
if ( (*p) < 10 ) {
|
889
|
+
if ( (*p) <= 9 ) {
|
890
|
+
_widec = (short)(128 + ((*p) - -128));
|
891
|
+
if (
|
892
|
+
#line 490 "parser.rl"
|
893
|
+
json->allow_trailing_comma ) _widec += 256;
|
894
|
+
}
|
895
|
+
} else if ( (*p) > 10 ) {
|
896
|
+
if ( 11 <= (*p) )
|
897
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
898
|
+
if (
|
899
|
+
#line 490 "parser.rl"
|
900
|
+
json->allow_trailing_comma ) _widec += 256;
|
901
|
+
}
|
902
|
+
} else {
|
903
|
+
_widec = (short)(128 + ((*p) - -128));
|
904
|
+
if (
|
905
|
+
#line 490 "parser.rl"
|
906
|
+
json->allow_trailing_comma ) _widec += 256;
|
907
|
+
}
|
908
|
+
switch( _widec ) {
|
909
|
+
case 266: goto st10;
|
910
|
+
case 522: goto st9;
|
911
|
+
}
|
912
|
+
if ( _widec > 383 ) {
|
913
|
+
if ( 384 <= _widec && _widec <= 639 )
|
914
|
+
goto st23;
|
915
|
+
} else if ( _widec >= 128 )
|
916
|
+
goto st19;
|
408
917
|
goto st0;
|
409
918
|
st24:
|
410
919
|
if ( ++p == pe )
|
411
920
|
goto _test_eof24;
|
412
921
|
case 24:
|
413
|
-
|
414
|
-
goto st25;
|
415
|
-
|
922
|
+
switch( (*p) ) {
|
923
|
+
case 42: goto st25;
|
924
|
+
case 47: goto st27;
|
925
|
+
}
|
926
|
+
goto st0;
|
416
927
|
st25:
|
417
928
|
if ( ++p == pe )
|
418
929
|
goto _test_eof25;
|
419
930
|
case 25:
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
}
|
424
|
-
goto st24;
|
931
|
+
if ( (*p) == 42 )
|
932
|
+
goto st26;
|
933
|
+
goto st25;
|
425
934
|
st26:
|
426
935
|
if ( ++p == pe )
|
427
936
|
goto _test_eof26;
|
428
937
|
case 26:
|
938
|
+
switch( (*p) ) {
|
939
|
+
case 42: goto st26;
|
940
|
+
case 47: goto st8;
|
941
|
+
}
|
942
|
+
goto st25;
|
943
|
+
st27:
|
944
|
+
if ( ++p == pe )
|
945
|
+
goto _test_eof27;
|
946
|
+
case 27:
|
947
|
+
if ( (*p) == 10 )
|
948
|
+
goto st8;
|
949
|
+
goto st27;
|
950
|
+
st28:
|
951
|
+
if ( ++p == pe )
|
952
|
+
goto _test_eof28;
|
953
|
+
case 28:
|
954
|
+
switch( (*p) ) {
|
955
|
+
case 42: goto st29;
|
956
|
+
case 47: goto st31;
|
957
|
+
}
|
958
|
+
goto st0;
|
959
|
+
st29:
|
960
|
+
if ( ++p == pe )
|
961
|
+
goto _test_eof29;
|
962
|
+
case 29:
|
963
|
+
if ( (*p) == 42 )
|
964
|
+
goto st30;
|
965
|
+
goto st29;
|
966
|
+
st30:
|
967
|
+
if ( ++p == pe )
|
968
|
+
goto _test_eof30;
|
969
|
+
case 30:
|
970
|
+
switch( (*p) ) {
|
971
|
+
case 42: goto st30;
|
972
|
+
case 47: goto st2;
|
973
|
+
}
|
974
|
+
goto st29;
|
975
|
+
st31:
|
976
|
+
if ( ++p == pe )
|
977
|
+
goto _test_eof31;
|
978
|
+
case 31:
|
429
979
|
if ( (*p) == 10 )
|
430
980
|
goto st2;
|
431
|
-
goto
|
981
|
+
goto st31;
|
432
982
|
}
|
433
983
|
_test_eof2: cs = 2; goto _test_eof;
|
434
984
|
_test_eof3: cs = 3; goto _test_eof;
|
@@ -438,6 +988,7 @@ case 26:
|
|
438
988
|
_test_eof7: cs = 7; goto _test_eof;
|
439
989
|
_test_eof8: cs = 8; goto _test_eof;
|
440
990
|
_test_eof9: cs = 9; goto _test_eof;
|
991
|
+
_test_eof32: cs = 32; goto _test_eof;
|
441
992
|
_test_eof10: cs = 10; goto _test_eof;
|
442
993
|
_test_eof11: cs = 11; goto _test_eof;
|
443
994
|
_test_eof12: cs = 12; goto _test_eof;
|
@@ -447,7 +998,6 @@ case 26:
|
|
447
998
|
_test_eof16: cs = 16; goto _test_eof;
|
448
999
|
_test_eof17: cs = 17; goto _test_eof;
|
449
1000
|
_test_eof18: cs = 18; goto _test_eof;
|
450
|
-
_test_eof27: cs = 27; goto _test_eof;
|
451
1001
|
_test_eof19: cs = 19; goto _test_eof;
|
452
1002
|
_test_eof20: cs = 20; goto _test_eof;
|
453
1003
|
_test_eof21: cs = 21; goto _test_eof;
|
@@ -456,24 +1006,56 @@ case 26:
|
|
456
1006
|
_test_eof24: cs = 24; goto _test_eof;
|
457
1007
|
_test_eof25: cs = 25; goto _test_eof;
|
458
1008
|
_test_eof26: cs = 26; goto _test_eof;
|
1009
|
+
_test_eof27: cs = 27; goto _test_eof;
|
1010
|
+
_test_eof28: cs = 28; goto _test_eof;
|
1011
|
+
_test_eof29: cs = 29; goto _test_eof;
|
1012
|
+
_test_eof30: cs = 30; goto _test_eof;
|
1013
|
+
_test_eof31: cs = 31; goto _test_eof;
|
459
1014
|
|
460
1015
|
_test_eof: {}
|
461
1016
|
_out: {}
|
462
1017
|
}
|
463
1018
|
|
464
|
-
#line
|
1019
|
+
#line 529 "parser.rl"
|
465
1020
|
|
466
1021
|
if (cs >= JSON_object_first_final) {
|
467
|
-
|
1022
|
+
long count = json->stack->head - stack_head;
|
1023
|
+
|
1024
|
+
if (RB_UNLIKELY(json->object_class)) {
|
1025
|
+
VALUE object = rb_class_new_instance(0, 0, json->object_class);
|
1026
|
+
long index = 0;
|
1027
|
+
VALUE *items = rvalue_stack_peek(json->stack, count);
|
1028
|
+
while (index < count) {
|
1029
|
+
VALUE name = items[index++];
|
1030
|
+
VALUE value = items[index++];
|
1031
|
+
rb_funcall(object, i_aset, 2, name, value);
|
1032
|
+
}
|
1033
|
+
*result = object;
|
1034
|
+
} else {
|
1035
|
+
VALUE hash;
|
1036
|
+
#ifdef HAVE_RB_HASH_NEW_CAPA
|
1037
|
+
hash = rb_hash_new_capa(count >> 1);
|
1038
|
+
#else
|
1039
|
+
hash = rb_hash_new();
|
1040
|
+
#endif
|
1041
|
+
rb_hash_bulk_insert(count, rvalue_stack_peek(json->stack, count), hash);
|
1042
|
+
*result = hash;
|
1043
|
+
}
|
1044
|
+
rvalue_stack_pop(json->stack, count);
|
1045
|
+
|
1046
|
+
if (RB_UNLIKELY(json->create_additions)) {
|
468
1047
|
VALUE klassname;
|
469
|
-
if (
|
470
|
-
|
1048
|
+
if (json->object_class) {
|
1049
|
+
klassname = rb_funcall(*result, i_aref, 1, json->create_id);
|
471
1050
|
} else {
|
472
|
-
|
1051
|
+
klassname = rb_hash_aref(*result, json->create_id);
|
473
1052
|
}
|
474
1053
|
if (!NIL_P(klassname)) {
|
475
1054
|
VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
|
476
1055
|
if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
|
1056
|
+
if (json->deprecated_create_additions) {
|
1057
|
+
json_deprecated(deprecated_create_additions_warning);
|
1058
|
+
}
|
477
1059
|
*result = rb_funcall(klass, i_json_create, 1, *result);
|
478
1060
|
}
|
479
1061
|
}
|
@@ -485,8 +1067,7 @@ case 26:
|
|
485
1067
|
}
|
486
1068
|
|
487
1069
|
|
488
|
-
|
489
|
-
#line 490 "parser.c"
|
1070
|
+
#line 1071 "parser.c"
|
490
1071
|
enum {JSON_value_start = 1};
|
491
1072
|
enum {JSON_value_first_final = 29};
|
492
1073
|
enum {JSON_value_error = 0};
|
@@ -494,7 +1075,7 @@ enum {JSON_value_error = 0};
|
|
494
1075
|
enum {JSON_value_en_main = 1};
|
495
1076
|
|
496
1077
|
|
497
|
-
#line
|
1078
|
+
#line 662 "parser.rl"
|
498
1079
|
|
499
1080
|
|
500
1081
|
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -502,14 +1083,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
502
1083
|
int cs = EVIL;
|
503
1084
|
|
504
1085
|
|
505
|
-
#line
|
1086
|
+
#line 1087 "parser.c"
|
506
1087
|
{
|
507
1088
|
cs = JSON_value_start;
|
508
1089
|
}
|
509
1090
|
|
510
|
-
#line
|
1091
|
+
#line 669 "parser.rl"
|
511
1092
|
|
512
|
-
#line
|
1093
|
+
#line 1094 "parser.c"
|
513
1094
|
{
|
514
1095
|
if ( p == pe )
|
515
1096
|
goto _test_eof;
|
@@ -543,14 +1124,19 @@ st0:
|
|
543
1124
|
cs = 0;
|
544
1125
|
goto _out;
|
545
1126
|
tr2:
|
546
|
-
#line
|
1127
|
+
#line 607 "parser.rl"
|
547
1128
|
{
|
548
1129
|
char *np = JSON_parse_string(json, p, pe, result);
|
549
|
-
if (np == NULL) {
|
1130
|
+
if (np == NULL) {
|
1131
|
+
p--;
|
1132
|
+
{p++; cs = 29; goto _out;}
|
1133
|
+
} else {
|
1134
|
+
{p = (( np))-1;}
|
1135
|
+
}
|
550
1136
|
}
|
551
1137
|
goto st29;
|
552
1138
|
tr3:
|
553
|
-
#line
|
1139
|
+
#line 617 "parser.rl"
|
554
1140
|
{
|
555
1141
|
char *np;
|
556
1142
|
if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
|
@@ -562,23 +1148,25 @@ tr3:
|
|
562
1148
|
raise_parse_error("unexpected token at '%s'", p);
|
563
1149
|
}
|
564
1150
|
}
|
565
|
-
np =
|
566
|
-
if (np != NULL) {
|
567
|
-
|
568
|
-
|
1151
|
+
np = JSON_parse_number(json, p, pe, result);
|
1152
|
+
if (np != NULL) {
|
1153
|
+
{p = (( np))-1;}
|
1154
|
+
}
|
569
1155
|
p--; {p++; cs = 29; goto _out;}
|
570
1156
|
}
|
571
1157
|
goto st29;
|
572
1158
|
tr7:
|
573
|
-
#line
|
1159
|
+
#line 635 "parser.rl"
|
574
1160
|
{
|
575
1161
|
char *np;
|
1162
|
+
json->in_array++;
|
576
1163
|
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
|
1164
|
+
json->in_array--;
|
577
1165
|
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
578
1166
|
}
|
579
1167
|
goto st29;
|
580
1168
|
tr11:
|
581
|
-
#line
|
1169
|
+
#line 643 "parser.rl"
|
582
1170
|
{
|
583
1171
|
char *np;
|
584
1172
|
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
|
@@ -586,7 +1174,7 @@ tr11:
|
|
586
1174
|
}
|
587
1175
|
goto st29;
|
588
1176
|
tr25:
|
589
|
-
#line
|
1177
|
+
#line 600 "parser.rl"
|
590
1178
|
{
|
591
1179
|
if (json->allow_nan) {
|
592
1180
|
*result = CInfinity;
|
@@ -596,7 +1184,7 @@ tr25:
|
|
596
1184
|
}
|
597
1185
|
goto st29;
|
598
1186
|
tr27:
|
599
|
-
#line
|
1187
|
+
#line 593 "parser.rl"
|
600
1188
|
{
|
601
1189
|
if (json->allow_nan) {
|
602
1190
|
*result = CNaN;
|
@@ -606,19 +1194,19 @@ tr27:
|
|
606
1194
|
}
|
607
1195
|
goto st29;
|
608
1196
|
tr31:
|
609
|
-
#line
|
1197
|
+
#line 587 "parser.rl"
|
610
1198
|
{
|
611
1199
|
*result = Qfalse;
|
612
1200
|
}
|
613
1201
|
goto st29;
|
614
1202
|
tr34:
|
615
|
-
#line
|
1203
|
+
#line 584 "parser.rl"
|
616
1204
|
{
|
617
1205
|
*result = Qnil;
|
618
1206
|
}
|
619
1207
|
goto st29;
|
620
1208
|
tr37:
|
621
|
-
#line
|
1209
|
+
#line 590 "parser.rl"
|
622
1210
|
{
|
623
1211
|
*result = Qtrue;
|
624
1212
|
}
|
@@ -627,9 +1215,9 @@ st29:
|
|
627
1215
|
if ( ++p == pe )
|
628
1216
|
goto _test_eof29;
|
629
1217
|
case 29:
|
630
|
-
#line
|
1218
|
+
#line 649 "parser.rl"
|
631
1219
|
{ p--; {p++; cs = 29; goto _out;} }
|
632
|
-
#line
|
1220
|
+
#line 1221 "parser.c"
|
633
1221
|
switch( (*p) ) {
|
634
1222
|
case 13: goto st29;
|
635
1223
|
case 32: goto st29;
|
@@ -870,13 +1458,14 @@ case 28:
|
|
870
1458
|
_out: {}
|
871
1459
|
}
|
872
1460
|
|
873
|
-
#line
|
1461
|
+
#line 670 "parser.rl"
|
874
1462
|
|
875
1463
|
if (json->freeze) {
|
876
1464
|
OBJ_FREEZE(*result);
|
877
1465
|
}
|
878
1466
|
|
879
1467
|
if (cs >= JSON_value_first_final) {
|
1468
|
+
PUSH(*result);
|
880
1469
|
return p;
|
881
1470
|
} else {
|
882
1471
|
return NULL;
|
@@ -884,7 +1473,7 @@ case 28:
|
|
884
1473
|
}
|
885
1474
|
|
886
1475
|
|
887
|
-
#line
|
1476
|
+
#line 1477 "parser.c"
|
888
1477
|
enum {JSON_integer_start = 1};
|
889
1478
|
enum {JSON_integer_first_final = 3};
|
890
1479
|
enum {JSON_integer_error = 0};
|
@@ -892,122 +1481,72 @@ enum {JSON_integer_error = 0};
|
|
892
1481
|
enum {JSON_integer_en_main = 1};
|
893
1482
|
|
894
1483
|
|
895
|
-
#line
|
1484
|
+
#line 691 "parser.rl"
|
896
1485
|
|
897
1486
|
|
898
|
-
|
1487
|
+
#define MAX_FAST_INTEGER_SIZE 18
|
1488
|
+
static inline VALUE fast_parse_integer(char *p, char *pe)
|
899
1489
|
{
|
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;
|
1490
|
+
bool negative = false;
|
1491
|
+
if (*p == '-') {
|
1492
|
+
negative = true;
|
1493
|
+
p++;
|
1494
|
+
}
|
966
1495
|
|
967
|
-
|
968
|
-
|
969
|
-
|
1496
|
+
long long memo = 0;
|
1497
|
+
while (p < pe) {
|
1498
|
+
memo *= 10;
|
1499
|
+
memo += *p - '0';
|
1500
|
+
p++;
|
1501
|
+
}
|
970
1502
|
|
971
|
-
|
1503
|
+
if (negative) {
|
1504
|
+
memo = -memo;
|
1505
|
+
}
|
1506
|
+
return LL2NUM(memo);
|
1507
|
+
}
|
972
1508
|
|
973
|
-
|
1509
|
+
static char *JSON_decode_integer(JSON_Parser *json, char *p, VALUE *result)
|
1510
|
+
{
|
974
1511
|
long len = p - json->memo;
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
1512
|
+
if (RB_LIKELY(len < MAX_FAST_INTEGER_SIZE)) {
|
1513
|
+
*result = fast_parse_integer(json->memo, p);
|
1514
|
+
} else {
|
1515
|
+
fbuffer_clear(&json->fbuffer);
|
1516
|
+
fbuffer_append(&json->fbuffer, json->memo, len);
|
1517
|
+
fbuffer_append_char(&json->fbuffer, '\0');
|
1518
|
+
*result = rb_cstr2inum(FBUFFER_PTR(&json->fbuffer), 10);
|
1519
|
+
}
|
979
1520
|
return p + 1;
|
980
|
-
} else {
|
981
|
-
return NULL;
|
982
|
-
}
|
983
1521
|
}
|
984
1522
|
|
985
1523
|
|
986
|
-
#line
|
1524
|
+
#line 1525 "parser.c"
|
987
1525
|
enum {JSON_float_start = 1};
|
988
|
-
enum {JSON_float_first_final =
|
1526
|
+
enum {JSON_float_first_final = 6};
|
989
1527
|
enum {JSON_float_error = 0};
|
990
1528
|
|
991
1529
|
enum {JSON_float_en_main = 1};
|
992
1530
|
|
993
1531
|
|
994
|
-
#line
|
1532
|
+
#line 743 "parser.rl"
|
995
1533
|
|
996
1534
|
|
997
|
-
static char *
|
1535
|
+
static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
998
1536
|
{
|
999
1537
|
int cs = EVIL;
|
1538
|
+
bool is_float = false;
|
1000
1539
|
|
1001
1540
|
|
1002
|
-
#line
|
1541
|
+
#line 1542 "parser.c"
|
1003
1542
|
{
|
1004
1543
|
cs = JSON_float_start;
|
1005
1544
|
}
|
1006
1545
|
|
1007
|
-
#line
|
1546
|
+
#line 751 "parser.rl"
|
1008
1547
|
json->memo = p;
|
1009
1548
|
|
1010
|
-
#line
|
1549
|
+
#line 1550 "parser.c"
|
1011
1550
|
{
|
1012
1551
|
if ( p == pe )
|
1013
1552
|
goto _test_eof;
|
@@ -1016,10 +1555,10 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
1016
1555
|
case 1:
|
1017
1556
|
switch( (*p) ) {
|
1018
1557
|
case 45: goto st2;
|
1019
|
-
case 48: goto
|
1558
|
+
case 48: goto st6;
|
1020
1559
|
}
|
1021
1560
|
if ( 49 <= (*p) && (*p) <= 57 )
|
1022
|
-
goto
|
1561
|
+
goto st10;
|
1023
1562
|
goto st0;
|
1024
1563
|
st0:
|
1025
1564
|
cs = 0;
|
@@ -1029,24 +1568,42 @@ st2:
|
|
1029
1568
|
goto _test_eof2;
|
1030
1569
|
case 2:
|
1031
1570
|
if ( (*p) == 48 )
|
1032
|
-
goto
|
1571
|
+
goto st6;
|
1033
1572
|
if ( 49 <= (*p) && (*p) <= 57 )
|
1034
|
-
goto
|
1573
|
+
goto st10;
|
1035
1574
|
goto st0;
|
1036
|
-
|
1575
|
+
st6:
|
1037
1576
|
if ( ++p == pe )
|
1038
|
-
goto
|
1039
|
-
case
|
1577
|
+
goto _test_eof6;
|
1578
|
+
case 6:
|
1040
1579
|
switch( (*p) ) {
|
1041
|
-
case
|
1042
|
-
case
|
1043
|
-
case
|
1580
|
+
case 45: goto st0;
|
1581
|
+
case 46: goto tr8;
|
1582
|
+
case 69: goto tr9;
|
1583
|
+
case 101: goto tr9;
|
1044
1584
|
}
|
1585
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1586
|
+
goto st0;
|
1587
|
+
goto tr7;
|
1588
|
+
tr7:
|
1589
|
+
#line 735 "parser.rl"
|
1590
|
+
{ p--; {p++; cs = 7; goto _out;} }
|
1591
|
+
goto st7;
|
1592
|
+
st7:
|
1593
|
+
if ( ++p == pe )
|
1594
|
+
goto _test_eof7;
|
1595
|
+
case 7:
|
1596
|
+
#line 1597 "parser.c"
|
1045
1597
|
goto st0;
|
1046
|
-
|
1598
|
+
tr8:
|
1599
|
+
#line 736 "parser.rl"
|
1600
|
+
{ is_float = true; }
|
1601
|
+
goto st3;
|
1602
|
+
st3:
|
1047
1603
|
if ( ++p == pe )
|
1048
|
-
goto
|
1049
|
-
case
|
1604
|
+
goto _test_eof3;
|
1605
|
+
case 3:
|
1606
|
+
#line 1607 "parser.c"
|
1050
1607
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1051
1608
|
goto st8;
|
1052
1609
|
goto st0;
|
@@ -1055,90 +1612,89 @@ st8:
|
|
1055
1612
|
goto _test_eof8;
|
1056
1613
|
case 8:
|
1057
1614
|
switch( (*p) ) {
|
1058
|
-
case 69: goto
|
1059
|
-
case 101: goto
|
1615
|
+
case 69: goto st4;
|
1616
|
+
case 101: goto st4;
|
1060
1617
|
}
|
1061
1618
|
if ( (*p) > 46 ) {
|
1062
1619
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1063
1620
|
goto st8;
|
1064
1621
|
} else if ( (*p) >= 45 )
|
1065
1622
|
goto st0;
|
1066
|
-
goto
|
1623
|
+
goto tr7;
|
1067
1624
|
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:
|
1625
|
+
#line 736 "parser.rl"
|
1626
|
+
{ is_float = true; }
|
1627
|
+
goto st4;
|
1628
|
+
st4:
|
1078
1629
|
if ( ++p == pe )
|
1079
|
-
goto
|
1080
|
-
case
|
1630
|
+
goto _test_eof4;
|
1631
|
+
case 4:
|
1632
|
+
#line 1633 "parser.c"
|
1081
1633
|
switch( (*p) ) {
|
1082
|
-
case 43: goto
|
1083
|
-
case 45: goto
|
1634
|
+
case 43: goto st5;
|
1635
|
+
case 45: goto st5;
|
1084
1636
|
}
|
1085
1637
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1086
|
-
goto
|
1638
|
+
goto st9;
|
1087
1639
|
goto st0;
|
1088
|
-
|
1640
|
+
st5:
|
1089
1641
|
if ( ++p == pe )
|
1090
|
-
goto
|
1091
|
-
case
|
1642
|
+
goto _test_eof5;
|
1643
|
+
case 5:
|
1092
1644
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1093
|
-
goto
|
1645
|
+
goto st9;
|
1094
1646
|
goto st0;
|
1095
|
-
|
1647
|
+
st9:
|
1096
1648
|
if ( ++p == pe )
|
1097
|
-
goto
|
1098
|
-
case
|
1649
|
+
goto _test_eof9;
|
1650
|
+
case 9:
|
1099
1651
|
switch( (*p) ) {
|
1100
1652
|
case 69: goto st0;
|
1101
1653
|
case 101: goto st0;
|
1102
1654
|
}
|
1103
1655
|
if ( (*p) > 46 ) {
|
1104
1656
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1105
|
-
goto
|
1657
|
+
goto st9;
|
1106
1658
|
} else if ( (*p) >= 45 )
|
1107
1659
|
goto st0;
|
1108
|
-
goto
|
1109
|
-
|
1660
|
+
goto tr7;
|
1661
|
+
st10:
|
1110
1662
|
if ( ++p == pe )
|
1111
|
-
goto
|
1112
|
-
case
|
1663
|
+
goto _test_eof10;
|
1664
|
+
case 10:
|
1113
1665
|
switch( (*p) ) {
|
1114
|
-
case
|
1115
|
-
case
|
1116
|
-
case
|
1666
|
+
case 45: goto st0;
|
1667
|
+
case 46: goto tr8;
|
1668
|
+
case 69: goto tr9;
|
1669
|
+
case 101: goto tr9;
|
1117
1670
|
}
|
1118
1671
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1119
|
-
goto
|
1120
|
-
goto
|
1672
|
+
goto st10;
|
1673
|
+
goto tr7;
|
1121
1674
|
}
|
1122
1675
|
_test_eof2: cs = 2; goto _test_eof;
|
1676
|
+
_test_eof6: cs = 6; goto _test_eof;
|
1677
|
+
_test_eof7: cs = 7; goto _test_eof;
|
1123
1678
|
_test_eof3: cs = 3; goto _test_eof;
|
1124
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1125
1679
|
_test_eof8: cs = 8; goto _test_eof;
|
1126
|
-
|
1680
|
+
_test_eof4: cs = 4; goto _test_eof;
|
1127
1681
|
_test_eof5: cs = 5; goto _test_eof;
|
1128
|
-
|
1682
|
+
_test_eof9: cs = 9; goto _test_eof;
|
1129
1683
|
_test_eof10: cs = 10; goto _test_eof;
|
1130
|
-
_test_eof7: cs = 7; goto _test_eof;
|
1131
1684
|
|
1132
1685
|
_test_eof: {}
|
1133
1686
|
_out: {}
|
1134
1687
|
}
|
1135
1688
|
|
1136
|
-
#line
|
1689
|
+
#line 753 "parser.rl"
|
1137
1690
|
|
1138
1691
|
if (cs >= JSON_float_first_final) {
|
1692
|
+
if (!is_float) {
|
1693
|
+
return JSON_decode_integer(json, p, result);
|
1694
|
+
}
|
1139
1695
|
VALUE mod = Qnil;
|
1140
1696
|
ID method_id = 0;
|
1141
|
-
if (
|
1697
|
+
if (json->decimal_class) {
|
1142
1698
|
if (rb_respond_to(json->decimal_class, i_try_convert)) {
|
1143
1699
|
mod = json->decimal_class;
|
1144
1700
|
method_id = i_try_convert;
|
@@ -1167,15 +1723,15 @@ case 7:
|
|
1167
1723
|
}
|
1168
1724
|
|
1169
1725
|
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');
|
1726
|
+
fbuffer_clear(&json->fbuffer);
|
1727
|
+
fbuffer_append(&json->fbuffer, json->memo, len);
|
1728
|
+
fbuffer_append_char(&json->fbuffer, '\0');
|
1173
1729
|
|
1174
1730
|
if (method_id) {
|
1175
|
-
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
1731
|
+
VALUE text = rb_str_new2(FBUFFER_PTR(&json->fbuffer));
|
1176
1732
|
*result = rb_funcallv(mod, method_id, 1, &text);
|
1177
1733
|
} else {
|
1178
|
-
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
1734
|
+
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(&json->fbuffer), 1));
|
1179
1735
|
}
|
1180
1736
|
|
1181
1737
|
return p + 1;
|
@@ -1186,37 +1742,37 @@ case 7:
|
|
1186
1742
|
|
1187
1743
|
|
1188
1744
|
|
1189
|
-
#line
|
1745
|
+
#line 1746 "parser.c"
|
1190
1746
|
enum {JSON_array_start = 1};
|
1191
|
-
enum {JSON_array_first_final =
|
1747
|
+
enum {JSON_array_first_final = 22};
|
1192
1748
|
enum {JSON_array_error = 0};
|
1193
1749
|
|
1194
1750
|
enum {JSON_array_en_main = 1};
|
1195
1751
|
|
1196
1752
|
|
1197
|
-
#line
|
1753
|
+
#line 833 "parser.rl"
|
1198
1754
|
|
1199
1755
|
|
1200
1756
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
1201
1757
|
{
|
1202
1758
|
int cs = EVIL;
|
1203
|
-
VALUE array_class = json->array_class;
|
1204
1759
|
|
1205
1760
|
if (json->max_nesting && current_nesting > json->max_nesting) {
|
1206
1761
|
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
1207
1762
|
}
|
1208
|
-
|
1763
|
+
long stack_head = json->stack->head;
|
1209
1764
|
|
1210
1765
|
|
1211
|
-
#line
|
1766
|
+
#line 1767 "parser.c"
|
1212
1767
|
{
|
1213
1768
|
cs = JSON_array_start;
|
1214
1769
|
}
|
1215
1770
|
|
1216
|
-
#line
|
1771
|
+
#line 845 "parser.rl"
|
1217
1772
|
|
1218
|
-
#line
|
1773
|
+
#line 1774 "parser.c"
|
1219
1774
|
{
|
1775
|
+
short _widec;
|
1220
1776
|
if ( p == pe )
|
1221
1777
|
goto _test_eof;
|
1222
1778
|
switch ( cs )
|
@@ -1237,7 +1793,7 @@ case 2:
|
|
1237
1793
|
case 32: goto st2;
|
1238
1794
|
case 34: goto tr2;
|
1239
1795
|
case 45: goto tr2;
|
1240
|
-
case 47: goto
|
1796
|
+
case 47: goto st18;
|
1241
1797
|
case 73: goto tr2;
|
1242
1798
|
case 78: goto tr2;
|
1243
1799
|
case 91: goto tr2;
|
@@ -1254,18 +1810,13 @@ case 2:
|
|
1254
1810
|
goto st2;
|
1255
1811
|
goto st0;
|
1256
1812
|
tr2:
|
1257
|
-
#line
|
1813
|
+
#line 813 "parser.rl"
|
1258
1814
|
{
|
1259
1815
|
VALUE v = Qnil;
|
1260
1816
|
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
1261
1817
|
if (np == NULL) {
|
1262
1818
|
p--; {p++; cs = 3; goto _out;}
|
1263
1819
|
} 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
1820
|
{p = (( np))-1;}
|
1270
1821
|
}
|
1271
1822
|
}
|
@@ -1274,15 +1825,23 @@ st3:
|
|
1274
1825
|
if ( ++p == pe )
|
1275
1826
|
goto _test_eof3;
|
1276
1827
|
case 3:
|
1277
|
-
#line
|
1278
|
-
|
1828
|
+
#line 1829 "parser.c"
|
1829
|
+
_widec = (*p);
|
1830
|
+
if ( 44 <= (*p) && (*p) <= 44 ) {
|
1831
|
+
_widec = (short)(128 + ((*p) - -128));
|
1832
|
+
if (
|
1833
|
+
#line 823 "parser.rl"
|
1834
|
+
json->allow_trailing_comma ) _widec += 256;
|
1835
|
+
}
|
1836
|
+
switch( _widec ) {
|
1279
1837
|
case 13: goto st3;
|
1280
1838
|
case 32: goto st3;
|
1281
|
-
case
|
1282
|
-
case 47: goto st9;
|
1839
|
+
case 47: goto st4;
|
1283
1840
|
case 93: goto tr4;
|
1841
|
+
case 300: goto st8;
|
1842
|
+
case 556: goto st13;
|
1284
1843
|
}
|
1285
|
-
if ( 9 <=
|
1844
|
+
if ( 9 <= _widec && _widec <= 10 )
|
1286
1845
|
goto st3;
|
1287
1846
|
goto st0;
|
1288
1847
|
st4:
|
@@ -1290,57 +1849,67 @@ st4:
|
|
1290
1849
|
goto _test_eof4;
|
1291
1850
|
case 4:
|
1292
1851
|
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;
|
1852
|
+
case 42: goto st5;
|
1853
|
+
case 47: goto st7;
|
1305
1854
|
}
|
1306
|
-
if ( (*p) > 10 ) {
|
1307
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1308
|
-
goto tr2;
|
1309
|
-
} else if ( (*p) >= 9 )
|
1310
|
-
goto st4;
|
1311
1855
|
goto st0;
|
1312
1856
|
st5:
|
1313
1857
|
if ( ++p == pe )
|
1314
1858
|
goto _test_eof5;
|
1315
1859
|
case 5:
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
}
|
1320
|
-
goto st0;
|
1860
|
+
if ( (*p) == 42 )
|
1861
|
+
goto st6;
|
1862
|
+
goto st5;
|
1321
1863
|
st6:
|
1322
1864
|
if ( ++p == pe )
|
1323
1865
|
goto _test_eof6;
|
1324
1866
|
case 6:
|
1325
|
-
|
1326
|
-
goto
|
1327
|
-
|
1867
|
+
switch( (*p) ) {
|
1868
|
+
case 42: goto st6;
|
1869
|
+
case 47: goto st3;
|
1870
|
+
}
|
1871
|
+
goto st5;
|
1328
1872
|
st7:
|
1329
1873
|
if ( ++p == pe )
|
1330
1874
|
goto _test_eof7;
|
1331
1875
|
case 7:
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1876
|
+
if ( (*p) == 10 )
|
1877
|
+
goto st3;
|
1878
|
+
goto st7;
|
1879
|
+
tr4:
|
1880
|
+
#line 825 "parser.rl"
|
1881
|
+
{ p--; {p++; cs = 22; goto _out;} }
|
1882
|
+
goto st22;
|
1883
|
+
st22:
|
1884
|
+
if ( ++p == pe )
|
1885
|
+
goto _test_eof22;
|
1886
|
+
case 22:
|
1887
|
+
#line 1888 "parser.c"
|
1888
|
+
goto st0;
|
1337
1889
|
st8:
|
1338
1890
|
if ( ++p == pe )
|
1339
1891
|
goto _test_eof8;
|
1340
1892
|
case 8:
|
1341
|
-
|
1342
|
-
goto
|
1343
|
-
|
1893
|
+
switch( (*p) ) {
|
1894
|
+
case 13: goto st8;
|
1895
|
+
case 32: goto st8;
|
1896
|
+
case 34: goto tr2;
|
1897
|
+
case 45: goto tr2;
|
1898
|
+
case 47: goto st9;
|
1899
|
+
case 73: goto tr2;
|
1900
|
+
case 78: goto tr2;
|
1901
|
+
case 91: goto tr2;
|
1902
|
+
case 102: goto tr2;
|
1903
|
+
case 110: goto tr2;
|
1904
|
+
case 116: goto tr2;
|
1905
|
+
case 123: goto tr2;
|
1906
|
+
}
|
1907
|
+
if ( (*p) > 10 ) {
|
1908
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1909
|
+
goto tr2;
|
1910
|
+
} else if ( (*p) >= 9 )
|
1911
|
+
goto st8;
|
1912
|
+
goto st0;
|
1344
1913
|
st9:
|
1345
1914
|
if ( ++p == pe )
|
1346
1915
|
goto _test_eof9;
|
@@ -1363,7 +1932,7 @@ st11:
|
|
1363
1932
|
case 11:
|
1364
1933
|
switch( (*p) ) {
|
1365
1934
|
case 42: goto st11;
|
1366
|
-
case 47: goto
|
1935
|
+
case 47: goto st8;
|
1367
1936
|
}
|
1368
1937
|
goto st10;
|
1369
1938
|
st12:
|
@@ -1371,50 +1940,252 @@ st12:
|
|
1371
1940
|
goto _test_eof12;
|
1372
1941
|
case 12:
|
1373
1942
|
if ( (*p) == 10 )
|
1374
|
-
goto
|
1943
|
+
goto st8;
|
1375
1944
|
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
1945
|
st13:
|
1387
1946
|
if ( ++p == pe )
|
1388
1947
|
goto _test_eof13;
|
1389
1948
|
case 13:
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1949
|
+
_widec = (*p);
|
1950
|
+
if ( (*p) < 13 ) {
|
1951
|
+
if ( (*p) > 9 ) {
|
1952
|
+
if ( 10 <= (*p) && (*p) <= 10 ) {
|
1953
|
+
_widec = (short)(128 + ((*p) - -128));
|
1954
|
+
if (
|
1955
|
+
#line 823 "parser.rl"
|
1956
|
+
json->allow_trailing_comma ) _widec += 256;
|
1957
|
+
}
|
1958
|
+
} else if ( (*p) >= 9 ) {
|
1959
|
+
_widec = (short)(128 + ((*p) - -128));
|
1960
|
+
if (
|
1961
|
+
#line 823 "parser.rl"
|
1962
|
+
json->allow_trailing_comma ) _widec += 256;
|
1963
|
+
}
|
1964
|
+
} else if ( (*p) > 13 ) {
|
1965
|
+
if ( (*p) > 32 ) {
|
1966
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
1967
|
+
_widec = (short)(128 + ((*p) - -128));
|
1968
|
+
if (
|
1969
|
+
#line 823 "parser.rl"
|
1970
|
+
json->allow_trailing_comma ) _widec += 256;
|
1971
|
+
}
|
1972
|
+
} else if ( (*p) >= 32 ) {
|
1973
|
+
_widec = (short)(128 + ((*p) - -128));
|
1974
|
+
if (
|
1975
|
+
#line 823 "parser.rl"
|
1976
|
+
json->allow_trailing_comma ) _widec += 256;
|
1977
|
+
}
|
1978
|
+
} else {
|
1979
|
+
_widec = (short)(128 + ((*p) - -128));
|
1980
|
+
if (
|
1981
|
+
#line 823 "parser.rl"
|
1982
|
+
json->allow_trailing_comma ) _widec += 256;
|
1983
|
+
}
|
1984
|
+
switch( _widec ) {
|
1985
|
+
case 34: goto tr2;
|
1986
|
+
case 45: goto tr2;
|
1987
|
+
case 73: goto tr2;
|
1988
|
+
case 78: goto tr2;
|
1989
|
+
case 91: goto tr2;
|
1990
|
+
case 93: goto tr4;
|
1991
|
+
case 102: goto tr2;
|
1992
|
+
case 110: goto tr2;
|
1993
|
+
case 116: goto tr2;
|
1994
|
+
case 123: goto tr2;
|
1995
|
+
case 269: goto st8;
|
1996
|
+
case 288: goto st8;
|
1997
|
+
case 303: goto st9;
|
1998
|
+
case 525: goto st13;
|
1999
|
+
case 544: goto st13;
|
2000
|
+
case 559: goto st14;
|
2001
|
+
}
|
2002
|
+
if ( _widec < 265 ) {
|
2003
|
+
if ( 48 <= _widec && _widec <= 57 )
|
2004
|
+
goto tr2;
|
2005
|
+
} else if ( _widec > 266 ) {
|
2006
|
+
if ( 521 <= _widec && _widec <= 522 )
|
2007
|
+
goto st13;
|
2008
|
+
} else
|
2009
|
+
goto st8;
|
1394
2010
|
goto st0;
|
1395
2011
|
st14:
|
1396
2012
|
if ( ++p == pe )
|
1397
2013
|
goto _test_eof14;
|
1398
2014
|
case 14:
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
2015
|
+
_widec = (*p);
|
2016
|
+
if ( (*p) > 42 ) {
|
2017
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
2018
|
+
_widec = (short)(128 + ((*p) - -128));
|
2019
|
+
if (
|
2020
|
+
#line 823 "parser.rl"
|
2021
|
+
json->allow_trailing_comma ) _widec += 256;
|
2022
|
+
}
|
2023
|
+
} else if ( (*p) >= 42 ) {
|
2024
|
+
_widec = (short)(128 + ((*p) - -128));
|
2025
|
+
if (
|
2026
|
+
#line 823 "parser.rl"
|
2027
|
+
json->allow_trailing_comma ) _widec += 256;
|
2028
|
+
}
|
2029
|
+
switch( _widec ) {
|
2030
|
+
case 298: goto st10;
|
2031
|
+
case 303: goto st12;
|
2032
|
+
case 554: goto st15;
|
2033
|
+
case 559: goto st17;
|
2034
|
+
}
|
2035
|
+
goto st0;
|
1402
2036
|
st15:
|
1403
2037
|
if ( ++p == pe )
|
1404
2038
|
goto _test_eof15;
|
1405
2039
|
case 15:
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
2040
|
+
_widec = (*p);
|
2041
|
+
if ( (*p) < 42 ) {
|
2042
|
+
if ( (*p) <= 41 ) {
|
2043
|
+
_widec = (short)(128 + ((*p) - -128));
|
2044
|
+
if (
|
2045
|
+
#line 823 "parser.rl"
|
2046
|
+
json->allow_trailing_comma ) _widec += 256;
|
2047
|
+
}
|
2048
|
+
} else if ( (*p) > 42 ) {
|
2049
|
+
if ( 43 <= (*p) )
|
2050
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2051
|
+
if (
|
2052
|
+
#line 823 "parser.rl"
|
2053
|
+
json->allow_trailing_comma ) _widec += 256;
|
2054
|
+
}
|
2055
|
+
} else {
|
2056
|
+
_widec = (short)(128 + ((*p) - -128));
|
2057
|
+
if (
|
2058
|
+
#line 823 "parser.rl"
|
2059
|
+
json->allow_trailing_comma ) _widec += 256;
|
2060
|
+
}
|
2061
|
+
switch( _widec ) {
|
2062
|
+
case 298: goto st11;
|
2063
|
+
case 554: goto st16;
|
2064
|
+
}
|
2065
|
+
if ( _widec > 383 ) {
|
2066
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2067
|
+
goto st15;
|
2068
|
+
} else if ( _widec >= 128 )
|
2069
|
+
goto st10;
|
2070
|
+
goto st0;
|
1411
2071
|
st16:
|
1412
2072
|
if ( ++p == pe )
|
1413
2073
|
goto _test_eof16;
|
1414
2074
|
case 16:
|
2075
|
+
_widec = (*p);
|
2076
|
+
if ( (*p) < 43 ) {
|
2077
|
+
if ( (*p) > 41 ) {
|
2078
|
+
if ( 42 <= (*p) && (*p) <= 42 ) {
|
2079
|
+
_widec = (short)(128 + ((*p) - -128));
|
2080
|
+
if (
|
2081
|
+
#line 823 "parser.rl"
|
2082
|
+
json->allow_trailing_comma ) _widec += 256;
|
2083
|
+
}
|
2084
|
+
} else {
|
2085
|
+
_widec = (short)(128 + ((*p) - -128));
|
2086
|
+
if (
|
2087
|
+
#line 823 "parser.rl"
|
2088
|
+
json->allow_trailing_comma ) _widec += 256;
|
2089
|
+
}
|
2090
|
+
} else if ( (*p) > 46 ) {
|
2091
|
+
if ( (*p) > 47 ) {
|
2092
|
+
if ( 48 <= (*p) )
|
2093
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2094
|
+
if (
|
2095
|
+
#line 823 "parser.rl"
|
2096
|
+
json->allow_trailing_comma ) _widec += 256;
|
2097
|
+
}
|
2098
|
+
} else if ( (*p) >= 47 ) {
|
2099
|
+
_widec = (short)(128 + ((*p) - -128));
|
2100
|
+
if (
|
2101
|
+
#line 823 "parser.rl"
|
2102
|
+
json->allow_trailing_comma ) _widec += 256;
|
2103
|
+
}
|
2104
|
+
} else {
|
2105
|
+
_widec = (short)(128 + ((*p) - -128));
|
2106
|
+
if (
|
2107
|
+
#line 823 "parser.rl"
|
2108
|
+
json->allow_trailing_comma ) _widec += 256;
|
2109
|
+
}
|
2110
|
+
switch( _widec ) {
|
2111
|
+
case 298: goto st11;
|
2112
|
+
case 303: goto st8;
|
2113
|
+
case 554: goto st16;
|
2114
|
+
case 559: goto st13;
|
2115
|
+
}
|
2116
|
+
if ( _widec > 383 ) {
|
2117
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2118
|
+
goto st15;
|
2119
|
+
} else if ( _widec >= 128 )
|
2120
|
+
goto st10;
|
2121
|
+
goto st0;
|
2122
|
+
st17:
|
2123
|
+
if ( ++p == pe )
|
2124
|
+
goto _test_eof17;
|
2125
|
+
case 17:
|
2126
|
+
_widec = (*p);
|
2127
|
+
if ( (*p) < 10 ) {
|
2128
|
+
if ( (*p) <= 9 ) {
|
2129
|
+
_widec = (short)(128 + ((*p) - -128));
|
2130
|
+
if (
|
2131
|
+
#line 823 "parser.rl"
|
2132
|
+
json->allow_trailing_comma ) _widec += 256;
|
2133
|
+
}
|
2134
|
+
} else if ( (*p) > 10 ) {
|
2135
|
+
if ( 11 <= (*p) )
|
2136
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2137
|
+
if (
|
2138
|
+
#line 823 "parser.rl"
|
2139
|
+
json->allow_trailing_comma ) _widec += 256;
|
2140
|
+
}
|
2141
|
+
} else {
|
2142
|
+
_widec = (short)(128 + ((*p) - -128));
|
2143
|
+
if (
|
2144
|
+
#line 823 "parser.rl"
|
2145
|
+
json->allow_trailing_comma ) _widec += 256;
|
2146
|
+
}
|
2147
|
+
switch( _widec ) {
|
2148
|
+
case 266: goto st8;
|
2149
|
+
case 522: goto st13;
|
2150
|
+
}
|
2151
|
+
if ( _widec > 383 ) {
|
2152
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2153
|
+
goto st17;
|
2154
|
+
} else if ( _widec >= 128 )
|
2155
|
+
goto st12;
|
2156
|
+
goto st0;
|
2157
|
+
st18:
|
2158
|
+
if ( ++p == pe )
|
2159
|
+
goto _test_eof18;
|
2160
|
+
case 18:
|
2161
|
+
switch( (*p) ) {
|
2162
|
+
case 42: goto st19;
|
2163
|
+
case 47: goto st21;
|
2164
|
+
}
|
2165
|
+
goto st0;
|
2166
|
+
st19:
|
2167
|
+
if ( ++p == pe )
|
2168
|
+
goto _test_eof19;
|
2169
|
+
case 19:
|
2170
|
+
if ( (*p) == 42 )
|
2171
|
+
goto st20;
|
2172
|
+
goto st19;
|
2173
|
+
st20:
|
2174
|
+
if ( ++p == pe )
|
2175
|
+
goto _test_eof20;
|
2176
|
+
case 20:
|
2177
|
+
switch( (*p) ) {
|
2178
|
+
case 42: goto st20;
|
2179
|
+
case 47: goto st2;
|
2180
|
+
}
|
2181
|
+
goto st19;
|
2182
|
+
st21:
|
2183
|
+
if ( ++p == pe )
|
2184
|
+
goto _test_eof21;
|
2185
|
+
case 21:
|
1415
2186
|
if ( (*p) == 10 )
|
1416
2187
|
goto st2;
|
1417
|
-
goto
|
2188
|
+
goto st21;
|
1418
2189
|
}
|
1419
2190
|
_test_eof2: cs = 2; goto _test_eof;
|
1420
2191
|
_test_eof3: cs = 3; goto _test_eof;
|
@@ -1422,24 +2193,45 @@ case 16:
|
|
1422
2193
|
_test_eof5: cs = 5; goto _test_eof;
|
1423
2194
|
_test_eof6: cs = 6; goto _test_eof;
|
1424
2195
|
_test_eof7: cs = 7; goto _test_eof;
|
2196
|
+
_test_eof22: cs = 22; goto _test_eof;
|
1425
2197
|
_test_eof8: cs = 8; goto _test_eof;
|
1426
2198
|
_test_eof9: cs = 9; goto _test_eof;
|
1427
2199
|
_test_eof10: cs = 10; goto _test_eof;
|
1428
2200
|
_test_eof11: cs = 11; goto _test_eof;
|
1429
2201
|
_test_eof12: cs = 12; goto _test_eof;
|
1430
|
-
_test_eof17: cs = 17; goto _test_eof;
|
1431
2202
|
_test_eof13: cs = 13; goto _test_eof;
|
1432
2203
|
_test_eof14: cs = 14; goto _test_eof;
|
1433
2204
|
_test_eof15: cs = 15; goto _test_eof;
|
1434
2205
|
_test_eof16: cs = 16; goto _test_eof;
|
2206
|
+
_test_eof17: cs = 17; goto _test_eof;
|
2207
|
+
_test_eof18: cs = 18; goto _test_eof;
|
2208
|
+
_test_eof19: cs = 19; goto _test_eof;
|
2209
|
+
_test_eof20: cs = 20; goto _test_eof;
|
2210
|
+
_test_eof21: cs = 21; goto _test_eof;
|
1435
2211
|
|
1436
2212
|
_test_eof: {}
|
1437
2213
|
_out: {}
|
1438
2214
|
}
|
1439
2215
|
|
1440
|
-
#line
|
2216
|
+
#line 846 "parser.rl"
|
1441
2217
|
|
1442
2218
|
if(cs >= JSON_array_first_final) {
|
2219
|
+
long count = json->stack->head - stack_head;
|
2220
|
+
|
2221
|
+
if (RB_UNLIKELY(json->array_class)) {
|
2222
|
+
VALUE array = rb_class_new_instance(0, 0, json->array_class);
|
2223
|
+
VALUE *items = rvalue_stack_peek(json->stack, count);
|
2224
|
+
long index;
|
2225
|
+
for (index = 0; index < count; index++) {
|
2226
|
+
rb_funcall(array, i_leftshift, 1, items[index]);
|
2227
|
+
}
|
2228
|
+
*result = array;
|
2229
|
+
} else {
|
2230
|
+
VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(json->stack, count));
|
2231
|
+
*result = array;
|
2232
|
+
}
|
2233
|
+
rvalue_stack_pop(json->stack, count);
|
2234
|
+
|
1443
2235
|
return p + 1;
|
1444
2236
|
} else {
|
1445
2237
|
raise_parse_error("unexpected token at '%s'", p);
|
@@ -1447,29 +2239,81 @@ case 16:
|
|
1447
2239
|
}
|
1448
2240
|
}
|
1449
2241
|
|
1450
|
-
static const
|
1451
|
-
|
2242
|
+
static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize)
|
2243
|
+
{
|
2244
|
+
if (symbolize) {
|
2245
|
+
intern = true;
|
2246
|
+
}
|
2247
|
+
VALUE result;
|
2248
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
2249
|
+
if (intern) {
|
2250
|
+
result = rb_enc_interned_str(start, (long)(end - start), enc_utf8);
|
2251
|
+
} else {
|
2252
|
+
result = rb_utf8_str_new(start, (long)(end - start));
|
2253
|
+
}
|
2254
|
+
# else
|
2255
|
+
result = rb_utf8_str_new(start, (long)(end - start));
|
2256
|
+
if (intern) {
|
2257
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
2258
|
+
}
|
2259
|
+
# endif
|
2260
|
+
|
2261
|
+
if (symbolize) {
|
2262
|
+
result = rb_str_intern(result);
|
2263
|
+
}
|
2264
|
+
|
2265
|
+
return result;
|
2266
|
+
}
|
2267
|
+
|
2268
|
+
static VALUE json_string_fastpath(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
|
2269
|
+
{
|
2270
|
+
size_t bufferSize = stringEnd - string;
|
2271
|
+
|
2272
|
+
if (is_name && json->in_array) {
|
2273
|
+
VALUE cached_key;
|
2274
|
+
if (RB_UNLIKELY(symbolize)) {
|
2275
|
+
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
|
2276
|
+
} else {
|
2277
|
+
cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
|
2278
|
+
}
|
2279
|
+
|
2280
|
+
if (RB_LIKELY(cached_key)) {
|
2281
|
+
return cached_key;
|
2282
|
+
}
|
2283
|
+
}
|
2284
|
+
|
2285
|
+
return build_string(string, stringEnd, intern, symbolize);
|
2286
|
+
}
|
2287
|
+
|
2288
|
+
static VALUE json_string_unescape(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
|
1452
2289
|
{
|
1453
|
-
VALUE result = Qnil;
|
1454
2290
|
size_t bufferSize = stringEnd - string;
|
1455
2291
|
char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
|
1456
2292
|
int unescape_len;
|
1457
2293
|
char buf[4];
|
1458
2294
|
|
1459
|
-
if (
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
2295
|
+
if (is_name && json->in_array) {
|
2296
|
+
VALUE cached_key;
|
2297
|
+
if (RB_UNLIKELY(symbolize)) {
|
2298
|
+
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
|
2299
|
+
} else {
|
2300
|
+
cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
|
2301
|
+
}
|
2302
|
+
|
2303
|
+
if (RB_LIKELY(cached_key)) {
|
2304
|
+
return cached_key;
|
2305
|
+
}
|
2306
|
+
}
|
2307
|
+
|
2308
|
+
pe = memchr(p, '\\', bufferSize);
|
2309
|
+
if (RB_UNLIKELY(pe == NULL)) {
|
2310
|
+
return build_string(string, stringEnd, intern, symbolize);
|
1471
2311
|
}
|
1472
2312
|
|
2313
|
+
VALUE result = rb_str_buf_new(bufferSize);
|
2314
|
+
rb_enc_associate_index(result, utf8_encindex);
|
2315
|
+
buffer = bufferStart = RSTRING_PTR(result);
|
2316
|
+
|
1473
2317
|
while (pe < stringEnd) {
|
1474
2318
|
if (*pe == '\\') {
|
1475
2319
|
unescape = (char *) "?";
|
@@ -1502,9 +2346,6 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1502
2346
|
break;
|
1503
2347
|
case 'u':
|
1504
2348
|
if (pe > stringEnd - 4) {
|
1505
|
-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
1506
|
-
ruby_xfree(bufferStart);
|
1507
|
-
}
|
1508
2349
|
raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
|
1509
2350
|
} else {
|
1510
2351
|
uint32_t ch = unescape_unicode((unsigned char *) ++pe);
|
@@ -1522,9 +2363,6 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1522
2363
|
if ((ch & 0xFC00) == 0xD800) {
|
1523
2364
|
pe++;
|
1524
2365
|
if (pe > stringEnd - 6) {
|
1525
|
-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
1526
|
-
ruby_xfree(bufferStart);
|
1527
|
-
}
|
1528
2366
|
raise_parse_error("incomplete surrogate pair at '%s'", p);
|
1529
2367
|
}
|
1530
2368
|
if (pe[0] == '\\' && pe[1] == 'u') {
|
@@ -1557,56 +2395,27 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1557
2395
|
MEMCPY(buffer, p, char, pe - p);
|
1558
2396
|
buffer += pe - p;
|
1559
2397
|
}
|
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
|
2398
|
+
rb_str_set_len(result, buffer - bufferStart);
|
1592
2399
|
|
1593
2400
|
if (symbolize) {
|
1594
|
-
|
2401
|
+
result = rb_str_intern(result);
|
2402
|
+
} else if (intern) {
|
2403
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
1595
2404
|
}
|
1596
2405
|
|
1597
2406
|
return result;
|
1598
2407
|
}
|
1599
2408
|
|
1600
2409
|
|
1601
|
-
#line
|
2410
|
+
#line 2411 "parser.c"
|
1602
2411
|
enum {JSON_string_start = 1};
|
1603
|
-
enum {JSON_string_first_final =
|
2412
|
+
enum {JSON_string_first_final = 9};
|
1604
2413
|
enum {JSON_string_error = 0};
|
1605
2414
|
|
1606
2415
|
enum {JSON_string_en_main = 1};
|
1607
2416
|
|
1608
2417
|
|
1609
|
-
#line
|
2418
|
+
#line 1069 "parser.rl"
|
1610
2419
|
|
1611
2420
|
|
1612
2421
|
static int
|
@@ -1627,15 +2436,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1627
2436
|
VALUE match_string;
|
1628
2437
|
|
1629
2438
|
|
1630
|
-
#line
|
2439
|
+
#line 2440 "parser.c"
|
1631
2440
|
{
|
1632
2441
|
cs = JSON_string_start;
|
1633
2442
|
}
|
1634
2443
|
|
1635
|
-
#line
|
2444
|
+
#line 1089 "parser.rl"
|
1636
2445
|
json->memo = p;
|
1637
2446
|
|
1638
|
-
#line
|
2447
|
+
#line 2448 "parser.c"
|
1639
2448
|
{
|
1640
2449
|
if ( p == pe )
|
1641
2450
|
goto _test_eof;
|
@@ -1660,47 +2469,56 @@ case 2:
|
|
1660
2469
|
goto st0;
|
1661
2470
|
goto st2;
|
1662
2471
|
tr2:
|
1663
|
-
#line
|
2472
|
+
#line 1051 "parser.rl"
|
1664
2473
|
{
|
1665
|
-
*result =
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
} else {
|
1670
|
-
{p = (( p + 1))-1;}
|
1671
|
-
}
|
2474
|
+
*result = json_string_fastpath(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2475
|
+
{p = (( p + 1))-1;}
|
2476
|
+
p--;
|
2477
|
+
{p++; cs = 9; goto _out;}
|
1672
2478
|
}
|
1673
|
-
#line
|
1674
|
-
{
|
1675
|
-
|
1676
|
-
|
2479
|
+
#line 1044 "parser.rl"
|
2480
|
+
{
|
2481
|
+
*result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2482
|
+
{p = (( p + 1))-1;}
|
2483
|
+
p--;
|
2484
|
+
{p++; cs = 9; goto _out;}
|
2485
|
+
}
|
2486
|
+
goto st9;
|
2487
|
+
tr6:
|
2488
|
+
#line 1044 "parser.rl"
|
2489
|
+
{
|
2490
|
+
*result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2491
|
+
{p = (( p + 1))-1;}
|
2492
|
+
p--;
|
2493
|
+
{p++; cs = 9; goto _out;}
|
2494
|
+
}
|
2495
|
+
goto st9;
|
2496
|
+
st9:
|
1677
2497
|
if ( ++p == pe )
|
1678
|
-
goto
|
1679
|
-
case
|
1680
|
-
#line
|
2498
|
+
goto _test_eof9;
|
2499
|
+
case 9:
|
2500
|
+
#line 2501 "parser.c"
|
1681
2501
|
goto st0;
|
1682
2502
|
st3:
|
1683
2503
|
if ( ++p == pe )
|
1684
2504
|
goto _test_eof3;
|
1685
2505
|
case 3:
|
1686
2506
|
if ( (*p) == 117 )
|
1687
|
-
goto
|
2507
|
+
goto st5;
|
1688
2508
|
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
1689
2509
|
goto st0;
|
1690
|
-
goto
|
2510
|
+
goto st4;
|
1691
2511
|
st4:
|
1692
2512
|
if ( ++p == pe )
|
1693
|
-
goto _test_eof4;
|
1694
|
-
case 4:
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
}
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
goto st5;
|
1703
|
-
goto st0;
|
2513
|
+
goto _test_eof4;
|
2514
|
+
case 4:
|
2515
|
+
switch( (*p) ) {
|
2516
|
+
case 34: goto tr6;
|
2517
|
+
case 92: goto st3;
|
2518
|
+
}
|
2519
|
+
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
2520
|
+
goto st0;
|
2521
|
+
goto st4;
|
1704
2522
|
st5:
|
1705
2523
|
if ( ++p == pe )
|
1706
2524
|
goto _test_eof5;
|
@@ -1733,27 +2551,41 @@ st7:
|
|
1733
2551
|
case 7:
|
1734
2552
|
if ( (*p) < 65 ) {
|
1735
2553
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1736
|
-
goto
|
2554
|
+
goto st8;
|
1737
2555
|
} else if ( (*p) > 70 ) {
|
1738
2556
|
if ( 97 <= (*p) && (*p) <= 102 )
|
1739
|
-
goto
|
2557
|
+
goto st8;
|
1740
2558
|
} else
|
1741
|
-
goto
|
2559
|
+
goto st8;
|
2560
|
+
goto st0;
|
2561
|
+
st8:
|
2562
|
+
if ( ++p == pe )
|
2563
|
+
goto _test_eof8;
|
2564
|
+
case 8:
|
2565
|
+
if ( (*p) < 65 ) {
|
2566
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
2567
|
+
goto st4;
|
2568
|
+
} else if ( (*p) > 70 ) {
|
2569
|
+
if ( 97 <= (*p) && (*p) <= 102 )
|
2570
|
+
goto st4;
|
2571
|
+
} else
|
2572
|
+
goto st4;
|
1742
2573
|
goto st0;
|
1743
2574
|
}
|
1744
2575
|
_test_eof2: cs = 2; goto _test_eof;
|
1745
|
-
|
2576
|
+
_test_eof9: cs = 9; goto _test_eof;
|
1746
2577
|
_test_eof3: cs = 3; goto _test_eof;
|
1747
2578
|
_test_eof4: cs = 4; goto _test_eof;
|
1748
2579
|
_test_eof5: cs = 5; goto _test_eof;
|
1749
2580
|
_test_eof6: cs = 6; goto _test_eof;
|
1750
2581
|
_test_eof7: cs = 7; goto _test_eof;
|
2582
|
+
_test_eof8: cs = 8; goto _test_eof;
|
1751
2583
|
|
1752
2584
|
_test_eof: {}
|
1753
2585
|
_out: {}
|
1754
2586
|
}
|
1755
2587
|
|
1756
|
-
#line
|
2588
|
+
#line 1091 "parser.rl"
|
1757
2589
|
|
1758
2590
|
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
1759
2591
|
VALUE klass;
|
@@ -1789,18 +2621,78 @@ static VALUE convert_encoding(VALUE source)
|
|
1789
2621
|
{
|
1790
2622
|
int encindex = RB_ENCODING_GET(source);
|
1791
2623
|
|
1792
|
-
if (encindex == utf8_encindex) {
|
2624
|
+
if (RB_LIKELY(encindex == utf8_encindex)) {
|
1793
2625
|
return source;
|
1794
2626
|
}
|
1795
2627
|
|
1796
2628
|
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
|
2629
|
+
// For historical reason, we silently reinterpret binary strings as UTF-8
|
1800
2630
|
return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
|
1801
2631
|
}
|
1802
2632
|
|
1803
|
-
return
|
2633
|
+
return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
|
2634
|
+
}
|
2635
|
+
|
2636
|
+
static int configure_parser_i(VALUE key, VALUE val, VALUE data)
|
2637
|
+
{
|
2638
|
+
JSON_Parser *json = (JSON_Parser *)data;
|
2639
|
+
|
2640
|
+
if (key == sym_max_nesting) { json->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
|
2641
|
+
else if (key == sym_allow_nan) { json->allow_nan = RTEST(val); }
|
2642
|
+
else if (key == sym_allow_trailing_comma) { json->allow_trailing_comma = RTEST(val); }
|
2643
|
+
else if (key == sym_symbolize_names) { json->symbolize_names = RTEST(val); }
|
2644
|
+
else if (key == sym_freeze) { json->freeze = RTEST(val); }
|
2645
|
+
else if (key == sym_create_id) { json->create_id = RTEST(val) ? val : Qfalse; }
|
2646
|
+
else if (key == sym_object_class) { json->object_class = RTEST(val) ? val : Qfalse; }
|
2647
|
+
else if (key == sym_array_class) { json->array_class = RTEST(val) ? val : Qfalse; }
|
2648
|
+
else if (key == sym_decimal_class) { json->decimal_class = RTEST(val) ? val : Qfalse; }
|
2649
|
+
else if (key == sym_match_string) { json->match_string = RTEST(val) ? val : Qfalse; }
|
2650
|
+
else if (key == sym_create_additions) {
|
2651
|
+
if (NIL_P(val)) {
|
2652
|
+
json->create_additions = true;
|
2653
|
+
json->deprecated_create_additions = true;
|
2654
|
+
} else {
|
2655
|
+
json->create_additions = RTEST(val);
|
2656
|
+
json->deprecated_create_additions = false;
|
2657
|
+
}
|
2658
|
+
}
|
2659
|
+
|
2660
|
+
return ST_CONTINUE;
|
2661
|
+
}
|
2662
|
+
|
2663
|
+
static void parser_init(JSON_Parser *json, VALUE source, VALUE opts)
|
2664
|
+
{
|
2665
|
+
if (json->Vsource) {
|
2666
|
+
rb_raise(rb_eTypeError, "already initialized instance");
|
2667
|
+
}
|
2668
|
+
|
2669
|
+
json->fbuffer.initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
|
2670
|
+
json->max_nesting = 100;
|
2671
|
+
|
2672
|
+
if (!NIL_P(opts)) {
|
2673
|
+
Check_Type(opts, T_HASH);
|
2674
|
+
if (RHASH_SIZE(opts) > 0) {
|
2675
|
+
// We assume in most cases few keys are set so it's faster to go over
|
2676
|
+
// the provided keys than to check all possible keys.
|
2677
|
+
rb_hash_foreach(opts, configure_parser_i, (VALUE)json);
|
2678
|
+
|
2679
|
+
if (json->symbolize_names && json->create_additions) {
|
2680
|
+
rb_raise(rb_eArgError,
|
2681
|
+
"options :symbolize_names and :create_additions cannot be "
|
2682
|
+
" used in conjunction");
|
2683
|
+
}
|
2684
|
+
|
2685
|
+
if (json->create_additions && !json->create_id) {
|
2686
|
+
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
2687
|
+
}
|
2688
|
+
}
|
2689
|
+
|
2690
|
+
}
|
2691
|
+
source = convert_encoding(StringValue(source));
|
2692
|
+
StringValue(source);
|
2693
|
+
json->len = RSTRING_LEN(source);
|
2694
|
+
json->source = RSTRING_PTR(source);
|
2695
|
+
json->Vsource = source;
|
1804
2696
|
}
|
1805
2697
|
|
1806
2698
|
/*
|
@@ -1837,116 +2729,16 @@ static VALUE convert_encoding(VALUE source)
|
|
1837
2729
|
*/
|
1838
2730
|
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
1839
2731
|
{
|
1840
|
-
VALUE source, opts;
|
1841
2732
|
GET_PARSER_INIT;
|
1842
2733
|
|
1843
|
-
if (json->Vsource) {
|
1844
|
-
rb_raise(rb_eTypeError, "already initialized instance");
|
1845
|
-
}
|
1846
|
-
|
1847
2734
|
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
2735
|
|
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;
|
2736
|
+
parser_init(json, argv[0], argc == 2 ? argv[1] : Qnil);
|
1945
2737
|
return self;
|
1946
2738
|
}
|
1947
2739
|
|
1948
2740
|
|
1949
|
-
#line
|
2741
|
+
#line 2742 "parser.c"
|
1950
2742
|
enum {JSON_start = 1};
|
1951
2743
|
enum {JSON_first_final = 10};
|
1952
2744
|
enum {JSON_error = 0};
|
@@ -1954,7 +2746,7 @@ enum {JSON_error = 0};
|
|
1954
2746
|
enum {JSON_en_main = 1};
|
1955
2747
|
|
1956
2748
|
|
1957
|
-
#line
|
2749
|
+
#line 1257 "parser.rl"
|
1958
2750
|
|
1959
2751
|
|
1960
2752
|
/*
|
@@ -1971,17 +2763,206 @@ static VALUE cParser_parse(VALUE self)
|
|
1971
2763
|
VALUE result = Qnil;
|
1972
2764
|
GET_PARSER;
|
1973
2765
|
|
2766
|
+
char stack_buffer[FBUFFER_STACK_SIZE];
|
2767
|
+
fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
|
2768
|
+
|
2769
|
+
VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
|
2770
|
+
rvalue_stack stack = {
|
2771
|
+
.type = RVALUE_STACK_STACK_ALLOCATED,
|
2772
|
+
.ptr = rvalue_stack_buffer,
|
2773
|
+
.capa = RVALUE_STACK_INITIAL_CAPA,
|
2774
|
+
};
|
2775
|
+
json->stack = &stack;
|
2776
|
+
|
2777
|
+
|
2778
|
+
#line 2779 "parser.c"
|
2779
|
+
{
|
2780
|
+
cs = JSON_start;
|
2781
|
+
}
|
2782
|
+
|
2783
|
+
#line 1285 "parser.rl"
|
2784
|
+
p = json->source;
|
2785
|
+
pe = p + json->len;
|
2786
|
+
|
2787
|
+
#line 2788 "parser.c"
|
2788
|
+
{
|
2789
|
+
if ( p == pe )
|
2790
|
+
goto _test_eof;
|
2791
|
+
switch ( cs )
|
2792
|
+
{
|
2793
|
+
st1:
|
2794
|
+
if ( ++p == pe )
|
2795
|
+
goto _test_eof1;
|
2796
|
+
case 1:
|
2797
|
+
switch( (*p) ) {
|
2798
|
+
case 13: goto st1;
|
2799
|
+
case 32: goto st1;
|
2800
|
+
case 34: goto tr2;
|
2801
|
+
case 45: goto tr2;
|
2802
|
+
case 47: goto st6;
|
2803
|
+
case 73: goto tr2;
|
2804
|
+
case 78: goto tr2;
|
2805
|
+
case 91: goto tr2;
|
2806
|
+
case 102: goto tr2;
|
2807
|
+
case 110: goto tr2;
|
2808
|
+
case 116: goto tr2;
|
2809
|
+
case 123: goto tr2;
|
2810
|
+
}
|
2811
|
+
if ( (*p) > 10 ) {
|
2812
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
2813
|
+
goto tr2;
|
2814
|
+
} else if ( (*p) >= 9 )
|
2815
|
+
goto st1;
|
2816
|
+
goto st0;
|
2817
|
+
st0:
|
2818
|
+
cs = 0;
|
2819
|
+
goto _out;
|
2820
|
+
tr2:
|
2821
|
+
#line 1249 "parser.rl"
|
2822
|
+
{
|
2823
|
+
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
2824
|
+
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
2825
|
+
}
|
2826
|
+
goto st10;
|
2827
|
+
st10:
|
2828
|
+
if ( ++p == pe )
|
2829
|
+
goto _test_eof10;
|
2830
|
+
case 10:
|
2831
|
+
#line 2832 "parser.c"
|
2832
|
+
switch( (*p) ) {
|
2833
|
+
case 13: goto st10;
|
2834
|
+
case 32: goto st10;
|
2835
|
+
case 47: goto st2;
|
2836
|
+
}
|
2837
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
2838
|
+
goto st10;
|
2839
|
+
goto st0;
|
2840
|
+
st2:
|
2841
|
+
if ( ++p == pe )
|
2842
|
+
goto _test_eof2;
|
2843
|
+
case 2:
|
2844
|
+
switch( (*p) ) {
|
2845
|
+
case 42: goto st3;
|
2846
|
+
case 47: goto st5;
|
2847
|
+
}
|
2848
|
+
goto st0;
|
2849
|
+
st3:
|
2850
|
+
if ( ++p == pe )
|
2851
|
+
goto _test_eof3;
|
2852
|
+
case 3:
|
2853
|
+
if ( (*p) == 42 )
|
2854
|
+
goto st4;
|
2855
|
+
goto st3;
|
2856
|
+
st4:
|
2857
|
+
if ( ++p == pe )
|
2858
|
+
goto _test_eof4;
|
2859
|
+
case 4:
|
2860
|
+
switch( (*p) ) {
|
2861
|
+
case 42: goto st4;
|
2862
|
+
case 47: goto st10;
|
2863
|
+
}
|
2864
|
+
goto st3;
|
2865
|
+
st5:
|
2866
|
+
if ( ++p == pe )
|
2867
|
+
goto _test_eof5;
|
2868
|
+
case 5:
|
2869
|
+
if ( (*p) == 10 )
|
2870
|
+
goto st10;
|
2871
|
+
goto st5;
|
2872
|
+
st6:
|
2873
|
+
if ( ++p == pe )
|
2874
|
+
goto _test_eof6;
|
2875
|
+
case 6:
|
2876
|
+
switch( (*p) ) {
|
2877
|
+
case 42: goto st7;
|
2878
|
+
case 47: goto st9;
|
2879
|
+
}
|
2880
|
+
goto st0;
|
2881
|
+
st7:
|
2882
|
+
if ( ++p == pe )
|
2883
|
+
goto _test_eof7;
|
2884
|
+
case 7:
|
2885
|
+
if ( (*p) == 42 )
|
2886
|
+
goto st8;
|
2887
|
+
goto st7;
|
2888
|
+
st8:
|
2889
|
+
if ( ++p == pe )
|
2890
|
+
goto _test_eof8;
|
2891
|
+
case 8:
|
2892
|
+
switch( (*p) ) {
|
2893
|
+
case 42: goto st8;
|
2894
|
+
case 47: goto st1;
|
2895
|
+
}
|
2896
|
+
goto st7;
|
2897
|
+
st9:
|
2898
|
+
if ( ++p == pe )
|
2899
|
+
goto _test_eof9;
|
2900
|
+
case 9:
|
2901
|
+
if ( (*p) == 10 )
|
2902
|
+
goto st1;
|
2903
|
+
goto st9;
|
2904
|
+
}
|
2905
|
+
_test_eof1: cs = 1; goto _test_eof;
|
2906
|
+
_test_eof10: cs = 10; goto _test_eof;
|
2907
|
+
_test_eof2: cs = 2; goto _test_eof;
|
2908
|
+
_test_eof3: cs = 3; goto _test_eof;
|
2909
|
+
_test_eof4: cs = 4; goto _test_eof;
|
2910
|
+
_test_eof5: cs = 5; goto _test_eof;
|
2911
|
+
_test_eof6: cs = 6; goto _test_eof;
|
2912
|
+
_test_eof7: cs = 7; goto _test_eof;
|
2913
|
+
_test_eof8: cs = 8; goto _test_eof;
|
2914
|
+
_test_eof9: cs = 9; goto _test_eof;
|
2915
|
+
|
2916
|
+
_test_eof: {}
|
2917
|
+
_out: {}
|
2918
|
+
}
|
2919
|
+
|
2920
|
+
#line 1288 "parser.rl"
|
2921
|
+
|
2922
|
+
if (json->stack_handle) {
|
2923
|
+
rvalue_stack_eagerly_release(json->stack_handle);
|
2924
|
+
}
|
2925
|
+
|
2926
|
+
if (cs >= JSON_first_final && p == pe) {
|
2927
|
+
return result;
|
2928
|
+
} else {
|
2929
|
+
raise_parse_error("unexpected token at '%s'", p);
|
2930
|
+
return Qnil;
|
2931
|
+
}
|
2932
|
+
}
|
2933
|
+
|
2934
|
+
static VALUE cParser_m_parse(VALUE klass, VALUE source, VALUE opts)
|
2935
|
+
{
|
2936
|
+
char *p, *pe;
|
2937
|
+
int cs = EVIL;
|
2938
|
+
VALUE result = Qnil;
|
2939
|
+
|
2940
|
+
JSON_Parser _parser = {0};
|
2941
|
+
JSON_Parser *json = &_parser;
|
2942
|
+
parser_init(json, source, opts);
|
2943
|
+
|
2944
|
+
char stack_buffer[FBUFFER_STACK_SIZE];
|
2945
|
+
fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
|
2946
|
+
|
2947
|
+
VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
|
2948
|
+
rvalue_stack stack = {
|
2949
|
+
.type = RVALUE_STACK_STACK_ALLOCATED,
|
2950
|
+
.ptr = rvalue_stack_buffer,
|
2951
|
+
.capa = RVALUE_STACK_INITIAL_CAPA,
|
2952
|
+
};
|
2953
|
+
json->stack = &stack;
|
2954
|
+
|
1974
2955
|
|
1975
|
-
#line
|
2956
|
+
#line 2957 "parser.c"
|
1976
2957
|
{
|
1977
2958
|
cs = JSON_start;
|
1978
2959
|
}
|
1979
2960
|
|
1980
|
-
#line
|
2961
|
+
#line 1323 "parser.rl"
|
1981
2962
|
p = json->source;
|
1982
2963
|
pe = p + json->len;
|
1983
2964
|
|
1984
|
-
#line
|
2965
|
+
#line 2966 "parser.c"
|
1985
2966
|
{
|
1986
2967
|
if ( p == pe )
|
1987
2968
|
goto _test_eof;
|
@@ -2015,7 +2996,7 @@ st0:
|
|
2015
2996
|
cs = 0;
|
2016
2997
|
goto _out;
|
2017
2998
|
tr2:
|
2018
|
-
#line
|
2999
|
+
#line 1249 "parser.rl"
|
2019
3000
|
{
|
2020
3001
|
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
2021
3002
|
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
@@ -2025,7 +3006,7 @@ st10:
|
|
2025
3006
|
if ( ++p == pe )
|
2026
3007
|
goto _test_eof10;
|
2027
3008
|
case 10:
|
2028
|
-
#line
|
3009
|
+
#line 3010 "parser.c"
|
2029
3010
|
switch( (*p) ) {
|
2030
3011
|
case 13: goto st10;
|
2031
3012
|
case 32: goto st10;
|
@@ -2114,7 +3095,11 @@ case 9:
|
|
2114
3095
|
_out: {}
|
2115
3096
|
}
|
2116
3097
|
|
2117
|
-
#line
|
3098
|
+
#line 1326 "parser.rl"
|
3099
|
+
|
3100
|
+
if (json->stack_handle) {
|
3101
|
+
rvalue_stack_eagerly_release(json->stack_handle);
|
3102
|
+
}
|
2118
3103
|
|
2119
3104
|
if (cs >= JSON_first_final && p == pe) {
|
2120
3105
|
return result;
|
@@ -2133,19 +3118,25 @@ static void JSON_mark(void *ptr)
|
|
2133
3118
|
rb_gc_mark(json->array_class);
|
2134
3119
|
rb_gc_mark(json->decimal_class);
|
2135
3120
|
rb_gc_mark(json->match_string);
|
3121
|
+
rb_gc_mark(json->stack_handle);
|
3122
|
+
|
3123
|
+
long index;
|
3124
|
+
for (index = 0; index < json->name_cache.length; index++) {
|
3125
|
+
rb_gc_mark(json->name_cache.entries[index]);
|
3126
|
+
}
|
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
|
/*
|