json-maglev- 1.5.4 → 1.6.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.
- 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");
|