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