oj 3.10.18 → 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 +2 -1
- 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 +406 -407
- 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 +1132 -918
- data/ext/oj/oj.h +286 -297
- data/ext/oj/parse.c +943 -926
- 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 +781 -716
- 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/easy_hash.rb +5 -4
- data/lib/oj/mimic.rb +0 -12
- data/lib/oj/version.rb +1 -1
- data/pages/Modes.md +2 -1
- data/pages/Options.md +8 -0
- data/test/activerecord/result_test.rb +7 -2
- data/test/foo.rb +35 -32
- data/test/helper.rb +10 -0
- data/test/json_gem/json_generator_test.rb +15 -3
- data/test/json_gem/test_helper.rb +8 -0
- data/test/test_compat.rb +3 -3
- data/test/test_hash.rb +10 -0
- data/test/test_scp.rb +1 -1
- data/test/test_various.rb +1 -0
- metadata +82 -82
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,54 +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
|
-
// TBD
|
368
367
|
memset(buf, 0, sizeof(buf));
|
369
368
|
|
370
|
-
out.buf
|
371
|
-
out.end
|
369
|
+
out.buf = buf;
|
370
|
+
out.end = buf + sizeof(buf) - 10;
|
372
371
|
out.allocated = false;
|
373
|
-
out.omit_nil
|
374
|
-
out.caller
|
372
|
+
out.omit_nil = copts->dump_opts.omit_nil;
|
373
|
+
out.caller = CALLER_GENERATE;
|
375
374
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
376
375
|
// it is.
|
377
376
|
copts->dump_opts.nan_dump = RaiseNan;
|
378
|
-
copts->mode
|
379
|
-
copts->to_json
|
377
|
+
copts->mode = CompatMode;
|
378
|
+
copts->to_json = Yes;
|
380
379
|
if (2 == argc && Qnil != argv[1]) {
|
381
|
-
|
380
|
+
oj_parse_mimic_dump_options(argv[1], copts);
|
382
381
|
}
|
383
382
|
/* seems like this is not correct
|
384
383
|
if (No == copts->nilnil && Qnil == *argv) {
|
385
|
-
|
384
|
+
rb_raise(rb_eTypeError, "nil not allowed.");
|
386
385
|
}
|
387
386
|
*/
|
388
|
-
|
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];
|
389
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
|
+
}
|
390
395
|
if (0 == out.buf) {
|
391
|
-
|
396
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
392
397
|
}
|
393
398
|
rstr = rb_str_new2(out.buf);
|
394
399
|
rstr = oj_encode(rstr);
|
395
400
|
if (out.allocated) {
|
396
|
-
|
401
|
+
xfree(out.buf);
|
397
402
|
}
|
398
403
|
return rstr;
|
399
404
|
}
|
@@ -418,13 +423,14 @@ mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
|
418
423
|
* - *:space_before* [_String_] String placed before a : delimiter
|
419
424
|
* - *:object_nl* [_String_] String placed after a JSON object
|
420
425
|
* - *:array_nl* [_String_] String placed after a JSON array
|
421
|
-
* - *: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.
|
422
428
|
*
|
423
429
|
* Returns [_String_] generated JSON.
|
424
430
|
*/
|
425
431
|
VALUE
|
426
432
|
oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
|
427
|
-
struct _options
|
433
|
+
struct _options copts = oj_default_options;
|
428
434
|
|
429
435
|
copts.str_rx.head = NULL;
|
430
436
|
copts.str_rx.tail = NULL;
|
@@ -442,33 +448,33 @@ oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
|
|
442
448
|
*/
|
443
449
|
VALUE
|
444
450
|
oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
445
|
-
struct _options
|
446
|
-
VALUE
|
447
|
-
volatile VALUE
|
451
|
+
struct _options copts = oj_default_options;
|
452
|
+
VALUE rargs[2];
|
453
|
+
volatile VALUE h;
|
448
454
|
|
449
455
|
// Some (all?) json gem to_json methods need a State instance and not just
|
450
456
|
// a Hash. I haven't dug deep enough to find out why but using a State
|
451
457
|
// instance and not a Hash gives the desired behavior.
|
452
458
|
*rargs = *argv;
|
453
459
|
if (1 == argc) {
|
454
|
-
|
460
|
+
h = rb_hash_new();
|
455
461
|
} else {
|
456
|
-
|
462
|
+
h = argv[1];
|
457
463
|
}
|
458
464
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_indent_sym)) {
|
459
|
-
|
465
|
+
rb_hash_aset(h, oj_indent_sym, rb_str_new2(" "));
|
460
466
|
}
|
461
467
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_before_sym)) {
|
462
|
-
|
468
|
+
rb_hash_aset(h, oj_space_before_sym, rb_str_new2(""));
|
463
469
|
}
|
464
470
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_sym)) {
|
465
|
-
|
471
|
+
rb_hash_aset(h, oj_space_sym, rb_str_new2(" "));
|
466
472
|
}
|
467
473
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_object_nl_sym)) {
|
468
|
-
|
474
|
+
rb_hash_aset(h, oj_object_nl_sym, rb_str_new2("\n"));
|
469
475
|
}
|
470
476
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_array_nl_sym)) {
|
471
|
-
|
477
|
+
rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
|
472
478
|
}
|
473
479
|
rargs[1] = rb_funcall(state_class, oj_new_id, 1, h);
|
474
480
|
|
@@ -484,110 +490,105 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
|
484
490
|
copts.dump_opts.hash_size = (uint8_t)strlen(copts.dump_opts.hash_nl);
|
485
491
|
strcpy(copts.dump_opts.array_nl, "\n");
|
486
492
|
copts.dump_opts.array_size = (uint8_t)strlen(copts.dump_opts.array_nl);
|
487
|
-
copts.dump_opts.use
|
493
|
+
copts.dump_opts.use = true;
|
488
494
|
|
489
495
|
return mimic_generate_core(2, rargs, &copts);
|
490
496
|
}
|
491
497
|
|
492
|
-
static VALUE
|
493
|
-
|
494
|
-
|
495
|
-
VALUE
|
496
|
-
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];
|
497
502
|
|
498
503
|
rb_scan_args(argc, argv, "11", NULL, &ropts);
|
499
504
|
parse_info_init(&pi);
|
500
505
|
oj_set_compat_callbacks(&pi);
|
501
506
|
|
502
507
|
pi.err_class = oj_json_parser_error_class;
|
503
|
-
//pi.err_class = Qnil;
|
508
|
+
// pi.err_class = Qnil;
|
504
509
|
|
505
|
-
pi.options
|
506
|
-
pi.options.auto_define
|
507
|
-
pi.options.quirks_mode
|
510
|
+
pi.options = oj_default_options;
|
511
|
+
pi.options.auto_define = No;
|
512
|
+
pi.options.quirks_mode = Yes;
|
508
513
|
pi.options.allow_invalid = No;
|
509
|
-
pi.options.empty_string
|
510
|
-
pi.options.create_ok
|
511
|
-
pi.options.allow_nan
|
512
|
-
pi.options.nilnil
|
513
|
-
pi.options.
|
514
|
-
pi.
|
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
|
-
|
577
|
-
|
578
|
-
|
579
|
-
}
|
580
|
-
oj_parse_opt_match_string(&pi.options.str_rx, ropts);
|
581
|
-
if (Yes == pi.options.create_ok && Yes == pi.options.sym_key) {
|
582
|
-
rb_raise(rb_eArgError, ":symbolize_names and :create_additions can not both be true.");
|
583
|
-
}
|
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
|
+
}
|
584
585
|
}
|
585
586
|
*args = *argv;
|
586
587
|
|
587
588
|
if (T_STRING == rb_type(*args)) {
|
588
|
-
|
589
|
+
return oj_pi_parse(1, args, &pi, 0, 0, false);
|
589
590
|
} else {
|
590
|
-
|
591
|
+
return oj_pi_sparse(1, args, &pi, 0);
|
591
592
|
}
|
592
593
|
}
|
593
594
|
|
@@ -600,8 +601,10 @@ mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
600
601
|
*
|
601
602
|
* - *source* [_String_|IO] source to parse
|
602
603
|
* - *opts* [_Hash_] options
|
603
|
-
* - *:symbolize* [Boolean] _names flag indicating JSON object keys should be Symbols instead of
|
604
|
-
*
|
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
|
605
608
|
*
|
606
609
|
* Returns [Object]
|
607
610
|
* @see create_id=
|
@@ -617,8 +620,7 @@ oj_mimic_parse(int argc, VALUE *argv, VALUE self) {
|
|
617
620
|
* Same as parse().
|
618
621
|
* @see parse
|
619
622
|
*/
|
620
|
-
static VALUE
|
621
|
-
mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
|
623
|
+
static VALUE mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
|
622
624
|
return mimic_parse_core(argc, argv, self, true);
|
623
625
|
}
|
624
626
|
|
@@ -630,8 +632,7 @@ mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
|
|
630
632
|
* - *obj* [_Hash_|Array] object to walk
|
631
633
|
* - *proc* [_Proc_] to yield to on each element
|
632
634
|
*/
|
633
|
-
static VALUE
|
634
|
-
mimic_recurse_proc(VALUE self, VALUE obj) {
|
635
|
+
static VALUE mimic_recurse_proc(VALUE self, VALUE obj) {
|
635
636
|
rb_need_block();
|
636
637
|
mimic_walk(Qnil, obj, Qnil);
|
637
638
|
|
@@ -648,23 +649,22 @@ mimic_recurse_proc(VALUE self, VALUE obj) {
|
|
648
649
|
*
|
649
650
|
* Returns [_String_] the id.
|
650
651
|
*/
|
651
|
-
static VALUE
|
652
|
-
mimic_set_create_id(VALUE self, VALUE id) {
|
652
|
+
static VALUE mimic_set_create_id(VALUE self, VALUE id) {
|
653
653
|
Check_Type(id, T_STRING);
|
654
654
|
|
655
655
|
if (NULL != oj_default_options.create_id) {
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
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;
|
661
661
|
}
|
662
662
|
if (Qnil != id) {
|
663
|
-
|
663
|
+
size_t len = RSTRING_LEN(id) + 1;
|
664
664
|
|
665
|
-
|
666
|
-
|
667
|
-
|
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;
|
668
668
|
}
|
669
669
|
return id;
|
670
670
|
}
|
@@ -674,101 +674,100 @@ mimic_set_create_id(VALUE self, VALUE id) {
|
|
674
674
|
*
|
675
675
|
* Returns [_String_] the create_id.
|
676
676
|
*/
|
677
|
-
static VALUE
|
678
|
-
mimic_create_id(VALUE self) {
|
677
|
+
static VALUE mimic_create_id(VALUE self) {
|
679
678
|
if (NULL != oj_default_options.create_id) {
|
680
|
-
|
679
|
+
return oj_encode(rb_str_new_cstr(oj_default_options.create_id));
|
681
680
|
}
|
682
681
|
return rb_str_new_cstr(oj_json_class);
|
683
682
|
}
|
684
683
|
|
685
|
-
static struct _options
|
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
|
-
|
743
|
-
|
744
|
-
mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
|
745
|
-
char
|
746
|
-
struct _out
|
747
|
-
VALUE
|
748
|
-
struct _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;
|
749
748
|
|
750
749
|
copts.str_rx.head = NULL;
|
751
750
|
copts.str_rx.tail = NULL;
|
752
|
-
out.buf
|
753
|
-
out.end
|
754
|
-
out.allocated
|
755
|
-
out.omit_nil
|
756
|
-
copts.mode
|
757
|
-
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;
|
758
757
|
if (1 <= argc && Qnil != argv[0]) {
|
759
|
-
|
758
|
+
oj_parse_mimic_dump_options(argv[0], &copts);
|
760
759
|
}
|
761
760
|
// To be strict the mimic_object_to_json_options should be used but people
|
762
761
|
// seem to prefer the option of changing that.
|
763
|
-
//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);
|
764
763
|
oj_dump_obj_to_json_using_params(self, &copts, &out, argc, argv);
|
765
|
-
if (
|
766
|
-
|
764
|
+
if (NULL == out.buf) {
|
765
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
767
766
|
}
|
768
767
|
rstr = rb_str_new2(out.buf);
|
769
768
|
rstr = oj_encode(rstr);
|
770
769
|
if (out.allocated) {
|
771
|
-
|
770
|
+
xfree(out.buf);
|
772
771
|
}
|
773
772
|
return rstr;
|
774
773
|
}
|
@@ -778,16 +777,14 @@ mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
|
|
778
777
|
*
|
779
778
|
* Returns [_JSON::State_] the JSON::State class.
|
780
779
|
*/
|
781
|
-
static VALUE
|
782
|
-
mimic_state(VALUE self) {
|
780
|
+
static VALUE mimic_state(VALUE self) {
|
783
781
|
return state_class;
|
784
782
|
}
|
785
783
|
|
786
|
-
void
|
787
|
-
|
788
|
-
VALUE
|
789
|
-
VALUE
|
790
|
-
VALUE ext;
|
784
|
+
void oj_mimic_json_methods(VALUE json) {
|
785
|
+
VALUE json_error;
|
786
|
+
VALUE generator;
|
787
|
+
VALUE ext;
|
791
788
|
|
792
789
|
rb_define_module_function(json, "create_id=", mimic_set_create_id, 1);
|
793
790
|
rb_define_module_function(json, "create_id", mimic_create_id, 0);
|
@@ -819,36 +816,38 @@ oj_mimic_json_methods(VALUE json) {
|
|
819
816
|
if (rb_const_defined_at(json, rb_intern("ParserError"))) {
|
820
817
|
oj_json_parser_error_class = rb_const_get(json, rb_intern("ParserError"));
|
821
818
|
} else {
|
822
|
-
|
819
|
+
oj_json_parser_error_class = rb_define_class_under(json, "ParserError", json_error);
|
823
820
|
}
|
824
821
|
if (rb_const_defined_at(json, rb_intern("GeneratorError"))) {
|
825
822
|
oj_json_generator_error_class = rb_const_get(json, rb_intern("GeneratorError"));
|
826
823
|
} else {
|
827
|
-
|
824
|
+
oj_json_generator_error_class = rb_define_class_under(json, "GeneratorError", json_error);
|
828
825
|
}
|
829
826
|
if (rb_const_defined_at(json, rb_intern("NestingError"))) {
|
830
827
|
rb_const_get(json, rb_intern("NestingError"));
|
831
828
|
} else {
|
832
|
-
|
829
|
+
rb_define_class_under(json, "NestingError", json_error);
|
833
830
|
}
|
834
831
|
|
835
832
|
if (rb_const_defined_at(json, rb_intern("Ext"))) {
|
836
|
-
|
837
|
-
|
838
|
-
|
833
|
+
ext = rb_const_get_at(json, rb_intern("Ext"));
|
834
|
+
} else {
|
835
|
+
ext = rb_define_module_under(json, "Ext");
|
839
836
|
}
|
840
837
|
if (rb_const_defined_at(ext, rb_intern("Generator"))) {
|
841
|
-
|
842
|
-
|
843
|
-
|
838
|
+
generator = rb_const_get_at(ext, rb_intern("Generator"));
|
839
|
+
} else {
|
840
|
+
generator = rb_define_module_under(ext, "Generator");
|
844
841
|
}
|
845
842
|
if (!rb_const_defined_at(generator, rb_intern("State"))) {
|
846
|
-
|
843
|
+
rb_require("oj/state");
|
847
844
|
}
|
848
845
|
// Pull in the JSON::State mimic file.
|
849
846
|
state_class = rb_const_get_at(generator, rb_intern("State"));
|
847
|
+
rb_gc_register_mark_object(state_class);
|
850
848
|
|
851
|
-
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);
|
852
851
|
}
|
853
852
|
|
854
853
|
/* Document-module: JSON
|
@@ -857,31 +856,31 @@ oj_mimic_json_methods(VALUE json) {
|
|
857
856
|
*/
|
858
857
|
VALUE
|
859
858
|
oj_define_mimic_json(int argc, VALUE *argv, VALUE self) {
|
860
|
-
VALUE
|
861
|
-
VALUE
|
862
|
-
VALUE
|
859
|
+
VALUE dummy;
|
860
|
+
VALUE verbose;
|
861
|
+
VALUE json;
|
863
862
|
|
864
863
|
// Either set the paths to indicate JSON has been loaded or replaces the
|
865
864
|
// methods if it has been loaded.
|
866
865
|
if (rb_const_defined_at(rb_cObject, rb_intern("JSON"))) {
|
867
|
-
|
866
|
+
json = rb_const_get_at(rb_cObject, rb_intern("JSON"));
|
868
867
|
} else {
|
869
|
-
|
868
|
+
json = rb_define_module("JSON");
|
870
869
|
}
|
871
870
|
verbose = rb_gv_get("$VERBOSE");
|
872
871
|
rb_gv_set("$VERBOSE", Qfalse);
|
873
872
|
rb_define_module_function(rb_cObject, "JSON", mimic_dump_load, -1);
|
874
873
|
dummy = rb_gv_get("$LOADED_FEATURES");
|
875
874
|
if (rb_type(dummy) == T_ARRAY) {
|
876
|
-
|
877
|
-
|
878
|
-
|
875
|
+
rb_ary_push(dummy, rb_str_new2("json"));
|
876
|
+
if (0 < argc) {
|
877
|
+
VALUE mimic_args[1];
|
879
878
|
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
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
|
+
}
|
885
884
|
}
|
886
885
|
oj_mimic_json_methods(json);
|
887
886
|
|
@@ -889,7 +888,7 @@ oj_define_mimic_json(int argc, VALUE *argv, VALUE self) {
|
|
889
888
|
|
890
889
|
rb_gv_set("$VERBOSE", verbose);
|
891
890
|
|
892
|
-
oj_default_options
|
891
|
+
oj_default_options = mimic_object_to_json_options;
|
893
892
|
oj_default_options.to_json = Yes;
|
894
893
|
|
895
894
|
return json;
|