json 2.7.2 → 2.7.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/BSDL +22 -0
- data/CHANGES.md +44 -17
- data/LEGAL +60 -0
- data/README.md +13 -165
- data/ext/json/ext/fbuffer/fbuffer.h +21 -62
- data/ext/json/ext/generator/extconf.rb +8 -2
- data/ext/json/ext/generator/generator.c +462 -653
- data/ext/json/ext/generator/generator.h +16 -64
- data/ext/json/ext/parser/extconf.rb +3 -1
- data/ext/json/ext/parser/parser.c +279 -253
- data/ext/json/ext/parser/parser.h +4 -40
- data/ext/json/ext/parser/parser.rl +208 -182
- data/json.gemspec +42 -49
- data/lib/json/add/bigdecimal.rb +1 -1
- data/lib/json/add/complex.rb +1 -1
- data/lib/json/add/core.rb +1 -1
- data/lib/json/add/date.rb +1 -1
- data/lib/json/add/date_time.rb +1 -1
- data/lib/json/add/exception.rb +1 -1
- data/lib/json/add/ostruct.rb +1 -1
- data/lib/json/add/range.rb +1 -1
- data/lib/json/add/rational.rb +1 -1
- data/lib/json/add/regexp.rb +1 -1
- data/lib/json/add/struct.rb +1 -1
- data/lib/json/add/symbol.rb +1 -2
- data/lib/json/add/time.rb +3 -10
- data/lib/json/common.rb +74 -43
- data/lib/json/ext/generator/state.rb +135 -0
- data/lib/json/ext.rb +15 -5
- data/lib/json/generic_object.rb +1 -1
- data/lib/json/pure/generator.rb +89 -22
- data/lib/json/pure/parser.rb +27 -33
- data/lib/json/pure.rb +1 -0
- data/lib/json/version.rb +3 -7
- data/lib/json.rb +1 -1
- metadata +17 -15
- data/ext/json/ext/generator/depend +0 -1
- data/ext/json/ext/parser/depend +0 -1
- data/ext/json/extconf.rb +0 -3
- /data/{LICENSE → COPYING} +0 -0
@@ -3,33 +3,11 @@
|
|
3
3
|
|
4
4
|
#include "ruby.h"
|
5
5
|
|
6
|
-
#ifndef HAVE_RUBY_RE_H
|
7
|
-
#include "re.h"
|
8
|
-
#endif
|
9
|
-
|
10
|
-
#ifdef HAVE_RUBY_ST_H
|
11
|
-
#include "ruby/st.h"
|
12
|
-
#else
|
13
|
-
#include "st.h"
|
14
|
-
#endif
|
15
|
-
|
16
6
|
#ifndef MAYBE_UNUSED
|
17
7
|
# define MAYBE_UNUSED(x) x
|
18
8
|
#endif
|
19
9
|
|
20
|
-
#define option_given_p(opts, key)
|
21
|
-
|
22
|
-
/* unicode */
|
23
|
-
|
24
|
-
typedef unsigned long UTF32; /* at least 32 bits */
|
25
|
-
typedef unsigned short UTF16; /* at least 16 bits */
|
26
|
-
typedef unsigned char UTF8; /* typically 8 bits */
|
27
|
-
|
28
|
-
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
|
29
|
-
#define UNI_SUR_HIGH_START (UTF32)0xD800
|
30
|
-
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
|
31
|
-
#define UNI_SUR_LOW_START (UTF32)0xDC00
|
32
|
-
#define UNI_SUR_LOW_END (UTF32)0xDFFF
|
10
|
+
#define option_given_p(opts, key) (rb_hash_lookup2(opts, key, Qundef) != Qundef)
|
33
11
|
|
34
12
|
typedef struct JSON_ParserStruct {
|
35
13
|
VALUE Vsource;
|
@@ -60,8 +38,8 @@ typedef struct JSON_ParserStruct {
|
|
60
38
|
#define MinusInfinity "-Infinity"
|
61
39
|
#define EVIL 0x666
|
62
40
|
|
63
|
-
static
|
64
|
-
static int convert_UTF32_to_UTF8(char *buf,
|
41
|
+
static uint32_t unescape_unicode(const unsigned char *p);
|
42
|
+
static int convert_UTF32_to_UTF8(char *buf, uint32_t ch);
|
65
43
|
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
66
44
|
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
67
45
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
@@ -76,21 +54,7 @@ static void JSON_mark(void *json);
|
|
76
54
|
static void JSON_free(void *json);
|
77
55
|
static VALUE cJSON_parser_s_allocate(VALUE klass);
|
78
56
|
static VALUE cParser_source(VALUE self);
|
79
|
-
|
80
|
-
#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
|
81
|
-
static inline void *ruby_zalloc(size_t n)
|
82
|
-
{
|
83
|
-
void *p = ruby_xmalloc(n);
|
84
|
-
memset(p, 0, n);
|
85
|
-
return p;
|
86
|
-
}
|
87
|
-
#endif
|
88
|
-
#ifdef TypedData_Make_Struct
|
57
|
+
|
89
58
|
static const rb_data_type_t JSON_Parser_type;
|
90
|
-
#define NEW_TYPEDDATA_WRAPPER 1
|
91
|
-
#else
|
92
|
-
#define TypedData_Make_Struct(klass, type, ignore, json) Data_Make_Struct(klass, type, NULL, JSON_free, json)
|
93
|
-
#define TypedData_Get_Struct(self, JSON_Parser, ignore, json) Data_Get_Struct(self, JSON_Parser, json)
|
94
|
-
#endif
|
95
59
|
|
96
60
|
#endif
|
@@ -1,28 +1,6 @@
|
|
1
1
|
#include "../fbuffer/fbuffer.h"
|
2
2
|
#include "parser.h"
|
3
3
|
|
4
|
-
#if defined HAVE_RUBY_ENCODING_H
|
5
|
-
# define EXC_ENCODING rb_utf8_encoding(),
|
6
|
-
# ifndef HAVE_RB_ENC_RAISE
|
7
|
-
static void
|
8
|
-
enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
|
9
|
-
{
|
10
|
-
va_list args;
|
11
|
-
VALUE mesg;
|
12
|
-
|
13
|
-
va_start(args, fmt);
|
14
|
-
mesg = rb_enc_vsprintf(enc, fmt, args);
|
15
|
-
va_end(args);
|
16
|
-
|
17
|
-
rb_exc_raise(rb_exc_new3(exc, mesg));
|
18
|
-
}
|
19
|
-
# define rb_enc_raise enc_raise
|
20
|
-
# endif
|
21
|
-
#else
|
22
|
-
# define EXC_ENCODING /* nothing */
|
23
|
-
# define rb_enc_raise rb_raise
|
24
|
-
#endif
|
25
|
-
|
26
4
|
/* unicode */
|
27
5
|
|
28
6
|
static const signed char digit_values[256] = {
|
@@ -42,26 +20,28 @@ static const signed char digit_values[256] = {
|
|
42
20
|
-1, -1, -1, -1, -1, -1, -1
|
43
21
|
};
|
44
22
|
|
45
|
-
static
|
23
|
+
static uint32_t unescape_unicode(const unsigned char *p)
|
46
24
|
{
|
25
|
+
const uint32_t replacement_char = 0xFFFD;
|
26
|
+
|
47
27
|
signed char b;
|
48
|
-
|
28
|
+
uint32_t result = 0;
|
49
29
|
b = digit_values[p[0]];
|
50
|
-
if (b < 0) return
|
30
|
+
if (b < 0) return replacement_char;
|
51
31
|
result = (result << 4) | (unsigned char)b;
|
52
32
|
b = digit_values[p[1]];
|
53
|
-
if (b < 0) return
|
33
|
+
if (b < 0) return replacement_char;
|
54
34
|
result = (result << 4) | (unsigned char)b;
|
55
35
|
b = digit_values[p[2]];
|
56
|
-
if (b < 0) return
|
36
|
+
if (b < 0) return replacement_char;
|
57
37
|
result = (result << 4) | (unsigned char)b;
|
58
38
|
b = digit_values[p[3]];
|
59
|
-
if (b < 0) return
|
39
|
+
if (b < 0) return replacement_char;
|
60
40
|
result = (result << 4) | (unsigned char)b;
|
61
41
|
return result;
|
62
42
|
}
|
63
43
|
|
64
|
-
static int convert_UTF32_to_UTF8(char *buf,
|
44
|
+
static int convert_UTF32_to_UTF8(char *buf, uint32_t ch)
|
65
45
|
{
|
66
46
|
int len = 1;
|
67
47
|
if (ch <= 0x7F) {
|
@@ -87,15 +67,39 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
87
67
|
return len;
|
88
68
|
}
|
89
69
|
|
90
|
-
|
70
|
+
#define PARSE_ERROR_FRAGMENT_LEN 32
|
71
|
+
#ifdef RBIMPL_ATTR_NORETURN
|
72
|
+
RBIMPL_ATTR_NORETURN()
|
73
|
+
#endif
|
74
|
+
static void raise_parse_error(const char *format, const char *start)
|
75
|
+
{
|
76
|
+
char buffer[PARSE_ERROR_FRAGMENT_LEN + 1];
|
77
|
+
|
78
|
+
size_t len = strnlen(start, PARSE_ERROR_FRAGMENT_LEN);
|
79
|
+
const char *ptr = start;
|
80
|
+
|
81
|
+
if (len == PARSE_ERROR_FRAGMENT_LEN) {
|
82
|
+
MEMCPY(buffer, start, char, PARSE_ERROR_FRAGMENT_LEN);
|
83
|
+
buffer[PARSE_ERROR_FRAGMENT_LEN] = '\0';
|
84
|
+
ptr = buffer;
|
85
|
+
}
|
86
|
+
|
87
|
+
rb_enc_raise(rb_utf8_encoding(), rb_path2class("JSON::ParserError"), format, ptr);
|
88
|
+
}
|
89
|
+
|
90
|
+
static VALUE mJSON, mExt, cParser, eNestingError;
|
91
91
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
92
92
|
|
93
93
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
94
94
|
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
95
|
-
i_object_class, i_array_class, i_decimal_class,
|
95
|
+
i_object_class, i_array_class, i_decimal_class,
|
96
96
|
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
|
97
97
|
i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
|
98
98
|
|
99
|
+
static int binary_encindex;
|
100
|
+
static int utf8_encindex;
|
101
|
+
|
102
|
+
|
99
103
|
%%{
|
100
104
|
machine JSON_common;
|
101
105
|
|
@@ -222,14 +226,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
222
226
|
if (json->allow_nan) {
|
223
227
|
*result = CNaN;
|
224
228
|
} else {
|
225
|
-
|
229
|
+
raise_parse_error("unexpected token at '%s'", p - 2);
|
226
230
|
}
|
227
231
|
}
|
228
232
|
action parse_infinity {
|
229
233
|
if (json->allow_nan) {
|
230
234
|
*result = CInfinity;
|
231
235
|
} else {
|
232
|
-
|
236
|
+
raise_parse_error("unexpected token at '%s'", p - 7);
|
233
237
|
}
|
234
238
|
}
|
235
239
|
action parse_string {
|
@@ -245,7 +249,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
245
249
|
fexec p + 10;
|
246
250
|
fhold; fbreak;
|
247
251
|
} else {
|
248
|
-
|
252
|
+
raise_parse_error("unexpected token at '%s'", p);
|
249
253
|
}
|
250
254
|
}
|
251
255
|
np = JSON_parse_float(json, fpc, pe, result);
|
@@ -355,29 +359,31 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
355
359
|
if (cs >= JSON_float_first_final) {
|
356
360
|
VALUE mod = Qnil;
|
357
361
|
ID method_id = 0;
|
358
|
-
if (
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
362
|
+
if (!NIL_P(json->decimal_class)) {
|
363
|
+
if (rb_respond_to(json->decimal_class, i_try_convert)) {
|
364
|
+
mod = json->decimal_class;
|
365
|
+
method_id = i_try_convert;
|
366
|
+
} else if (rb_respond_to(json->decimal_class, i_new)) {
|
367
|
+
mod = json->decimal_class;
|
368
|
+
method_id = i_new;
|
369
|
+
} else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
|
370
|
+
VALUE name = rb_class_name(json->decimal_class);
|
371
|
+
const char *name_cstr = RSTRING_PTR(name);
|
372
|
+
const char *last_colon = strrchr(name_cstr, ':');
|
373
|
+
if (last_colon) {
|
374
|
+
const char *mod_path_end = last_colon - 1;
|
375
|
+
VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
|
376
|
+
mod = rb_path_to_class(mod_path);
|
377
|
+
|
378
|
+
const char *method_name_beg = last_colon + 1;
|
379
|
+
long before_len = method_name_beg - name_cstr;
|
380
|
+
long len = RSTRING_LEN(name) - before_len;
|
381
|
+
VALUE method_name = rb_str_substr(name, before_len, len);
|
382
|
+
method_id = SYM2ID(rb_str_intern(method_name));
|
383
|
+
} else {
|
384
|
+
mod = rb_mKernel;
|
385
|
+
method_id = SYM2ID(rb_str_intern(name));
|
386
|
+
}
|
381
387
|
}
|
382
388
|
}
|
383
389
|
|
@@ -447,7 +453,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
447
453
|
if(cs >= JSON_array_first_final) {
|
448
454
|
return p + 1;
|
449
455
|
} else {
|
450
|
-
|
456
|
+
raise_parse_error("unexpected token at '%s'", p);
|
451
457
|
return NULL;
|
452
458
|
}
|
453
459
|
}
|
@@ -510,26 +516,30 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
510
516
|
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
511
517
|
ruby_xfree(bufferStart);
|
512
518
|
}
|
513
|
-
|
514
|
-
EXC_ENCODING eParserError,
|
515
|
-
"incomplete unicode character escape sequence at '%s'", p
|
516
|
-
);
|
519
|
+
raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
|
517
520
|
} else {
|
518
|
-
|
521
|
+
uint32_t ch = unescape_unicode((unsigned char *) ++pe);
|
519
522
|
pe += 3;
|
520
|
-
|
523
|
+
/* To handle values above U+FFFF, we take a sequence of
|
524
|
+
* \uXXXX escapes in the U+D800..U+DBFF then
|
525
|
+
* U+DC00..U+DFFF ranges, take the low 10 bits from each
|
526
|
+
* to make a 20-bit number, then add 0x10000 to get the
|
527
|
+
* final codepoint.
|
528
|
+
*
|
529
|
+
* See Unicode 15: 3.8 "Surrogates", 5.3 "Handling
|
530
|
+
* Surrogate Pairs in UTF-16", and 23.6 "Surrogates
|
531
|
+
* Area".
|
532
|
+
*/
|
533
|
+
if ((ch & 0xFC00) == 0xD800) {
|
521
534
|
pe++;
|
522
535
|
if (pe > stringEnd - 6) {
|
523
536
|
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
524
537
|
ruby_xfree(bufferStart);
|
525
538
|
}
|
526
|
-
|
527
|
-
EXC_ENCODING eParserError,
|
528
|
-
"incomplete surrogate pair at '%s'", p
|
529
|
-
);
|
539
|
+
raise_parse_error("incomplete surrogate pair at '%s'", p);
|
530
540
|
}
|
531
541
|
if (pe[0] == '\\' && pe[1] == 'u') {
|
532
|
-
|
542
|
+
uint32_t sur = unescape_unicode((unsigned char *) pe + 2);
|
533
543
|
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
|
534
544
|
| (sur & 0x3FF));
|
535
545
|
pe += 5;
|
@@ -672,18 +682,20 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
672
682
|
|
673
683
|
static VALUE convert_encoding(VALUE source)
|
674
684
|
{
|
675
|
-
|
676
|
-
|
677
|
-
if (
|
678
|
-
if (OBJ_FROZEN(source)) {
|
679
|
-
source = rb_str_dup(source);
|
680
|
-
}
|
681
|
-
FORCE_UTF8(source);
|
682
|
-
} else {
|
683
|
-
source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
|
684
|
-
}
|
685
|
-
#endif
|
685
|
+
int encindex = RB_ENCODING_GET(source);
|
686
|
+
|
687
|
+
if (encindex == utf8_encindex) {
|
686
688
|
return source;
|
689
|
+
}
|
690
|
+
|
691
|
+
if (encindex == binary_encindex) {
|
692
|
+
// For historical reason, we silently reinterpret binary strings as UTF-8 if it would work.
|
693
|
+
// TODO: Deprecate in 2.8.0
|
694
|
+
// TODO: Remove in 3.0.0
|
695
|
+
return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
|
696
|
+
}
|
697
|
+
|
698
|
+
return rb_str_conv_enc(source, rb_enc_from_index(encindex), rb_utf8_encoding());
|
687
699
|
}
|
688
700
|
|
689
701
|
/*
|
@@ -708,8 +720,15 @@ static VALUE convert_encoding(VALUE source)
|
|
708
720
|
* * *create_additions*: If set to false, the Parser doesn't create
|
709
721
|
* additions even if a matching class and create_id was found. This option
|
710
722
|
* defaults to false.
|
711
|
-
* * *object_class*: Defaults to Hash
|
712
|
-
*
|
723
|
+
* * *object_class*: Defaults to Hash. If another type is provided, it will be used
|
724
|
+
* instead of Hash to represent JSON objects. The type must respond to
|
725
|
+
* +new+ without arguments, and return an object that respond to +[]=+.
|
726
|
+
* * *array_class*: Defaults to Array If another type is provided, it will be used
|
727
|
+
* instead of Hash to represent JSON arrays. The type must respond to
|
728
|
+
* +new+ without arguments, and return an object that respond to +<<+.
|
729
|
+
* * *decimal_class*: Specifies which class to use instead of the default
|
730
|
+
* (Float) when parsing decimal numbers. This class must accept a single
|
731
|
+
* string argument in its constructor.
|
713
732
|
*/
|
714
733
|
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
715
734
|
{
|
@@ -719,80 +738,91 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
719
738
|
if (json->Vsource) {
|
720
739
|
rb_raise(rb_eTypeError, "already initialized instance");
|
721
740
|
}
|
722
|
-
|
741
|
+
|
742
|
+
rb_check_arity(argc, 1, 2);
|
743
|
+
source = argv[0];
|
744
|
+
opts = Qnil;
|
745
|
+
if (argc == 2) {
|
746
|
+
opts = argv[1];
|
747
|
+
Check_Type(argv[1], T_HASH);
|
748
|
+
if (RHASH_SIZE(argv[1]) > 0) {
|
749
|
+
opts = argv[1];
|
750
|
+
}
|
751
|
+
}
|
752
|
+
|
723
753
|
if (!NIL_P(opts)) {
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
754
|
+
VALUE tmp = ID2SYM(i_max_nesting);
|
755
|
+
if (option_given_p(opts, tmp)) {
|
756
|
+
VALUE max_nesting = rb_hash_aref(opts, tmp);
|
757
|
+
if (RTEST(max_nesting)) {
|
758
|
+
Check_Type(max_nesting, T_FIXNUM);
|
759
|
+
json->max_nesting = FIX2INT(max_nesting);
|
760
|
+
} else {
|
761
|
+
json->max_nesting = 0;
|
762
|
+
}
|
763
|
+
} else {
|
764
|
+
json->max_nesting = 100;
|
765
|
+
}
|
766
|
+
tmp = ID2SYM(i_allow_nan);
|
767
|
+
if (option_given_p(opts, tmp)) {
|
768
|
+
json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
769
|
+
} else {
|
770
|
+
json->allow_nan = 0;
|
771
|
+
}
|
772
|
+
tmp = ID2SYM(i_symbolize_names);
|
773
|
+
if (option_given_p(opts, tmp)) {
|
774
|
+
json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
775
|
+
} else {
|
776
|
+
json->symbolize_names = 0;
|
777
|
+
}
|
778
|
+
tmp = ID2SYM(i_freeze);
|
779
|
+
if (option_given_p(opts, tmp)) {
|
780
|
+
json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
781
|
+
} else {
|
782
|
+
json->freeze = 0;
|
783
|
+
}
|
784
|
+
tmp = ID2SYM(i_create_additions);
|
785
|
+
if (option_given_p(opts, tmp)) {
|
786
|
+
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
787
|
+
} else {
|
788
|
+
json->create_additions = 0;
|
789
|
+
}
|
790
|
+
if (json->symbolize_names && json->create_additions) {
|
791
|
+
rb_raise(rb_eArgError,
|
792
|
+
"options :symbolize_names and :create_additions cannot be "
|
793
|
+
" used in conjunction");
|
794
|
+
}
|
795
|
+
tmp = ID2SYM(i_create_id);
|
796
|
+
if (option_given_p(opts, tmp)) {
|
797
|
+
json->create_id = rb_hash_aref(opts, tmp);
|
798
|
+
} else {
|
799
|
+
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
800
|
+
}
|
801
|
+
tmp = ID2SYM(i_object_class);
|
802
|
+
if (option_given_p(opts, tmp)) {
|
803
|
+
json->object_class = rb_hash_aref(opts, tmp);
|
804
|
+
} else {
|
805
|
+
json->object_class = Qnil;
|
806
|
+
}
|
807
|
+
tmp = ID2SYM(i_array_class);
|
808
|
+
if (option_given_p(opts, tmp)) {
|
809
|
+
json->array_class = rb_hash_aref(opts, tmp);
|
810
|
+
} else {
|
811
|
+
json->array_class = Qnil;
|
812
|
+
}
|
813
|
+
tmp = ID2SYM(i_decimal_class);
|
814
|
+
if (option_given_p(opts, tmp)) {
|
815
|
+
json->decimal_class = rb_hash_aref(opts, tmp);
|
816
|
+
} else {
|
817
|
+
json->decimal_class = Qnil;
|
818
|
+
}
|
819
|
+
tmp = ID2SYM(i_match_string);
|
820
|
+
if (option_given_p(opts, tmp)) {
|
821
|
+
VALUE match_string = rb_hash_aref(opts, tmp);
|
822
|
+
json->match_string = RTEST(match_string) ? match_string : Qnil;
|
823
|
+
} else {
|
824
|
+
json->match_string = Qnil;
|
825
|
+
}
|
796
826
|
} else {
|
797
827
|
json->max_nesting = 100;
|
798
828
|
json->allow_nan = 0;
|
@@ -836,33 +866,33 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
836
866
|
*/
|
837
867
|
static VALUE cParser_parse(VALUE self)
|
838
868
|
{
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
869
|
+
char *p, *pe;
|
870
|
+
int cs = EVIL;
|
871
|
+
VALUE result = Qnil;
|
872
|
+
GET_PARSER;
|
843
873
|
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
874
|
+
%% write init;
|
875
|
+
p = json->source;
|
876
|
+
pe = p + json->len;
|
877
|
+
%% write exec;
|
848
878
|
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
879
|
+
if (cs >= JSON_first_final && p == pe) {
|
880
|
+
return result;
|
881
|
+
} else {
|
882
|
+
raise_parse_error("unexpected token at '%s'", p);
|
883
|
+
return Qnil;
|
884
|
+
}
|
855
885
|
}
|
856
886
|
|
857
887
|
static void JSON_mark(void *ptr)
|
858
888
|
{
|
859
889
|
JSON_Parser *json = ptr;
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
890
|
+
rb_gc_mark(json->Vsource);
|
891
|
+
rb_gc_mark(json->create_id);
|
892
|
+
rb_gc_mark(json->object_class);
|
893
|
+
rb_gc_mark(json->array_class);
|
894
|
+
rb_gc_mark(json->decimal_class);
|
895
|
+
rb_gc_mark(json->match_string);
|
866
896
|
}
|
867
897
|
|
868
898
|
static void JSON_free(void *ptr)
|
@@ -878,16 +908,12 @@ static size_t JSON_memsize(const void *ptr)
|
|
878
908
|
return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
|
879
909
|
}
|
880
910
|
|
881
|
-
#ifdef NEW_TYPEDDATA_WRAPPER
|
882
911
|
static const rb_data_type_t JSON_Parser_type = {
|
883
912
|
"JSON/Parser",
|
884
913
|
{JSON_mark, JSON_free, JSON_memsize,},
|
885
|
-
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
886
914
|
0, 0,
|
887
915
|
RUBY_TYPED_FREE_IMMEDIATELY,
|
888
|
-
#endif
|
889
916
|
};
|
890
|
-
#endif
|
891
917
|
|
892
918
|
static VALUE cJSON_parser_s_allocate(VALUE klass)
|
893
919
|
{
|
@@ -920,9 +946,7 @@ void Init_parser(void)
|
|
920
946
|
mJSON = rb_define_module("JSON");
|
921
947
|
mExt = rb_define_module_under(mJSON, "Ext");
|
922
948
|
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
923
|
-
eParserError = rb_path2class("JSON::ParserError");
|
924
949
|
eNestingError = rb_path2class("JSON::NestingError");
|
925
|
-
rb_gc_register_mark_object(eParserError);
|
926
950
|
rb_gc_register_mark_object(eNestingError);
|
927
951
|
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
|
928
952
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
@@ -951,7 +975,6 @@ void Init_parser(void)
|
|
951
975
|
i_decimal_class = rb_intern("decimal_class");
|
952
976
|
i_match = rb_intern("match");
|
953
977
|
i_match_string = rb_intern("match_string");
|
954
|
-
i_key_p = rb_intern("key?");
|
955
978
|
i_deep_const_get = rb_intern("deep_const_get");
|
956
979
|
i_aset = rb_intern("[]=");
|
957
980
|
i_aref = rb_intern("[]");
|
@@ -960,6 +983,9 @@ void Init_parser(void)
|
|
960
983
|
i_try_convert = rb_intern("try_convert");
|
961
984
|
i_freeze = rb_intern("freeze");
|
962
985
|
i_uminus = rb_intern("-@");
|
986
|
+
|
987
|
+
binary_encindex = rb_ascii8bit_encindex();
|
988
|
+
utf8_encindex = rb_utf8_encindex();
|
963
989
|
}
|
964
990
|
|
965
991
|
/*
|