json-maglev- 1.5.4 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +11 -1
- data/Rakefile +14 -12
- data/VERSION +1 -1
- data/ext/json/ext/generator/extconf.rb +0 -7
- data/ext/json/ext/generator/generator.c +55 -10
- data/ext/json/ext/generator/generator.h +7 -5
- data/ext/json/ext/parser/extconf.rb +0 -3
- data/ext/json/ext/parser/parser.c +418 -207
- data/ext/json/ext/parser/parser.h +11 -10
- data/ext/json/ext/parser/parser.rl +178 -104
- data/install.rb +1 -8
- data/java/src/json/ext/Generator.java +3 -3
- data/java/src/json/ext/GeneratorMethods.java +2 -2
- data/java/src/json/ext/GeneratorService.java +1 -1
- data/java/src/json/ext/GeneratorState.java +41 -13
- data/java/src/json/ext/OptionsReader.java +1 -1
- data/java/src/json/ext/Parser.java +382 -107
- data/java/src/json/ext/Parser.rl +97 -28
- data/java/src/json/ext/ParserService.java +1 -1
- data/java/src/json/ext/Utils.java +1 -1
- data/json.gemspec +5 -6
- data/json_pure.gemspec +5 -9
- data/lib/json.rb +4 -4
- data/lib/json/add/complex.rb +22 -0
- data/lib/json/add/core.rb +9 -241
- data/lib/json/add/date.rb +34 -0
- data/lib/json/add/date_time.rb +50 -0
- data/lib/json/add/exception.rb +31 -0
- data/lib/json/add/range.rb +29 -0
- data/lib/json/add/rational.rb +22 -0
- data/lib/json/add/regexp.rb +30 -0
- data/lib/json/add/struct.rb +30 -0
- data/lib/json/add/symbol.rb +25 -0
- data/lib/json/add/time.rb +35 -0
- data/lib/json/common.rb +47 -35
- data/lib/json/ext.rb +2 -15
- data/lib/json/pure/generator.rb +17 -2
- data/lib/json/pure/parser.rb +89 -55
- data/lib/json/version.rb +1 -1
- data/tests/test_json.rb +36 -0
- data/tests/test_json_addition.rb +8 -1
- data/tests/test_json_generate.rb +34 -1
- data/tools/server.rb +1 -0
- metadata +20 -24
- data/bin/edit_json.rb +0 -9
- data/bin/prettify_json.rb +0 -48
- data/lib/json/Array.xpm +0 -21
- data/lib/json/FalseClass.xpm +0 -21
- data/lib/json/Hash.xpm +0 -21
- data/lib/json/Key.xpm +0 -73
- data/lib/json/NilClass.xpm +0 -21
- data/lib/json/Numeric.xpm +0 -28
- data/lib/json/String.xpm +0 -96
- data/lib/json/TrueClass.xpm +0 -21
- data/lib/json/add/rails.rb +0 -8
- data/lib/json/editor.rb +0 -1369
- data/lib/json/json.xpm +0 -1499
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
#include "ruby.h"
|
5
5
|
|
6
|
-
#
|
6
|
+
#ifndef HAVE_RUBY_RE_H
|
7
7
|
#include "re.h"
|
8
8
|
#endif
|
9
9
|
|
@@ -36,15 +36,16 @@ typedef unsigned char UTF8; /* typically 8 bits */
|
|
36
36
|
typedef struct JSON_ParserStruct {
|
37
37
|
VALUE dwrapped_parser;
|
38
38
|
VALUE Vsource;
|
39
|
-
|
39
|
+
char *source;
|
40
40
|
long len;
|
41
|
-
|
41
|
+
char *memo;
|
42
42
|
VALUE create_id;
|
43
43
|
int max_nesting;
|
44
44
|
int current_nesting;
|
45
45
|
int allow_nan;
|
46
46
|
int parsing_name;
|
47
47
|
int symbolize_names;
|
48
|
+
int quirks_mode;
|
48
49
|
VALUE object_class;
|
49
50
|
VALUE array_class;
|
50
51
|
int create_additions;
|
@@ -63,13 +64,13 @@ typedef struct JSON_ParserStruct {
|
|
63
64
|
|
64
65
|
static UTF32 unescape_unicode(const unsigned char *p);
|
65
66
|
static int convert_UTF32_to_UTF8(char *buf, UTF32 ch);
|
66
|
-
static
|
67
|
-
static
|
68
|
-
static
|
69
|
-
static
|
70
|
-
static
|
71
|
-
static VALUE json_string_unescape(VALUE result,
|
72
|
-
static
|
67
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
68
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
69
|
+
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
70
|
+
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
71
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
72
|
+
static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd);
|
73
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
73
74
|
static VALUE convert_encoding(VALUE source);
|
74
75
|
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self);
|
75
76
|
static VALUE cParser_parse(VALUE self);
|
@@ -76,8 +76,9 @@ static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
|
76
76
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
77
77
|
|
78
78
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
79
|
-
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
80
|
-
i_array_class, i_key_p, i_deep_const_get, i_match,
|
79
|
+
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
|
80
|
+
i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
|
81
|
+
i_match_string, i_aset, i_leftshift;
|
81
82
|
|
82
83
|
%%{
|
83
84
|
machine JSON_common;
|
@@ -115,7 +116,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
|
115
116
|
|
116
117
|
action parse_value {
|
117
118
|
VALUE v = Qnil;
|
118
|
-
|
119
|
+
char *np = JSON_parse_value(json, fpc, pe, &v);
|
119
120
|
if (np == NULL) {
|
120
121
|
fhold; fbreak;
|
121
122
|
} else {
|
@@ -129,7 +130,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
|
129
130
|
}
|
130
131
|
|
131
132
|
action parse_name {
|
132
|
-
|
133
|
+
char *np;
|
133
134
|
json->parsing_name = 1;
|
134
135
|
np = JSON_parse_string(json, fpc, pe, &last_name);
|
135
136
|
json->parsing_name = 0;
|
@@ -138,16 +139,17 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
|
138
139
|
|
139
140
|
action exit { fhold; fbreak; }
|
140
141
|
|
141
|
-
|
142
|
-
|
143
|
-
begin_value >parse_value;
|
142
|
+
pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value;
|
143
|
+
next_pair = ignore* value_separator pair;
|
144
144
|
|
145
|
-
main :=
|
146
|
-
|
147
|
-
|
145
|
+
main := (
|
146
|
+
begin_object
|
147
|
+
(pair (next_pair)*)? ignore*
|
148
|
+
end_object
|
149
|
+
) @exit;
|
148
150
|
}%%
|
149
151
|
|
150
|
-
static
|
152
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
151
153
|
{
|
152
154
|
int cs = EVIL;
|
153
155
|
VALUE last_name = Qnil;
|
@@ -178,6 +180,7 @@ static const char *JSON_parse_object(JSON_Parser *json, const char *p, const cha
|
|
178
180
|
}
|
179
181
|
}
|
180
182
|
|
183
|
+
|
181
184
|
%%{
|
182
185
|
machine JSON_value;
|
183
186
|
include JSON_common;
|
@@ -208,13 +211,13 @@ static const char *JSON_parse_object(JSON_Parser *json, const char *p, const cha
|
|
208
211
|
}
|
209
212
|
}
|
210
213
|
action parse_string {
|
211
|
-
|
214
|
+
char *np = JSON_parse_string(json, fpc, pe, result);
|
212
215
|
if (np == NULL) { fhold; fbreak; } else fexec np;
|
213
216
|
}
|
214
217
|
|
215
218
|
action parse_number {
|
216
|
-
|
217
|
-
if(pe > fpc + 9 && !strncmp(MinusInfinity, fpc, 9)) {
|
219
|
+
char *np;
|
220
|
+
if(pe > fpc + 9 - json->quirks_mode && !strncmp(MinusInfinity, fpc, 9)) {
|
218
221
|
if (json->allow_nan) {
|
219
222
|
*result = CMinusInfinity;
|
220
223
|
fexec p + 10;
|
@@ -231,7 +234,7 @@ static const char *JSON_parse_object(JSON_Parser *json, const char *p, const cha
|
|
231
234
|
}
|
232
235
|
|
233
236
|
action parse_array {
|
234
|
-
|
237
|
+
char *np;
|
235
238
|
json->current_nesting++;
|
236
239
|
np = JSON_parse_array(json, fpc, pe, result);
|
237
240
|
json->current_nesting--;
|
@@ -239,7 +242,7 @@ static const char *JSON_parse_object(JSON_Parser *json, const char *p, const cha
|
|
239
242
|
}
|
240
243
|
|
241
244
|
action parse_object {
|
242
|
-
|
245
|
+
char *np;
|
243
246
|
json->current_nesting++;
|
244
247
|
np = JSON_parse_object(json, fpc, pe, result);
|
245
248
|
json->current_nesting--;
|
@@ -261,7 +264,7 @@ main := (
|
|
261
264
|
) %*exit;
|
262
265
|
}%%
|
263
266
|
|
264
|
-
static
|
267
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
265
268
|
{
|
266
269
|
int cs = EVIL;
|
267
270
|
|
@@ -282,10 +285,10 @@ static const char *JSON_parse_value(JSON_Parser *json, const char *p, const char
|
|
282
285
|
|
283
286
|
action exit { fhold; fbreak; }
|
284
287
|
|
285
|
-
main := '-'? ('0' | [1-9][0-9]*) (^[0-9] @exit);
|
288
|
+
main := '-'? ('0' | [1-9][0-9]*) (^[0-9]? @exit);
|
286
289
|
}%%
|
287
290
|
|
288
|
-
static
|
291
|
+
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
289
292
|
{
|
290
293
|
int cs = EVIL;
|
291
294
|
|
@@ -313,10 +316,10 @@ static const char *JSON_parse_integer(JSON_Parser *json, const char *p, const ch
|
|
313
316
|
main := '-'? (
|
314
317
|
(('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
|
315
318
|
| (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
|
316
|
-
) (^[0-9Ee.\-] @exit );
|
319
|
+
) (^[0-9Ee.\-]? @exit );
|
317
320
|
}%%
|
318
321
|
|
319
|
-
static
|
322
|
+
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
320
323
|
{
|
321
324
|
int cs = EVIL;
|
322
325
|
|
@@ -342,7 +345,7 @@ static const char *JSON_parse_float(JSON_Parser *json, const char *p, const char
|
|
342
345
|
|
343
346
|
action parse_value {
|
344
347
|
VALUE v = Qnil;
|
345
|
-
|
348
|
+
char *np = JSON_parse_value(json, fpc, pe, &v);
|
346
349
|
if (np == NULL) {
|
347
350
|
fhold; fbreak;
|
348
351
|
} else {
|
@@ -365,7 +368,7 @@ static const char *JSON_parse_float(JSON_Parser *json, const char *p, const char
|
|
365
368
|
end_array @exit;
|
366
369
|
}%%
|
367
370
|
|
368
|
-
static
|
371
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
369
372
|
{
|
370
373
|
int cs = EVIL;
|
371
374
|
VALUE array_class = json->array_class;
|
@@ -386,9 +389,9 @@ static const char *JSON_parse_array(JSON_Parser *json, const char *p, const char
|
|
386
389
|
}
|
387
390
|
}
|
388
391
|
|
389
|
-
static VALUE json_string_unescape(VALUE result,
|
392
|
+
static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
390
393
|
{
|
391
|
-
|
394
|
+
char *p = string, *pe = string, *unescape;
|
392
395
|
int unescape_len;
|
393
396
|
|
394
397
|
while (pe < stringEnd) {
|
@@ -490,17 +493,17 @@ match_i(VALUE regexp, VALUE klass, VALUE memo)
|
|
490
493
|
return ST_CONTINUE;
|
491
494
|
}
|
492
495
|
|
493
|
-
static
|
496
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
494
497
|
{
|
495
498
|
int cs = EVIL;
|
499
|
+
VALUE match_string;
|
500
|
+
|
496
501
|
*result = rb_str_buf_new(0);
|
497
502
|
%% write init;
|
498
503
|
json->memo = p;
|
499
504
|
%% write exec;
|
500
505
|
|
501
|
-
if (json->create_additions) {
|
502
|
-
VALUE match_string = json->match_string;
|
503
|
-
if (RTEST(match_string)) {
|
506
|
+
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
504
507
|
VALUE klass;
|
505
508
|
VALUE memo = rb_ary_new2(2);
|
506
509
|
rb_ary_push(memo, *result);
|
@@ -509,7 +512,6 @@ static const char *JSON_parse_string(JSON_Parser *json, const char *p, const cha
|
|
509
512
|
if (RTEST(klass)) {
|
510
513
|
*result = rb_funcall(klass, i_json_create, 1, *result);
|
511
514
|
}
|
512
|
-
}
|
513
515
|
}
|
514
516
|
|
515
517
|
if (json->symbolize_names && json->parsing_name) {
|
@@ -522,34 +524,6 @@ static const char *JSON_parse_string(JSON_Parser *json, const char *p, const cha
|
|
522
524
|
}
|
523
525
|
}
|
524
526
|
|
525
|
-
|
526
|
-
%%{
|
527
|
-
machine JSON;
|
528
|
-
|
529
|
-
write data;
|
530
|
-
|
531
|
-
include JSON_common;
|
532
|
-
|
533
|
-
action parse_object {
|
534
|
-
const char *np;
|
535
|
-
json->current_nesting = 1;
|
536
|
-
np = JSON_parse_object(json, fpc, pe, &result);
|
537
|
-
if (np == NULL) { fhold; fbreak; } else fexec np;
|
538
|
-
}
|
539
|
-
|
540
|
-
action parse_array {
|
541
|
-
const char *np;
|
542
|
-
json->current_nesting = 1;
|
543
|
-
np = JSON_parse_array(json, fpc, pe, &result);
|
544
|
-
if (np == NULL) { fhold; fbreak; } else fexec np;
|
545
|
-
}
|
546
|
-
|
547
|
-
main := ignore* (
|
548
|
-
begin_object >parse_object |
|
549
|
-
begin_array >parse_array
|
550
|
-
) ignore*;
|
551
|
-
}%%
|
552
|
-
|
553
527
|
/*
|
554
528
|
* Document-class: JSON::Ext::Parser
|
555
529
|
*
|
@@ -564,7 +538,7 @@ static const char *JSON_parse_string(JSON_Parser *json, const char *p, const cha
|
|
564
538
|
|
565
539
|
static VALUE convert_encoding(VALUE source)
|
566
540
|
{
|
567
|
-
|
541
|
+
char *ptr = RSTRING_PTR(source);
|
568
542
|
long len = RSTRING_LEN(source);
|
569
543
|
if (len < 2) {
|
570
544
|
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
@@ -603,12 +577,15 @@ static VALUE convert_encoding(VALUE source)
|
|
603
577
|
return source;
|
604
578
|
}
|
605
579
|
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
580
|
+
#if defined MAGLEV
|
581
|
+
// Maglev doesn't support the mark function, keep a reference in the object
|
582
|
+
#define QUOTE(x) #x
|
583
|
+
#define PARSER_SET_REFERENCE(json, field, val) \
|
584
|
+
(json)->field = (val); \
|
585
|
+
rb_iv_set(json->dwrapped_parser, QUOTE(@field), (json)->field);
|
586
|
+
#else
|
587
|
+
#define PARSER_SET_REFERENCE(json, field, val) (json)->field = (val);
|
588
|
+
#endif
|
612
589
|
|
613
590
|
/*
|
614
591
|
* call-seq: new(source, opts => {})
|
@@ -636,26 +613,15 @@ static inline void parser_iv_set(JSON_Parser *json, const char* iv_name, VALUE v
|
|
636
613
|
* * *object_class*: Defaults to Hash
|
637
614
|
* * *array_class*: Defaults to Array
|
638
615
|
*/
|
639
|
-
|
640
|
-
static int init_count = 0;
|
641
616
|
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
642
617
|
{
|
643
|
-
const char *ptr;
|
644
|
-
long len;
|
645
618
|
VALUE source, opts;
|
646
|
-
|
647
619
|
GET_PARSER_INIT;
|
648
|
-
init_count += 1;
|
649
620
|
|
650
|
-
|
651
|
-
if (json->Vsource) {
|
621
|
+
if (RTEST(json->Vsource)) {
|
652
622
|
rb_raise(rb_eTypeError, "already initialized instance");
|
653
623
|
}
|
654
|
-
#endif
|
655
624
|
rb_scan_args(argc, argv, "11", &source, &opts);
|
656
|
-
source = convert_encoding(StringValue(source));
|
657
|
-
ptr = RSTRING_PTR(source);
|
658
|
-
len = RSTRING_LEN(source);
|
659
625
|
if (!NIL_P(opts)) {
|
660
626
|
opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
|
661
627
|
if (NIL_P(opts)) {
|
@@ -685,6 +651,13 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
685
651
|
} else {
|
686
652
|
json->symbolize_names = 0;
|
687
653
|
}
|
654
|
+
tmp = ID2SYM(i_quirks_mode);
|
655
|
+
if (option_given_p(opts, tmp)) {
|
656
|
+
VALUE quirks_mode = rb_hash_aref(opts, tmp);
|
657
|
+
json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
|
658
|
+
} else {
|
659
|
+
json->quirks_mode = 0;
|
660
|
+
}
|
688
661
|
tmp = ID2SYM(i_create_additions);
|
689
662
|
if (option_given_p(opts, tmp)) {
|
690
663
|
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
@@ -693,52 +666,78 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
693
666
|
}
|
694
667
|
tmp = ID2SYM(i_create_id);
|
695
668
|
if (option_given_p(opts, tmp)) {
|
696
|
-
json
|
669
|
+
PARSER_SET_REFERENCE(json, create_id, rb_hash_aref(opts, tmp));
|
697
670
|
} else {
|
698
|
-
json
|
671
|
+
PARSER_SET_REFERENCE(json, create_id, rb_funcall(mJSON, i_create_id, 0));
|
699
672
|
}
|
700
|
-
parser_iv_set(json, "@create_id", json->create_id);
|
701
673
|
tmp = ID2SYM(i_object_class);
|
702
674
|
if (option_given_p(opts, tmp)) {
|
703
|
-
json
|
704
|
-
|
675
|
+
PARSER_SET_REFERENCE(json, object_class, rb_hash_aref(opts, tmp));
|
676
|
+
} else {
|
677
|
+
PARSER_SET_REFERENCE(json, object_class, Qnil);
|
705
678
|
}
|
706
679
|
tmp = ID2SYM(i_array_class);
|
707
680
|
if (option_given_p(opts, tmp)) {
|
708
|
-
json
|
709
|
-
|
681
|
+
PARSER_SET_REFERENCE(json, array_class, rb_hash_aref(opts, tmp));
|
682
|
+
} else {
|
683
|
+
PARSER_SET_REFERENCE(json, array_class, Qnil);
|
710
684
|
}
|
711
685
|
tmp = ID2SYM(i_match_string);
|
712
686
|
if (option_given_p(opts, tmp)) {
|
713
687
|
VALUE match_string = rb_hash_aref(opts, tmp);
|
714
|
-
json
|
715
|
-
|
688
|
+
PARSER_SET_REFERENCE(json, match_string, RTEST(match_string) ? match_string : Qnil);
|
689
|
+
} else {
|
690
|
+
PARSER_SET_REFERENCE(json, match_string, Qnil);
|
716
691
|
}
|
717
692
|
}
|
718
693
|
} else {
|
719
694
|
json->max_nesting = 19;
|
720
695
|
json->allow_nan = 0;
|
721
696
|
json->create_additions = 1;
|
722
|
-
json
|
723
|
-
|
697
|
+
PARSER_SET_REFERENCE(json, create_id, rb_funcall(mJSON, i_create_id, 0));
|
698
|
+
json->object_class = Qnil;
|
699
|
+
json->array_class = Qnil;
|
700
|
+
}
|
701
|
+
if (!json->quirks_mode) {
|
702
|
+
source = convert_encoding(StringValue(source));
|
724
703
|
}
|
725
704
|
json->current_nesting = 0;
|
726
|
-
json->len =
|
727
|
-
json->source =
|
728
|
-
json
|
729
|
-
parser_iv_set(json, "@vsource", json->Vsource);
|
705
|
+
json->len = RSTRING_LEN(source);
|
706
|
+
json->source = RSTRING_PTR(source);;
|
707
|
+
PARSER_SET_REFERENCE(json, Vsource, source);
|
730
708
|
return self;
|
731
709
|
}
|
732
710
|
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
711
|
+
%%{
|
712
|
+
machine JSON;
|
713
|
+
|
714
|
+
write data;
|
715
|
+
|
716
|
+
include JSON_common;
|
717
|
+
|
718
|
+
action parse_object {
|
719
|
+
char *np;
|
720
|
+
json->current_nesting = 1;
|
721
|
+
np = JSON_parse_object(json, fpc, pe, &result);
|
722
|
+
if (np == NULL) { fhold; fbreak; } else fexec np;
|
723
|
+
}
|
724
|
+
|
725
|
+
action parse_array {
|
726
|
+
char *np;
|
727
|
+
json->current_nesting = 1;
|
728
|
+
np = JSON_parse_array(json, fpc, pe, &result);
|
729
|
+
if (np == NULL) { fhold; fbreak; } else fexec np;
|
730
|
+
}
|
731
|
+
|
732
|
+
main := ignore* (
|
733
|
+
begin_object >parse_object |
|
734
|
+
begin_array >parse_array
|
735
|
+
) ignore*;
|
736
|
+
}%%
|
737
|
+
|
738
|
+
static VALUE cParser_parse_strict(VALUE self)
|
740
739
|
{
|
741
|
-
|
740
|
+
char *p, *pe;
|
742
741
|
int cs = EVIL;
|
743
742
|
VALUE result = Qnil;
|
744
743
|
GET_PARSER;
|
@@ -756,6 +755,62 @@ static VALUE cParser_parse(VALUE self)
|
|
756
755
|
}
|
757
756
|
}
|
758
757
|
|
758
|
+
|
759
|
+
%%{
|
760
|
+
machine JSON_quirks_mode;
|
761
|
+
|
762
|
+
write data;
|
763
|
+
|
764
|
+
include JSON_common;
|
765
|
+
|
766
|
+
action parse_value {
|
767
|
+
char *np = JSON_parse_value(json, fpc, pe, &result);
|
768
|
+
if (np == NULL) { fhold; fbreak; } else fexec np;
|
769
|
+
}
|
770
|
+
|
771
|
+
main := ignore* (
|
772
|
+
begin_value >parse_value
|
773
|
+
) ignore*;
|
774
|
+
}%%
|
775
|
+
|
776
|
+
static VALUE cParser_parse_quirks_mode(VALUE self)
|
777
|
+
{
|
778
|
+
char *p, *pe;
|
779
|
+
int cs = EVIL;
|
780
|
+
VALUE result = Qnil;
|
781
|
+
GET_PARSER;
|
782
|
+
|
783
|
+
%% write init;
|
784
|
+
p = json->source;
|
785
|
+
pe = p + json->len;
|
786
|
+
%% write exec;
|
787
|
+
|
788
|
+
if (cs >= JSON_quirks_mode_first_final && p == pe) {
|
789
|
+
return result;
|
790
|
+
} else {
|
791
|
+
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
792
|
+
return Qnil;
|
793
|
+
}
|
794
|
+
}
|
795
|
+
|
796
|
+
/*
|
797
|
+
* call-seq: parse()
|
798
|
+
*
|
799
|
+
* Parses the current JSON text _source_ and returns the complete data
|
800
|
+
* structure as a result.
|
801
|
+
*/
|
802
|
+
static VALUE cParser_parse(VALUE self)
|
803
|
+
{
|
804
|
+
GET_PARSER;
|
805
|
+
|
806
|
+
if (json->quirks_mode) {
|
807
|
+
return cParser_parse_quirks_mode(self);
|
808
|
+
} else {
|
809
|
+
return cParser_parse_strict(self);
|
810
|
+
}
|
811
|
+
}
|
812
|
+
|
813
|
+
|
759
814
|
static JSON_Parser *JSON_allocate()
|
760
815
|
{
|
761
816
|
JSON_Parser *json = ALLOC(JSON_Parser);
|
@@ -770,7 +825,14 @@ static JSON_Parser *JSON_allocate()
|
|
770
825
|
return json;
|
771
826
|
}
|
772
827
|
|
773
|
-
|
828
|
+
static void JSON_mark(JSON_Parser *json)
|
829
|
+
{
|
830
|
+
rb_gc_mark_maybe(json->Vsource);
|
831
|
+
rb_gc_mark_maybe(json->create_id);
|
832
|
+
rb_gc_mark_maybe(json->object_class);
|
833
|
+
rb_gc_mark_maybe(json->array_class);
|
834
|
+
rb_gc_mark_maybe(json->match_string);
|
835
|
+
}
|
774
836
|
|
775
837
|
static void JSON_free(JSON_Parser *json)
|
776
838
|
{
|
@@ -780,9 +842,7 @@ static void JSON_free(JSON_Parser *json)
|
|
780
842
|
static VALUE cJSON_parser_s_allocate(VALUE klass)
|
781
843
|
{
|
782
844
|
JSON_Parser *json = JSON_allocate();
|
783
|
-
|
784
|
-
json->dwrapped_parser = data_obj;
|
785
|
-
return data_obj;
|
845
|
+
return json->dwrapped_parser = Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
|
786
846
|
}
|
787
847
|
|
788
848
|
/*
|
@@ -797,6 +857,18 @@ static VALUE cParser_source(VALUE self)
|
|
797
857
|
return rb_str_dup(json->Vsource);
|
798
858
|
}
|
799
859
|
|
860
|
+
/*
|
861
|
+
* call-seq: quirks_mode?()
|
862
|
+
*
|
863
|
+
* Returns a true, if this parser is in quirks_mode, false otherwise.
|
864
|
+
*/
|
865
|
+
static VALUE cParser_quirks_mode_p(VALUE self)
|
866
|
+
{
|
867
|
+
GET_PARSER;
|
868
|
+
return json->quirks_mode ? Qtrue : Qfalse;
|
869
|
+
}
|
870
|
+
|
871
|
+
|
800
872
|
void Init_parser()
|
801
873
|
{
|
802
874
|
rb_require("json/common");
|
@@ -809,6 +881,7 @@ void Init_parser()
|
|
809
881
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
810
882
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
811
883
|
rb_define_method(cParser, "source", cParser_source, 0);
|
884
|
+
rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
|
812
885
|
|
813
886
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
814
887
|
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
|
@@ -822,6 +895,7 @@ void Init_parser()
|
|
822
895
|
i_max_nesting = rb_intern("max_nesting");
|
823
896
|
i_allow_nan = rb_intern("allow_nan");
|
824
897
|
i_symbolize_names = rb_intern("symbolize_names");
|
898
|
+
i_quirks_mode = rb_intern("quirks_mode");
|
825
899
|
i_object_class = rb_intern("object_class");
|
826
900
|
i_array_class = rb_intern("array_class");
|
827
901
|
i_match = rb_intern("match");
|