oj 3.13.23 → 3.16.10
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/CHANGELOG.md +86 -0
- data/README.md +2 -2
- data/ext/oj/buf.h +7 -6
- data/ext/oj/cache.c +29 -26
- data/ext/oj/cache.h +3 -2
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +7 -5
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +5 -12
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +20 -60
- data/ext/oj/custom.c +26 -59
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +103 -53
- data/ext/oj/dump.h +1 -4
- data/ext/oj/dump_compat.c +557 -592
- data/ext/oj/dump_leaf.c +3 -5
- data/ext/oj/dump_object.c +42 -48
- data/ext/oj/dump_strict.c +10 -22
- data/ext/oj/encoder.c +1 -1
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +16 -7
- data/ext/oj/fast.c +63 -98
- data/ext/oj/intern.c +62 -47
- data/ext/oj/intern.h +3 -7
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +54 -38
- data/ext/oj/object.c +33 -43
- data/ext/oj/odd.c +8 -6
- data/ext/oj/odd.h +4 -4
- data/ext/oj/oj.c +245 -216
- data/ext/oj/oj.h +83 -81
- data/ext/oj/parse.c +109 -153
- data/ext/oj/parse.h +21 -24
- data/ext/oj/parser.c +80 -67
- data/ext/oj/parser.h +9 -8
- data/ext/oj/rails.c +71 -94
- data/ext/oj/reader.c +9 -14
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +13 -15
- data/ext/oj/saj2.c +37 -49
- data/ext/oj/saj2.h +1 -1
- data/ext/oj/scp.c +6 -20
- data/ext/oj/sparse.c +22 -70
- data/ext/oj/stream_writer.c +46 -48
- data/ext/oj/strict.c +22 -56
- data/ext/oj/string_writer.c +64 -40
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +125 -114
- data/ext/oj/usual.h +7 -6
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +13 -2
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/wab.c +25 -57
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +0 -1
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +7 -7
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +8 -5
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/InstallOptions.md +20 -0
- data/pages/Options.md +4 -0
- metadata +46 -121
- data/test/_test_active.rb +0 -76
- data/test/_test_active_mimic.rb +0 -96
- data/test/_test_mimic_rails.rb +0 -126
- data/test/activerecord/result_test.rb +0 -32
- data/test/activesupport4/decoding_test.rb +0 -108
- data/test/activesupport4/encoding_test.rb +0 -531
- data/test/activesupport4/test_helper.rb +0 -41
- data/test/activesupport5/abstract_unit.rb +0 -45
- data/test/activesupport5/decoding_test.rb +0 -133
- data/test/activesupport5/encoding_test.rb +0 -500
- data/test/activesupport5/encoding_test_cases.rb +0 -98
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/activesupport5/time_zone_test_helpers.rb +0 -39
- data/test/activesupport6/abstract_unit.rb +0 -44
- data/test/activesupport6/decoding_test.rb +0 -133
- data/test/activesupport6/encoding_test.rb +0 -507
- data/test/activesupport6/encoding_test_cases.rb +0 -98
- data/test/activesupport6/test_common.rb +0 -17
- data/test/activesupport6/test_helper.rb +0 -163
- data/test/activesupport6/time_zone_test_helpers.rb +0 -39
- data/test/activesupport7/abstract_unit.rb +0 -49
- data/test/activesupport7/decoding_test.rb +0 -125
- data/test/activesupport7/encoding_test.rb +0 -486
- data/test/activesupport7/encoding_test_cases.rb +0 -104
- data/test/activesupport7/time_zone_test_helpers.rb +0 -47
- data/test/bar.rb +0 -11
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/files.rb +0 -29
- data/test/foo.rb +0 -77
- data/test/helper.rb +0 -42
- data/test/isolated/shared.rb +0 -308
- data/test/isolated/test_mimic_after.rb +0 -13
- data/test/isolated/test_mimic_alone.rb +0 -12
- data/test/isolated/test_mimic_as_json.rb +0 -45
- data/test/isolated/test_mimic_before.rb +0 -13
- data/test/isolated/test_mimic_define.rb +0 -28
- data/test/isolated/test_mimic_rails_after.rb +0 -22
- data/test/isolated/test_mimic_rails_before.rb +0 -21
- data/test/isolated/test_mimic_redefine.rb +0 -15
- data/test/json_gem/json_addition_test.rb +0 -216
- data/test/json_gem/json_common_interface_test.rb +0 -153
- data/test/json_gem/json_encoding_test.rb +0 -107
- data/test/json_gem/json_ext_parser_test.rb +0 -20
- data/test/json_gem/json_fixtures_test.rb +0 -35
- data/test/json_gem/json_generator_test.rb +0 -396
- data/test/json_gem/json_generic_object_test.rb +0 -90
- data/test/json_gem/json_parser_test.rb +0 -477
- data/test/json_gem/json_string_matching_test.rb +0 -42
- data/test/json_gem/test_helper.rb +0 -30
- data/test/mem.rb +0 -33
- data/test/perf.rb +0 -107
- data/test/perf_compat.rb +0 -130
- data/test/perf_dump.rb +0 -50
- data/test/perf_fast.rb +0 -164
- data/test/perf_file.rb +0 -64
- data/test/perf_object.rb +0 -138
- data/test/perf_once.rb +0 -58
- data/test/perf_parser.rb +0 -189
- data/test/perf_saj.rb +0 -109
- data/test/perf_scp.rb +0 -152
- data/test/perf_simple.rb +0 -287
- data/test/perf_strict.rb +0 -139
- data/test/perf_wab.rb +0 -131
- data/test/prec.rb +0 -23
- data/test/sample/change.rb +0 -14
- data/test/sample/dir.rb +0 -19
- data/test/sample/doc.rb +0 -36
- data/test/sample/file.rb +0 -48
- data/test/sample/group.rb +0 -16
- data/test/sample/hasprops.rb +0 -16
- data/test/sample/layer.rb +0 -12
- data/test/sample/line.rb +0 -20
- data/test/sample/oval.rb +0 -10
- data/test/sample/rect.rb +0 -10
- data/test/sample/shape.rb +0 -35
- data/test/sample/text.rb +0 -20
- data/test/sample.rb +0 -54
- data/test/sample_json.rb +0 -37
- data/test/test_compat.rb +0 -540
- data/test/test_custom.rb +0 -544
- data/test/test_debian.rb +0 -53
- data/test/test_fast.rb +0 -530
- data/test/test_file.rb +0 -255
- data/test/test_gc.rb +0 -60
- data/test/test_generate.rb +0 -21
- data/test/test_hash.rb +0 -39
- data/test/test_integer_range.rb +0 -72
- data/test/test_null.rb +0 -376
- data/test/test_object.rb +0 -1025
- data/test/test_parser.rb +0 -11
- data/test/test_parser_debug.rb +0 -27
- data/test/test_parser_saj.rb +0 -335
- data/test/test_parser_usual.rb +0 -217
- data/test/test_rails.rb +0 -35
- data/test/test_saj.rb +0 -186
- data/test/test_scp.rb +0 -431
- data/test/test_strict.rb +0 -435
- data/test/test_various.rb +0 -752
- data/test/test_wab.rb +0 -309
- data/test/test_writer.rb +0 -380
- data/test/tests.rb +0 -33
- data/test/tests_mimic.rb +0 -23
- data/test/tests_mimic_addition.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/saj.c
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
#define OJ_INFINITY (1.0 / 0.0)
|
16
16
|
|
17
17
|
#include "encode.h"
|
18
|
+
#include "mem.h"
|
18
19
|
#include "oj.h"
|
19
20
|
|
20
21
|
typedef struct _parseInfo {
|
@@ -28,7 +29,7 @@ typedef struct _parseInfo {
|
|
28
29
|
int has_array_end;
|
29
30
|
int has_add_value;
|
30
31
|
int has_error;
|
31
|
-
} *
|
32
|
+
} *ParseInfo;
|
32
33
|
|
33
34
|
static void read_next(ParseInfo pi, const char *key);
|
34
35
|
static void read_hash(ParseInfo pi, const char *key);
|
@@ -93,8 +94,7 @@ inline static void call_add_value(VALUE handler, VALUE value, const char *key) {
|
|
93
94
|
if (0 == key) {
|
94
95
|
k = Qnil;
|
95
96
|
} else {
|
96
|
-
k =
|
97
|
-
k = oj_encode(k);
|
97
|
+
k = rb_utf8_str_new_cstr(key);
|
98
98
|
}
|
99
99
|
rb_funcall(handler, oj_add_value_id, 2, value, k);
|
100
100
|
}
|
@@ -105,8 +105,7 @@ inline static void call_no_value(VALUE handler, ID method, const char *key) {
|
|
105
105
|
if (0 == key) {
|
106
106
|
k = Qnil;
|
107
107
|
} else {
|
108
|
-
k =
|
109
|
-
k = oj_encode(k);
|
108
|
+
k = rb_utf8_str_new_cstr(key);
|
110
109
|
}
|
111
110
|
rb_funcall(handler, method, 1, k);
|
112
111
|
}
|
@@ -256,9 +255,8 @@ static void read_str(ParseInfo pi, const char *key) {
|
|
256
255
|
|
257
256
|
text = read_quoted_value(pi);
|
258
257
|
if (pi->has_add_value) {
|
259
|
-
VALUE s =
|
258
|
+
VALUE s = rb_utf8_str_new_cstr(text);
|
260
259
|
|
261
|
-
s = oj_encode(s);
|
262
260
|
call_add_value(pi->handler, s, key);
|
263
261
|
}
|
264
262
|
}
|
@@ -577,7 +575,7 @@ static void saj_parse(VALUE handler, char *json) {
|
|
577
575
|
/* initialize parse info */
|
578
576
|
pi.str = json;
|
579
577
|
pi.s = json;
|
580
|
-
#if IS_WINDOWS
|
578
|
+
#if IS_WINDOWS || !defined(HAVE_GETRLIMIT)
|
581
579
|
pi.stack_min = (void *)((char *)&obj - (512L * 1024L)); /* assume a 1M stack and give half to ruby */
|
582
580
|
#else
|
583
581
|
{
|
@@ -631,7 +629,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
631
629
|
if (rb_type(input) == T_STRING) {
|
632
630
|
// the json string gets modified so make a copy of it
|
633
631
|
len = RSTRING_LEN(input) + 1;
|
634
|
-
json =
|
632
|
+
json = OJ_R_ALLOC_N(char, len);
|
635
633
|
strcpy(json, StringValuePtr(input));
|
636
634
|
} else {
|
637
635
|
VALUE clas = rb_obj_class(input);
|
@@ -640,8 +638,8 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
640
638
|
if (oj_stringio_class == clas) {
|
641
639
|
s = rb_funcall2(input, oj_string_id, 0, 0);
|
642
640
|
len = RSTRING_LEN(s) + 1;
|
643
|
-
json =
|
644
|
-
strcpy(json,
|
641
|
+
json = OJ_R_ALLOC_N(char, len);
|
642
|
+
strcpy(json, StringValueCStr(s));
|
645
643
|
#if !IS_WINDOWS
|
646
644
|
} else if (rb_cFile == clas && 0 == FIX2INT(rb_funcall(input, oj_pos_id, 0))) {
|
647
645
|
int fd = FIX2INT(rb_funcall(input, oj_fileno_id, 0));
|
@@ -649,7 +647,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
649
647
|
|
650
648
|
len = lseek(fd, 0, SEEK_END);
|
651
649
|
lseek(fd, 0, SEEK_SET);
|
652
|
-
json =
|
650
|
+
json = OJ_R_ALLOC_N(char, len + 1);
|
653
651
|
if (0 >= (cnt = read(fd, json, len)) || cnt != (ssize_t)len) {
|
654
652
|
rb_raise(rb_eIOError, "failed to read from IO Object.");
|
655
653
|
}
|
@@ -658,14 +656,14 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
658
656
|
} else if (rb_respond_to(input, oj_read_id)) {
|
659
657
|
s = rb_funcall2(input, oj_read_id, 0, 0);
|
660
658
|
len = RSTRING_LEN(s) + 1;
|
661
|
-
json =
|
662
|
-
strcpy(json,
|
659
|
+
json = OJ_R_ALLOC_N(char, len);
|
660
|
+
strcpy(json, StringValueCStr(s));
|
663
661
|
} else {
|
664
662
|
rb_raise(rb_eArgError, "saj_parse() expected a String or IO Object.");
|
665
663
|
}
|
666
664
|
}
|
667
665
|
saj_parse(*argv, json);
|
668
|
-
|
666
|
+
OJ_R_FREE(json);
|
669
667
|
|
670
668
|
return Qnil;
|
671
669
|
}
|
data/ext/oj/saj2.c
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
// Copyright (c) 2021, Peter Ohler, All rights reserved.
|
2
2
|
|
3
|
+
#include "saj2.h"
|
4
|
+
|
3
5
|
#include "cache.h"
|
6
|
+
#include "mem.h"
|
4
7
|
#include "oj.h"
|
5
8
|
#include "parser.h"
|
6
|
-
#include "saj2.h"
|
7
9
|
|
8
10
|
static VALUE get_key(ojParser p) {
|
9
|
-
Saj
|
11
|
+
Saj d = (Saj)p->ctx;
|
10
12
|
const char *key = buf_str(&p->key);
|
11
13
|
size_t len = buf_len(&p->key);
|
12
14
|
volatile VALUE rkey;
|
@@ -24,7 +26,7 @@ static void push_key(Saj d, VALUE key) {
|
|
24
26
|
size_t off = d->tail - d->keys;
|
25
27
|
|
26
28
|
d->klen += d->klen / 2;
|
27
|
-
|
29
|
+
OJ_R_REALLOC_N(d->keys, VALUE, d->klen);
|
28
30
|
d->tail = d->keys + off;
|
29
31
|
}
|
30
32
|
*d->tail = key;
|
@@ -43,7 +45,7 @@ static void open_object_loc(ojParser p) {
|
|
43
45
|
}
|
44
46
|
|
45
47
|
static void open_object_key(ojParser p) {
|
46
|
-
Saj
|
48
|
+
Saj d = (Saj)p->ctx;
|
47
49
|
volatile VALUE key = get_key(p);
|
48
50
|
|
49
51
|
push_key(d, key);
|
@@ -51,7 +53,7 @@ static void open_object_key(ojParser p) {
|
|
51
53
|
}
|
52
54
|
|
53
55
|
static void open_object_loc_key(ojParser p) {
|
54
|
-
Saj
|
56
|
+
Saj d = (Saj)p->ctx;
|
55
57
|
volatile VALUE key = get_key(p);
|
56
58
|
|
57
59
|
push_key(d, key);
|
@@ -67,7 +69,7 @@ static void open_array_loc(ojParser p) {
|
|
67
69
|
}
|
68
70
|
|
69
71
|
static void open_array_key(ojParser p) {
|
70
|
-
Saj
|
72
|
+
Saj d = (Saj)p->ctx;
|
71
73
|
volatile VALUE key = get_key(p);
|
72
74
|
|
73
75
|
push_key(d, key);
|
@@ -75,7 +77,7 @@ static void open_array_key(ojParser p) {
|
|
75
77
|
}
|
76
78
|
|
77
79
|
static void open_array_loc_key(ojParser p) {
|
78
|
-
Saj
|
80
|
+
Saj d = (Saj)p->ctx;
|
79
81
|
volatile VALUE key = get_key(p);
|
80
82
|
|
81
83
|
push_key(d, key);
|
@@ -83,8 +85,8 @@ static void open_array_loc_key(ojParser p) {
|
|
83
85
|
}
|
84
86
|
|
85
87
|
static void close_object(ojParser p) {
|
86
|
-
Saj
|
87
|
-
VALUE
|
88
|
+
Saj d = (Saj)p->ctx;
|
89
|
+
VALUE key = Qnil;
|
88
90
|
|
89
91
|
if (OBJECT_FUN == p->stack[p->depth]) {
|
90
92
|
d->tail--;
|
@@ -97,8 +99,8 @@ static void close_object(ojParser p) {
|
|
97
99
|
}
|
98
100
|
|
99
101
|
static void close_object_loc(ojParser p) {
|
100
|
-
Saj
|
101
|
-
VALUE
|
102
|
+
Saj d = (Saj)p->ctx;
|
103
|
+
VALUE key = Qnil;
|
102
104
|
|
103
105
|
if (OBJECT_FUN == p->stack[p->depth]) {
|
104
106
|
d->tail--;
|
@@ -111,8 +113,8 @@ static void close_object_loc(ojParser p) {
|
|
111
113
|
}
|
112
114
|
|
113
115
|
static void close_array(ojParser p) {
|
114
|
-
Saj
|
115
|
-
VALUE
|
116
|
+
Saj d = (Saj)p->ctx;
|
117
|
+
VALUE key = Qnil;
|
116
118
|
|
117
119
|
if (OBJECT_FUN == p->stack[p->depth]) {
|
118
120
|
d->tail--;
|
@@ -125,8 +127,8 @@ static void close_array(ojParser p) {
|
|
125
127
|
}
|
126
128
|
|
127
129
|
static void close_array_loc(ojParser p) {
|
128
|
-
Saj
|
129
|
-
VALUE
|
130
|
+
Saj d = (Saj)p->ctx;
|
131
|
+
VALUE key = Qnil;
|
130
132
|
|
131
133
|
if (OBJECT_FUN == p->stack[p->depth]) {
|
132
134
|
d->tail--;
|
@@ -143,13 +145,7 @@ static void add_null(ojParser p) {
|
|
143
145
|
}
|
144
146
|
|
145
147
|
static void add_null_loc(ojParser p) {
|
146
|
-
rb_funcall(((Saj)p->ctx)->handler,
|
147
|
-
oj_add_value_id,
|
148
|
-
4,
|
149
|
-
Qnil,
|
150
|
-
Qnil,
|
151
|
-
LONG2FIX(p->line),
|
152
|
-
LONG2FIX(p->cur - p->col));
|
148
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 4, Qnil, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
153
149
|
}
|
154
150
|
|
155
151
|
static void add_null_key(ojParser p) {
|
@@ -171,13 +167,7 @@ static void add_true(ojParser p) {
|
|
171
167
|
}
|
172
168
|
|
173
169
|
static void add_true_loc(ojParser p) {
|
174
|
-
rb_funcall(((Saj)p->ctx)->handler,
|
175
|
-
oj_add_value_id,
|
176
|
-
4,
|
177
|
-
Qtrue,
|
178
|
-
Qnil,
|
179
|
-
LONG2FIX(p->line),
|
180
|
-
LONG2FIX(p->cur - p->col));
|
170
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 4, Qtrue, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
181
171
|
}
|
182
172
|
|
183
173
|
static void add_true_key(ojParser p) {
|
@@ -199,13 +189,7 @@ static void add_false(ojParser p) {
|
|
199
189
|
}
|
200
190
|
|
201
191
|
static void add_false_loc(ojParser p) {
|
202
|
-
rb_funcall(((Saj)p->ctx)->handler,
|
203
|
-
oj_add_value_id,
|
204
|
-
4,
|
205
|
-
Qfalse,
|
206
|
-
Qnil,
|
207
|
-
LONG2FIX(p->line),
|
208
|
-
LONG2FIX(p->cur - p->col));
|
192
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 4, Qfalse, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
209
193
|
}
|
210
194
|
|
211
195
|
static void add_false_key(ojParser p) {
|
@@ -315,7 +299,7 @@ static void add_big_key_loc(ojParser p) {
|
|
315
299
|
}
|
316
300
|
|
317
301
|
static void add_str(ojParser p) {
|
318
|
-
Saj
|
302
|
+
Saj d = (Saj)p->ctx;
|
319
303
|
volatile VALUE rstr;
|
320
304
|
const char *str = buf_str(&p->buf);
|
321
305
|
size_t len = buf_len(&p->buf);
|
@@ -329,7 +313,7 @@ static void add_str(ojParser p) {
|
|
329
313
|
}
|
330
314
|
|
331
315
|
static void add_str_loc(ojParser p) {
|
332
|
-
Saj
|
316
|
+
Saj d = (Saj)p->ctx;
|
333
317
|
volatile VALUE rstr;
|
334
318
|
const char *str = buf_str(&p->buf);
|
335
319
|
size_t len = buf_len(&p->buf);
|
@@ -343,7 +327,7 @@ static void add_str_loc(ojParser p) {
|
|
343
327
|
}
|
344
328
|
|
345
329
|
static void add_str_key(ojParser p) {
|
346
|
-
Saj
|
330
|
+
Saj d = (Saj)p->ctx;
|
347
331
|
volatile VALUE rstr;
|
348
332
|
const char *str = buf_str(&p->buf);
|
349
333
|
size_t len = buf_len(&p->buf);
|
@@ -357,7 +341,7 @@ static void add_str_key(ojParser p) {
|
|
357
341
|
}
|
358
342
|
|
359
343
|
static void add_str_key_loc(ojParser p) {
|
360
|
-
Saj
|
344
|
+
Saj d = (Saj)p->ctx;
|
361
345
|
volatile VALUE rstr;
|
362
346
|
const char *str = buf_str(&p->buf);
|
363
347
|
size_t len = buf_len(&p->buf);
|
@@ -546,18 +530,18 @@ static void dfree(ojParser p) {
|
|
546
530
|
Saj d = (Saj)p->ctx;
|
547
531
|
|
548
532
|
if (NULL != d->keys) {
|
549
|
-
|
533
|
+
OJ_R_FREE(d->keys);
|
550
534
|
}
|
551
535
|
cache_free(d->str_cache);
|
552
|
-
|
536
|
+
OJ_R_FREE(p->ctx);
|
553
537
|
}
|
554
538
|
|
555
539
|
static void mark(ojParser p) {
|
556
540
|
if (NULL == p || NULL == p->ctx) {
|
557
541
|
return;
|
558
542
|
}
|
559
|
-
Saj
|
560
|
-
VALUE
|
543
|
+
Saj d = (Saj)p->ctx;
|
544
|
+
VALUE *kp;
|
561
545
|
|
562
546
|
cache_mark(d->str_cache);
|
563
547
|
if (Qnil != d->handler) {
|
@@ -575,10 +559,14 @@ static VALUE form_str(const char *str, size_t len) {
|
|
575
559
|
}
|
576
560
|
|
577
561
|
void oj_init_saj(ojParser p, Saj d) {
|
578
|
-
d->klen
|
579
|
-
d->keys
|
580
|
-
d->tail
|
581
|
-
d->
|
562
|
+
d->klen = 256;
|
563
|
+
d->keys = OJ_R_ALLOC_N(VALUE, d->klen);
|
564
|
+
d->tail = d->keys;
|
565
|
+
d->handler = Qnil;
|
566
|
+
d->str_cache = cache_create(0, form_str, true, false);
|
567
|
+
d->cache_str = 16;
|
568
|
+
d->cache_keys = true;
|
569
|
+
d->thread_safe = false;
|
582
570
|
|
583
571
|
p->ctx = (void *)d;
|
584
572
|
reset(p);
|
@@ -590,7 +578,7 @@ void oj_init_saj(ojParser p, Saj d) {
|
|
590
578
|
}
|
591
579
|
|
592
580
|
void oj_set_parser_saj(ojParser p) {
|
593
|
-
Saj d =
|
581
|
+
Saj d = OJ_R_ALLOC(struct _saj);
|
594
582
|
|
595
583
|
oj_init_saj(p, d);
|
596
584
|
}
|
data/ext/oj/saj2.h
CHANGED
@@ -15,7 +15,7 @@ typedef struct _saj {
|
|
15
15
|
uint8_t cache_str;
|
16
16
|
bool cache_keys;
|
17
17
|
bool thread_safe;
|
18
|
-
} *
|
18
|
+
} *Saj;
|
19
19
|
|
20
20
|
// Initialize the parser with the SAJ delegate. If the SAJ delegate is wrapped
|
21
21
|
// then this function is called first and then the parser functions can be
|
data/ext/oj/scp.c
CHANGED
@@ -33,8 +33,7 @@ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
|
33
33
|
return Qundef;
|
34
34
|
}
|
35
35
|
|
36
|
-
static void
|
37
|
-
noop_hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
36
|
+
static void noop_hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
38
37
|
}
|
39
38
|
|
40
39
|
static void noop_hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
@@ -57,9 +56,8 @@ static void add_value(ParseInfo pi, VALUE val) {
|
|
57
56
|
}
|
58
57
|
|
59
58
|
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
60
|
-
volatile VALUE rstr =
|
59
|
+
volatile VALUE rstr = rb_utf8_str_new(str, len);
|
61
60
|
|
62
|
-
rstr = oj_encode(rstr);
|
63
61
|
rb_funcall(pi->handler, oj_add_value_id, 1, rstr);
|
64
62
|
}
|
65
63
|
|
@@ -88,15 +86,9 @@ static VALUE hash_key(ParseInfo pi, const char *key, size_t klen) {
|
|
88
86
|
}
|
89
87
|
|
90
88
|
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
91
|
-
volatile VALUE rstr =
|
89
|
+
volatile VALUE rstr = rb_utf8_str_new(str, len);
|
92
90
|
|
93
|
-
|
94
|
-
rb_funcall(pi->handler,
|
95
|
-
oj_hash_set_id,
|
96
|
-
3,
|
97
|
-
stack_peek(&pi->stack)->val,
|
98
|
-
oj_calc_hash_key(pi, kval),
|
99
|
-
rstr);
|
91
|
+
rb_funcall(pi->handler, oj_hash_set_id, 3, stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, kval), rstr);
|
100
92
|
}
|
101
93
|
|
102
94
|
static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
@@ -109,18 +101,12 @@ static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
|
109
101
|
}
|
110
102
|
|
111
103
|
static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
112
|
-
rb_funcall(pi->handler,
|
113
|
-
oj_hash_set_id,
|
114
|
-
3,
|
115
|
-
stack_peek(&pi->stack)->val,
|
116
|
-
oj_calc_hash_key(pi, kval),
|
117
|
-
value);
|
104
|
+
rb_funcall(pi->handler, oj_hash_set_id, 3, stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, kval), value);
|
118
105
|
}
|
119
106
|
|
120
107
|
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
121
|
-
volatile VALUE rstr =
|
108
|
+
volatile VALUE rstr = rb_utf8_str_new(str, len);
|
122
109
|
|
123
|
-
rstr = oj_encode(rstr);
|
124
110
|
rb_funcall(pi->handler, oj_array_append_id, 2, stack_peek(&pi->stack)->val, rstr);
|
125
111
|
}
|
126
112
|
|
data/ext/oj/sparse.c
CHANGED
@@ -10,6 +10,7 @@
|
|
10
10
|
#include "buf.h"
|
11
11
|
#include "encode.h"
|
12
12
|
#include "intern.h" // for oj_strndup()
|
13
|
+
#include "mem.h"
|
13
14
|
#include "oj.h"
|
14
15
|
#include "parse.h"
|
15
16
|
#include "val_stack.h"
|
@@ -71,7 +72,7 @@ static void add_value(ParseInfo pi, VALUE rval) {
|
|
71
72
|
case NEXT_HASH_VALUE:
|
72
73
|
pi->hash_set_value(pi, parent, rval);
|
73
74
|
if (parent->kalloc) {
|
74
|
-
|
75
|
+
OJ_R_FREE((char *)parent->key);
|
75
76
|
}
|
76
77
|
parent->key = 0;
|
77
78
|
parent->kalloc = 0;
|
@@ -110,7 +111,7 @@ static void add_num_value(ParseInfo pi, NumInfo ni) {
|
|
110
111
|
case NEXT_HASH_VALUE:
|
111
112
|
pi->hash_set_num(pi, parent, ni);
|
112
113
|
if (parent->kalloc) {
|
113
|
-
|
114
|
+
OJ_R_FREE((char *)parent->key);
|
114
115
|
}
|
115
116
|
parent->key = 0;
|
116
117
|
parent->kalloc = 0;
|
@@ -212,11 +213,7 @@ static void read_escaped_str(ParseInfo pi) {
|
|
212
213
|
}
|
213
214
|
while ('\"' != (c = reader_get(&pi->rd))) {
|
214
215
|
if ('\0' == c) {
|
215
|
-
oj_set_error_at(pi,
|
216
|
-
oj_parse_error_class,
|
217
|
-
__FILE__,
|
218
|
-
__LINE__,
|
219
|
-
"quoted string not terminated");
|
216
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "quoted string not terminated");
|
220
217
|
buf_cleanup(&buf);
|
221
218
|
return;
|
222
219
|
} else if ('\\' == c) {
|
@@ -249,11 +246,7 @@ static void read_escaped_str(ParseInfo pi) {
|
|
249
246
|
reader_backup(&pi->rd);
|
250
247
|
break;
|
251
248
|
}
|
252
|
-
oj_set_error_at(pi,
|
253
|
-
oj_parse_error_class,
|
254
|
-
__FILE__,
|
255
|
-
__LINE__,
|
256
|
-
"invalid escaped character");
|
249
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid escaped character");
|
257
250
|
buf_cleanup(&buf);
|
258
251
|
return;
|
259
252
|
}
|
@@ -277,11 +270,7 @@ static void read_escaped_str(ParseInfo pi) {
|
|
277
270
|
buf_append(&buf, c);
|
278
271
|
break;
|
279
272
|
}
|
280
|
-
oj_set_error_at(pi,
|
281
|
-
oj_parse_error_class,
|
282
|
-
__FILE__,
|
283
|
-
__LINE__,
|
284
|
-
"invalid escaped character");
|
273
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid escaped character");
|
285
274
|
buf_cleanup(&buf);
|
286
275
|
return;
|
287
276
|
}
|
@@ -315,7 +304,7 @@ static void read_escaped_str(ParseInfo pi) {
|
|
315
304
|
case NEXT_HASH_VALUE:
|
316
305
|
pi->hash_set_cstr(pi, parent, buf.head, buf_len(&buf), pi->rd.str);
|
317
306
|
if (parent->kalloc) {
|
318
|
-
|
307
|
+
OJ_R_FREE((char *)parent->key);
|
319
308
|
}
|
320
309
|
parent->key = 0;
|
321
310
|
parent->kalloc = 0;
|
@@ -345,11 +334,7 @@ static void read_str(ParseInfo pi) {
|
|
345
334
|
reader_protect(&pi->rd);
|
346
335
|
while ('\"' != (c = reader_get(&pi->rd))) {
|
347
336
|
if ('\0' == c) {
|
348
|
-
oj_set_error_at(pi,
|
349
|
-
oj_parse_error_class,
|
350
|
-
__FILE__,
|
351
|
-
__LINE__,
|
352
|
-
"quoted string not terminated");
|
337
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "quoted string not terminated");
|
353
338
|
return;
|
354
339
|
} else if ('\\' == c) {
|
355
340
|
reader_backup(&pi->rd);
|
@@ -386,7 +371,7 @@ static void read_str(ParseInfo pi) {
|
|
386
371
|
case NEXT_HASH_VALUE:
|
387
372
|
pi->hash_set_cstr(pi, parent, pi->rd.str, pi->rd.tail - pi->rd.str - 1, pi->rd.str);
|
388
373
|
if (parent->kalloc) {
|
389
|
-
|
374
|
+
OJ_R_FREE((char *)parent->key);
|
390
375
|
}
|
391
376
|
parent->key = 0;
|
392
377
|
parent->kalloc = 0;
|
@@ -429,7 +414,7 @@ static void read_num(ParseInfo pi) {
|
|
429
414
|
ni.no_big = !pi->options.compat_bigdec;
|
430
415
|
ni.bigdec_load = pi->options.compat_bigdec;
|
431
416
|
} else {
|
432
|
-
ni.no_big
|
417
|
+
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load ||
|
433
418
|
RubyDec == pi->options.bigdec_load);
|
434
419
|
ni.bigdec_load = pi->options.bigdec_load;
|
435
420
|
}
|
@@ -443,18 +428,10 @@ static void read_num(ParseInfo pi) {
|
|
443
428
|
}
|
444
429
|
if ('I' == c) {
|
445
430
|
if (No == pi->options.allow_nan) {
|
446
|
-
oj_set_error_at(pi,
|
447
|
-
oj_parse_error_class,
|
448
|
-
__FILE__,
|
449
|
-
__LINE__,
|
450
|
-
"not a number or other value");
|
431
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
451
432
|
return;
|
452
433
|
} else if (0 != reader_expect(&pi->rd, "nfinity")) {
|
453
|
-
oj_set_error_at(pi,
|
454
|
-
oj_parse_error_class,
|
455
|
-
__FILE__,
|
456
|
-
__LINE__,
|
457
|
-
"not a number or other value");
|
434
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
458
435
|
return;
|
459
436
|
}
|
460
437
|
ni.infinity = 1;
|
@@ -476,11 +453,7 @@ static void read_num(ParseInfo pi) {
|
|
476
453
|
|
477
454
|
if (0 < d) {
|
478
455
|
if (zero1 && CompatMode == pi->options.mode) {
|
479
|
-
oj_set_error_at(pi,
|
480
|
-
oj_parse_error_class,
|
481
|
-
__FILE__,
|
482
|
-
__LINE__,
|
483
|
-
"not a number");
|
456
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number");
|
484
457
|
return;
|
485
458
|
}
|
486
459
|
zero1 = false;
|
@@ -591,7 +564,7 @@ static void read_nan(ParseInfo pi) {
|
|
591
564
|
ni.no_big = !pi->options.compat_bigdec;
|
592
565
|
ni.bigdec_load = pi->options.compat_bigdec;
|
593
566
|
} else {
|
594
|
-
ni.no_big
|
567
|
+
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load ||
|
595
568
|
RubyDec == pi->options.bigdec_load);
|
596
569
|
ni.bigdec_load = pi->options.bigdec_load;
|
597
570
|
}
|
@@ -716,11 +689,7 @@ void oj_sparse2(ParseInfo pi) {
|
|
716
689
|
case '"': read_str(pi); break;
|
717
690
|
case '+':
|
718
691
|
if (CompatMode == pi->options.mode) {
|
719
|
-
oj_set_error_at(pi,
|
720
|
-
oj_parse_error_class,
|
721
|
-
__FILE__,
|
722
|
-
__LINE__,
|
723
|
-
"unexpected character");
|
692
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "unexpected character");
|
724
693
|
return;
|
725
694
|
}
|
726
695
|
pi->cur--;
|
@@ -745,11 +714,7 @@ void oj_sparse2(ParseInfo pi) {
|
|
745
714
|
reader_backup(&pi->rd);
|
746
715
|
read_num(pi);
|
747
716
|
} else {
|
748
|
-
oj_set_error_at(pi,
|
749
|
-
oj_parse_error_class,
|
750
|
-
__FILE__,
|
751
|
-
__LINE__,
|
752
|
-
"unexpected character");
|
717
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "unexpected character");
|
753
718
|
return;
|
754
719
|
}
|
755
720
|
break;
|
@@ -757,11 +722,7 @@ void oj_sparse2(ParseInfo pi) {
|
|
757
722
|
if (Yes == pi->options.allow_nan) {
|
758
723
|
read_nan(pi);
|
759
724
|
} else {
|
760
|
-
oj_set_error_at(pi,
|
761
|
-
oj_parse_error_class,
|
762
|
-
__FILE__,
|
763
|
-
__LINE__,
|
764
|
-
"unexpected character");
|
725
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "unexpected character");
|
765
726
|
return;
|
766
727
|
}
|
767
728
|
break;
|
@@ -799,8 +760,7 @@ void oj_sparse2(ParseInfo pi) {
|
|
799
760
|
ni.no_big = !pi->options.compat_bigdec;
|
800
761
|
ni.bigdec_load = pi->options.compat_bigdec;
|
801
762
|
} else {
|
802
|
-
ni.no_big = (FloatDec == pi->options.bigdec_load ||
|
803
|
-
FastDec == pi->options.bigdec_load ||
|
763
|
+
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load ||
|
804
764
|
RubyDec == pi->options.bigdec_load);
|
805
765
|
ni.bigdec_load = pi->options.bigdec_load;
|
806
766
|
}
|
@@ -813,13 +773,7 @@ void oj_sparse2(ParseInfo pi) {
|
|
813
773
|
case '/': skip_comment(pi); break;
|
814
774
|
case '\0': return;
|
815
775
|
default:
|
816
|
-
oj_set_error_at(pi,
|
817
|
-
oj_parse_error_class,
|
818
|
-
__FILE__,
|
819
|
-
__LINE__,
|
820
|
-
"unexpected character '%c' [0x%02x]",
|
821
|
-
c,
|
822
|
-
c);
|
776
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "unexpected character '%c' [0x%02x]", c, c);
|
823
777
|
return;
|
824
778
|
}
|
825
779
|
if (err_has(&pi->err)) {
|
@@ -878,8 +832,8 @@ oj_pi_sparse(int argc, VALUE *argv, ParseInfo pi, int fd) {
|
|
878
832
|
} else {
|
879
833
|
rb_raise(rb_eTypeError, "Nil is not a valid JSON source.");
|
880
834
|
}
|
881
|
-
} else if (CompatMode == pi->options.mode && T_STRING == rb_type(input) &&
|
882
|
-
|
835
|
+
} else if (CompatMode == pi->options.mode && T_STRING == rb_type(input) && No == pi->options.nilnil &&
|
836
|
+
0 == RSTRING_LEN(input)) {
|
883
837
|
rb_raise(oj_json_parser_error_class, "An empty string is not a valid JSON string.");
|
884
838
|
}
|
885
839
|
if (rb_block_given_p()) {
|
@@ -932,9 +886,7 @@ oj_pi_sparse(int argc, VALUE *argv, ParseInfo pi, int fd) {
|
|
932
886
|
switch (v->next) {
|
933
887
|
case NEXT_ARRAY_NEW:
|
934
888
|
case NEXT_ARRAY_ELEMENT:
|
935
|
-
case NEXT_ARRAY_COMMA:
|
936
|
-
oj_set_error_at(pi, err_class, __FILE__, __LINE__, "Array not terminated");
|
937
|
-
break;
|
889
|
+
case NEXT_ARRAY_COMMA: oj_set_error_at(pi, err_class, __FILE__, __LINE__, "Array not terminated"); break;
|
938
890
|
case NEXT_HASH_NEW:
|
939
891
|
case NEXT_HASH_KEY:
|
940
892
|
case NEXT_HASH_COLON:
|