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