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