oj 3.10.6 → 3.12.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/README.md +6 -1
- data/ext/oj/buf.h +36 -68
- data/ext/oj/cache8.c +59 -62
- data/ext/oj/cache8.h +9 -36
- data/ext/oj/circarray.c +36 -42
- data/ext/oj/circarray.h +12 -13
- data/ext/oj/code.c +172 -179
- data/ext/oj/code.h +22 -24
- data/ext/oj/compat.c +168 -181
- data/ext/oj/custom.c +800 -864
- data/ext/oj/dump.c +774 -776
- data/ext/oj/dump.h +50 -55
- data/ext/oj/dump_compat.c +2 -4
- data/ext/oj/dump_leaf.c +118 -162
- data/ext/oj/dump_object.c +610 -632
- data/ext/oj/dump_strict.c +319 -331
- data/ext/oj/encode.h +4 -33
- data/ext/oj/err.c +40 -29
- data/ext/oj/err.h +25 -44
- data/ext/oj/extconf.rb +2 -1
- data/ext/oj/fast.c +1054 -1081
- data/ext/oj/hash.c +78 -95
- data/ext/oj/hash.h +10 -35
- data/ext/oj/hash_test.c +451 -472
- data/ext/oj/mimic_json.c +415 -402
- data/ext/oj/object.c +588 -532
- data/ext/oj/odd.c +124 -132
- data/ext/oj/odd.h +28 -29
- data/ext/oj/oj.c +1178 -905
- data/ext/oj/oj.h +289 -298
- data/ext/oj/parse.c +946 -870
- data/ext/oj/parse.h +81 -79
- data/ext/oj/rails.c +837 -842
- data/ext/oj/rails.h +8 -11
- data/ext/oj/reader.c +139 -147
- data/ext/oj/reader.h +68 -84
- data/ext/oj/resolve.c +44 -47
- data/ext/oj/resolve.h +4 -6
- data/ext/oj/rxclass.c +69 -73
- data/ext/oj/rxclass.h +13 -14
- data/ext/oj/saj.c +453 -484
- data/ext/oj/scp.c +88 -113
- data/ext/oj/sparse.c +783 -714
- data/ext/oj/stream_writer.c +123 -157
- data/ext/oj/strict.c +133 -106
- data/ext/oj/string_writer.c +199 -247
- data/ext/oj/trace.c +34 -41
- data/ext/oj/trace.h +15 -15
- data/ext/oj/util.c +104 -104
- data/ext/oj/util.h +4 -3
- data/ext/oj/val_stack.c +48 -76
- data/ext/oj/val_stack.h +80 -115
- data/ext/oj/wab.c +317 -328
- data/lib/oj.rb +0 -8
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +5 -4
- data/lib/oj/mimic.rb +45 -13
- data/lib/oj/version.rb +1 -1
- data/pages/Modes.md +1 -0
- data/pages/Options.md +23 -11
- data/test/activerecord/result_test.rb +7 -2
- data/test/foo.rb +8 -40
- data/test/helper.rb +10 -0
- data/test/json_gem/json_common_interface_test.rb +8 -3
- data/test/json_gem/json_generator_test.rb +15 -3
- data/test/json_gem/test_helper.rb +8 -0
- data/test/perf.rb +1 -1
- data/test/perf_scp.rb +11 -10
- data/test/perf_strict.rb +17 -23
- data/test/prec.rb +23 -0
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +16 -3
- data/test/test_custom.rb +11 -0
- data/test/test_fast.rb +32 -2
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +10 -0
- data/test/test_rails.rb +9 -0
- data/test/test_scp.rb +1 -1
- data/test/test_various.rb +4 -2
- metadata +89 -85
data/ext/oj/mimic_json.c
CHANGED
@@ -1,27 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
5
3
|
|
6
|
-
#include "oj.h"
|
7
|
-
#include "encode.h"
|
8
4
|
#include "dump.h"
|
5
|
+
#include "encode.h"
|
6
|
+
#include "oj.h"
|
9
7
|
#include "parse.h"
|
10
8
|
|
11
|
-
static VALUE
|
9
|
+
static VALUE symbolize_names_sym = Qundef;
|
12
10
|
|
13
|
-
extern const char
|
11
|
+
extern const char oj_json_class[];
|
14
12
|
|
15
|
-
VALUE
|
16
|
-
VALUE
|
17
|
-
VALUE
|
18
|
-
VALUE
|
19
|
-
VALUE
|
20
|
-
VALUE
|
21
|
-
VALUE
|
22
|
-
VALUE
|
13
|
+
VALUE oj_array_nl_sym;
|
14
|
+
VALUE oj_ascii_only_sym;
|
15
|
+
VALUE oj_json_generator_error_class;
|
16
|
+
VALUE oj_json_parser_error_class;
|
17
|
+
VALUE oj_max_nesting_sym;
|
18
|
+
VALUE oj_object_nl_sym;
|
19
|
+
VALUE oj_space_before_sym;
|
20
|
+
VALUE oj_space_sym;
|
23
21
|
|
24
|
-
static VALUE
|
22
|
+
static VALUE state_class = Qundef;
|
25
23
|
|
26
24
|
// mimic JSON documentation
|
27
25
|
|
@@ -56,14 +54,14 @@ static VALUE state_class;
|
|
56
54
|
|
57
55
|
VALUE
|
58
56
|
oj_get_json_err_class(const char *err_classname) {
|
59
|
-
volatile VALUE
|
60
|
-
volatile VALUE
|
61
|
-
volatile VALUE
|
57
|
+
volatile VALUE json_module;
|
58
|
+
volatile VALUE clas;
|
59
|
+
volatile VALUE json_error_class;
|
62
60
|
|
63
61
|
if (rb_const_defined_at(rb_cObject, rb_intern("JSON"))) {
|
64
|
-
|
62
|
+
json_module = rb_const_get_at(rb_cObject, rb_intern("JSON"));
|
65
63
|
} else {
|
66
|
-
|
64
|
+
json_module = rb_define_module("JSON");
|
67
65
|
}
|
68
66
|
if (rb_const_defined_at(json_module, rb_intern("JSONError"))) {
|
69
67
|
json_error_class = rb_const_get(json_module, rb_intern("JSONError"));
|
@@ -71,113 +69,121 @@ oj_get_json_err_class(const char *err_classname) {
|
|
71
69
|
json_error_class = rb_define_class_under(json_module, "JSONError", rb_eStandardError);
|
72
70
|
}
|
73
71
|
if (0 == strcmp(err_classname, "JSONError")) {
|
74
|
-
|
72
|
+
clas = json_error_class;
|
75
73
|
} else {
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
74
|
+
if (rb_const_defined_at(json_module, rb_intern(err_classname))) {
|
75
|
+
clas = rb_const_get(json_module, rb_intern(err_classname));
|
76
|
+
} else {
|
77
|
+
clas = rb_define_class_under(json_module, err_classname, json_error_class);
|
78
|
+
}
|
81
79
|
}
|
82
80
|
return clas;
|
83
81
|
}
|
84
82
|
|
85
|
-
void
|
86
|
-
|
87
|
-
|
88
|
-
size_t len;
|
83
|
+
void oj_parse_mimic_dump_options(VALUE ropts, Options copts) {
|
84
|
+
VALUE v;
|
85
|
+
size_t len;
|
89
86
|
|
90
87
|
if (T_HASH != rb_type(ropts)) {
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
88
|
+
if (rb_respond_to(ropts, oj_to_hash_id)) {
|
89
|
+
ropts = rb_funcall(ropts, oj_to_hash_id, 0);
|
90
|
+
} else if (rb_respond_to(ropts, oj_to_h_id)) {
|
91
|
+
ropts = rb_funcall(ropts, oj_to_h_id, 0);
|
92
|
+
} else if (Qnil == ropts) {
|
93
|
+
return;
|
94
|
+
} else {
|
95
|
+
rb_raise(rb_eArgError, "options must be a hash.");
|
96
|
+
}
|
100
97
|
}
|
101
98
|
v = rb_hash_lookup(ropts, oj_max_nesting_sym);
|
102
99
|
if (Qtrue == v) {
|
103
|
-
|
100
|
+
copts->dump_opts.max_depth = 100;
|
104
101
|
} else if (Qfalse == v || Qnil == v) {
|
105
|
-
|
102
|
+
copts->dump_opts.max_depth = MAX_DEPTH;
|
106
103
|
} else if (T_FIXNUM == rb_type(v)) {
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
104
|
+
copts->dump_opts.max_depth = NUM2INT(v);
|
105
|
+
if (0 >= copts->dump_opts.max_depth) {
|
106
|
+
copts->dump_opts.max_depth = MAX_DEPTH;
|
107
|
+
}
|
111
108
|
}
|
112
109
|
if (Qnil != (v = rb_hash_lookup(ropts, oj_allow_nan_sym))) {
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
110
|
+
if (Qtrue == v) {
|
111
|
+
copts->dump_opts.nan_dump = WordNan;
|
112
|
+
} else {
|
113
|
+
copts->dump_opts.nan_dump = RaiseNan;
|
114
|
+
}
|
118
115
|
}
|
119
116
|
if (Qnil != (v = rb_hash_lookup(ropts, oj_indent_sym))) {
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
117
|
+
rb_check_type(v, T_STRING);
|
118
|
+
if (sizeof(copts->dump_opts.indent_str) <= (len = RSTRING_LEN(v))) {
|
119
|
+
rb_raise(rb_eArgError,
|
120
|
+
"indent string is limited to %lu characters.",
|
121
|
+
(unsigned long)sizeof(copts->dump_opts.indent_str));
|
122
|
+
}
|
123
|
+
strcpy(copts->dump_opts.indent_str, StringValuePtr(v));
|
124
|
+
copts->dump_opts.indent_size = (uint8_t)len;
|
125
|
+
copts->dump_opts.use = true;
|
127
126
|
}
|
128
127
|
if (Qnil != (v = rb_hash_lookup(ropts, oj_space_sym))) {
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
128
|
+
rb_check_type(v, T_STRING);
|
129
|
+
if (sizeof(copts->dump_opts.after_sep) <= (len = RSTRING_LEN(v))) {
|
130
|
+
rb_raise(rb_eArgError,
|
131
|
+
"space string is limited to %lu characters.",
|
132
|
+
(unsigned long)sizeof(copts->dump_opts.after_sep));
|
133
|
+
}
|
134
|
+
strcpy(copts->dump_opts.after_sep, StringValuePtr(v));
|
135
|
+
copts->dump_opts.after_size = (uint8_t)len;
|
136
|
+
copts->dump_opts.use = true;
|
136
137
|
}
|
137
138
|
if (Qnil != (v = rb_hash_lookup(ropts, oj_space_before_sym))) {
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
139
|
+
rb_check_type(v, T_STRING);
|
140
|
+
if (sizeof(copts->dump_opts.before_sep) <= (len = RSTRING_LEN(v))) {
|
141
|
+
rb_raise(rb_eArgError,
|
142
|
+
"space_before string is limited to %lu characters.",
|
143
|
+
(unsigned long)sizeof(copts->dump_opts.before_sep));
|
144
|
+
}
|
145
|
+
strcpy(copts->dump_opts.before_sep, StringValuePtr(v));
|
146
|
+
copts->dump_opts.before_size = (uint8_t)len;
|
147
|
+
copts->dump_opts.use = true;
|
145
148
|
}
|
146
149
|
if (Qnil != (v = rb_hash_lookup(ropts, oj_object_nl_sym))) {
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
150
|
+
rb_check_type(v, T_STRING);
|
151
|
+
if (sizeof(copts->dump_opts.hash_nl) <= (len = RSTRING_LEN(v))) {
|
152
|
+
rb_raise(rb_eArgError,
|
153
|
+
"object_nl string is limited to %lu characters.",
|
154
|
+
(unsigned long)sizeof(copts->dump_opts.hash_nl));
|
155
|
+
}
|
156
|
+
strcpy(copts->dump_opts.hash_nl, StringValuePtr(v));
|
157
|
+
copts->dump_opts.hash_size = (uint8_t)len;
|
158
|
+
copts->dump_opts.use = true;
|
154
159
|
}
|
155
160
|
if (Qnil != (v = rb_hash_lookup(ropts, oj_array_nl_sym))) {
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
161
|
+
rb_check_type(v, T_STRING);
|
162
|
+
if (sizeof(copts->dump_opts.array_nl) <= (len = RSTRING_LEN(v))) {
|
163
|
+
rb_raise(rb_eArgError,
|
164
|
+
"array_nl string is limited to %lu characters.",
|
165
|
+
(unsigned long)sizeof(copts->dump_opts.array_nl));
|
166
|
+
}
|
167
|
+
strcpy(copts->dump_opts.array_nl, StringValuePtr(v));
|
168
|
+
copts->dump_opts.array_size = (uint8_t)len;
|
169
|
+
copts->dump_opts.use = true;
|
163
170
|
}
|
164
171
|
if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
|
165
|
-
|
172
|
+
copts->quirks_mode = (Qtrue == v) ? Yes : No;
|
166
173
|
}
|
167
174
|
if (Qnil != (v = rb_hash_lookup(ropts, oj_ascii_only_sym))) {
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
175
|
+
// generate seems to assume anything except nil and false are true.
|
176
|
+
if (Qfalse == v) {
|
177
|
+
copts->escape_mode = JXEsc;
|
178
|
+
} else {
|
179
|
+
copts->escape_mode = ASCIIEsc;
|
180
|
+
}
|
174
181
|
}
|
175
182
|
}
|
176
183
|
|
177
|
-
static int
|
178
|
-
mimic_limit_arg(VALUE a) {
|
184
|
+
static int mimic_limit_arg(VALUE a) {
|
179
185
|
if (Qnil == a || T_FIXNUM != rb_type(a)) {
|
180
|
-
|
186
|
+
return -1;
|
181
187
|
}
|
182
188
|
return NUM2INT(a);
|
183
189
|
}
|
@@ -193,44 +199,43 @@ mimic_limit_arg(VALUE a) {
|
|
193
199
|
*
|
194
200
|
* Returns [_String_] a JSON string.
|
195
201
|
*/
|
196
|
-
static VALUE
|
197
|
-
|
198
|
-
|
199
|
-
struct
|
200
|
-
|
201
|
-
VALUE
|
202
|
-
VALUE active_hack[1];
|
202
|
+
static VALUE mimic_dump(int argc, VALUE *argv, VALUE self) {
|
203
|
+
char buf[4096];
|
204
|
+
struct _out out;
|
205
|
+
struct _options copts = oj_default_options;
|
206
|
+
VALUE rstr;
|
207
|
+
VALUE active_hack[1];
|
203
208
|
|
204
209
|
copts.str_rx.head = NULL;
|
205
210
|
copts.str_rx.tail = NULL;
|
206
|
-
out.buf
|
207
|
-
out.end
|
208
|
-
out.allocated
|
209
|
-
out.caller
|
211
|
+
out.buf = buf;
|
212
|
+
out.end = buf + sizeof(buf) - 10;
|
213
|
+
out.allocated = false;
|
214
|
+
out.caller = CALLER_DUMP;
|
210
215
|
copts.escape_mode = JXEsc;
|
211
|
-
copts.mode
|
216
|
+
copts.mode = CompatMode;
|
212
217
|
|
213
218
|
/* seems like this is not correct
|
214
219
|
if (No == copts.nilnil && Qnil == *argv) {
|
215
|
-
|
220
|
+
rb_raise(rb_eTypeError, "nil not allowed.");
|
216
221
|
}
|
217
222
|
*/
|
218
|
-
copts.dump_opts.max_depth = MAX_DEPTH;
|
219
|
-
out.omit_nil
|
223
|
+
copts.dump_opts.max_depth = MAX_DEPTH; // when using dump there is no limit
|
224
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
220
225
|
|
221
226
|
if (2 <= argc) {
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
227
|
+
int limit;
|
228
|
+
|
229
|
+
// The json gem take a more liberal approach to optional
|
230
|
+
// arguments. Expected are (obj, anIO=nil, limit=nil) yet the io
|
231
|
+
// argument can be left off completely and the 2nd argument is then
|
232
|
+
// the limit.
|
233
|
+
if (0 <= (limit = mimic_limit_arg(argv[1]))) {
|
234
|
+
copts.dump_opts.max_depth = limit;
|
235
|
+
}
|
236
|
+
if (3 <= argc && 0 <= (limit = mimic_limit_arg(argv[2]))) {
|
237
|
+
copts.dump_opts.max_depth = limit;
|
238
|
+
}
|
234
239
|
}
|
235
240
|
// ActiveSupport in active_support/core_ext/object/json.rb check the
|
236
241
|
// optional argument type to to_json and it the argument is a
|
@@ -242,53 +247,48 @@ mimic_dump(int argc, VALUE *argv, VALUE self) {
|
|
242
247
|
oj_dump_obj_to_json_using_params(*argv, &copts, &out, 1, active_hack);
|
243
248
|
|
244
249
|
if (0 == out.buf) {
|
245
|
-
|
250
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
246
251
|
}
|
247
252
|
rstr = rb_str_new2(out.buf);
|
248
253
|
rstr = oj_encode(rstr);
|
249
254
|
if (2 <= argc && Qnil != argv[1] && rb_respond_to(argv[1], oj_write_id)) {
|
250
|
-
|
251
|
-
|
255
|
+
VALUE io = argv[1];
|
256
|
+
VALUE args[1];
|
252
257
|
|
253
|
-
|
254
|
-
|
255
|
-
|
258
|
+
*args = rstr;
|
259
|
+
rb_funcall2(io, oj_write_id, 1, args);
|
260
|
+
rstr = io;
|
256
261
|
}
|
257
262
|
if (out.allocated) {
|
258
|
-
|
263
|
+
xfree(out.buf);
|
259
264
|
}
|
260
265
|
return rstr;
|
261
266
|
}
|
262
267
|
|
263
268
|
// This is the signature for the hash_foreach callback also.
|
264
|
-
static int
|
265
|
-
mimic_walk(VALUE key, VALUE obj, VALUE proc) {
|
269
|
+
static int mimic_walk(VALUE key, VALUE obj, VALUE proc) {
|
266
270
|
switch (rb_type(obj)) {
|
267
|
-
case T_HASH:
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
break;
|
279
|
-
}
|
280
|
-
default:
|
281
|
-
break;
|
271
|
+
case T_HASH: rb_hash_foreach(obj, mimic_walk, proc); break;
|
272
|
+
case T_ARRAY: {
|
273
|
+
size_t cnt = RARRAY_LEN(obj);
|
274
|
+
size_t i;
|
275
|
+
|
276
|
+
for (i = 0; i < cnt; i++) {
|
277
|
+
mimic_walk(Qnil, rb_ary_entry(obj, i), proc);
|
278
|
+
}
|
279
|
+
break;
|
280
|
+
}
|
281
|
+
default: break;
|
282
282
|
}
|
283
283
|
if (Qnil == proc) {
|
284
|
-
|
285
|
-
|
286
|
-
|
284
|
+
if (rb_block_given_p()) {
|
285
|
+
rb_yield(obj);
|
286
|
+
}
|
287
287
|
} else {
|
288
|
-
|
288
|
+
VALUE args[1];
|
289
289
|
|
290
|
-
|
291
|
-
|
290
|
+
*args = obj;
|
291
|
+
rb_proc_call_with_block(proc, 1, args, Qnil);
|
292
292
|
}
|
293
293
|
return ST_CONTINUE;
|
294
294
|
}
|
@@ -318,20 +318,19 @@ mimic_walk(VALUE key, VALUE obj, VALUE proc) {
|
|
318
318
|
*
|
319
319
|
* Returns [_Object_] the decode Object.
|
320
320
|
*/
|
321
|
-
static VALUE
|
322
|
-
|
323
|
-
VALUE
|
324
|
-
VALUE p = Qnil;
|
321
|
+
static VALUE mimic_load(int argc, VALUE *argv, VALUE self) {
|
322
|
+
VALUE obj;
|
323
|
+
VALUE p = Qnil;
|
325
324
|
|
326
325
|
obj = oj_compat_load(argc, argv, self);
|
327
326
|
if (2 <= argc) {
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
327
|
+
if (rb_cProc == rb_obj_class(argv[1])) {
|
328
|
+
p = argv[1];
|
329
|
+
} else if (3 <= argc) {
|
330
|
+
if (rb_cProc == rb_obj_class(argv[2])) {
|
331
|
+
p = argv[2];
|
332
|
+
}
|
333
|
+
}
|
335
334
|
}
|
336
335
|
mimic_walk(Qnil, obj, p);
|
337
336
|
|
@@ -349,54 +348,60 @@ mimic_load(int argc, VALUE *argv, VALUE self) {
|
|
349
348
|
*
|
350
349
|
* Returns [_Object_]
|
351
350
|
*/
|
352
|
-
static VALUE
|
353
|
-
mimic_dump_load(int argc, VALUE *argv, VALUE self) {
|
351
|
+
static VALUE mimic_dump_load(int argc, VALUE *argv, VALUE self) {
|
354
352
|
if (1 > argc) {
|
355
|
-
|
353
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
|
356
354
|
} else if (T_STRING == rb_type(*argv)) {
|
357
|
-
|
355
|
+
return mimic_load(argc, argv, self);
|
358
356
|
} else {
|
359
|
-
|
357
|
+
return mimic_dump(argc, argv, self);
|
360
358
|
}
|
361
359
|
return Qnil;
|
362
360
|
}
|
363
361
|
|
364
|
-
static VALUE
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
VALUE rstr;
|
362
|
+
static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
363
|
+
char buf[4096];
|
364
|
+
struct _out out;
|
365
|
+
VALUE rstr;
|
369
366
|
|
370
|
-
// TBD
|
371
367
|
memset(buf, 0, sizeof(buf));
|
372
368
|
|
373
|
-
out.buf
|
374
|
-
out.end
|
369
|
+
out.buf = buf;
|
370
|
+
out.end = buf + sizeof(buf) - 10;
|
375
371
|
out.allocated = false;
|
376
|
-
out.omit_nil
|
377
|
-
out.caller
|
372
|
+
out.omit_nil = copts->dump_opts.omit_nil;
|
373
|
+
out.caller = CALLER_GENERATE;
|
378
374
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
379
375
|
// it is.
|
380
376
|
copts->dump_opts.nan_dump = RaiseNan;
|
381
|
-
copts->mode
|
382
|
-
copts->to_json
|
377
|
+
copts->mode = CompatMode;
|
378
|
+
copts->to_json = Yes;
|
383
379
|
if (2 == argc && Qnil != argv[1]) {
|
384
|
-
|
380
|
+
oj_parse_mimic_dump_options(argv[1], copts);
|
385
381
|
}
|
386
382
|
/* seems like this is not correct
|
387
383
|
if (No == copts->nilnil && Qnil == *argv) {
|
388
|
-
|
384
|
+
rb_raise(rb_eTypeError, "nil not allowed.");
|
389
385
|
}
|
390
386
|
*/
|
391
|
-
|
387
|
+
if (1 < argc) {
|
388
|
+
oj_dump_obj_to_json_using_params(*argv, copts, &out, argc - 1, argv + 1);
|
389
|
+
} else {
|
390
|
+
VALUE active_hack[1];
|
392
391
|
|
392
|
+
if (Qundef == state_class) {
|
393
|
+
oj_define_mimic_json(0, NULL, Qnil);
|
394
|
+
}
|
395
|
+
active_hack[0] = rb_funcall(state_class, oj_new_id, 0);
|
396
|
+
oj_dump_obj_to_json_using_params(*argv, copts, &out, 1, active_hack);
|
397
|
+
}
|
393
398
|
if (0 == out.buf) {
|
394
|
-
|
399
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
395
400
|
}
|
396
401
|
rstr = rb_str_new2(out.buf);
|
397
402
|
rstr = oj_encode(rstr);
|
398
403
|
if (out.allocated) {
|
399
|
-
|
404
|
+
xfree(out.buf);
|
400
405
|
}
|
401
406
|
return rstr;
|
402
407
|
}
|
@@ -421,13 +426,14 @@ mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
|
421
426
|
* - *:space_before* [_String_] String placed before a : delimiter
|
422
427
|
* - *:object_nl* [_String_] String placed after a JSON object
|
423
428
|
* - *:array_nl* [_String_] String placed after a JSON array
|
424
|
-
* - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters in the output.
|
429
|
+
* - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters in the output.
|
430
|
+
* Note JSON.generate does support this even if it is not documented.
|
425
431
|
*
|
426
432
|
* Returns [_String_] generated JSON.
|
427
433
|
*/
|
428
434
|
VALUE
|
429
435
|
oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
|
430
|
-
struct _options
|
436
|
+
struct _options copts = oj_default_options;
|
431
437
|
|
432
438
|
copts.str_rx.head = NULL;
|
433
439
|
copts.str_rx.tail = NULL;
|
@@ -445,33 +451,36 @@ oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
|
|
445
451
|
*/
|
446
452
|
VALUE
|
447
453
|
oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
448
|
-
struct _options
|
449
|
-
VALUE
|
450
|
-
volatile VALUE
|
454
|
+
struct _options copts = oj_default_options;
|
455
|
+
VALUE rargs[2];
|
456
|
+
volatile VALUE h;
|
451
457
|
|
452
458
|
// Some (all?) json gem to_json methods need a State instance and not just
|
453
459
|
// a Hash. I haven't dug deep enough to find out why but using a State
|
454
460
|
// instance and not a Hash gives the desired behavior.
|
455
461
|
*rargs = *argv;
|
456
462
|
if (1 == argc) {
|
457
|
-
|
463
|
+
h = rb_hash_new();
|
458
464
|
} else {
|
459
|
-
|
465
|
+
h = argv[1];
|
460
466
|
}
|
461
467
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_indent_sym)) {
|
462
|
-
|
468
|
+
rb_hash_aset(h, oj_indent_sym, rb_str_new2(" "));
|
463
469
|
}
|
464
470
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_before_sym)) {
|
465
|
-
|
471
|
+
rb_hash_aset(h, oj_space_before_sym, rb_str_new2(""));
|
466
472
|
}
|
467
473
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_sym)) {
|
468
|
-
|
474
|
+
rb_hash_aset(h, oj_space_sym, rb_str_new2(" "));
|
469
475
|
}
|
470
476
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_object_nl_sym)) {
|
471
|
-
|
477
|
+
rb_hash_aset(h, oj_object_nl_sym, rb_str_new2("\n"));
|
472
478
|
}
|
473
479
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_array_nl_sym)) {
|
474
|
-
|
480
|
+
rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
|
481
|
+
}
|
482
|
+
if (Qundef == state_class) {
|
483
|
+
oj_define_mimic_json(0, NULL, Qnil);
|
475
484
|
}
|
476
485
|
rargs[1] = rb_funcall(state_class, oj_new_id, 1, h);
|
477
486
|
|
@@ -487,101 +496,105 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
|
487
496
|
copts.dump_opts.hash_size = (uint8_t)strlen(copts.dump_opts.hash_nl);
|
488
497
|
strcpy(copts.dump_opts.array_nl, "\n");
|
489
498
|
copts.dump_opts.array_size = (uint8_t)strlen(copts.dump_opts.array_nl);
|
490
|
-
copts.dump_opts.use
|
499
|
+
copts.dump_opts.use = true;
|
491
500
|
|
492
501
|
return mimic_generate_core(2, rargs, &copts);
|
493
502
|
}
|
494
503
|
|
495
|
-
static VALUE
|
496
|
-
|
497
|
-
|
498
|
-
VALUE
|
499
|
-
VALUE args[1];
|
504
|
+
static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
505
|
+
struct _parseInfo pi;
|
506
|
+
VALUE ropts;
|
507
|
+
VALUE args[1];
|
500
508
|
|
501
509
|
rb_scan_args(argc, argv, "11", NULL, &ropts);
|
502
510
|
parse_info_init(&pi);
|
503
511
|
oj_set_compat_callbacks(&pi);
|
504
512
|
|
505
513
|
pi.err_class = oj_json_parser_error_class;
|
506
|
-
//pi.err_class = Qnil;
|
514
|
+
// pi.err_class = Qnil;
|
507
515
|
|
508
|
-
pi.options
|
509
|
-
pi.options.auto_define
|
510
|
-
pi.options.quirks_mode
|
516
|
+
pi.options = oj_default_options;
|
517
|
+
pi.options.auto_define = No;
|
518
|
+
pi.options.quirks_mode = Yes;
|
511
519
|
pi.options.allow_invalid = No;
|
512
|
-
pi.options.empty_string
|
513
|
-
pi.options.create_ok
|
514
|
-
pi.options.allow_nan
|
515
|
-
pi.options.nilnil
|
516
|
-
pi.options.bigdec_load
|
517
|
-
pi.options.mode
|
518
|
-
pi.max_depth
|
520
|
+
pi.options.empty_string = No;
|
521
|
+
pi.options.create_ok = No;
|
522
|
+
pi.options.allow_nan = (bang ? Yes : No);
|
523
|
+
pi.options.nilnil = No;
|
524
|
+
pi.options.bigdec_load = RubyDec;
|
525
|
+
pi.options.mode = CompatMode;
|
526
|
+
pi.max_depth = 100;
|
519
527
|
|
520
528
|
if (Qnil != ropts) {
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
529
|
+
VALUE v;
|
530
|
+
|
531
|
+
if (T_HASH != rb_type(ropts)) {
|
532
|
+
rb_raise(rb_eArgError, "options must be a hash.");
|
533
|
+
}
|
534
|
+
if (Qundef == symbolize_names_sym) {
|
535
|
+
symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
|
536
|
+
rb_gc_register_address(&symbolize_names_sym);
|
537
|
+
}
|
538
|
+
if (Qnil != (v = rb_hash_lookup(ropts, symbolize_names_sym))) {
|
539
|
+
pi.options.sym_key = (Qtrue == v) ? Yes : No;
|
540
|
+
}
|
541
|
+
if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
|
542
|
+
pi.options.quirks_mode = (Qtrue == v) ? Yes : No;
|
543
|
+
}
|
544
|
+
if (Qnil != (v = rb_hash_lookup(ropts, oj_create_additions_sym))) {
|
545
|
+
pi.options.create_ok = (Qtrue == v) ? Yes : No;
|
546
|
+
}
|
547
|
+
if (Qnil != (v = rb_hash_lookup(ropts, oj_allow_nan_sym))) {
|
548
|
+
pi.options.allow_nan = (Qtrue == v) ? Yes : No;
|
549
|
+
}
|
550
|
+
|
551
|
+
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_hash_class_sym)) {
|
552
|
+
if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
|
553
|
+
pi.options.hash_class = Qnil;
|
554
|
+
} else {
|
555
|
+
rb_check_type(v, T_CLASS);
|
556
|
+
pi.options.hash_class = v;
|
557
|
+
}
|
558
|
+
}
|
559
|
+
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_class_sym)) {
|
560
|
+
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
|
561
|
+
pi.options.hash_class = Qnil;
|
562
|
+
} else {
|
563
|
+
rb_check_type(v, T_CLASS);
|
564
|
+
pi.options.hash_class = v;
|
565
|
+
}
|
566
|
+
}
|
567
|
+
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_class_sym)) {
|
568
|
+
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
|
569
|
+
pi.options.array_class = Qnil;
|
570
|
+
} else {
|
571
|
+
rb_check_type(v, T_CLASS);
|
572
|
+
pi.options.array_class = v;
|
573
|
+
}
|
574
|
+
}
|
575
|
+
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_decimal_class_sym)) {
|
576
|
+
pi.options.compat_bigdec = (oj_bigdecimal_class ==
|
577
|
+
rb_hash_lookup(ropts, oj_decimal_class_sym));
|
578
|
+
}
|
579
|
+
v = rb_hash_lookup(ropts, oj_max_nesting_sym);
|
580
|
+
if (Qtrue == v) {
|
581
|
+
pi.max_depth = 100;
|
582
|
+
} else if (Qfalse == v || Qnil == v) {
|
583
|
+
pi.max_depth = 0;
|
584
|
+
} else if (T_FIXNUM == rb_type(v)) {
|
585
|
+
pi.max_depth = NUM2INT(v);
|
586
|
+
}
|
587
|
+
oj_parse_opt_match_string(&pi.options.str_rx, ropts);
|
588
|
+
if (Yes == pi.options.create_ok && Yes == pi.options.sym_key) {
|
589
|
+
rb_raise(rb_eArgError, ":symbolize_names and :create_additions can not both be true.");
|
590
|
+
}
|
578
591
|
}
|
579
592
|
*args = *argv;
|
580
593
|
|
581
594
|
if (T_STRING == rb_type(*args)) {
|
582
|
-
|
595
|
+
return oj_pi_parse(1, args, &pi, 0, 0, false);
|
583
596
|
} else {
|
584
|
-
|
597
|
+
return oj_pi_sparse(1, args, &pi, 0);
|
585
598
|
}
|
586
599
|
}
|
587
600
|
|
@@ -594,8 +607,10 @@ mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
594
607
|
*
|
595
608
|
* - *source* [_String_|IO] source to parse
|
596
609
|
* - *opts* [_Hash_] options
|
597
|
-
* - *:symbolize* [Boolean] _names flag indicating JSON object keys should be Symbols instead of
|
598
|
-
*
|
610
|
+
* - *:symbolize* [Boolean] _names flag indicating JSON object keys should be Symbols instead of
|
611
|
+
* Strings
|
612
|
+
* - *:create_additions* [Boolean] flag indicating a key matching +create_id+ in a JSON object
|
613
|
+
* should trigger the creation of Ruby Object
|
599
614
|
*
|
600
615
|
* Returns [Object]
|
601
616
|
* @see create_id=
|
@@ -611,8 +626,7 @@ oj_mimic_parse(int argc, VALUE *argv, VALUE self) {
|
|
611
626
|
* Same as parse().
|
612
627
|
* @see parse
|
613
628
|
*/
|
614
|
-
static VALUE
|
615
|
-
mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
|
629
|
+
static VALUE mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
|
616
630
|
return mimic_parse_core(argc, argv, self, true);
|
617
631
|
}
|
618
632
|
|
@@ -624,8 +638,7 @@ mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
|
|
624
638
|
* - *obj* [_Hash_|Array] object to walk
|
625
639
|
* - *proc* [_Proc_] to yield to on each element
|
626
640
|
*/
|
627
|
-
static VALUE
|
628
|
-
mimic_recurse_proc(VALUE self, VALUE obj) {
|
641
|
+
static VALUE mimic_recurse_proc(VALUE self, VALUE obj) {
|
629
642
|
rb_need_block();
|
630
643
|
mimic_walk(Qnil, obj, Qnil);
|
631
644
|
|
@@ -642,23 +655,22 @@ mimic_recurse_proc(VALUE self, VALUE obj) {
|
|
642
655
|
*
|
643
656
|
* Returns [_String_] the id.
|
644
657
|
*/
|
645
|
-
static VALUE
|
646
|
-
mimic_set_create_id(VALUE self, VALUE id) {
|
658
|
+
static VALUE mimic_set_create_id(VALUE self, VALUE id) {
|
647
659
|
Check_Type(id, T_STRING);
|
648
660
|
|
649
661
|
if (NULL != oj_default_options.create_id) {
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
662
|
+
if (oj_json_class != oj_default_options.create_id) {
|
663
|
+
xfree((char *)oj_default_options.create_id);
|
664
|
+
}
|
665
|
+
oj_default_options.create_id = NULL;
|
666
|
+
oj_default_options.create_id_len = 0;
|
655
667
|
}
|
656
668
|
if (Qnil != id) {
|
657
|
-
|
669
|
+
size_t len = RSTRING_LEN(id) + 1;
|
658
670
|
|
659
|
-
|
660
|
-
|
661
|
-
|
671
|
+
oj_default_options.create_id = ALLOC_N(char, len);
|
672
|
+
strcpy((char *)oj_default_options.create_id, StringValuePtr(id));
|
673
|
+
oj_default_options.create_id_len = len - 1;
|
662
674
|
}
|
663
675
|
return id;
|
664
676
|
}
|
@@ -668,101 +680,102 @@ mimic_set_create_id(VALUE self, VALUE id) {
|
|
668
680
|
*
|
669
681
|
* Returns [_String_] the create_id.
|
670
682
|
*/
|
671
|
-
static VALUE
|
672
|
-
mimic_create_id(VALUE self) {
|
683
|
+
static VALUE mimic_create_id(VALUE self) {
|
673
684
|
if (NULL != oj_default_options.create_id) {
|
674
|
-
|
685
|
+
return oj_encode(rb_str_new_cstr(oj_default_options.create_id));
|
675
686
|
}
|
676
687
|
return rb_str_new_cstr(oj_json_class);
|
677
688
|
}
|
678
689
|
|
679
|
-
static struct _options
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
struct
|
690
|
+
static struct _options mimic_object_to_json_options = {0, // indent
|
691
|
+
No, // circular
|
692
|
+
No, // auto_define
|
693
|
+
No, // sym_key
|
694
|
+
JXEsc, // escape_mode
|
695
|
+
CompatMode, // mode
|
696
|
+
No, // class_cache
|
697
|
+
RubyTime, // time_format
|
698
|
+
No, // bigdec_as_num
|
699
|
+
RubyDec, // bigdec_load
|
700
|
+
false, // compat_bigdec
|
701
|
+
No, // to_hash
|
702
|
+
No, // to_json
|
703
|
+
No, // as_json
|
704
|
+
No, // raw_json
|
705
|
+
No, // nilnil
|
706
|
+
No, // empty_string
|
707
|
+
Yes, // allow_gc
|
708
|
+
Yes, // quirks_mode
|
709
|
+
No, // allow_invalid
|
710
|
+
No, // create_ok
|
711
|
+
No, // allow_nan
|
712
|
+
No, // trace
|
713
|
+
No, // safe
|
714
|
+
false, // sec_prec_set
|
715
|
+
No, // ignore_under
|
716
|
+
Yes, // cache_keys
|
717
|
+
3, // cache_str
|
718
|
+
0, // int_range_min
|
719
|
+
0, // int_range_max
|
720
|
+
oj_json_class, // create_id
|
721
|
+
10, // create_id_len
|
722
|
+
3, // sec_prec
|
723
|
+
0, // float_prec
|
724
|
+
"%0.16g", // float_fmt
|
725
|
+
Qnil, // hash_class
|
726
|
+
Qnil, // array_class
|
727
|
+
{
|
728
|
+
// dump_opts
|
729
|
+
false, // use
|
730
|
+
"", // indent
|
731
|
+
"", // before_sep
|
732
|
+
"", // after_sep
|
733
|
+
"", // hash_nl
|
734
|
+
"", // array_nl
|
735
|
+
0, // indent_size
|
736
|
+
0, // before_size
|
737
|
+
0, // after_size
|
738
|
+
0, // hash_size
|
739
|
+
0, // array_size
|
740
|
+
RaiseNan, // nan_dump
|
741
|
+
false, // omit_nil
|
742
|
+
100, // max_depth
|
743
|
+
},
|
744
|
+
{
|
745
|
+
// str_rx
|
746
|
+
NULL, // head
|
747
|
+
NULL, // tail
|
748
|
+
{'\0'}, // err
|
749
|
+
}};
|
750
|
+
|
751
|
+
static VALUE mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
|
752
|
+
char buf[4096];
|
753
|
+
struct _out out;
|
754
|
+
VALUE rstr;
|
755
|
+
struct _options copts = oj_default_options;
|
743
756
|
|
744
757
|
copts.str_rx.head = NULL;
|
745
758
|
copts.str_rx.tail = NULL;
|
746
|
-
out.buf
|
747
|
-
out.end
|
748
|
-
out.allocated
|
749
|
-
out.omit_nil
|
750
|
-
copts.mode
|
751
|
-
copts.to_json
|
759
|
+
out.buf = buf;
|
760
|
+
out.end = buf + sizeof(buf) - 10;
|
761
|
+
out.allocated = false;
|
762
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
763
|
+
copts.mode = CompatMode;
|
764
|
+
copts.to_json = No;
|
752
765
|
if (1 <= argc && Qnil != argv[0]) {
|
753
|
-
|
766
|
+
oj_parse_mimic_dump_options(argv[0], &copts);
|
754
767
|
}
|
755
768
|
// To be strict the mimic_object_to_json_options should be used but people
|
756
769
|
// seem to prefer the option of changing that.
|
757
|
-
//oj_dump_obj_to_json(self, &mimic_object_to_json_options, &out);
|
770
|
+
// oj_dump_obj_to_json(self, &mimic_object_to_json_options, &out);
|
758
771
|
oj_dump_obj_to_json_using_params(self, &copts, &out, argc, argv);
|
759
|
-
if (
|
760
|
-
|
772
|
+
if (NULL == out.buf) {
|
773
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
761
774
|
}
|
762
775
|
rstr = rb_str_new2(out.buf);
|
763
776
|
rstr = oj_encode(rstr);
|
764
777
|
if (out.allocated) {
|
765
|
-
|
778
|
+
xfree(out.buf);
|
766
779
|
}
|
767
780
|
return rstr;
|
768
781
|
}
|
@@ -772,16 +785,14 @@ mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
|
|
772
785
|
*
|
773
786
|
* Returns [_JSON::State_] the JSON::State class.
|
774
787
|
*/
|
775
|
-
static VALUE
|
776
|
-
mimic_state(VALUE self) {
|
788
|
+
static VALUE mimic_state(VALUE self) {
|
777
789
|
return state_class;
|
778
790
|
}
|
779
791
|
|
780
|
-
void
|
781
|
-
|
782
|
-
VALUE
|
783
|
-
VALUE
|
784
|
-
VALUE ext;
|
792
|
+
void oj_mimic_json_methods(VALUE json) {
|
793
|
+
VALUE json_error;
|
794
|
+
VALUE generator;
|
795
|
+
VALUE ext;
|
785
796
|
|
786
797
|
rb_define_module_function(json, "create_id=", mimic_set_create_id, 1);
|
787
798
|
rb_define_module_function(json, "create_id", mimic_create_id, 0);
|
@@ -813,36 +824,38 @@ oj_mimic_json_methods(VALUE json) {
|
|
813
824
|
if (rb_const_defined_at(json, rb_intern("ParserError"))) {
|
814
825
|
oj_json_parser_error_class = rb_const_get(json, rb_intern("ParserError"));
|
815
826
|
} else {
|
816
|
-
|
827
|
+
oj_json_parser_error_class = rb_define_class_under(json, "ParserError", json_error);
|
817
828
|
}
|
818
829
|
if (rb_const_defined_at(json, rb_intern("GeneratorError"))) {
|
819
830
|
oj_json_generator_error_class = rb_const_get(json, rb_intern("GeneratorError"));
|
820
831
|
} else {
|
821
|
-
|
832
|
+
oj_json_generator_error_class = rb_define_class_under(json, "GeneratorError", json_error);
|
822
833
|
}
|
823
834
|
if (rb_const_defined_at(json, rb_intern("NestingError"))) {
|
824
835
|
rb_const_get(json, rb_intern("NestingError"));
|
825
836
|
} else {
|
826
|
-
|
837
|
+
rb_define_class_under(json, "NestingError", json_error);
|
827
838
|
}
|
828
839
|
|
829
840
|
if (rb_const_defined_at(json, rb_intern("Ext"))) {
|
830
|
-
|
831
|
-
|
832
|
-
|
841
|
+
ext = rb_const_get_at(json, rb_intern("Ext"));
|
842
|
+
} else {
|
843
|
+
ext = rb_define_module_under(json, "Ext");
|
833
844
|
}
|
834
845
|
if (rb_const_defined_at(ext, rb_intern("Generator"))) {
|
835
|
-
|
836
|
-
|
837
|
-
|
846
|
+
generator = rb_const_get_at(ext, rb_intern("Generator"));
|
847
|
+
} else {
|
848
|
+
generator = rb_define_module_under(ext, "Generator");
|
838
849
|
}
|
839
850
|
if (!rb_const_defined_at(generator, rb_intern("State"))) {
|
840
|
-
|
851
|
+
rb_require("oj/state");
|
841
852
|
}
|
842
853
|
// Pull in the JSON::State mimic file.
|
843
854
|
state_class = rb_const_get_at(generator, rb_intern("State"));
|
855
|
+
rb_gc_register_mark_object(state_class);
|
844
856
|
|
845
|
-
symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
|
857
|
+
symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
|
858
|
+
rb_gc_register_address(&symbolize_names_sym);
|
846
859
|
}
|
847
860
|
|
848
861
|
/* Document-module: JSON
|
@@ -851,31 +864,31 @@ oj_mimic_json_methods(VALUE json) {
|
|
851
864
|
*/
|
852
865
|
VALUE
|
853
866
|
oj_define_mimic_json(int argc, VALUE *argv, VALUE self) {
|
854
|
-
VALUE
|
855
|
-
VALUE
|
856
|
-
VALUE
|
867
|
+
VALUE dummy;
|
868
|
+
VALUE verbose;
|
869
|
+
VALUE json;
|
857
870
|
|
858
871
|
// Either set the paths to indicate JSON has been loaded or replaces the
|
859
872
|
// methods if it has been loaded.
|
860
873
|
if (rb_const_defined_at(rb_cObject, rb_intern("JSON"))) {
|
861
|
-
|
874
|
+
json = rb_const_get_at(rb_cObject, rb_intern("JSON"));
|
862
875
|
} else {
|
863
|
-
|
876
|
+
json = rb_define_module("JSON");
|
864
877
|
}
|
865
878
|
verbose = rb_gv_get("$VERBOSE");
|
866
879
|
rb_gv_set("$VERBOSE", Qfalse);
|
867
880
|
rb_define_module_function(rb_cObject, "JSON", mimic_dump_load, -1);
|
868
881
|
dummy = rb_gv_get("$LOADED_FEATURES");
|
869
882
|
if (rb_type(dummy) == T_ARRAY) {
|
870
|
-
|
871
|
-
|
872
|
-
|
883
|
+
rb_ary_push(dummy, rb_str_new2("json"));
|
884
|
+
if (0 < argc) {
|
885
|
+
VALUE mimic_args[1];
|
873
886
|
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
887
|
+
*mimic_args = *argv;
|
888
|
+
rb_funcall2(Oj, rb_intern("mimic_loaded"), 1, mimic_args);
|
889
|
+
} else {
|
890
|
+
rb_funcall2(Oj, rb_intern("mimic_loaded"), 0, 0);
|
891
|
+
}
|
879
892
|
}
|
880
893
|
oj_mimic_json_methods(json);
|
881
894
|
|
@@ -883,7 +896,7 @@ oj_define_mimic_json(int argc, VALUE *argv, VALUE self) {
|
|
883
896
|
|
884
897
|
rb_gv_set("$VERBOSE", verbose);
|
885
898
|
|
886
|
-
oj_default_options
|
899
|
+
oj_default_options = mimic_object_to_json_options;
|
887
900
|
oj_default_options.to_json = Yes;
|
888
901
|
|
889
902
|
return json;
|