oj 3.11.1 → 3.11.6
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 +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 +1042 -1041
- 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 +412 -402
- 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 +1123 -924
- 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/easy_hash.rb +5 -4
- 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_fast.rb +32 -2
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +10 -0
- data/test/test_scp.rb +1 -1
- metadata +4 -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 = Qundef;
|
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,60 @@ 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
|
+
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
|
+
}
|
389
398
|
if (0 == out.buf) {
|
390
|
-
|
399
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
391
400
|
}
|
392
401
|
rstr = rb_str_new2(out.buf);
|
393
402
|
rstr = oj_encode(rstr);
|
394
403
|
if (out.allocated) {
|
395
|
-
|
404
|
+
xfree(out.buf);
|
396
405
|
}
|
397
406
|
return rstr;
|
398
407
|
}
|
@@ -417,13 +426,14 @@ mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
|
417
426
|
* - *:space_before* [_String_] String placed before a : delimiter
|
418
427
|
* - *:object_nl* [_String_] String placed after a JSON object
|
419
428
|
* - *: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.
|
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.
|
421
431
|
*
|
422
432
|
* Returns [_String_] generated JSON.
|
423
433
|
*/
|
424
434
|
VALUE
|
425
435
|
oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
|
426
|
-
struct _options
|
436
|
+
struct _options copts = oj_default_options;
|
427
437
|
|
428
438
|
copts.str_rx.head = NULL;
|
429
439
|
copts.str_rx.tail = NULL;
|
@@ -441,33 +451,36 @@ oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
|
|
441
451
|
*/
|
442
452
|
VALUE
|
443
453
|
oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
444
|
-
struct _options
|
445
|
-
VALUE
|
446
|
-
volatile VALUE
|
454
|
+
struct _options copts = oj_default_options;
|
455
|
+
VALUE rargs[2];
|
456
|
+
volatile VALUE h;
|
447
457
|
|
448
458
|
// Some (all?) json gem to_json methods need a State instance and not just
|
449
459
|
// a Hash. I haven't dug deep enough to find out why but using a State
|
450
460
|
// instance and not a Hash gives the desired behavior.
|
451
461
|
*rargs = *argv;
|
452
462
|
if (1 == argc) {
|
453
|
-
|
463
|
+
h = rb_hash_new();
|
454
464
|
} else {
|
455
|
-
|
465
|
+
h = argv[1];
|
456
466
|
}
|
457
467
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_indent_sym)) {
|
458
|
-
|
468
|
+
rb_hash_aset(h, oj_indent_sym, rb_str_new2(" "));
|
459
469
|
}
|
460
470
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_before_sym)) {
|
461
|
-
|
471
|
+
rb_hash_aset(h, oj_space_before_sym, rb_str_new2(""));
|
462
472
|
}
|
463
473
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_sym)) {
|
464
|
-
|
474
|
+
rb_hash_aset(h, oj_space_sym, rb_str_new2(" "));
|
465
475
|
}
|
466
476
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_object_nl_sym)) {
|
467
|
-
|
477
|
+
rb_hash_aset(h, oj_object_nl_sym, rb_str_new2("\n"));
|
468
478
|
}
|
469
479
|
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_array_nl_sym)) {
|
470
|
-
|
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);
|
471
484
|
}
|
472
485
|
rargs[1] = rb_funcall(state_class, oj_new_id, 1, h);
|
473
486
|
|
@@ -483,104 +496,105 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
|
483
496
|
copts.dump_opts.hash_size = (uint8_t)strlen(copts.dump_opts.hash_nl);
|
484
497
|
strcpy(copts.dump_opts.array_nl, "\n");
|
485
498
|
copts.dump_opts.array_size = (uint8_t)strlen(copts.dump_opts.array_nl);
|
486
|
-
copts.dump_opts.use
|
499
|
+
copts.dump_opts.use = true;
|
487
500
|
|
488
501
|
return mimic_generate_core(2, rargs, &copts);
|
489
502
|
}
|
490
503
|
|
491
|
-
static VALUE
|
492
|
-
|
493
|
-
|
494
|
-
VALUE
|
495
|
-
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];
|
496
508
|
|
497
509
|
rb_scan_args(argc, argv, "11", NULL, &ropts);
|
498
510
|
parse_info_init(&pi);
|
499
511
|
oj_set_compat_callbacks(&pi);
|
500
512
|
|
501
513
|
pi.err_class = oj_json_parser_error_class;
|
502
|
-
//pi.err_class = Qnil;
|
514
|
+
// pi.err_class = Qnil;
|
503
515
|
|
504
|
-
pi.options
|
505
|
-
pi.options.auto_define
|
506
|
-
pi.options.quirks_mode
|
516
|
+
pi.options = oj_default_options;
|
517
|
+
pi.options.auto_define = No;
|
518
|
+
pi.options.quirks_mode = Yes;
|
507
519
|
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
|
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;
|
515
527
|
|
516
528
|
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
|
-
|
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
|
+
}
|
577
591
|
}
|
578
592
|
*args = *argv;
|
579
593
|
|
580
594
|
if (T_STRING == rb_type(*args)) {
|
581
|
-
|
595
|
+
return oj_pi_parse(1, args, &pi, 0, 0, false);
|
582
596
|
} else {
|
583
|
-
|
597
|
+
return oj_pi_sparse(1, args, &pi, 0);
|
584
598
|
}
|
585
599
|
}
|
586
600
|
|
@@ -593,8 +607,10 @@ mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
593
607
|
*
|
594
608
|
* - *source* [_String_|IO] source to parse
|
595
609
|
* - *opts* [_Hash_] options
|
596
|
-
* - *:symbolize* [Boolean] _names flag indicating JSON object keys should be Symbols instead of
|
597
|
-
*
|
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
|
598
614
|
*
|
599
615
|
* Returns [Object]
|
600
616
|
* @see create_id=
|
@@ -610,8 +626,7 @@ oj_mimic_parse(int argc, VALUE *argv, VALUE self) {
|
|
610
626
|
* Same as parse().
|
611
627
|
* @see parse
|
612
628
|
*/
|
613
|
-
static VALUE
|
614
|
-
mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
|
629
|
+
static VALUE mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
|
615
630
|
return mimic_parse_core(argc, argv, self, true);
|
616
631
|
}
|
617
632
|
|
@@ -623,8 +638,7 @@ mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
|
|
623
638
|
* - *obj* [_Hash_|Array] object to walk
|
624
639
|
* - *proc* [_Proc_] to yield to on each element
|
625
640
|
*/
|
626
|
-
static VALUE
|
627
|
-
mimic_recurse_proc(VALUE self, VALUE obj) {
|
641
|
+
static VALUE mimic_recurse_proc(VALUE self, VALUE obj) {
|
628
642
|
rb_need_block();
|
629
643
|
mimic_walk(Qnil, obj, Qnil);
|
630
644
|
|
@@ -641,23 +655,22 @@ mimic_recurse_proc(VALUE self, VALUE obj) {
|
|
641
655
|
*
|
642
656
|
* Returns [_String_] the id.
|
643
657
|
*/
|
644
|
-
static VALUE
|
645
|
-
mimic_set_create_id(VALUE self, VALUE id) {
|
658
|
+
static VALUE mimic_set_create_id(VALUE self, VALUE id) {
|
646
659
|
Check_Type(id, T_STRING);
|
647
660
|
|
648
661
|
if (NULL != oj_default_options.create_id) {
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
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;
|
654
667
|
}
|
655
668
|
if (Qnil != id) {
|
656
|
-
|
669
|
+
size_t len = RSTRING_LEN(id) + 1;
|
657
670
|
|
658
|
-
|
659
|
-
|
660
|
-
|
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;
|
661
674
|
}
|
662
675
|
return id;
|
663
676
|
}
|
@@ -667,102 +680,100 @@ mimic_set_create_id(VALUE self, VALUE id) {
|
|
667
680
|
*
|
668
681
|
* Returns [_String_] the create_id.
|
669
682
|
*/
|
670
|
-
static VALUE
|
671
|
-
mimic_create_id(VALUE self) {
|
683
|
+
static VALUE mimic_create_id(VALUE self) {
|
672
684
|
if (NULL != oj_default_options.create_id) {
|
673
|
-
|
685
|
+
return oj_encode(rb_str_new_cstr(oj_default_options.create_id));
|
674
686
|
}
|
675
687
|
return rb_str_new_cstr(oj_json_class);
|
676
688
|
}
|
677
689
|
|
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;
|
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
|
+
0, // int_range_min
|
717
|
+
0, // int_range_max
|
718
|
+
oj_json_class, // create_id
|
719
|
+
10, // create_id_len
|
720
|
+
3, // sec_prec
|
721
|
+
0, // float_prec
|
722
|
+
"%0.16g", // float_fmt
|
723
|
+
Qnil, // hash_class
|
724
|
+
Qnil, // array_class
|
725
|
+
{
|
726
|
+
// dump_opts
|
727
|
+
false, // use
|
728
|
+
"", // indent
|
729
|
+
"", // before_sep
|
730
|
+
"", // after_sep
|
731
|
+
"", // hash_nl
|
732
|
+
"", // array_nl
|
733
|
+
0, // indent_size
|
734
|
+
0, // before_size
|
735
|
+
0, // after_size
|
736
|
+
0, // hash_size
|
737
|
+
0, // array_size
|
738
|
+
RaiseNan, // nan_dump
|
739
|
+
false, // omit_nil
|
740
|
+
100, // max_depth
|
741
|
+
},
|
742
|
+
{
|
743
|
+
// str_rx
|
744
|
+
NULL, // head
|
745
|
+
NULL, // tail
|
746
|
+
{'\0'}, // err
|
747
|
+
}};
|
748
|
+
|
749
|
+
static VALUE mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
|
750
|
+
char buf[4096];
|
751
|
+
struct _out out;
|
752
|
+
VALUE rstr;
|
753
|
+
struct _options copts = oj_default_options;
|
743
754
|
|
744
755
|
copts.str_rx.head = NULL;
|
745
756
|
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
|
757
|
+
out.buf = buf;
|
758
|
+
out.end = buf + sizeof(buf) - 10;
|
759
|
+
out.allocated = false;
|
760
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
761
|
+
copts.mode = CompatMode;
|
762
|
+
copts.to_json = No;
|
752
763
|
if (1 <= argc && Qnil != argv[0]) {
|
753
|
-
|
764
|
+
oj_parse_mimic_dump_options(argv[0], &copts);
|
754
765
|
}
|
755
766
|
// To be strict the mimic_object_to_json_options should be used but people
|
756
767
|
// seem to prefer the option of changing that.
|
757
|
-
//oj_dump_obj_to_json(self, &mimic_object_to_json_options, &out);
|
768
|
+
// oj_dump_obj_to_json(self, &mimic_object_to_json_options, &out);
|
758
769
|
oj_dump_obj_to_json_using_params(self, &copts, &out, argc, argv);
|
759
|
-
if (
|
760
|
-
|
770
|
+
if (NULL == out.buf) {
|
771
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
761
772
|
}
|
762
773
|
rstr = rb_str_new2(out.buf);
|
763
774
|
rstr = oj_encode(rstr);
|
764
775
|
if (out.allocated) {
|
765
|
-
|
776
|
+
xfree(out.buf);
|
766
777
|
}
|
767
778
|
return rstr;
|
768
779
|
}
|
@@ -772,16 +783,14 @@ mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
|
|
772
783
|
*
|
773
784
|
* Returns [_JSON::State_] the JSON::State class.
|
774
785
|
*/
|
775
|
-
static VALUE
|
776
|
-
mimic_state(VALUE self) {
|
786
|
+
static VALUE mimic_state(VALUE self) {
|
777
787
|
return state_class;
|
778
788
|
}
|
779
789
|
|
780
|
-
void
|
781
|
-
|
782
|
-
VALUE
|
783
|
-
VALUE
|
784
|
-
VALUE ext;
|
790
|
+
void oj_mimic_json_methods(VALUE json) {
|
791
|
+
VALUE json_error;
|
792
|
+
VALUE generator;
|
793
|
+
VALUE ext;
|
785
794
|
|
786
795
|
rb_define_module_function(json, "create_id=", mimic_set_create_id, 1);
|
787
796
|
rb_define_module_function(json, "create_id", mimic_create_id, 0);
|
@@ -813,37 +822,38 @@ oj_mimic_json_methods(VALUE json) {
|
|
813
822
|
if (rb_const_defined_at(json, rb_intern("ParserError"))) {
|
814
823
|
oj_json_parser_error_class = rb_const_get(json, rb_intern("ParserError"));
|
815
824
|
} else {
|
816
|
-
|
825
|
+
oj_json_parser_error_class = rb_define_class_under(json, "ParserError", json_error);
|
817
826
|
}
|
818
827
|
if (rb_const_defined_at(json, rb_intern("GeneratorError"))) {
|
819
828
|
oj_json_generator_error_class = rb_const_get(json, rb_intern("GeneratorError"));
|
820
829
|
} else {
|
821
|
-
|
830
|
+
oj_json_generator_error_class = rb_define_class_under(json, "GeneratorError", json_error);
|
822
831
|
}
|
823
832
|
if (rb_const_defined_at(json, rb_intern("NestingError"))) {
|
824
833
|
rb_const_get(json, rb_intern("NestingError"));
|
825
834
|
} else {
|
826
|
-
|
835
|
+
rb_define_class_under(json, "NestingError", json_error);
|
827
836
|
}
|
828
837
|
|
829
838
|
if (rb_const_defined_at(json, rb_intern("Ext"))) {
|
830
|
-
|
831
|
-
|
832
|
-
|
839
|
+
ext = rb_const_get_at(json, rb_intern("Ext"));
|
840
|
+
} else {
|
841
|
+
ext = rb_define_module_under(json, "Ext");
|
833
842
|
}
|
834
843
|
if (rb_const_defined_at(ext, rb_intern("Generator"))) {
|
835
|
-
|
836
|
-
|
837
|
-
|
844
|
+
generator = rb_const_get_at(ext, rb_intern("Generator"));
|
845
|
+
} else {
|
846
|
+
generator = rb_define_module_under(ext, "Generator");
|
838
847
|
}
|
839
848
|
if (!rb_const_defined_at(generator, rb_intern("State"))) {
|
840
|
-
|
849
|
+
rb_require("oj/state");
|
841
850
|
}
|
842
851
|
// Pull in the JSON::State mimic file.
|
843
852
|
state_class = rb_const_get_at(generator, rb_intern("State"));
|
844
853
|
rb_gc_register_mark_object(state_class);
|
845
854
|
|
846
|
-
symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
|
855
|
+
symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
|
856
|
+
rb_gc_register_address(&symbolize_names_sym);
|
847
857
|
}
|
848
858
|
|
849
859
|
/* Document-module: JSON
|
@@ -852,31 +862,31 @@ oj_mimic_json_methods(VALUE json) {
|
|
852
862
|
*/
|
853
863
|
VALUE
|
854
864
|
oj_define_mimic_json(int argc, VALUE *argv, VALUE self) {
|
855
|
-
VALUE
|
856
|
-
VALUE
|
857
|
-
VALUE
|
865
|
+
VALUE dummy;
|
866
|
+
VALUE verbose;
|
867
|
+
VALUE json;
|
858
868
|
|
859
869
|
// Either set the paths to indicate JSON has been loaded or replaces the
|
860
870
|
// methods if it has been loaded.
|
861
871
|
if (rb_const_defined_at(rb_cObject, rb_intern("JSON"))) {
|
862
|
-
|
872
|
+
json = rb_const_get_at(rb_cObject, rb_intern("JSON"));
|
863
873
|
} else {
|
864
|
-
|
874
|
+
json = rb_define_module("JSON");
|
865
875
|
}
|
866
876
|
verbose = rb_gv_get("$VERBOSE");
|
867
877
|
rb_gv_set("$VERBOSE", Qfalse);
|
868
878
|
rb_define_module_function(rb_cObject, "JSON", mimic_dump_load, -1);
|
869
879
|
dummy = rb_gv_get("$LOADED_FEATURES");
|
870
880
|
if (rb_type(dummy) == T_ARRAY) {
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
881
|
+
rb_ary_push(dummy, rb_str_new2("json"));
|
882
|
+
if (0 < argc) {
|
883
|
+
VALUE mimic_args[1];
|
884
|
+
|
885
|
+
*mimic_args = *argv;
|
886
|
+
rb_funcall2(Oj, rb_intern("mimic_loaded"), 1, mimic_args);
|
887
|
+
} else {
|
888
|
+
rb_funcall2(Oj, rb_intern("mimic_loaded"), 0, 0);
|
889
|
+
}
|
880
890
|
}
|
881
891
|
oj_mimic_json_methods(json);
|
882
892
|
|
@@ -884,7 +894,7 @@ oj_define_mimic_json(int argc, VALUE *argv, VALUE self) {
|
|
884
894
|
|
885
895
|
rb_gv_set("$VERBOSE", verbose);
|
886
896
|
|
887
|
-
oj_default_options
|
897
|
+
oj_default_options = mimic_object_to_json_options;
|
888
898
|
oj_default_options.to_json = Yes;
|
889
899
|
|
890
900
|
return json;
|