oj 2.18.3 → 3.13.14
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 +5 -5
- data/CHANGELOG.md +1324 -0
- data/README.md +51 -204
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +49 -72
- data/ext/oj/cache.c +326 -0
- data/ext/oj/cache.h +21 -0
- data/ext/oj/cache8.c +61 -64
- data/ext/oj/cache8.h +12 -39
- data/ext/oj/circarray.c +37 -68
- data/ext/oj/circarray.h +16 -42
- data/ext/oj/code.c +221 -0
- data/ext/oj/code.h +40 -0
- data/ext/oj/compat.c +231 -107
- data/ext/oj/custom.c +1125 -0
- data/ext/oj/debug.c +132 -0
- data/ext/oj/dump.c +935 -2513
- data/ext/oj/dump.h +108 -0
- data/ext/oj/dump_compat.c +936 -0
- data/ext/oj/dump_leaf.c +164 -0
- data/ext/oj/dump_object.c +761 -0
- data/ext/oj/dump_strict.c +410 -0
- data/ext/oj/encode.h +7 -42
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +40 -54
- data/ext/oj/err.h +52 -46
- data/ext/oj/extconf.rb +21 -30
- data/ext/oj/fast.c +1097 -1080
- data/ext/oj/intern.c +301 -0
- data/ext/oj/intern.h +26 -0
- data/ext/oj/mimic_json.c +893 -0
- data/ext/oj/object.c +549 -620
- data/ext/oj/odd.c +155 -167
- data/ext/oj/odd.h +37 -63
- data/ext/oj/oj.c +1661 -2063
- data/ext/oj/oj.h +341 -270
- data/ext/oj/parse.c +974 -737
- data/ext/oj/parse.h +105 -97
- data/ext/oj/parser.c +1526 -0
- data/ext/oj/parser.h +90 -0
- data/ext/oj/rails.c +1504 -0
- data/ext/oj/rails.h +18 -0
- data/ext/oj/reader.c +141 -163
- data/ext/oj/reader.h +75 -113
- data/ext/oj/resolve.c +45 -93
- data/ext/oj/resolve.h +7 -34
- data/ext/oj/rxclass.c +143 -0
- data/ext/oj/rxclass.h +26 -0
- data/ext/oj/saj.c +447 -511
- data/ext/oj/saj2.c +348 -0
- data/ext/oj/scp.c +91 -138
- data/ext/oj/sparse.c +793 -644
- data/ext/oj/stream_writer.c +331 -0
- data/ext/oj/strict.c +145 -109
- data/ext/oj/string_writer.c +493 -0
- data/ext/oj/trace.c +72 -0
- data/ext/oj/trace.h +28 -0
- data/ext/oj/usual.c +1254 -0
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +20 -0
- data/ext/oj/val_stack.c +62 -70
- data/ext/oj/val_stack.h +95 -129
- data/ext/oj/validate.c +51 -0
- data/ext/oj/wab.c +622 -0
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +17 -8
- data/lib/oj/error.rb +10 -11
- data/lib/oj/json.rb +176 -0
- data/lib/oj/mimic.rb +158 -19
- data/lib/oj/state.rb +132 -0
- data/lib/oj/version.rb +2 -2
- data/lib/oj.rb +1 -31
- data/pages/Advanced.md +22 -0
- data/pages/Compatibility.md +25 -0
- data/pages/Custom.md +23 -0
- data/pages/Encoding.md +65 -0
- data/pages/JsonGem.md +94 -0
- data/pages/Modes.md +161 -0
- data/pages/Options.md +327 -0
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +167 -0
- data/pages/Security.md +20 -0
- data/pages/WAB.md +13 -0
- data/test/activerecord/result_test.rb +32 -0
- data/test/activesupport4/decoding_test.rb +108 -0
- data/test/activesupport4/encoding_test.rb +531 -0
- data/test/activesupport4/test_helper.rb +41 -0
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +133 -0
- data/test/activesupport5/encoding_test.rb +500 -0
- data/test/activesupport5/encoding_test_cases.rb +98 -0
- data/test/activesupport5/test_helper.rb +72 -0
- data/test/activesupport5/time_zone_test_helpers.rb +39 -0
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +9 -0
- data/test/baz.rb +16 -0
- data/test/bug.rb +11 -46
- data/test/foo.rb +69 -16
- data/test/helper.rb +10 -1
- data/test/isolated/shared.rb +12 -8
- data/test/isolated/test_mimic_rails_after.rb +3 -3
- data/test/isolated/test_mimic_rails_before.rb +3 -3
- data/test/json_gem/json_addition_test.rb +216 -0
- data/test/json_gem/json_common_interface_test.rb +153 -0
- data/test/json_gem/json_encoding_test.rb +107 -0
- data/test/json_gem/json_ext_parser_test.rb +20 -0
- data/test/json_gem/json_fixtures_test.rb +35 -0
- data/test/json_gem/json_generator_test.rb +397 -0
- data/test/json_gem/json_generic_object_test.rb +90 -0
- data/test/json_gem/json_parser_test.rb +470 -0
- data/test/json_gem/json_string_matching_test.rb +42 -0
- data/test/json_gem/test_helper.rb +26 -0
- data/test/mem.rb +33 -0
- data/test/perf.rb +1 -1
- data/test/perf_compat.rb +30 -28
- data/test/perf_dump.rb +50 -0
- data/test/perf_object.rb +1 -1
- data/test/perf_once.rb +58 -0
- data/test/perf_parser.rb +189 -0
- data/test/perf_scp.rb +11 -10
- data/test/perf_strict.rb +30 -19
- data/test/perf_wab.rb +131 -0
- data/test/prec.rb +23 -0
- data/test/sample.rb +0 -1
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +219 -102
- data/test/test_custom.rb +533 -0
- data/test/test_fast.rb +107 -35
- data/test/test_file.rb +19 -25
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +11 -1
- data/test/test_integer_range.rb +72 -0
- data/test/test_null.rb +376 -0
- data/test/test_object.rb +357 -70
- data/test/test_parser.rb +27 -0
- data/test/test_parser_saj.rb +245 -0
- data/test/test_parser_usual.rb +217 -0
- data/test/test_rails.rb +35 -0
- data/test/test_saj.rb +1 -1
- data/test/test_scp.rb +39 -2
- data/test/test_strict.rb +186 -7
- data/test/test_various.rb +160 -774
- data/test/test_wab.rb +307 -0
- data/test/test_writer.rb +90 -2
- data/test/tests.rb +24 -0
- data/test/tests_mimic.rb +14 -0
- data/test/tests_mimic_addition.rb +7 -0
- data/test/zoo.rb +13 -0
- metadata +194 -56
- data/ext/oj/hash.c +0 -163
- data/ext/oj/hash.h +0 -46
- data/ext/oj/hash_test.c +0 -512
- data/test/activesupport_datetime_test.rb +0 -23
- data/test/bug2.rb +0 -10
- data/test/bug3.rb +0 -46
- data/test/bug_fast.rb +0 -32
- data/test/bug_load.rb +0 -24
- data/test/crash.rb +0 -111
- data/test/curl/curl_oj.rb +0 -46
- data/test/curl/get_oj.rb +0 -24
- data/test/curl/just_curl.rb +0 -31
- data/test/curl/just_oj.rb +0 -51
- data/test/example.rb +0 -11
- data/test/io.rb +0 -48
- data/test/isolated/test_mimic_rails_datetime.rb +0 -27
- data/test/mod.rb +0 -16
- data/test/rails.rb +0 -50
- data/test/russian.rb +0 -18
- data/test/struct.rb +0 -29
- data/test/test_serializer.rb +0 -59
- data/test/write_timebars.rb +0 -31
data/ext/oj/saj2.c
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
// Copyright (c) 2021, Peter Ohler, All rights reserved.
|
|
2
|
+
|
|
3
|
+
#include "cache.h"
|
|
4
|
+
#include "oj.h"
|
|
5
|
+
#include "parser.h"
|
|
6
|
+
|
|
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
|
+
static VALUE get_key(ojParser p) {
|
|
19
|
+
Delegate d = (Delegate)p->ctx;
|
|
20
|
+
const char * key = buf_str(&p->key);
|
|
21
|
+
size_t len = buf_len(&p->key);
|
|
22
|
+
volatile VALUE rkey;
|
|
23
|
+
|
|
24
|
+
if (d->cache_keys) {
|
|
25
|
+
rkey = cache_intern(d->str_cache, key, len);
|
|
26
|
+
} else {
|
|
27
|
+
rkey = rb_utf8_str_new(key, len);
|
|
28
|
+
}
|
|
29
|
+
return rkey;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static void push_key(Delegate d, VALUE key) {
|
|
33
|
+
if (d->klen <= (size_t)(d->tail - d->keys)) {
|
|
34
|
+
size_t off = d->tail - d->keys;
|
|
35
|
+
|
|
36
|
+
d->klen += d->klen / 2;
|
|
37
|
+
REALLOC_N(d->keys, VALUE, d->klen);
|
|
38
|
+
d->tail = d->keys + off;
|
|
39
|
+
}
|
|
40
|
+
*d->tail = key;
|
|
41
|
+
d->tail++;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static void noop(ojParser p) {
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static void open_object(ojParser p) {
|
|
48
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_hash_start_id, 1, Qnil);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static void open_object_key(ojParser p) {
|
|
52
|
+
Delegate d = (Delegate)p->ctx;
|
|
53
|
+
volatile VALUE key = get_key(p);
|
|
54
|
+
|
|
55
|
+
push_key(d, key);
|
|
56
|
+
rb_funcall(d->handler, oj_hash_start_id, 1, key);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static void open_array(ojParser p) {
|
|
60
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_array_start_id, 1, Qnil);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static void open_array_key(ojParser p) {
|
|
64
|
+
Delegate d = (Delegate)p->ctx;
|
|
65
|
+
volatile VALUE key = get_key(p);
|
|
66
|
+
|
|
67
|
+
push_key(d, key);
|
|
68
|
+
rb_funcall(d->handler, oj_array_start_id, 1, key);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static void close_object(ojParser p) {
|
|
72
|
+
Delegate d = (Delegate)p->ctx;
|
|
73
|
+
VALUE key = Qnil;
|
|
74
|
+
|
|
75
|
+
if (OBJECT_FUN == p->stack[p->depth]) {
|
|
76
|
+
d->tail--;
|
|
77
|
+
if (d->tail < d->keys) {
|
|
78
|
+
rb_raise(rb_eIndexError, "accessing key stack");
|
|
79
|
+
}
|
|
80
|
+
key = *d->tail;
|
|
81
|
+
}
|
|
82
|
+
rb_funcall(d->handler, oj_hash_end_id, 1, key);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static void close_array(ojParser p) {
|
|
86
|
+
Delegate d = (Delegate)p->ctx;
|
|
87
|
+
VALUE key = Qnil;
|
|
88
|
+
|
|
89
|
+
if (OBJECT_FUN == p->stack[p->depth]) {
|
|
90
|
+
d->tail--;
|
|
91
|
+
if (d->tail < d->keys) {
|
|
92
|
+
rb_raise(rb_eIndexError, "accessing key stack");
|
|
93
|
+
}
|
|
94
|
+
key = *d->tail;
|
|
95
|
+
}
|
|
96
|
+
rb_funcall(d->handler, oj_array_end_id, 1, key);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static void add_null(ojParser p) {
|
|
100
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qnil, Qnil);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static void add_null_key(ojParser p) {
|
|
104
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qnil, get_key(p));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static void add_true(ojParser p) {
|
|
108
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qtrue, Qnil);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static void add_true_key(ojParser p) {
|
|
112
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qtrue, get_key(p));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static void add_false(ojParser p) {
|
|
116
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qfalse, Qnil);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
static void add_false_key(ojParser p) {
|
|
120
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qfalse, get_key(p));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static void add_int(ojParser p) {
|
|
124
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, LONG2NUM(p->num.fixnum), Qnil);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static void add_int_key(ojParser p) {
|
|
128
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, LONG2NUM(p->num.fixnum), get_key(p));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
static void add_float(ojParser p) {
|
|
132
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, rb_float_new(p->num.dub), Qnil);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static void add_float_key(ojParser p) {
|
|
136
|
+
rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, rb_float_new(p->num.dub), get_key(p));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static void add_big(ojParser p) {
|
|
140
|
+
rb_funcall((VALUE)p->ctx,
|
|
141
|
+
oj_add_value_id,
|
|
142
|
+
2,
|
|
143
|
+
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
|
144
|
+
Qnil);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static void add_big_key(ojParser p) {
|
|
148
|
+
rb_funcall((VALUE)p->ctx,
|
|
149
|
+
oj_add_value_id,
|
|
150
|
+
2,
|
|
151
|
+
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
|
152
|
+
get_key(p));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
static void add_str(ojParser p) {
|
|
156
|
+
Delegate d = (Delegate)p->ctx;
|
|
157
|
+
volatile VALUE rstr;
|
|
158
|
+
const char * str = buf_str(&p->buf);
|
|
159
|
+
size_t len = buf_len(&p->buf);
|
|
160
|
+
|
|
161
|
+
if (d->cache_str < len) {
|
|
162
|
+
rstr = cache_intern(d->str_cache, str, len);
|
|
163
|
+
} else {
|
|
164
|
+
rstr = rb_utf8_str_new(str, len);
|
|
165
|
+
}
|
|
166
|
+
rb_funcall(d->handler, oj_add_value_id, 2, rstr, Qnil);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
static void add_str_key(ojParser p) {
|
|
170
|
+
Delegate d = (Delegate)p->ctx;
|
|
171
|
+
volatile VALUE rstr;
|
|
172
|
+
const char * str = buf_str(&p->buf);
|
|
173
|
+
size_t len = buf_len(&p->buf);
|
|
174
|
+
|
|
175
|
+
if (d->cache_str < len) {
|
|
176
|
+
rstr = cache_intern(d->str_cache, str, len);
|
|
177
|
+
} else {
|
|
178
|
+
rstr = rb_utf8_str_new(str, len);
|
|
179
|
+
}
|
|
180
|
+
rb_funcall(d->handler, oj_add_value_id, 2, rstr, get_key(p));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static void reset(ojParser p) {
|
|
184
|
+
Funcs end = p->funcs + 3;
|
|
185
|
+
Funcs f;
|
|
186
|
+
|
|
187
|
+
for (f = p->funcs; f < end; f++) {
|
|
188
|
+
f->add_null = noop;
|
|
189
|
+
f->add_true = noop;
|
|
190
|
+
f->add_false = noop;
|
|
191
|
+
f->add_int = noop;
|
|
192
|
+
f->add_float = noop;
|
|
193
|
+
f->add_big = noop;
|
|
194
|
+
f->add_str = noop;
|
|
195
|
+
f->open_array = noop;
|
|
196
|
+
f->close_array = noop;
|
|
197
|
+
f->open_object = noop;
|
|
198
|
+
f->close_object = noop;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
203
|
+
Delegate d = (Delegate)p->ctx;
|
|
204
|
+
|
|
205
|
+
if (0 == strcmp(key, "handler")) {
|
|
206
|
+
return d->handler;
|
|
207
|
+
}
|
|
208
|
+
if (0 == strcmp(key, "handler=")) {
|
|
209
|
+
d->tail = d->keys;
|
|
210
|
+
d->handler = value;
|
|
211
|
+
reset(p);
|
|
212
|
+
if (rb_respond_to(value, oj_hash_start_id)) {
|
|
213
|
+
p->funcs[TOP_FUN].open_object = open_object;
|
|
214
|
+
p->funcs[ARRAY_FUN].open_object = open_object;
|
|
215
|
+
p->funcs[OBJECT_FUN].open_object = open_object_key;
|
|
216
|
+
}
|
|
217
|
+
if (rb_respond_to(value, oj_array_start_id)) {
|
|
218
|
+
p->funcs[TOP_FUN].open_array = open_array;
|
|
219
|
+
p->funcs[ARRAY_FUN].open_array = open_array;
|
|
220
|
+
p->funcs[OBJECT_FUN].open_array = open_array_key;
|
|
221
|
+
}
|
|
222
|
+
if (rb_respond_to(value, oj_hash_end_id)) {
|
|
223
|
+
p->funcs[TOP_FUN].close_object = close_object;
|
|
224
|
+
p->funcs[ARRAY_FUN].close_object = close_object;
|
|
225
|
+
p->funcs[OBJECT_FUN].close_object = close_object;
|
|
226
|
+
}
|
|
227
|
+
if (rb_respond_to(value, oj_array_end_id)) {
|
|
228
|
+
p->funcs[TOP_FUN].close_array = close_array;
|
|
229
|
+
p->funcs[ARRAY_FUN].close_array = close_array;
|
|
230
|
+
p->funcs[OBJECT_FUN].close_array = close_array;
|
|
231
|
+
}
|
|
232
|
+
if (rb_respond_to(value, oj_add_value_id)) {
|
|
233
|
+
p->funcs[TOP_FUN].add_null = add_null;
|
|
234
|
+
p->funcs[ARRAY_FUN].add_null = add_null;
|
|
235
|
+
p->funcs[OBJECT_FUN].add_null = add_null_key;
|
|
236
|
+
|
|
237
|
+
p->funcs[TOP_FUN].add_true = add_true;
|
|
238
|
+
p->funcs[ARRAY_FUN].add_true = add_true;
|
|
239
|
+
p->funcs[OBJECT_FUN].add_true = add_true_key;
|
|
240
|
+
|
|
241
|
+
p->funcs[TOP_FUN].add_false = add_false;
|
|
242
|
+
p->funcs[ARRAY_FUN].add_false = add_false;
|
|
243
|
+
p->funcs[OBJECT_FUN].add_false = add_false_key;
|
|
244
|
+
|
|
245
|
+
p->funcs[TOP_FUN].add_int = add_int;
|
|
246
|
+
p->funcs[ARRAY_FUN].add_int = add_int;
|
|
247
|
+
p->funcs[OBJECT_FUN].add_int = add_int_key;
|
|
248
|
+
|
|
249
|
+
p->funcs[TOP_FUN].add_float = add_float;
|
|
250
|
+
p->funcs[ARRAY_FUN].add_float = add_float;
|
|
251
|
+
p->funcs[OBJECT_FUN].add_float = add_float_key;
|
|
252
|
+
|
|
253
|
+
p->funcs[TOP_FUN].add_big = add_big;
|
|
254
|
+
p->funcs[ARRAY_FUN].add_big = add_big;
|
|
255
|
+
p->funcs[OBJECT_FUN].add_big = add_big_key;
|
|
256
|
+
|
|
257
|
+
p->funcs[TOP_FUN].add_str = add_str;
|
|
258
|
+
p->funcs[ARRAY_FUN].add_str = add_str;
|
|
259
|
+
p->funcs[OBJECT_FUN].add_str = add_str_key;
|
|
260
|
+
}
|
|
261
|
+
return Qnil;
|
|
262
|
+
}
|
|
263
|
+
if (0 == strcmp(key, "cache_keys")) {
|
|
264
|
+
return d->cache_keys ? Qtrue : Qfalse;
|
|
265
|
+
}
|
|
266
|
+
if (0 == strcmp(key, "cache_keys=")) {
|
|
267
|
+
d->cache_keys = (Qtrue == value);
|
|
268
|
+
|
|
269
|
+
return d->cache_keys ? Qtrue : Qfalse;
|
|
270
|
+
}
|
|
271
|
+
if (0 == strcmp(key, "cache_strings")) {
|
|
272
|
+
return INT2NUM((int)d->cache_str);
|
|
273
|
+
}
|
|
274
|
+
if (0 == strcmp(key, "cache_strings=")) {
|
|
275
|
+
int limit = NUM2INT(value);
|
|
276
|
+
|
|
277
|
+
if (CACHE_MAX_KEY < limit) {
|
|
278
|
+
limit = CACHE_MAX_KEY;
|
|
279
|
+
} else if (limit < 0) {
|
|
280
|
+
limit = 0;
|
|
281
|
+
}
|
|
282
|
+
d->cache_str = limit;
|
|
283
|
+
|
|
284
|
+
return INT2NUM((int)d->cache_str);
|
|
285
|
+
}
|
|
286
|
+
rb_raise(rb_eArgError, "%s is not an option for the SAJ (Simple API for JSON) delegate", key);
|
|
287
|
+
|
|
288
|
+
return Qnil; // Never reached due to the raise but required by the compiler.
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
static VALUE result(ojParser p) {
|
|
292
|
+
return Qnil;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
static void start(ojParser p) {
|
|
296
|
+
Delegate d = (Delegate)p->ctx;
|
|
297
|
+
|
|
298
|
+
d->tail = d->keys;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
static void dfree(ojParser p) {
|
|
302
|
+
Delegate d = (Delegate)p->ctx;
|
|
303
|
+
|
|
304
|
+
if (NULL != d->keys) {
|
|
305
|
+
xfree(d->keys);
|
|
306
|
+
}
|
|
307
|
+
cache_free(d->str_cache);
|
|
308
|
+
xfree(p->ctx);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
static void mark(ojParser p) {
|
|
312
|
+
if (NULL == p->ctx) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
Delegate d = (Delegate)p->ctx;
|
|
316
|
+
VALUE *kp;
|
|
317
|
+
|
|
318
|
+
cache_mark(d->str_cache);
|
|
319
|
+
if (Qnil != d->handler) {
|
|
320
|
+
rb_gc_mark(d->handler);
|
|
321
|
+
}
|
|
322
|
+
if (!d->cache_keys) {
|
|
323
|
+
for (kp = d->keys; kp < d->tail; kp++) {
|
|
324
|
+
rb_gc_mark(*kp);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
static VALUE form_str(const char *str, size_t len) {
|
|
330
|
+
return rb_str_freeze(rb_utf8_str_new(str, len));
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
void oj_set_parser_saj(ojParser p) {
|
|
334
|
+
Delegate d = ALLOC(struct _delegate);
|
|
335
|
+
|
|
336
|
+
d->klen = 256;
|
|
337
|
+
d->keys = ALLOC_N(VALUE, d->klen);
|
|
338
|
+
d->tail = d->keys;
|
|
339
|
+
d->str_cache = cache_create(0, form_str, true, false);
|
|
340
|
+
|
|
341
|
+
p->ctx = (void *)d;
|
|
342
|
+
reset(p);
|
|
343
|
+
p->option = option;
|
|
344
|
+
p->result = result;
|
|
345
|
+
p->free = dfree;
|
|
346
|
+
p->mark = mark;
|
|
347
|
+
p->start = start;
|
|
348
|
+
}
|
data/ext/oj/scp.c
CHANGED
|
@@ -1,67 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
*
|
|
5
|
-
* Redistribution and use in source and binary forms, with or without
|
|
6
|
-
* modification, are permitted provided that the following conditions are met:
|
|
7
|
-
*
|
|
8
|
-
* - Redistributions of source code must retain the above copyright notice, this
|
|
9
|
-
* list of conditions and the following disclaimer.
|
|
10
|
-
*
|
|
11
|
-
* - Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
-
* this list of conditions and the following disclaimer in the documentation
|
|
13
|
-
* and/or other materials provided with the distribution.
|
|
14
|
-
*
|
|
15
|
-
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
|
16
|
-
* used to endorse or promote products derived from this software without
|
|
17
|
-
* specific prior written permission.
|
|
18
|
-
*
|
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
29
|
-
*/
|
|
1
|
+
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
|
30
3
|
|
|
31
|
-
#include <
|
|
4
|
+
#include <math.h>
|
|
32
5
|
#include <stdio.h>
|
|
6
|
+
#include <stdlib.h>
|
|
33
7
|
#include <string.h>
|
|
34
|
-
#include <math.h>
|
|
35
8
|
#include <sys/types.h>
|
|
36
9
|
#include <unistd.h>
|
|
37
10
|
|
|
11
|
+
#include "encode.h"
|
|
12
|
+
#include "intern.h"
|
|
38
13
|
#include "oj.h"
|
|
39
14
|
#include "parse.h"
|
|
40
|
-
#include "encode.h"
|
|
41
15
|
|
|
42
|
-
static VALUE
|
|
43
|
-
noop_start(ParseInfo pi) {
|
|
16
|
+
static VALUE noop_start(ParseInfo pi) {
|
|
44
17
|
return Qnil;
|
|
45
18
|
}
|
|
46
19
|
|
|
47
|
-
static void
|
|
48
|
-
noop_end(ParseInfo pi) {
|
|
20
|
+
static void noop_end(ParseInfo pi) {
|
|
49
21
|
}
|
|
50
22
|
|
|
51
|
-
static void
|
|
52
|
-
noop_add_value(ParseInfo pi, VALUE val) {
|
|
23
|
+
static void noop_add_value(ParseInfo pi, VALUE val) {
|
|
53
24
|
}
|
|
54
25
|
|
|
55
|
-
static void
|
|
56
|
-
noop_add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
|
26
|
+
static void noop_add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
|
57
27
|
}
|
|
58
28
|
|
|
59
|
-
static void
|
|
60
|
-
noop_add_num(ParseInfo pi, NumInfo ni) {
|
|
29
|
+
static void noop_add_num(ParseInfo pi, NumInfo ni) {
|
|
61
30
|
}
|
|
62
31
|
|
|
63
|
-
static VALUE
|
|
64
|
-
noop_hash_key(struct _ParseInfo *pi, const char *key, size_t klen) {
|
|
32
|
+
static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
|
65
33
|
return Qundef;
|
|
66
34
|
}
|
|
67
35
|
|
|
@@ -69,178 +37,163 @@ static void
|
|
|
69
37
|
noop_hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
|
70
38
|
}
|
|
71
39
|
|
|
72
|
-
static void
|
|
73
|
-
noop_hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
|
40
|
+
static void noop_hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
|
74
41
|
}
|
|
75
42
|
|
|
76
|
-
static void
|
|
77
|
-
noop_hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
|
43
|
+
static void noop_hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
|
78
44
|
}
|
|
79
45
|
|
|
80
|
-
static void
|
|
81
|
-
noop_array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
|
46
|
+
static void noop_array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
|
82
47
|
}
|
|
83
48
|
|
|
84
|
-
static void
|
|
85
|
-
noop_array_append_num(ParseInfo pi, NumInfo ni) {
|
|
49
|
+
static void noop_array_append_num(ParseInfo pi, NumInfo ni) {
|
|
86
50
|
}
|
|
87
51
|
|
|
88
|
-
static void
|
|
89
|
-
noop_array_append_value(ParseInfo pi, VALUE value) {
|
|
52
|
+
static void noop_array_append_value(ParseInfo pi, VALUE value) {
|
|
90
53
|
}
|
|
91
54
|
|
|
92
|
-
static void
|
|
93
|
-
add_value(ParseInfo pi, VALUE val) {
|
|
55
|
+
static void add_value(ParseInfo pi, VALUE val) {
|
|
94
56
|
rb_funcall(pi->handler, oj_add_value_id, 1, val);
|
|
95
57
|
}
|
|
96
58
|
|
|
97
|
-
static void
|
|
98
|
-
|
|
99
|
-
volatile VALUE rstr = rb_str_new(str, len);
|
|
59
|
+
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
|
60
|
+
volatile VALUE rstr = rb_str_new(str, len);
|
|
100
61
|
|
|
101
62
|
rstr = oj_encode(rstr);
|
|
102
63
|
rb_funcall(pi->handler, oj_add_value_id, 1, rstr);
|
|
103
64
|
}
|
|
104
65
|
|
|
105
|
-
static void
|
|
106
|
-
add_num(ParseInfo pi, NumInfo ni) {
|
|
66
|
+
static void add_num(ParseInfo pi, NumInfo ni) {
|
|
107
67
|
rb_funcall(pi->handler, oj_add_value_id, 1, oj_num_as_value(ni));
|
|
108
68
|
}
|
|
109
69
|
|
|
110
|
-
static VALUE
|
|
111
|
-
start_hash(ParseInfo pi) {
|
|
70
|
+
static VALUE start_hash(ParseInfo pi) {
|
|
112
71
|
return rb_funcall(pi->handler, oj_hash_start_id, 0);
|
|
113
72
|
}
|
|
114
73
|
|
|
115
|
-
static void
|
|
116
|
-
end_hash(ParseInfo pi) {
|
|
74
|
+
static void end_hash(ParseInfo pi) {
|
|
117
75
|
rb_funcall(pi->handler, oj_hash_end_id, 0);
|
|
118
76
|
}
|
|
119
77
|
|
|
120
|
-
static VALUE
|
|
121
|
-
start_array(ParseInfo pi) {
|
|
78
|
+
static VALUE start_array(ParseInfo pi) {
|
|
122
79
|
return rb_funcall(pi->handler, oj_array_start_id, 0);
|
|
123
80
|
}
|
|
124
81
|
|
|
125
|
-
static void
|
|
126
|
-
end_array(ParseInfo pi) {
|
|
82
|
+
static void end_array(ParseInfo pi) {
|
|
127
83
|
rb_funcall(pi->handler, oj_array_end_id, 0);
|
|
128
84
|
}
|
|
129
85
|
|
|
130
|
-
static VALUE
|
|
131
|
-
calc_hash_key(ParseInfo pi, Val kval) {
|
|
132
|
-
volatile VALUE rkey = kval->key_val;
|
|
133
|
-
|
|
134
|
-
if (Qundef == rkey) {
|
|
135
|
-
rkey = rb_str_new(kval->key, kval->klen);
|
|
136
|
-
rkey = oj_encode(rkey);
|
|
137
|
-
if (Yes == pi->options.sym_key) {
|
|
138
|
-
rkey = rb_str_intern(rkey);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return rkey;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
static VALUE
|
|
145
|
-
hash_key(struct _ParseInfo *pi, const char *key, size_t klen) {
|
|
86
|
+
static VALUE hash_key(ParseInfo pi, const char *key, size_t klen) {
|
|
146
87
|
return rb_funcall(pi->handler, oj_hash_key_id, 1, rb_str_new(key, klen));
|
|
147
88
|
}
|
|
148
89
|
|
|
149
|
-
static void
|
|
150
|
-
|
|
151
|
-
volatile VALUE rstr = rb_str_new(str, len);
|
|
90
|
+
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
|
91
|
+
volatile VALUE rstr = rb_str_new(str, len);
|
|
152
92
|
|
|
153
93
|
rstr = oj_encode(rstr);
|
|
154
|
-
rb_funcall(pi->handler,
|
|
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);
|
|
155
100
|
}
|
|
156
101
|
|
|
157
|
-
static void
|
|
158
|
-
|
|
159
|
-
|
|
102
|
+
static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
|
103
|
+
rb_funcall(pi->handler,
|
|
104
|
+
oj_hash_set_id,
|
|
105
|
+
3,
|
|
106
|
+
stack_peek(&pi->stack)->val,
|
|
107
|
+
oj_calc_hash_key(pi, kval),
|
|
108
|
+
oj_num_as_value(ni));
|
|
160
109
|
}
|
|
161
110
|
|
|
162
|
-
static void
|
|
163
|
-
|
|
164
|
-
|
|
111
|
+
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);
|
|
165
118
|
}
|
|
166
119
|
|
|
167
|
-
static void
|
|
168
|
-
|
|
169
|
-
volatile VALUE rstr = rb_str_new(str, len);
|
|
120
|
+
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
|
121
|
+
volatile VALUE rstr = rb_str_new(str, len);
|
|
170
122
|
|
|
171
123
|
rstr = oj_encode(rstr);
|
|
172
124
|
rb_funcall(pi->handler, oj_array_append_id, 2, stack_peek(&pi->stack)->val, rstr);
|
|
173
125
|
}
|
|
174
126
|
|
|
175
|
-
static void
|
|
176
|
-
array_append_num(ParseInfo pi, NumInfo ni) {
|
|
127
|
+
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
|
177
128
|
rb_funcall(pi->handler, oj_array_append_id, 2, stack_peek(&pi->stack)->val, oj_num_as_value(ni));
|
|
178
129
|
}
|
|
179
130
|
|
|
180
|
-
static void
|
|
181
|
-
array_append_value(ParseInfo pi, VALUE value) {
|
|
131
|
+
static void array_append_value(ParseInfo pi, VALUE value) {
|
|
182
132
|
rb_funcall(pi->handler, oj_array_append_id, 2, stack_peek(&pi->stack)->val, value);
|
|
183
133
|
}
|
|
184
134
|
|
|
185
135
|
VALUE
|
|
186
136
|
oj_sc_parse(int argc, VALUE *argv, VALUE self) {
|
|
187
|
-
struct
|
|
188
|
-
VALUE
|
|
137
|
+
struct _parseInfo pi;
|
|
138
|
+
VALUE input = argv[1];
|
|
189
139
|
|
|
140
|
+
parse_info_init(&pi);
|
|
190
141
|
pi.err_class = Qnil;
|
|
191
|
-
pi.
|
|
142
|
+
pi.max_depth = 0;
|
|
143
|
+
pi.options = oj_default_options;
|
|
192
144
|
if (3 == argc) {
|
|
193
|
-
|
|
145
|
+
oj_parse_options(argv[2], &pi.options);
|
|
194
146
|
}
|
|
195
147
|
if (rb_block_given_p()) {
|
|
196
|
-
|
|
148
|
+
pi.proc = Qnil;
|
|
197
149
|
} else {
|
|
198
|
-
|
|
150
|
+
pi.proc = Qundef;
|
|
199
151
|
}
|
|
200
152
|
pi.handler = *argv;
|
|
201
153
|
|
|
202
|
-
pi.start_hash
|
|
203
|
-
pi.end_hash
|
|
204
|
-
pi.hash_key
|
|
154
|
+
pi.start_hash = rb_respond_to(pi.handler, oj_hash_start_id) ? start_hash : noop_start;
|
|
155
|
+
pi.end_hash = rb_respond_to(pi.handler, oj_hash_end_id) ? end_hash : noop_end;
|
|
156
|
+
pi.hash_key = rb_respond_to(pi.handler, oj_hash_key_id) ? hash_key : noop_hash_key;
|
|
205
157
|
pi.start_array = rb_respond_to(pi.handler, oj_array_start_id) ? start_array : noop_start;
|
|
206
|
-
pi.end_array
|
|
158
|
+
pi.end_array = rb_respond_to(pi.handler, oj_array_end_id) ? end_array : noop_end;
|
|
207
159
|
if (rb_respond_to(pi.handler, oj_hash_set_id)) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
160
|
+
pi.hash_set_value = hash_set_value;
|
|
161
|
+
pi.hash_set_cstr = hash_set_cstr;
|
|
162
|
+
pi.hash_set_num = hash_set_num;
|
|
163
|
+
pi.expect_value = 1;
|
|
212
164
|
} else {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
165
|
+
pi.hash_set_value = noop_hash_set_value;
|
|
166
|
+
pi.hash_set_cstr = noop_hash_set_cstr;
|
|
167
|
+
pi.hash_set_num = noop_hash_set_num;
|
|
168
|
+
pi.expect_value = 0;
|
|
217
169
|
}
|
|
218
170
|
if (rb_respond_to(pi.handler, oj_array_append_id)) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
171
|
+
pi.array_append_value = array_append_value;
|
|
172
|
+
pi.array_append_cstr = array_append_cstr;
|
|
173
|
+
pi.array_append_num = array_append_num;
|
|
174
|
+
pi.expect_value = 1;
|
|
223
175
|
} else {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
176
|
+
pi.array_append_value = noop_array_append_value;
|
|
177
|
+
pi.array_append_cstr = noop_array_append_cstr;
|
|
178
|
+
pi.array_append_num = noop_array_append_num;
|
|
179
|
+
pi.expect_value = 0;
|
|
228
180
|
}
|
|
229
181
|
if (rb_respond_to(pi.handler, oj_add_value_id)) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
182
|
+
pi.add_cstr = add_cstr;
|
|
183
|
+
pi.add_num = add_num;
|
|
184
|
+
pi.add_value = add_value;
|
|
185
|
+
pi.expect_value = 1;
|
|
234
186
|
} else {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
187
|
+
pi.add_cstr = noop_add_cstr;
|
|
188
|
+
pi.add_num = noop_add_num;
|
|
189
|
+
pi.add_value = noop_add_value;
|
|
190
|
+
pi.expect_value = 0;
|
|
239
191
|
}
|
|
192
|
+
pi.has_callbacks = true;
|
|
240
193
|
|
|
241
194
|
if (T_STRING == rb_type(input)) {
|
|
242
|
-
|
|
195
|
+
return oj_pi_parse(argc - 1, argv + 1, &pi, 0, 0, 1);
|
|
243
196
|
} else {
|
|
244
|
-
|
|
197
|
+
return oj_pi_sparse(argc - 1, argv + 1, &pi, 0);
|
|
245
198
|
}
|
|
246
199
|
}
|