oj 3.13.11 → 3.15.0
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 +74 -0
- data/README.md +4 -2
- data/ext/oj/buf.h +11 -6
- data/ext/oj/cache.c +25 -24
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +8 -6
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +17 -24
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +17 -44
- data/ext/oj/custom.c +70 -141
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +128 -118
- data/ext/oj/dump.h +12 -8
- data/ext/oj/dump_compat.c +564 -641
- data/ext/oj/dump_leaf.c +17 -63
- data/ext/oj/dump_object.c +70 -199
- data/ext/oj/dump_strict.c +22 -46
- 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 +14 -5
- data/ext/oj/fast.c +75 -103
- data/ext/oj/intern.c +52 -50
- data/ext/oj/intern.h +4 -8
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +75 -47
- data/ext/oj/object.c +49 -66
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +140 -99
- data/ext/oj/oj.h +80 -51
- data/ext/oj/parse.c +162 -184
- data/ext/oj/parse.h +7 -10
- data/ext/oj/parser.c +89 -34
- data/ext/oj/parser.h +18 -7
- data/ext/oj/rails.c +82 -146
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +11 -12
- 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 +20 -31
- data/ext/oj/saj2.c +329 -93
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +26 -70
- data/ext/oj/stream_writer.c +12 -22
- data/ext/oj/strict.c +20 -52
- data/ext/oj/string_writer.c +21 -21
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +105 -150
- data/ext/oj/usual.h +68 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +31 -68
- data/lib/oj/active_support_helper.rb +0 -1
- 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 +4 -2
- data/lib/oj/mimic.rb +4 -2
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +9 -6
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/Compatibility.md +1 -1
- data/pages/InstallOptions.md +20 -0
- data/pages/Options.md +10 -0
- data/test/_test_active.rb +8 -9
- data/test/_test_active_mimic.rb +7 -8
- data/test/_test_mimic_rails.rb +17 -20
- data/test/activerecord/result_test.rb +5 -6
- data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
- data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
- data/test/{activesupport5 → activesupport7}/encoding_test.rb +20 -34
- data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
- data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
- data/test/files.rb +15 -15
- data/test/foo.rb +9 -71
- data/test/helper.rb +11 -8
- data/test/isolated/shared.rb +3 -2
- data/test/json_gem/json_addition_test.rb +2 -2
- data/test/json_gem/json_common_interface_test.rb +4 -4
- data/test/json_gem/json_encoding_test.rb +0 -0
- data/test/json_gem/json_ext_parser_test.rb +1 -0
- data/test/json_gem/json_fixtures_test.rb +3 -2
- data/test/json_gem/json_generator_test.rb +48 -36
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +54 -47
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/json_gem/test_helper.rb +7 -3
- data/test/mem.rb +13 -12
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +50 -0
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -69
- data/test/perf_once.rb +12 -11
- data/test/perf_parser.rb +42 -48
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +3 -3
- data/test/sample/change.rb +0 -1
- data/test/sample/dir.rb +0 -1
- data/test/sample/doc.rb +0 -1
- data/test/sample/file.rb +0 -1
- data/test/sample/group.rb +0 -1
- data/test/sample/hasprops.rb +0 -1
- data/test/sample/layer.rb +0 -1
- data/test/sample/rect.rb +0 -1
- data/test/sample/shape.rb +0 -1
- data/test/sample/text.rb +0 -1
- data/test/sample.rb +16 -16
- data/test/sample_json.rb +8 -8
- data/test/test_compat.rb +76 -42
- data/test/test_custom.rb +72 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +86 -90
- data/test/test_file.rb +41 -30
- data/test/test_gc.rb +16 -5
- data/test/test_generate.rb +5 -5
- data/test/test_hash.rb +4 -4
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +85 -96
- data/test/test_parser.rb +6 -22
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +115 -23
- data/test/test_parser_usual.rb +6 -6
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +37 -39
- data/test/test_strict.rb +30 -32
- data/test/test_various.rb +147 -99
- data/test/test_wab.rb +48 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +13 -4
- data/test/tests_mimic.rb +12 -3
- data/test/tests_mimic_addition.rb +12 -3
- metadata +33 -144
- 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/test_helper.rb +0 -72
- data/test/bar.rb +0 -16
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/saj2.c
CHANGED
@@ -1,23 +1,15 @@
|
|
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
9
|
|
7
|
-
typedef struct _delegate {
|
8
|
-
VALUE handler;
|
9
|
-
VALUE * keys;
|
10
|
-
VALUE * tail;
|
11
|
-
size_t klen;
|
12
|
-
struct _cache *str_cache;
|
13
|
-
uint8_t cache_str;
|
14
|
-
bool cache_keys;
|
15
|
-
bool thread_safe;
|
16
|
-
} * Delegate;
|
17
|
-
|
18
10
|
static VALUE get_key(ojParser p) {
|
19
|
-
|
20
|
-
const char
|
11
|
+
Saj d = (Saj)p->ctx;
|
12
|
+
const char *key = buf_str(&p->key);
|
21
13
|
size_t len = buf_len(&p->key);
|
22
14
|
volatile VALUE rkey;
|
23
15
|
|
@@ -29,12 +21,12 @@ static VALUE get_key(ojParser p) {
|
|
29
21
|
return rkey;
|
30
22
|
}
|
31
23
|
|
32
|
-
static void push_key(
|
24
|
+
static void push_key(Saj d, VALUE key) {
|
33
25
|
if (d->klen <= (size_t)(d->tail - d->keys)) {
|
34
26
|
size_t off = d->tail - d->keys;
|
35
27
|
|
36
28
|
d->klen += d->klen / 2;
|
37
|
-
|
29
|
+
OJ_R_REALLOC_N(d->keys, VALUE, d->klen);
|
38
30
|
d->tail = d->keys + off;
|
39
31
|
}
|
40
32
|
*d->tail = key;
|
@@ -45,32 +37,56 @@ static void noop(ojParser p) {
|
|
45
37
|
}
|
46
38
|
|
47
39
|
static void open_object(ojParser p) {
|
48
|
-
rb_funcall(((
|
40
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_hash_start_id, 1, Qnil);
|
41
|
+
}
|
42
|
+
|
43
|
+
static void open_object_loc(ojParser p) {
|
44
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_hash_start_id, 3, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
49
45
|
}
|
50
46
|
|
51
47
|
static void open_object_key(ojParser p) {
|
52
|
-
|
48
|
+
Saj d = (Saj)p->ctx;
|
53
49
|
volatile VALUE key = get_key(p);
|
54
50
|
|
55
51
|
push_key(d, key);
|
56
52
|
rb_funcall(d->handler, oj_hash_start_id, 1, key);
|
57
53
|
}
|
58
54
|
|
55
|
+
static void open_object_loc_key(ojParser p) {
|
56
|
+
Saj d = (Saj)p->ctx;
|
57
|
+
volatile VALUE key = get_key(p);
|
58
|
+
|
59
|
+
push_key(d, key);
|
60
|
+
rb_funcall(d->handler, oj_hash_start_id, 3, key, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
61
|
+
}
|
62
|
+
|
59
63
|
static void open_array(ojParser p) {
|
60
|
-
rb_funcall(((
|
64
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_array_start_id, 1, Qnil);
|
65
|
+
}
|
66
|
+
|
67
|
+
static void open_array_loc(ojParser p) {
|
68
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_array_start_id, 3, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
61
69
|
}
|
62
70
|
|
63
71
|
static void open_array_key(ojParser p) {
|
64
|
-
|
72
|
+
Saj d = (Saj)p->ctx;
|
65
73
|
volatile VALUE key = get_key(p);
|
66
74
|
|
67
75
|
push_key(d, key);
|
68
76
|
rb_funcall(d->handler, oj_array_start_id, 1, key);
|
69
77
|
}
|
70
78
|
|
79
|
+
static void open_array_loc_key(ojParser p) {
|
80
|
+
Saj d = (Saj)p->ctx;
|
81
|
+
volatile VALUE key = get_key(p);
|
82
|
+
|
83
|
+
push_key(d, key);
|
84
|
+
rb_funcall(d->handler, oj_array_start_id, 3, key, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
85
|
+
}
|
86
|
+
|
71
87
|
static void close_object(ojParser p) {
|
72
|
-
|
73
|
-
VALUE
|
88
|
+
Saj d = (Saj)p->ctx;
|
89
|
+
VALUE key = Qnil;
|
74
90
|
|
75
91
|
if (OBJECT_FUN == p->stack[p->depth]) {
|
76
92
|
d->tail--;
|
@@ -82,9 +98,23 @@ static void close_object(ojParser p) {
|
|
82
98
|
rb_funcall(d->handler, oj_hash_end_id, 1, key);
|
83
99
|
}
|
84
100
|
|
101
|
+
static void close_object_loc(ojParser p) {
|
102
|
+
Saj d = (Saj)p->ctx;
|
103
|
+
VALUE key = Qnil;
|
104
|
+
|
105
|
+
if (OBJECT_FUN == p->stack[p->depth]) {
|
106
|
+
d->tail--;
|
107
|
+
if (d->tail < d->keys) {
|
108
|
+
rb_raise(rb_eIndexError, "accessing key stack");
|
109
|
+
}
|
110
|
+
key = *d->tail;
|
111
|
+
}
|
112
|
+
rb_funcall(d->handler, oj_hash_end_id, 3, key, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
113
|
+
}
|
114
|
+
|
85
115
|
static void close_array(ojParser p) {
|
86
|
-
|
87
|
-
VALUE
|
116
|
+
Saj d = (Saj)p->ctx;
|
117
|
+
VALUE key = Qnil;
|
88
118
|
|
89
119
|
if (OBJECT_FUN == p->stack[p->depth]) {
|
90
120
|
d->tail--;
|
@@ -96,66 +126,182 @@ static void close_array(ojParser p) {
|
|
96
126
|
rb_funcall(d->handler, oj_array_end_id, 1, key);
|
97
127
|
}
|
98
128
|
|
129
|
+
static void close_array_loc(ojParser p) {
|
130
|
+
Saj d = (Saj)p->ctx;
|
131
|
+
VALUE key = Qnil;
|
132
|
+
|
133
|
+
if (OBJECT_FUN == p->stack[p->depth]) {
|
134
|
+
d->tail--;
|
135
|
+
if (d->tail < d->keys) {
|
136
|
+
rb_raise(rb_eIndexError, "accessing key stack");
|
137
|
+
}
|
138
|
+
key = *d->tail;
|
139
|
+
}
|
140
|
+
rb_funcall(d->handler, oj_array_end_id, 3, key, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
141
|
+
}
|
142
|
+
|
99
143
|
static void add_null(ojParser p) {
|
100
|
-
rb_funcall(((
|
144
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qnil, Qnil);
|
145
|
+
}
|
146
|
+
|
147
|
+
static void add_null_loc(ojParser p) {
|
148
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 4, Qnil, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
101
149
|
}
|
102
150
|
|
103
151
|
static void add_null_key(ojParser p) {
|
104
|
-
rb_funcall(((
|
152
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qnil, get_key(p));
|
153
|
+
}
|
154
|
+
|
155
|
+
static void add_null_key_loc(ojParser p) {
|
156
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
157
|
+
oj_add_value_id,
|
158
|
+
4,
|
159
|
+
Qnil,
|
160
|
+
get_key(p),
|
161
|
+
LONG2FIX(p->line),
|
162
|
+
LONG2FIX(p->cur - p->col));
|
105
163
|
}
|
106
164
|
|
107
165
|
static void add_true(ojParser p) {
|
108
|
-
rb_funcall(((
|
166
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qtrue, Qnil);
|
167
|
+
}
|
168
|
+
|
169
|
+
static void add_true_loc(ojParser p) {
|
170
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 4, Qtrue, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
109
171
|
}
|
110
172
|
|
111
173
|
static void add_true_key(ojParser p) {
|
112
|
-
rb_funcall(((
|
174
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qtrue, get_key(p));
|
175
|
+
}
|
176
|
+
|
177
|
+
static void add_true_key_loc(ojParser p) {
|
178
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
179
|
+
oj_add_value_id,
|
180
|
+
4,
|
181
|
+
Qtrue,
|
182
|
+
get_key(p),
|
183
|
+
LONG2FIX(p->line),
|
184
|
+
LONG2FIX(p->cur - p->col));
|
113
185
|
}
|
114
186
|
|
115
187
|
static void add_false(ojParser p) {
|
116
|
-
rb_funcall(((
|
188
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qfalse, Qnil);
|
189
|
+
}
|
190
|
+
|
191
|
+
static void add_false_loc(ojParser p) {
|
192
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 4, Qfalse, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
117
193
|
}
|
118
194
|
|
119
195
|
static void add_false_key(ojParser p) {
|
120
|
-
rb_funcall(((
|
196
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qfalse, get_key(p));
|
197
|
+
}
|
198
|
+
|
199
|
+
static void add_false_key_loc(ojParser p) {
|
200
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
201
|
+
oj_add_value_id,
|
202
|
+
4,
|
203
|
+
Qfalse,
|
204
|
+
get_key(p),
|
205
|
+
LONG2FIX(p->line),
|
206
|
+
LONG2FIX(p->cur - p->col));
|
121
207
|
}
|
122
208
|
|
123
209
|
static void add_int(ojParser p) {
|
124
|
-
rb_funcall(((
|
210
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, LONG2NUM(p->num.fixnum), Qnil);
|
211
|
+
}
|
212
|
+
|
213
|
+
static void add_int_loc(ojParser p) {
|
214
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
215
|
+
oj_add_value_id,
|
216
|
+
4,
|
217
|
+
LONG2NUM(p->num.fixnum),
|
218
|
+
Qnil,
|
219
|
+
LONG2FIX(p->line),
|
220
|
+
LONG2FIX(p->cur - p->col));
|
125
221
|
}
|
126
222
|
|
127
223
|
static void add_int_key(ojParser p) {
|
128
|
-
rb_funcall(((
|
224
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, LONG2NUM(p->num.fixnum), get_key(p));
|
225
|
+
}
|
226
|
+
|
227
|
+
static void add_int_key_loc(ojParser p) {
|
228
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
229
|
+
oj_add_value_id,
|
230
|
+
4,
|
231
|
+
LONG2NUM(p->num.fixnum),
|
232
|
+
get_key(p),
|
233
|
+
LONG2FIX(p->line),
|
234
|
+
LONG2FIX(p->cur - p->col));
|
129
235
|
}
|
130
236
|
|
131
237
|
static void add_float(ojParser p) {
|
132
|
-
rb_funcall(((
|
238
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, rb_float_new(p->num.dub), Qnil);
|
239
|
+
}
|
240
|
+
|
241
|
+
static void add_float_loc(ojParser p) {
|
242
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
243
|
+
oj_add_value_id,
|
244
|
+
4,
|
245
|
+
rb_float_new(p->num.dub),
|
246
|
+
Qnil,
|
247
|
+
LONG2FIX(p->line),
|
248
|
+
LONG2FIX(p->cur - p->col));
|
133
249
|
}
|
134
250
|
|
135
251
|
static void add_float_key(ojParser p) {
|
136
|
-
rb_funcall(((
|
252
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, rb_float_new(p->num.dub), get_key(p));
|
253
|
+
}
|
254
|
+
|
255
|
+
static void add_float_key_loc(ojParser p) {
|
256
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
257
|
+
oj_add_value_id,
|
258
|
+
4,
|
259
|
+
rb_float_new(p->num.dub),
|
260
|
+
get_key(p),
|
261
|
+
LONG2FIX(p->line),
|
262
|
+
LONG2FIX(p->cur - p->col));
|
137
263
|
}
|
138
264
|
|
139
265
|
static void add_big(ojParser p) {
|
140
|
-
rb_funcall((
|
266
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
141
267
|
oj_add_value_id,
|
142
268
|
2,
|
143
269
|
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
144
270
|
Qnil);
|
145
271
|
}
|
146
272
|
|
273
|
+
static void add_big_loc(ojParser p) {
|
274
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
275
|
+
oj_add_value_id,
|
276
|
+
4,
|
277
|
+
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
278
|
+
Qnil,
|
279
|
+
LONG2FIX(p->line),
|
280
|
+
LONG2FIX(p->cur - p->col));
|
281
|
+
}
|
282
|
+
|
147
283
|
static void add_big_key(ojParser p) {
|
148
|
-
rb_funcall((
|
284
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
149
285
|
oj_add_value_id,
|
150
286
|
2,
|
151
287
|
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
152
288
|
get_key(p));
|
153
289
|
}
|
154
290
|
|
291
|
+
static void add_big_key_loc(ojParser p) {
|
292
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
293
|
+
oj_add_value_id,
|
294
|
+
4,
|
295
|
+
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
296
|
+
get_key(p),
|
297
|
+
LONG2FIX(p->line),
|
298
|
+
LONG2FIX(p->cur - p->col));
|
299
|
+
}
|
300
|
+
|
155
301
|
static void add_str(ojParser p) {
|
156
|
-
|
302
|
+
Saj d = (Saj)p->ctx;
|
157
303
|
volatile VALUE rstr;
|
158
|
-
const char
|
304
|
+
const char *str = buf_str(&p->buf);
|
159
305
|
size_t len = buf_len(&p->buf);
|
160
306
|
|
161
307
|
if (d->cache_str < len) {
|
@@ -166,10 +312,24 @@ static void add_str(ojParser p) {
|
|
166
312
|
rb_funcall(d->handler, oj_add_value_id, 2, rstr, Qnil);
|
167
313
|
}
|
168
314
|
|
315
|
+
static void add_str_loc(ojParser p) {
|
316
|
+
Saj d = (Saj)p->ctx;
|
317
|
+
volatile VALUE rstr;
|
318
|
+
const char *str = buf_str(&p->buf);
|
319
|
+
size_t len = buf_len(&p->buf);
|
320
|
+
|
321
|
+
if (d->cache_str < len) {
|
322
|
+
rstr = cache_intern(d->str_cache, str, len);
|
323
|
+
} else {
|
324
|
+
rstr = rb_utf8_str_new(str, len);
|
325
|
+
}
|
326
|
+
rb_funcall(d->handler, oj_add_value_id, 4, rstr, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
327
|
+
}
|
328
|
+
|
169
329
|
static void add_str_key(ojParser p) {
|
170
|
-
|
330
|
+
Saj d = (Saj)p->ctx;
|
171
331
|
volatile VALUE rstr;
|
172
|
-
const char
|
332
|
+
const char *str = buf_str(&p->buf);
|
173
333
|
size_t len = buf_len(&p->buf);
|
174
334
|
|
175
335
|
if (d->cache_str < len) {
|
@@ -180,6 +340,20 @@ static void add_str_key(ojParser p) {
|
|
180
340
|
rb_funcall(d->handler, oj_add_value_id, 2, rstr, get_key(p));
|
181
341
|
}
|
182
342
|
|
343
|
+
static void add_str_key_loc(ojParser p) {
|
344
|
+
Saj d = (Saj)p->ctx;
|
345
|
+
volatile VALUE rstr;
|
346
|
+
const char *str = buf_str(&p->buf);
|
347
|
+
size_t len = buf_len(&p->buf);
|
348
|
+
|
349
|
+
if (d->cache_str < len) {
|
350
|
+
rstr = cache_intern(d->str_cache, str, len);
|
351
|
+
} else {
|
352
|
+
rstr = rb_utf8_str_new(str, len);
|
353
|
+
}
|
354
|
+
rb_funcall(d->handler, oj_add_value_id, 4, rstr, get_key(p), LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
355
|
+
}
|
356
|
+
|
183
357
|
static void reset(ojParser p) {
|
184
358
|
Funcs end = p->funcs + 3;
|
185
359
|
Funcs f;
|
@@ -200,7 +374,7 @@ static void reset(ojParser p) {
|
|
200
374
|
}
|
201
375
|
|
202
376
|
static VALUE option(ojParser p, const char *key, VALUE value) {
|
203
|
-
|
377
|
+
Saj d = (Saj)p->ctx;
|
204
378
|
|
205
379
|
if (0 == strcmp(key, "handler")) {
|
206
380
|
return d->handler;
|
@@ -210,53 +384,107 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
210
384
|
d->handler = value;
|
211
385
|
reset(p);
|
212
386
|
if (rb_respond_to(value, oj_hash_start_id)) {
|
213
|
-
|
214
|
-
|
215
|
-
|
387
|
+
if (1 == rb_obj_method_arity(value, oj_hash_start_id)) {
|
388
|
+
p->funcs[TOP_FUN].open_object = open_object;
|
389
|
+
p->funcs[ARRAY_FUN].open_object = open_object;
|
390
|
+
p->funcs[OBJECT_FUN].open_object = open_object_key;
|
391
|
+
} else {
|
392
|
+
p->funcs[TOP_FUN].open_object = open_object_loc;
|
393
|
+
p->funcs[ARRAY_FUN].open_object = open_object_loc;
|
394
|
+
p->funcs[OBJECT_FUN].open_object = open_object_loc_key;
|
395
|
+
}
|
216
396
|
}
|
217
397
|
if (rb_respond_to(value, oj_array_start_id)) {
|
218
|
-
|
219
|
-
|
220
|
-
|
398
|
+
if (1 == rb_obj_method_arity(value, oj_array_start_id)) {
|
399
|
+
p->funcs[TOP_FUN].open_array = open_array;
|
400
|
+
p->funcs[ARRAY_FUN].open_array = open_array;
|
401
|
+
p->funcs[OBJECT_FUN].open_array = open_array_key;
|
402
|
+
} else {
|
403
|
+
p->funcs[TOP_FUN].open_array = open_array_loc;
|
404
|
+
p->funcs[ARRAY_FUN].open_array = open_array_loc;
|
405
|
+
p->funcs[OBJECT_FUN].open_array = open_array_loc_key;
|
406
|
+
}
|
221
407
|
}
|
222
408
|
if (rb_respond_to(value, oj_hash_end_id)) {
|
223
|
-
|
224
|
-
|
225
|
-
|
409
|
+
if (1 == rb_obj_method_arity(value, oj_hash_end_id)) {
|
410
|
+
p->funcs[TOP_FUN].close_object = close_object;
|
411
|
+
p->funcs[ARRAY_FUN].close_object = close_object;
|
412
|
+
p->funcs[OBJECT_FUN].close_object = close_object;
|
413
|
+
} else {
|
414
|
+
p->funcs[TOP_FUN].close_object = close_object_loc;
|
415
|
+
p->funcs[ARRAY_FUN].close_object = close_object_loc;
|
416
|
+
p->funcs[OBJECT_FUN].close_object = close_object_loc;
|
417
|
+
}
|
226
418
|
}
|
227
419
|
if (rb_respond_to(value, oj_array_end_id)) {
|
228
|
-
|
229
|
-
|
230
|
-
|
420
|
+
if (1 == rb_obj_method_arity(value, oj_array_end_id)) {
|
421
|
+
p->funcs[TOP_FUN].close_array = close_array;
|
422
|
+
p->funcs[ARRAY_FUN].close_array = close_array;
|
423
|
+
p->funcs[OBJECT_FUN].close_array = close_array;
|
424
|
+
} else {
|
425
|
+
p->funcs[TOP_FUN].close_array = close_array_loc;
|
426
|
+
p->funcs[ARRAY_FUN].close_array = close_array_loc;
|
427
|
+
p->funcs[OBJECT_FUN].close_array = close_array_loc;
|
428
|
+
}
|
231
429
|
}
|
232
430
|
if (rb_respond_to(value, oj_add_value_id)) {
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
431
|
+
if (2 == rb_obj_method_arity(value, oj_add_value_id)) {
|
432
|
+
p->funcs[TOP_FUN].add_null = add_null;
|
433
|
+
p->funcs[ARRAY_FUN].add_null = add_null;
|
434
|
+
p->funcs[OBJECT_FUN].add_null = add_null_key;
|
435
|
+
|
436
|
+
p->funcs[TOP_FUN].add_true = add_true;
|
437
|
+
p->funcs[ARRAY_FUN].add_true = add_true;
|
438
|
+
p->funcs[OBJECT_FUN].add_true = add_true_key;
|
439
|
+
|
440
|
+
p->funcs[TOP_FUN].add_false = add_false;
|
441
|
+
p->funcs[ARRAY_FUN].add_false = add_false;
|
442
|
+
p->funcs[OBJECT_FUN].add_false = add_false_key;
|
443
|
+
|
444
|
+
p->funcs[TOP_FUN].add_int = add_int;
|
445
|
+
p->funcs[ARRAY_FUN].add_int = add_int;
|
446
|
+
p->funcs[OBJECT_FUN].add_int = add_int_key;
|
447
|
+
|
448
|
+
p->funcs[TOP_FUN].add_float = add_float;
|
449
|
+
p->funcs[ARRAY_FUN].add_float = add_float;
|
450
|
+
p->funcs[OBJECT_FUN].add_float = add_float_key;
|
451
|
+
|
452
|
+
p->funcs[TOP_FUN].add_big = add_big;
|
453
|
+
p->funcs[ARRAY_FUN].add_big = add_big;
|
454
|
+
p->funcs[OBJECT_FUN].add_big = add_big_key;
|
455
|
+
|
456
|
+
p->funcs[TOP_FUN].add_str = add_str;
|
457
|
+
p->funcs[ARRAY_FUN].add_str = add_str;
|
458
|
+
p->funcs[OBJECT_FUN].add_str = add_str_key;
|
459
|
+
} else {
|
460
|
+
p->funcs[TOP_FUN].add_null = add_null_loc;
|
461
|
+
p->funcs[ARRAY_FUN].add_null = add_null_loc;
|
462
|
+
p->funcs[OBJECT_FUN].add_null = add_null_key_loc;
|
463
|
+
|
464
|
+
p->funcs[TOP_FUN].add_true = add_true_loc;
|
465
|
+
p->funcs[ARRAY_FUN].add_true = add_true_loc;
|
466
|
+
p->funcs[OBJECT_FUN].add_true = add_true_key_loc;
|
467
|
+
|
468
|
+
p->funcs[TOP_FUN].add_false = add_false_loc;
|
469
|
+
p->funcs[ARRAY_FUN].add_false = add_false_loc;
|
470
|
+
p->funcs[OBJECT_FUN].add_false = add_false_key_loc;
|
471
|
+
|
472
|
+
p->funcs[TOP_FUN].add_int = add_int_loc;
|
473
|
+
p->funcs[ARRAY_FUN].add_int = add_int_loc;
|
474
|
+
p->funcs[OBJECT_FUN].add_int = add_int_key_loc;
|
475
|
+
|
476
|
+
p->funcs[TOP_FUN].add_float = add_float_loc;
|
477
|
+
p->funcs[ARRAY_FUN].add_float = add_float_loc;
|
478
|
+
p->funcs[OBJECT_FUN].add_float = add_float_key_loc;
|
479
|
+
|
480
|
+
p->funcs[TOP_FUN].add_big = add_big_loc;
|
481
|
+
p->funcs[ARRAY_FUN].add_big = add_big_loc;
|
482
|
+
p->funcs[OBJECT_FUN].add_big = add_big_key_loc;
|
483
|
+
|
484
|
+
p->funcs[TOP_FUN].add_str = add_str_loc;
|
485
|
+
p->funcs[ARRAY_FUN].add_str = add_str_loc;
|
486
|
+
p->funcs[OBJECT_FUN].add_str = add_str_key_loc;
|
487
|
+
}
|
260
488
|
}
|
261
489
|
return Qnil;
|
262
490
|
}
|
@@ -283,7 +511,7 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
283
511
|
|
284
512
|
return INT2NUM((int)d->cache_str);
|
285
513
|
}
|
286
|
-
rb_raise(rb_eArgError, "%s is not an option for the SAJ (Simple API for JSON)
|
514
|
+
rb_raise(rb_eArgError, "%s is not an option for the SAJ (Simple API for JSON) saj", key);
|
287
515
|
|
288
516
|
return Qnil; // Never reached due to the raise but required by the compiler.
|
289
517
|
}
|
@@ -293,26 +521,26 @@ static VALUE result(ojParser p) {
|
|
293
521
|
}
|
294
522
|
|
295
523
|
static void start(ojParser p) {
|
296
|
-
|
524
|
+
Saj d = (Saj)p->ctx;
|
297
525
|
|
298
526
|
d->tail = d->keys;
|
299
527
|
}
|
300
528
|
|
301
529
|
static void dfree(ojParser p) {
|
302
|
-
|
530
|
+
Saj d = (Saj)p->ctx;
|
303
531
|
|
304
532
|
if (NULL != d->keys) {
|
305
|
-
|
533
|
+
OJ_R_FREE(d->keys);
|
306
534
|
}
|
307
535
|
cache_free(d->str_cache);
|
308
|
-
|
536
|
+
OJ_R_FREE(p->ctx);
|
309
537
|
}
|
310
538
|
|
311
539
|
static void mark(ojParser p) {
|
312
|
-
if (NULL == p->ctx) {
|
540
|
+
if (NULL == p || NULL == p->ctx) {
|
313
541
|
return;
|
314
542
|
}
|
315
|
-
|
543
|
+
Saj d = (Saj)p->ctx;
|
316
544
|
VALUE *kp;
|
317
545
|
|
318
546
|
cache_mark(d->str_cache);
|
@@ -330,13 +558,15 @@ static VALUE form_str(const char *str, size_t len) {
|
|
330
558
|
return rb_str_freeze(rb_utf8_str_new(str, len));
|
331
559
|
}
|
332
560
|
|
333
|
-
void
|
334
|
-
|
335
|
-
|
336
|
-
d->
|
337
|
-
d->
|
338
|
-
d->
|
339
|
-
d->
|
561
|
+
void oj_init_saj(ojParser p, Saj 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;
|
340
570
|
|
341
571
|
p->ctx = (void *)d;
|
342
572
|
reset(p);
|
@@ -346,3 +576,9 @@ void oj_set_parser_saj(ojParser p) {
|
|
346
576
|
p->mark = mark;
|
347
577
|
p->start = start;
|
348
578
|
}
|
579
|
+
|
580
|
+
void oj_set_parser_saj(ojParser p) {
|
581
|
+
Saj d = OJ_R_ALLOC(struct _saj);
|
582
|
+
|
583
|
+
oj_init_saj(p, d);
|
584
|
+
}
|
data/ext/oj/saj2.h
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
// Copyright (c) 2021, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#include <ruby.h>
|
4
|
+
#include <stdbool.h>
|
5
|
+
|
6
|
+
struct _cache;
|
7
|
+
struct _ojParser;
|
8
|
+
|
9
|
+
typedef struct _saj {
|
10
|
+
VALUE handler;
|
11
|
+
VALUE *keys;
|
12
|
+
VALUE *tail;
|
13
|
+
size_t klen;
|
14
|
+
struct _cache *str_cache;
|
15
|
+
uint8_t cache_str;
|
16
|
+
bool cache_keys;
|
17
|
+
bool thread_safe;
|
18
|
+
} *Saj;
|
19
|
+
|
20
|
+
// Initialize the parser with the SAJ delegate. If the SAJ delegate is wrapped
|
21
|
+
// then this function is called first and then the parser functions can be
|
22
|
+
// replaced.
|
23
|
+
extern void oj_init_saj(struct _ojParser *p, Saj d);
|
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) {
|
@@ -91,12 +90,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
|
|
91
90
|
volatile VALUE rstr = rb_str_new(str, len);
|
92
91
|
|
93
92
|
rstr = oj_encode(rstr);
|
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);
|
93
|
+
rb_funcall(pi->handler, oj_hash_set_id, 3, stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, kval), rstr);
|
100
94
|
}
|
101
95
|
|
102
96
|
static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
@@ -109,12 +103,7 @@ static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
|
109
103
|
}
|
110
104
|
|
111
105
|
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);
|
106
|
+
rb_funcall(pi->handler, oj_hash_set_id, 3, stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, kval), value);
|
118
107
|
}
|
119
108
|
|
120
109
|
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|