oj 3.7.4 → 3.11.2
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 +12 -4
- data/ext/oj/buf.h +6 -34
- data/ext/oj/cache8.c +3 -3
- data/ext/oj/cache8.h +5 -33
- data/ext/oj/circarray.c +5 -9
- data/ext/oj/circarray.h +5 -8
- data/ext/oj/code.c +3 -6
- data/ext/oj/code.h +7 -10
- data/ext/oj/compat.c +11 -14
- data/ext/oj/custom.c +108 -75
- data/ext/oj/dump.c +132 -92
- data/ext/oj/dump.h +6 -7
- data/ext/oj/dump_compat.c +37 -34
- data/ext/oj/dump_leaf.c +3 -6
- data/ext/oj/dump_object.c +23 -17
- data/ext/oj/dump_strict.c +7 -9
- data/ext/oj/encode.h +6 -32
- data/ext/oj/err.c +2 -5
- data/ext/oj/err.h +6 -34
- data/ext/oj/extconf.rb +6 -0
- data/ext/oj/fast.c +39 -56
- data/ext/oj/hash.c +11 -39
- data/ext/oj/hash.h +5 -33
- data/ext/oj/hash_test.c +3 -31
- data/ext/oj/mimic_json.c +65 -44
- data/ext/oj/object.c +38 -69
- data/ext/oj/odd.c +18 -17
- data/ext/oj/odd.h +6 -9
- data/ext/oj/oj.c +139 -93
- data/ext/oj/oj.h +43 -35
- data/ext/oj/parse.c +164 -60
- data/ext/oj/parse.h +30 -31
- data/ext/oj/rails.c +119 -83
- data/ext/oj/rails.h +4 -7
- data/ext/oj/reader.c +5 -8
- data/ext/oj/reader.h +7 -10
- data/ext/oj/resolve.c +4 -7
- data/ext/oj/resolve.h +4 -7
- data/ext/oj/rxclass.c +8 -11
- data/ext/oj/rxclass.h +8 -11
- data/ext/oj/saj.c +9 -12
- data/ext/oj/scp.c +4 -7
- data/ext/oj/sparse.c +67 -33
- data/ext/oj/stream_writer.c +16 -15
- data/ext/oj/strict.c +9 -12
- data/ext/oj/string_writer.c +27 -8
- data/ext/oj/trace.c +5 -8
- data/ext/oj/trace.h +9 -12
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +19 -0
- data/ext/oj/val_stack.c +28 -36
- data/ext/oj/val_stack.h +19 -50
- data/ext/oj/wab.c +29 -29
- data/lib/oj.rb +0 -8
- data/lib/oj/json.rb +1 -1
- data/lib/oj/mimic.rb +46 -2
- data/lib/oj/version.rb +2 -2
- data/pages/Modes.md +47 -45
- data/pages/Options.md +43 -10
- data/pages/Rails.md +60 -21
- data/pages/Security.md +1 -1
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +68 -60
- data/test/activesupport5/encoding_test.rb +111 -96
- data/test/activesupport5/encoding_test_cases.rb +33 -25
- data/test/activesupport5/test_helper.rb +43 -21
- data/test/activesupport5/time_zone_test_helpers.rb +18 -3
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/bar.rb +24 -6
- data/test/baz.rb +16 -0
- data/test/foo.rb +26 -57
- data/test/helper.rb +10 -0
- data/test/json_gem/json_common_interface_test.rb +8 -3
- data/test/json_gem/json_generator_test.rb +15 -3
- data/test/json_gem/test_helper.rb +8 -0
- data/test/prec.rb +23 -0
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +21 -10
- data/test/test_custom.rb +135 -8
- data/test/test_integer_range.rb +1 -2
- data/test/test_object.rb +35 -2
- data/test/test_rails.rb +35 -0
- data/test/test_strict.rb +24 -1
- data/test/test_various.rb +52 -63
- data/test/test_writer.rb +19 -2
- data/test/tests.rb +1 -0
- data/test/zoo.rb +13 -0
- metadata +100 -75
data/ext/oj/odd.c
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2011, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include <string.h>
|
7
4
|
|
8
5
|
#include "odd.h"
|
9
6
|
|
10
|
-
static struct
|
11
|
-
static struct
|
7
|
+
static struct _odd _odds[4]; // bump up if new initial Odd classes are added
|
8
|
+
static struct _odd *odds = _odds;
|
12
9
|
static long odd_cnt = 0;
|
13
10
|
static ID sec_id;
|
14
11
|
static ID sec_fraction_id;
|
@@ -38,11 +35,11 @@ set_class(Odd odd, const char *classname) {
|
|
38
35
|
|
39
36
|
static VALUE
|
40
37
|
get_datetime_secs(VALUE obj) {
|
41
|
-
VALUE rsecs = rb_funcall(obj, sec_id, 0);
|
42
|
-
VALUE rfrac = rb_funcall(obj, sec_fraction_id, 0);
|
43
|
-
long
|
44
|
-
long long
|
45
|
-
long long
|
38
|
+
volatile VALUE rsecs = rb_funcall(obj, sec_id, 0);
|
39
|
+
volatile VALUE rfrac = rb_funcall(obj, sec_fraction_id, 0);
|
40
|
+
long sec = NUM2LONG(rsecs);
|
41
|
+
long long num = rb_num2ll(rb_funcall(rfrac, numerator_id, 0));
|
42
|
+
long long den = rb_num2ll(rb_funcall(rfrac, denominator_id, 0));
|
46
43
|
|
47
44
|
num += sec * den;
|
48
45
|
|
@@ -152,7 +149,7 @@ oj_get_oddc(const char *classname, size_t len) {
|
|
152
149
|
|
153
150
|
OddArgs
|
154
151
|
oj_odd_alloc_args(Odd odd) {
|
155
|
-
OddArgs oa = ALLOC_N(struct
|
152
|
+
OddArgs oa = ALLOC_N(struct _oddArgs, 1);
|
156
153
|
VALUE *a;
|
157
154
|
int i;
|
158
155
|
|
@@ -191,15 +188,17 @@ oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE
|
|
191
188
|
AttrGetFunc *fp;
|
192
189
|
|
193
190
|
if (_odds == odds) {
|
194
|
-
odds = ALLOC_N(struct
|
191
|
+
odds = ALLOC_N(struct _odd, odd_cnt + 1);
|
195
192
|
|
196
|
-
memcpy(odds, _odds, sizeof(struct
|
193
|
+
memcpy(odds, _odds, sizeof(struct _odd) * odd_cnt);
|
197
194
|
} else {
|
198
|
-
REALLOC_N(odds, struct
|
195
|
+
REALLOC_N(odds, struct _odd, odd_cnt + 1);
|
199
196
|
}
|
200
197
|
odd = odds + odd_cnt;
|
201
198
|
odd->clas = clas;
|
202
|
-
odd->classname = strdup(rb_class2name(clas))
|
199
|
+
if (NULL == (odd->classname = strdup(rb_class2name(clas)))) {
|
200
|
+
rb_raise(rb_eNoMemError, "for attribute name.");
|
201
|
+
}
|
203
202
|
odd->clen = strlen(odd->classname);
|
204
203
|
odd->create_obj = create_object;
|
205
204
|
odd->create_op = SYM2ID(create_method);
|
@@ -210,7 +209,9 @@ oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE
|
|
210
209
|
*fp = 0;
|
211
210
|
switch (rb_type(*members)) {
|
212
211
|
case T_STRING:
|
213
|
-
*np = strdup(rb_string_value_ptr(members))
|
212
|
+
if (NULL == (*np = strdup(rb_string_value_ptr(members)))) {
|
213
|
+
rb_raise(rb_eNoMemError, "for attribute name.");
|
214
|
+
}
|
214
215
|
break;
|
215
216
|
case T_SYMBOL:
|
216
217
|
*np = rb_id2name(SYM2ID(*members));
|
data/ext/oj/odd.h
CHANGED
@@ -1,10 +1,7 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2011, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
5
2
|
|
6
|
-
#ifndef
|
7
|
-
#define
|
3
|
+
#ifndef OJ_ODD_H
|
4
|
+
#define OJ_ODD_H
|
8
5
|
|
9
6
|
#include <stdbool.h>
|
10
7
|
|
@@ -14,7 +11,7 @@
|
|
14
11
|
|
15
12
|
typedef VALUE (*AttrGetFunc)(VALUE obj);
|
16
13
|
|
17
|
-
typedef struct
|
14
|
+
typedef struct _odd {
|
18
15
|
const char *classname;
|
19
16
|
size_t clen;
|
20
17
|
VALUE clas; // Ruby class or module
|
@@ -28,7 +25,7 @@ typedef struct _Odd {
|
|
28
25
|
AttrGetFunc attrFuncs[MAX_ODD_ARGS];
|
29
26
|
} *Odd;
|
30
27
|
|
31
|
-
typedef struct
|
28
|
+
typedef struct _oddArgs {
|
32
29
|
Odd odd;
|
33
30
|
VALUE args[MAX_ODD_ARGS];
|
34
31
|
} *OddArgs;
|
@@ -41,4 +38,4 @@ extern void oj_odd_free(OddArgs args);
|
|
41
38
|
extern int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value);
|
42
39
|
extern void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw);
|
43
40
|
|
44
|
-
#endif /*
|
41
|
+
#endif /* OJ_ODD_H */
|
data/ext/oj/oj.c
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
* Copyright (c) 2012, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
5
2
|
|
6
3
|
#include <stdlib.h>
|
7
4
|
#include <errno.h>
|
@@ -19,7 +16,7 @@
|
|
19
16
|
#include "rails.h"
|
20
17
|
#include "encode.h"
|
21
18
|
|
22
|
-
typedef struct
|
19
|
+
typedef struct _yesNoOpt {
|
23
20
|
VALUE sym;
|
24
21
|
char *attr;
|
25
22
|
} *YesNoOpt;
|
@@ -53,6 +50,7 @@ ID oj_length_id;
|
|
53
50
|
ID oj_new_id;
|
54
51
|
ID oj_parse_id;
|
55
52
|
ID oj_pos_id;
|
53
|
+
ID oj_raw_json_id;
|
56
54
|
ID oj_read_id;
|
57
55
|
ID oj_readpartial_id;
|
58
56
|
ID oj_replace_id;
|
@@ -90,10 +88,12 @@ VALUE oj_slash_string;
|
|
90
88
|
VALUE oj_allow_nan_sym;
|
91
89
|
VALUE oj_array_class_sym;
|
92
90
|
VALUE oj_create_additions_sym;
|
91
|
+
VALUE oj_decimal_class_sym;
|
93
92
|
VALUE oj_hash_class_sym;
|
94
93
|
VALUE oj_indent_sym;
|
95
94
|
VALUE oj_object_class_sym;
|
96
95
|
VALUE oj_quirks_mode_sym;
|
96
|
+
VALUE oj_safe_sym;
|
97
97
|
VALUE oj_trace_sym;
|
98
98
|
|
99
99
|
static VALUE allow_blank_sym;
|
@@ -107,16 +107,19 @@ static VALUE bigdecimal_load_sym;
|
|
107
107
|
static VALUE bigdecimal_sym;
|
108
108
|
static VALUE circular_sym;
|
109
109
|
static VALUE class_cache_sym;
|
110
|
+
static VALUE compat_bigdecimal_sym;
|
110
111
|
static VALUE compat_sym;
|
111
112
|
static VALUE create_id_sym;
|
112
113
|
static VALUE custom_sym;
|
113
114
|
static VALUE empty_string_sym;
|
114
115
|
static VALUE escape_mode_sym;
|
115
116
|
static VALUE integer_range_sym;
|
117
|
+
static VALUE fast_sym;
|
116
118
|
static VALUE float_prec_sym;
|
117
119
|
static VALUE float_sym;
|
118
120
|
static VALUE huge_sym;
|
119
121
|
static VALUE ignore_sym;
|
122
|
+
static VALUE ignore_under_sym;
|
120
123
|
static VALUE json_sym;
|
121
124
|
static VALUE match_string_sym;
|
122
125
|
static VALUE mode_sym;
|
@@ -137,6 +140,7 @@ static VALUE unicode_xss_sym;
|
|
137
140
|
static VALUE unix_sym;
|
138
141
|
static VALUE unix_zone_sym;
|
139
142
|
static VALUE use_as_json_sym;
|
143
|
+
static VALUE use_raw_json_sym;
|
140
144
|
static VALUE use_to_hash_sym;
|
141
145
|
static VALUE use_to_json_sym;
|
142
146
|
static VALUE wab_sym;
|
@@ -146,7 +150,7 @@ static VALUE xss_safe_sym;
|
|
146
150
|
|
147
151
|
rb_encoding *oj_utf8_encoding = 0;
|
148
152
|
|
149
|
-
#
|
153
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
150
154
|
pthread_mutex_t oj_cache_mutex;
|
151
155
|
#else
|
152
156
|
VALUE oj_cache_mutex = Qnil;
|
@@ -154,7 +158,7 @@ VALUE oj_cache_mutex = Qnil;
|
|
154
158
|
|
155
159
|
const char oj_json_class[] = "json_class";
|
156
160
|
|
157
|
-
struct
|
161
|
+
struct _options oj_default_options = {
|
158
162
|
0, // indent
|
159
163
|
No, // circular
|
160
164
|
No, // auto_define
|
@@ -165,9 +169,11 @@ struct _Options oj_default_options = {
|
|
165
169
|
UnixTime, // time_format
|
166
170
|
NotSet, // bigdec_as_num
|
167
171
|
AutoDec, // bigdec_load
|
172
|
+
false, // compat_bigdec
|
168
173
|
No, // to_hash
|
169
174
|
No, // to_json
|
170
175
|
No, // as_json
|
176
|
+
No, // raw_json
|
171
177
|
No, // nilnil
|
172
178
|
Yes, // empty_string
|
173
179
|
Yes, // allow_gc
|
@@ -176,8 +182,11 @@ struct _Options oj_default_options = {
|
|
176
182
|
No, // create_ok
|
177
183
|
Yes, // allow_nan
|
178
184
|
No, // trace
|
179
|
-
|
180
|
-
|
185
|
+
No, // safe
|
186
|
+
false, // sec_prec_set
|
187
|
+
No, // ignore_under
|
188
|
+
0, // int_range_min
|
189
|
+
0, // int_range_max
|
181
190
|
oj_json_class, // create_id
|
182
191
|
10, // create_id_len
|
183
192
|
9, // sec_prec
|
@@ -222,13 +231,15 @@ struct _Options oj_default_options = {
|
|
222
231
|
* - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and dump modes to use for JSON
|
223
232
|
* - *:time_format* [_:unix_|_:unix_zone_|_:xmlschema_|_:ruby_] time format when dumping
|
224
233
|
* - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a String
|
225
|
-
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_] load decimals as BigDecimal instead of as a Float. :auto pick the most precise for the number of digits.
|
234
|
+
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_] load decimals as BigDecimal instead of as a Float. :auto pick the most precise for the number of digits. :float should be the same as ruby. :fast may require rounding but is must faster.
|
235
|
+
* - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float when in compat or rails mode.
|
226
236
|
* - *:create_id* [_String_|_nil_] create id for json compatible object encoding, default is 'json_class'
|
227
237
|
* - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using create_id on load.
|
228
238
|
* - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal when dumping the seconds portion of time
|
229
239
|
* - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping floats, 0 indicates use Ruby
|
230
240
|
* - *:use_to_json* [_Boolean_|_nil_] call to_json() methods on dump, default is false
|
231
241
|
* - *:use_as_json* [_Boolean_|_nil_] call as_json() methods on dump, default is false
|
242
|
+
* - *:use_raw_json* [_Boolean_|_nil_] call raw_json() methods on dump, default is false
|
232
243
|
* - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an Exception
|
233
244
|
* - *:empty_string* [_Boolean_|_nil_] if true an empty input will not raise an Exception
|
234
245
|
* - *:allow_gc* [_Boolean_|_nil_] allow or prohibit GC during parsing, default is true (allow)
|
@@ -245,8 +256,10 @@ struct _Options oj_default_options = {
|
|
245
256
|
* - *:array_class* [_Class_|_nil_] Class to use instead of Array on load
|
246
257
|
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted
|
247
258
|
* - *:ignore* [_nil_|Array] either nil or an Array of classes to ignore when dumping
|
248
|
-
* - *:
|
259
|
+
* - *:ignore_under* [Boolean] if true then attributes that start with _ are ignored when dumping in object or custom mode.
|
260
|
+
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
249
261
|
* - *:trace* [_true,_|_false_] Trace all load and dump calls, default is false (trace is off)
|
262
|
+
* - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default is false (safe is off)
|
250
263
|
*
|
251
264
|
* Return [_Hash_] all current option settings.
|
252
265
|
*/
|
@@ -269,6 +282,7 @@ get_def_opts(VALUE self) {
|
|
269
282
|
rb_hash_aset(opts, use_to_json_sym, (Yes == oj_default_options.to_json) ? Qtrue : ((No == oj_default_options.to_json) ? Qfalse : Qnil));
|
270
283
|
rb_hash_aset(opts, use_to_hash_sym, (Yes == oj_default_options.to_hash) ? Qtrue : ((No == oj_default_options.to_hash) ? Qfalse : Qnil));
|
271
284
|
rb_hash_aset(opts, use_as_json_sym, (Yes == oj_default_options.as_json) ? Qtrue : ((No == oj_default_options.as_json) ? Qfalse : Qnil));
|
285
|
+
rb_hash_aset(opts, use_raw_json_sym, (Yes == oj_default_options.raw_json) ? Qtrue : ((No == oj_default_options.raw_json) ? Qfalse : Qnil));
|
272
286
|
rb_hash_aset(opts, nilnil_sym, (Yes == oj_default_options.nilnil) ? Qtrue : ((No == oj_default_options.nilnil) ? Qfalse : Qnil));
|
273
287
|
rb_hash_aset(opts, empty_string_sym, (Yes == oj_default_options.empty_string) ? Qtrue : ((No == oj_default_options.empty_string) ? Qfalse : Qnil));
|
274
288
|
rb_hash_aset(opts, allow_gc_sym, (Yes == oj_default_options.allow_gc) ? Qtrue : ((No == oj_default_options.allow_gc) ? Qfalse : Qnil));
|
@@ -276,7 +290,9 @@ get_def_opts(VALUE self) {
|
|
276
290
|
rb_hash_aset(opts, allow_invalid_unicode_sym, (Yes == oj_default_options.allow_invalid) ? Qtrue : ((No == oj_default_options.allow_invalid) ? Qfalse : Qnil));
|
277
291
|
rb_hash_aset(opts, oj_allow_nan_sym, (Yes == oj_default_options.allow_nan) ? Qtrue : ((No == oj_default_options.allow_nan) ? Qfalse : Qnil));
|
278
292
|
rb_hash_aset(opts, oj_trace_sym, (Yes == oj_default_options.trace) ? Qtrue : ((No == oj_default_options.trace) ? Qfalse : Qnil));
|
293
|
+
rb_hash_aset(opts, oj_safe_sym, (Yes == oj_default_options.safe) ? Qtrue : ((No == oj_default_options.safe) ? Qfalse : Qnil));
|
279
294
|
rb_hash_aset(opts, float_prec_sym, INT2FIX(oj_default_options.float_prec));
|
295
|
+
rb_hash_aset(opts, ignore_under_sym, (Yes == oj_default_options.ignore_under) ? Qtrue : ((No == oj_default_options.ignore_under) ? Qfalse : Qnil));
|
280
296
|
switch (oj_default_options.mode) {
|
281
297
|
case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
|
282
298
|
case CompatMode: rb_hash_aset(opts, mode_sym, compat_sym); break;
|
@@ -287,17 +303,17 @@ get_def_opts(VALUE self) {
|
|
287
303
|
case WabMode: rb_hash_aset(opts, mode_sym, wab_sym); break;
|
288
304
|
default: rb_hash_aset(opts, mode_sym, object_sym); break;
|
289
305
|
}
|
290
|
-
|
291
|
-
if (oj_default_options.
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
else {
|
300
|
-
|
306
|
+
|
307
|
+
if (oj_default_options.int_range_max != 0 || oj_default_options.int_range_min != 0) {
|
308
|
+
VALUE range = rb_obj_alloc(rb_cRange);
|
309
|
+
VALUE min = LONG2FIX(oj_default_options.int_range_min);
|
310
|
+
VALUE max = LONG2FIX(oj_default_options.int_range_max);
|
311
|
+
|
312
|
+
rb_ivar_set(range, oj_begin_id, min);
|
313
|
+
rb_ivar_set(range, oj_end_id, max);
|
314
|
+
rb_hash_aset(opts, integer_range_sym, range);
|
315
|
+
} else {
|
316
|
+
rb_hash_aset(opts, integer_range_sym, Qnil);
|
301
317
|
}
|
302
318
|
switch (oj_default_options.escape_mode) {
|
303
319
|
case NLEsc: rb_hash_aset(opts, escape_mode_sym, newline_sym); break;
|
@@ -317,10 +333,12 @@ get_def_opts(VALUE self) {
|
|
317
333
|
switch (oj_default_options.bigdec_load) {
|
318
334
|
case BigDec: rb_hash_aset(opts, bigdecimal_load_sym, bigdecimal_sym);break;
|
319
335
|
case FloatDec: rb_hash_aset(opts, bigdecimal_load_sym, float_sym); break;
|
336
|
+
case FastDec: rb_hash_aset(opts, bigdecimal_load_sym, fast_sym); break;
|
320
337
|
case AutoDec:
|
321
338
|
default: rb_hash_aset(opts, bigdecimal_load_sym, auto_sym); break;
|
322
339
|
}
|
323
|
-
rb_hash_aset(opts,
|
340
|
+
rb_hash_aset(opts, compat_bigdecimal_sym, oj_default_options.compat_bigdec ? Qtrue : Qfalse);
|
341
|
+
rb_hash_aset(opts, create_id_sym, (NULL == oj_default_options.create_id) ? Qnil : rb_str_new2(oj_default_options.create_id));
|
324
342
|
rb_hash_aset(opts, oj_space_sym, (0 == oj_default_options.dump_opts.after_size) ? Qnil : rb_str_new2(oj_default_options.dump_opts.after_sep));
|
325
343
|
rb_hash_aset(opts, oj_space_before_sym, (0 == oj_default_options.dump_opts.before_size) ? Qnil : rb_str_new2(oj_default_options.dump_opts.before_sep));
|
326
344
|
rb_hash_aset(opts, oj_object_nl_sym, (0 == oj_default_options.dump_opts.hash_size) ? Qnil : rb_str_new2(oj_default_options.dump_opts.hash_nl));
|
@@ -343,7 +361,7 @@ get_def_opts(VALUE self) {
|
|
343
361
|
} else {
|
344
362
|
VALUE *vp;
|
345
363
|
volatile VALUE a = rb_ary_new();
|
346
|
-
|
364
|
+
|
347
365
|
for (vp = oj_default_options.ignore; Qnil != *vp; vp++) {
|
348
366
|
rb_ary_push(a, *vp);
|
349
367
|
}
|
@@ -365,6 +383,7 @@ get_def_opts(VALUE self) {
|
|
365
383
|
* - *:escape* [_:newline_|_:json_|_:xss_safe_|_:ascii_|_unicode_xss_|_nil_] mode encodes all high-bit characters as escaped sequences if :ascii, :json is standand UTF-8 JSON encoding, :newline is the same as :json but newlines are not escaped, :unicode_xss allows unicode but escapes &, <, and >, and any \u20xx characters along with some others, and :xss_safe escapes &, <, and >, and some others.
|
366
384
|
* - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a String.
|
367
385
|
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_nil_] load decimals as BigDecimal instead of as a Float. :auto pick the most precise for the number of digits.
|
386
|
+
* - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float in compat mode.
|
368
387
|
* - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and dump mode to use for JSON :strict raises an exception when a non-supported Object is encountered. :compat attempts to extract variable values from an Object using to_json() or to_hash() then it walks the Object's variables if neither is found. The :object mode ignores to_hash() and to_json() methods and encodes variables using code internal to the Oj gem. The :null mode ignores non-supported Objects and replaces them with a null. The :custom mode honors all dump options. The :rails more mimics rails and Active behavior.
|
369
388
|
* - *:time_format* [_:unix_|_:xmlschema_|_:ruby_] time format when dumping in :compat mode :unix decimal number denoting the number of seconds since 1/1/1970, :unix_zone decimal number denoting the number of seconds since 1/1/1970 plus the utc_offset in the exponent, :xmlschema date-time format taken from XML Schema as a String, :ruby Time.to_s formatted String.
|
370
389
|
* - *:create_id* [_String_|_nil_] create id for json compatible object encoding
|
@@ -374,6 +393,7 @@ get_def_opts(VALUE self) {
|
|
374
393
|
* - *:use_to_json* [_Boolean_|_nil_] call to_json() methods on dump, default is false.
|
375
394
|
* - *:use_as_json* [_Boolean_|_nil_] call as_json() methods on dump, default is false.
|
376
395
|
* - *:use_to_hash* [_Boolean_|_nil_] call to_hash() methods on dump, default is false.
|
396
|
+
* - *:use_raw_json* [_Boolean_|_nil_] call raw_json() methods on dump, default is false.
|
377
397
|
* - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an Exception.
|
378
398
|
* - *:allow_gc* [_Boolean_|_nil_] allow or prohibit GC during parsing, default is true (allow).
|
379
399
|
* - *:quirks_mode* [_Boolean_|_nil_] allow single JSON values instead of documents, default is true (allow).
|
@@ -388,8 +408,10 @@ get_def_opts(VALUE self) {
|
|
388
408
|
* - *:array_class* [_Class_|_nil_] Class to use instead of Array on load.
|
389
409
|
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted.
|
390
410
|
* - *:ignore* [_nil_|Array] either nil or an Array of classes to ignore when dumping
|
391
|
-
* - *:
|
411
|
+
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when dumping in object or custom mode.
|
412
|
+
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
392
413
|
* - *:trace* [_Boolean_] turn trace on or off.
|
414
|
+
* - *:safe* [_Boolean_] turn safe mimic on or off.
|
393
415
|
*/
|
394
416
|
static VALUE
|
395
417
|
set_def_opts(VALUE self, VALUE opts) {
|
@@ -401,7 +423,7 @@ set_def_opts(VALUE self, VALUE opts) {
|
|
401
423
|
|
402
424
|
void
|
403
425
|
oj_parse_options(VALUE ropts, Options copts) {
|
404
|
-
struct
|
426
|
+
struct _yesNoOpt ynos[] = {
|
405
427
|
{ circular_sym, &copts->circular },
|
406
428
|
{ auto_define_sym, &copts->auto_define },
|
407
429
|
{ symbol_keys_sym, &copts->sym_key },
|
@@ -410,6 +432,7 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
410
432
|
{ use_to_hash_sym, &copts->to_hash },
|
411
433
|
{ use_to_json_sym, &copts->to_json },
|
412
434
|
{ use_as_json_sym, &copts->as_json },
|
435
|
+
{ use_raw_json_sym, &copts->raw_json },
|
413
436
|
{ nilnil_sym, &copts->nilnil },
|
414
437
|
{ allow_blank_sym, &copts->nilnil }, // same as nilnil
|
415
438
|
{ empty_string_sym, &copts->empty_string },
|
@@ -418,13 +441,15 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
418
441
|
{ allow_invalid_unicode_sym, &copts->allow_invalid },
|
419
442
|
{ oj_allow_nan_sym, &copts->allow_nan },
|
420
443
|
{ oj_trace_sym, &copts->trace },
|
444
|
+
{ oj_safe_sym, &copts->safe },
|
445
|
+
{ ignore_under_sym, &copts->ignore_under },
|
421
446
|
{ oj_create_additions_sym, &copts->create_ok },
|
422
447
|
{ Qnil, 0 }
|
423
448
|
};
|
424
449
|
YesNoOpt o;
|
425
450
|
volatile VALUE v;
|
426
451
|
size_t len;
|
427
|
-
|
452
|
+
|
428
453
|
if (T_HASH != rb_type(ropts)) {
|
429
454
|
return;
|
430
455
|
}
|
@@ -493,8 +518,12 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
493
518
|
n = NUM2INT(v);
|
494
519
|
if (0 > n) {
|
495
520
|
n = 0;
|
521
|
+
copts->sec_prec_set = false;
|
496
522
|
} else if (9 < n) {
|
497
523
|
n = 9;
|
524
|
+
copts->sec_prec_set = true;
|
525
|
+
} else {
|
526
|
+
copts->sec_prec_set = true;
|
498
527
|
}
|
499
528
|
copts->sec_prec = n;
|
500
529
|
}
|
@@ -550,12 +579,27 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
550
579
|
copts->bigdec_load = BigDec;
|
551
580
|
} else if (float_sym == v) {
|
552
581
|
copts->bigdec_load = FloatDec;
|
582
|
+
} else if (fast_sym == v) {
|
583
|
+
copts->bigdec_load = FastDec;
|
553
584
|
} else if (auto_sym == v || Qfalse == v) {
|
554
585
|
copts->bigdec_load = AutoDec;
|
555
586
|
} else {
|
556
587
|
rb_raise(rb_eArgError, ":bigdecimal_load must be :bigdecimal, :float, or :auto.");
|
557
588
|
}
|
558
589
|
}
|
590
|
+
if (Qnil != (v = rb_hash_lookup(ropts, compat_bigdecimal_sym))) {
|
591
|
+
copts->compat_bigdec = (Qtrue == v);
|
592
|
+
}
|
593
|
+
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_decimal_class_sym)) {
|
594
|
+
v = rb_hash_lookup(ropts, oj_decimal_class_sym);
|
595
|
+
if (rb_cFloat == v) {
|
596
|
+
copts->compat_bigdec = false;
|
597
|
+
} else if (oj_bigdecimal_class == v) {
|
598
|
+
copts->compat_bigdec = true;
|
599
|
+
} else {
|
600
|
+
rb_raise(rb_eArgError, ":decimal_class must be BigDecimal or Float.");
|
601
|
+
}
|
602
|
+
}
|
559
603
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, create_id_sym)) {
|
560
604
|
v = rb_hash_lookup(ropts, create_id_sym);
|
561
605
|
if (Qnil == v) {
|
@@ -715,7 +759,7 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
715
759
|
cnt = (int)RARRAY_LEN(v);
|
716
760
|
if (0 < cnt) {
|
717
761
|
int i;
|
718
|
-
|
762
|
+
|
719
763
|
copts->ignore = ALLOC_N(VALUE, cnt + 1);
|
720
764
|
for (i = 0; i < cnt; i++) {
|
721
765
|
copts->ignore[i] = rb_ary_entry(v, i);
|
@@ -725,24 +769,26 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
725
769
|
}
|
726
770
|
}
|
727
771
|
if (Qnil != (v = rb_hash_lookup(ropts, integer_range_sym))) {
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
772
|
+
if (TYPE(v) == T_STRUCT && rb_obj_class(v) == rb_cRange) {
|
773
|
+
VALUE min = rb_funcall(v, oj_begin_id, 0);
|
774
|
+
VALUE max = rb_funcall(v, oj_end_id, 0);
|
775
|
+
|
776
|
+
if (TYPE(min) != T_FIXNUM || TYPE(max) != T_FIXNUM) {
|
777
|
+
rb_raise(rb_eArgError, ":integer_range range bounds is not Fixnum.");
|
778
|
+
}
|
779
|
+
|
780
|
+
copts->int_range_min = FIX2LONG(min);
|
781
|
+
copts->int_range_max = FIX2LONG(max);
|
782
|
+
} else if (Qfalse != v) {
|
783
|
+
rb_raise(rb_eArgError, ":integer_range must be a range of Fixnum.");
|
784
|
+
}
|
741
785
|
}
|
742
786
|
}
|
743
787
|
|
744
788
|
static int
|
745
|
-
match_string_cb(VALUE key, VALUE value,
|
789
|
+
match_string_cb(VALUE key, VALUE value, VALUE rx) {
|
790
|
+
RxClass rc = (RxClass)rx;
|
791
|
+
|
746
792
|
if (T_CLASS != rb_type(value)) {
|
747
793
|
rb_raise(rb_eArgError, "for :match_string, the hash values must be a Class.");
|
748
794
|
}
|
@@ -777,7 +823,7 @@ oj_parse_opt_match_string(RxClass rc, VALUE ropts) {
|
|
777
823
|
}
|
778
824
|
|
779
825
|
/* Document-method: load
|
780
|
-
* call-seq: load(json, options) { _|_obj, start, len_|_ }
|
826
|
+
* call-seq: load(json, options={}) { _|_obj, start, len_|_ }
|
781
827
|
*
|
782
828
|
* Parses a JSON document String into a Object, Hash, Array, String, Fixnum,
|
783
829
|
* Float, true, false, or nil according to the default mode or the mode
|
@@ -802,11 +848,10 @@ oj_parse_opt_match_string(RxClass rc, VALUE ropts) {
|
|
802
848
|
*
|
803
849
|
* - *json* [_String_|_IO_] JSON String or an Object that responds to read()
|
804
850
|
* - *options* [_Hash_] load options (same as default_options)
|
805
|
-
* - -
|
806
851
|
* - *obj* [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_] parsed object.
|
807
852
|
* - *start* [_optional, _Integer_] start position of parsed JSON for obj.
|
808
853
|
* - *len* [_optional, _Integer_] length of parsed JSON for obj.
|
809
|
-
*
|
854
|
+
*
|
810
855
|
* Returns [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_]
|
811
856
|
*/
|
812
857
|
static VALUE
|
@@ -862,7 +907,7 @@ load(int argc, VALUE *argv, VALUE self) {
|
|
862
907
|
}
|
863
908
|
|
864
909
|
/* Document-method: load_file
|
865
|
-
* call-seq: load_file(path, options) { _|_obj, start, len_|_ }
|
910
|
+
* call-seq: load_file(path, options={}) { _|_obj, start, len_|_ }
|
866
911
|
*
|
867
912
|
* Parses a JSON document String into a Object, Hash, Array, String, Fixnum,
|
868
913
|
* Float, true, false, or nil according to the default mode or the mode
|
@@ -889,7 +934,6 @@ load(int argc, VALUE *argv, VALUE self) {
|
|
889
934
|
*
|
890
935
|
* - *path* [_String_] to a file containing a JSON document
|
891
936
|
* - *options* [_Hash_] load options (same as default_options)
|
892
|
-
* - -
|
893
937
|
* - *obj* [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_] parsed object.
|
894
938
|
* - *start* [_optional, _Integer_] start position of parsed JSON for obj.
|
895
939
|
* - *len* [_optional, _Integer_] length of parsed JSON for obj.
|
@@ -901,7 +945,7 @@ load_file(int argc, VALUE *argv, VALUE self) {
|
|
901
945
|
char *path;
|
902
946
|
int fd;
|
903
947
|
Mode mode = oj_default_options.mode;
|
904
|
-
struct
|
948
|
+
struct _parseInfo pi;
|
905
949
|
|
906
950
|
if (1 > argc) {
|
907
951
|
rb_raise(rb_eArgError, "Wrong number of arguments to load().");
|
@@ -943,11 +987,13 @@ load_file(int argc, VALUE *argv, VALUE self) {
|
|
943
987
|
}
|
944
988
|
switch (mode) {
|
945
989
|
case StrictMode:
|
990
|
+
case NullMode:
|
946
991
|
oj_set_strict_callbacks(&pi);
|
947
992
|
return oj_pi_sparse(argc, argv, &pi, fd);
|
948
|
-
case NullMode:
|
949
|
-
case CompatMode:
|
950
993
|
case CustomMode:
|
994
|
+
oj_set_custom_callbacks(&pi);
|
995
|
+
return oj_pi_sparse(argc, argv, &pi, fd);
|
996
|
+
case CompatMode:
|
951
997
|
case RailsMode:
|
952
998
|
oj_set_compat_callbacks(&pi);
|
953
999
|
return oj_pi_sparse(argc, argv, &pi, fd);
|
@@ -976,7 +1022,7 @@ load_file(int argc, VALUE *argv, VALUE self) {
|
|
976
1022
|
*/
|
977
1023
|
static VALUE
|
978
1024
|
safe_load(VALUE self, VALUE doc) {
|
979
|
-
struct
|
1025
|
+
struct _parseInfo pi;
|
980
1026
|
VALUE args[1];
|
981
1027
|
|
982
1028
|
parse_info_init(&pi);
|
@@ -1019,7 +1065,7 @@ safe_load(VALUE self, VALUE doc) {
|
|
1019
1065
|
*/
|
1020
1066
|
|
1021
1067
|
/* Document-method: dump
|
1022
|
-
* call-seq: dump(obj, options)
|
1068
|
+
* call-seq: dump(obj, options={})
|
1023
1069
|
*
|
1024
1070
|
* Dumps an Object (obj) to a string.
|
1025
1071
|
* - *obj* [_Object_] Object to serialize as an JSON document String
|
@@ -1028,8 +1074,8 @@ safe_load(VALUE self, VALUE doc) {
|
|
1028
1074
|
static VALUE
|
1029
1075
|
dump(int argc, VALUE *argv, VALUE self) {
|
1030
1076
|
char buf[4096];
|
1031
|
-
struct
|
1032
|
-
struct
|
1077
|
+
struct _out out;
|
1078
|
+
struct _options copts = oj_default_options;
|
1033
1079
|
VALUE rstr;
|
1034
1080
|
|
1035
1081
|
if (1 > argc) {
|
@@ -1041,6 +1087,9 @@ dump(int argc, VALUE *argv, VALUE self) {
|
|
1041
1087
|
if (2 == argc) {
|
1042
1088
|
oj_parse_options(argv[1], &copts);
|
1043
1089
|
}
|
1090
|
+
if (CompatMode == copts.mode && copts.escape_mode != ASCIIEsc) {
|
1091
|
+
copts.escape_mode = JSONEsc;
|
1092
|
+
}
|
1044
1093
|
out.buf = buf;
|
1045
1094
|
out.end = buf + sizeof(buf) - 10;
|
1046
1095
|
out.allocated = false;
|
@@ -1064,7 +1113,7 @@ dump(int argc, VALUE *argv, VALUE self) {
|
|
1064
1113
|
* Dumps an Object (obj) to a string. If the object has a to_json method that
|
1065
1114
|
* will be called. The mode is set to :compat.
|
1066
1115
|
* - *obj* [_Object_] Object to serialize as an JSON document String
|
1067
|
-
* - *options* [_Hash_]
|
1116
|
+
* - *options* [_Hash_]
|
1068
1117
|
* - *:max_nesting* [_boolean_] It true nesting is limited to 100. The option to detect circular references is available but is not compatible with the json gem., default is false
|
1069
1118
|
* - *:allow_nan* [_boolean_] If true non JSON compliant words such as Nan and Infinity will be used as appropriate, default is true.
|
1070
1119
|
* - *:quirks_mode* [_boolean_] Allow single JSON values instead of documents, default is true (allow).
|
@@ -1080,8 +1129,8 @@ dump(int argc, VALUE *argv, VALUE self) {
|
|
1080
1129
|
static VALUE
|
1081
1130
|
to_json(int argc, VALUE *argv, VALUE self) {
|
1082
1131
|
char buf[4096];
|
1083
|
-
struct
|
1084
|
-
struct
|
1132
|
+
struct _out out;
|
1133
|
+
struct _options copts = oj_default_options;
|
1085
1134
|
VALUE rstr;
|
1086
1135
|
|
1087
1136
|
if (1 > argc) {
|
@@ -1114,7 +1163,7 @@ to_json(int argc, VALUE *argv, VALUE self) {
|
|
1114
1163
|
}
|
1115
1164
|
|
1116
1165
|
/* Document-method: to_file
|
1117
|
-
* call-seq: to_file(file_path, obj, options)
|
1166
|
+
* call-seq: to_file(file_path, obj, options={})
|
1118
1167
|
*
|
1119
1168
|
* Dumps an Object to the specified file.
|
1120
1169
|
* - *file* [_String_] _path file path to write the JSON document to
|
@@ -1125,8 +1174,8 @@ to_json(int argc, VALUE *argv, VALUE self) {
|
|
1125
1174
|
*/
|
1126
1175
|
static VALUE
|
1127
1176
|
to_file(int argc, VALUE *argv, VALUE self) {
|
1128
|
-
struct
|
1129
|
-
|
1177
|
+
struct _options copts = oj_default_options;
|
1178
|
+
|
1130
1179
|
if (3 == argc) {
|
1131
1180
|
oj_parse_options(argv[2], &copts);
|
1132
1181
|
}
|
@@ -1137,7 +1186,7 @@ to_file(int argc, VALUE *argv, VALUE self) {
|
|
1137
1186
|
}
|
1138
1187
|
|
1139
1188
|
/* Document-method: to_stream
|
1140
|
-
* call-seq: to_stream(io, obj, options)
|
1189
|
+
* call-seq: to_stream(io, obj, options={})
|
1141
1190
|
*
|
1142
1191
|
* Dumps an Object to the specified IO stream.
|
1143
1192
|
* - *io* [_IO_] IO stream to write the JSON document to
|
@@ -1148,8 +1197,8 @@ to_file(int argc, VALUE *argv, VALUE self) {
|
|
1148
1197
|
*/
|
1149
1198
|
static VALUE
|
1150
1199
|
to_stream(int argc, VALUE *argv, VALUE self) {
|
1151
|
-
struct
|
1152
|
-
|
1200
|
+
struct _options copts = oj_default_options;
|
1201
|
+
|
1153
1202
|
if (3 == argc) {
|
1154
1203
|
oj_parse_options(argv[2], &copts);
|
1155
1204
|
}
|
@@ -1265,7 +1314,6 @@ register_odd_raw(int argc, VALUE *argv, VALUE self) {
|
|
1265
1314
|
*
|
1266
1315
|
* - *json* [_String_|_IO_] JSON String or an Object that responds to read().
|
1267
1316
|
* - *options* [_Hash_] load options (same as default_options).
|
1268
|
-
* - -
|
1269
1317
|
* - *obj* [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_] parsed object.
|
1270
1318
|
* - *start* [_optional, _Integer_] start position of parsed JSON for obj.
|
1271
1319
|
* - *len* [_optional, _Integer_] length of parsed JSON for obj.
|
@@ -1300,7 +1348,6 @@ extern VALUE oj_strict_parse(int argc, VALUE *argv, VALUE self);
|
|
1300
1348
|
*
|
1301
1349
|
* - *json* [_String_|_IO_] JSON String or an Object that responds to read().
|
1302
1350
|
* - *options* [_Hash_] load options (same as default_options).
|
1303
|
-
* - -
|
1304
1351
|
* - *obj* [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_] parsed object.
|
1305
1352
|
* - *start* [_optional, _Integer_] start position of parsed JSON for obj.
|
1306
1353
|
* - *len* [_optional, _Integer_] length of parsed JSON for obj.
|
@@ -1322,22 +1369,6 @@ extern VALUE oj_compat_parse(int argc, VALUE *argv, VALUE self);
|
|
1322
1369
|
* valid. If the input is not a valid JSON document (an empty string is not a
|
1323
1370
|
* valid JSON document) an exception is raised.
|
1324
1371
|
*
|
1325
|
-
* Note: Oj is not able to automatically deserialize all classes that are a
|
1326
|
-
* subclass of a Ruby Exception. Only exception that take one required string
|
1327
|
-
* argument in the initialize() method are supported. This is an example of how
|
1328
|
-
* to write an Exception subclass that supports both a single string intializer
|
1329
|
-
* and an Exception as an argument. Additional optional arguments can be added
|
1330
|
-
* as well.
|
1331
|
-
*
|
1332
|
-
* The reason for this restriction has to do with a design decision on the part
|
1333
|
-
* of the Ruby developers. Exceptions are special Objects. They do not follow the
|
1334
|
-
* rules of other Objects. Exceptions have 'mesg' and a 'bt' attribute. Note that
|
1335
|
-
* these are not '@mesg' and '@bt'. They can not be set using the normal C or
|
1336
|
-
* Ruby calls. The only way I have found to set the 'mesg' attribute is through
|
1337
|
-
* the initializer. Unfortunately that means any subclass that provides a
|
1338
|
-
* different initializer can not be automatically decoded. A way around this is
|
1339
|
-
* to use a create function but this example shows an alternative.
|
1340
|
-
*
|
1341
1372
|
* A block can be provided with a single argument. That argument will be the
|
1342
1373
|
* parsed JSON document. This is useful when parsing a string that includes
|
1343
1374
|
* multiple JSON documents. The block can take up to 3 arguments, the parsed
|
@@ -1347,7 +1378,6 @@ extern VALUE oj_compat_parse(int argc, VALUE *argv, VALUE self);
|
|
1347
1378
|
*
|
1348
1379
|
* - *json* [_String_|_IO_] JSON String or an Object that responds to read().
|
1349
1380
|
* - *options* [_Hash_] load options (same as default_options).
|
1350
|
-
* - -
|
1351
1381
|
* - *obj* [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_] parsed object.
|
1352
1382
|
* - *start* [_optional, _Integer_] start position of parsed JSON for obj.
|
1353
1383
|
* - *len* [_optional, _Integer_] length of parsed JSON for obj.
|
@@ -1383,7 +1413,6 @@ extern VALUE oj_object_parse(int argc, VALUE *argv, VALUE self);
|
|
1383
1413
|
*
|
1384
1414
|
* - *json* [_String_|_IO_] JSON String or an Object that responds to read().
|
1385
1415
|
* - *options* [_Hash_] load options (same as default_options).
|
1386
|
-
* - -
|
1387
1416
|
* - *obj* [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_] parsed object.
|
1388
1417
|
* - *start* [_optional, _Integer_] start position of parsed JSON for obj.
|
1389
1418
|
* - *len* [_optional, _Integer_] length of parsed JSON for obj.
|
@@ -1445,16 +1474,16 @@ extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
|
|
1445
1474
|
|
1446
1475
|
/* Document-method: generate
|
1447
1476
|
* call-seq: generate(obj, opts=nil)
|
1448
|
-
*
|
1477
|
+
*
|
1449
1478
|
* Encode obj as a JSON String. The obj argument must be a Hash, Array, or
|
1450
1479
|
* respond to to_h or to_json. Options other than those listed such as
|
1451
1480
|
* +:allow_nan+ or +:max_nesting+ are ignored.
|
1452
|
-
*
|
1481
|
+
*
|
1453
1482
|
* - *obj* [_Object__|_Hash_|_Array_] object to convert to a JSON String
|
1454
1483
|
* - *opts* [_Hash_] options
|
1455
|
-
*
|
1484
|
+
* - *:indent* [_String_] String to use for indentation.
|
1456
1485
|
* - *:space* [_String_] String placed after a , or : delimiter
|
1457
|
-
* - *:
|
1486
|
+
* - *:space_before* [_String_] String placed before a : delimiter
|
1458
1487
|
* - *:object_nl* [_String_] String placed after a JSON object
|
1459
1488
|
* - *:array_nl* [_String_] String placed after a JSON array
|
1460
1489
|
* - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters in the output. Note JSON.generate does support this even if it is not documented.
|
@@ -1497,15 +1526,15 @@ protect_require(VALUE x) {
|
|
1497
1526
|
* modes are:
|
1498
1527
|
*
|
1499
1528
|
* - *:strict* mode will only allow the 7 basic JSON types to be serialized. Any other Object
|
1500
|
-
* will raise an Exception.
|
1501
|
-
*
|
1529
|
+
* will raise an Exception.
|
1530
|
+
*
|
1502
1531
|
* - *:null* mode is similar to the :strict mode except any Object that is not
|
1503
1532
|
* one of the JSON base types is replaced by a JSON null.
|
1504
|
-
*
|
1533
|
+
*
|
1505
1534
|
* - *:object* mode will dump any Object as a JSON Object with keys that match
|
1506
1535
|
* the Ruby Object's variable names without the '@' character. This is the
|
1507
1536
|
* highest performance mode.
|
1508
|
-
*
|
1537
|
+
*
|
1509
1538
|
* - *:compat* or *:json* mode is the compatible mode for the json gem. It mimics
|
1510
1539
|
* the json gem including the options, defaults, and restrictions.
|
1511
1540
|
*
|
@@ -1591,6 +1620,7 @@ Init_oj() {
|
|
1591
1620
|
oj_new_id = rb_intern("new");
|
1592
1621
|
oj_parse_id = rb_intern("parse");
|
1593
1622
|
oj_pos_id = rb_intern("pos");
|
1623
|
+
oj_raw_json_id = rb_intern("raw_json");
|
1594
1624
|
oj_read_id = rb_intern("read");
|
1595
1625
|
oj_readpartial_id = rb_intern("readpartial");
|
1596
1626
|
oj_replace_id = rb_intern("replace");
|
@@ -1617,13 +1647,21 @@ Init_oj() {
|
|
1617
1647
|
rb_require("oj/schandler");
|
1618
1648
|
|
1619
1649
|
oj_bag_class = rb_const_get_at(Oj, rb_intern("Bag"));
|
1650
|
+
rb_gc_register_mark_object(oj_bag_class);
|
1620
1651
|
oj_bigdecimal_class = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
|
1652
|
+
rb_gc_register_mark_object(oj_bigdecimal_class);
|
1621
1653
|
oj_date_class = rb_const_get(rb_cObject, rb_intern("Date"));
|
1654
|
+
rb_gc_register_mark_object(oj_date_class);
|
1622
1655
|
oj_datetime_class = rb_const_get(rb_cObject, rb_intern("DateTime"));
|
1656
|
+
rb_gc_register_mark_object(oj_datetime_class);
|
1623
1657
|
oj_enumerable_class = rb_const_get(rb_cObject, rb_intern("Enumerable"));
|
1658
|
+
rb_gc_register_mark_object(oj_enumerable_class);
|
1624
1659
|
oj_parse_error_class = rb_const_get_at(Oj, rb_intern("ParseError"));
|
1660
|
+
rb_gc_register_mark_object(oj_parse_error_class);
|
1625
1661
|
oj_stringio_class = rb_const_get(rb_cObject, rb_intern("StringIO"));
|
1662
|
+
rb_gc_register_mark_object(oj_stringio_class);
|
1626
1663
|
oj_struct_class = rb_const_get(rb_cObject, rb_intern("Struct"));
|
1664
|
+
rb_gc_register_mark_object(oj_struct_class);
|
1627
1665
|
oj_json_parser_error_class = rb_eEncodingError; // replaced if mimic is called
|
1628
1666
|
oj_json_generator_error_class = rb_eEncodingError; // replaced if mimic is called
|
1629
1667
|
|
@@ -1638,16 +1676,19 @@ Init_oj() {
|
|
1638
1676
|
bigdecimal_sym = ID2SYM(rb_intern("bigdecimal")); rb_gc_register_address(&bigdecimal_sym);
|
1639
1677
|
circular_sym = ID2SYM(rb_intern("circular")); rb_gc_register_address(&circular_sym);
|
1640
1678
|
class_cache_sym = ID2SYM(rb_intern("class_cache")); rb_gc_register_address(&class_cache_sym);
|
1679
|
+
compat_bigdecimal_sym = ID2SYM(rb_intern("compat_bigdecimal"));rb_gc_register_address(&compat_bigdecimal_sym);
|
1641
1680
|
compat_sym = ID2SYM(rb_intern("compat")); rb_gc_register_address(&compat_sym);
|
1642
1681
|
create_id_sym = ID2SYM(rb_intern("create_id")); rb_gc_register_address(&create_id_sym);
|
1643
1682
|
custom_sym = ID2SYM(rb_intern("custom")); rb_gc_register_address(&custom_sym);
|
1644
1683
|
empty_string_sym = ID2SYM(rb_intern("empty_string")); rb_gc_register_address(&empty_string_sym);
|
1645
1684
|
escape_mode_sym = ID2SYM(rb_intern("escape_mode")); rb_gc_register_address(&escape_mode_sym);
|
1646
1685
|
integer_range_sym = ID2SYM(rb_intern("integer_range")); rb_gc_register_address(&integer_range_sym);
|
1686
|
+
fast_sym = ID2SYM(rb_intern("fast")); rb_gc_register_address(&fast_sym);
|
1647
1687
|
float_prec_sym = ID2SYM(rb_intern("float_precision")); rb_gc_register_address(&float_prec_sym);
|
1648
1688
|
float_sym = ID2SYM(rb_intern("float")); rb_gc_register_address(&float_sym);
|
1649
1689
|
huge_sym = ID2SYM(rb_intern("huge")); rb_gc_register_address(&huge_sym);
|
1650
1690
|
ignore_sym = ID2SYM(rb_intern("ignore")); rb_gc_register_address(&ignore_sym);
|
1691
|
+
ignore_under_sym = ID2SYM(rb_intern("ignore_under")); rb_gc_register_address(&ignore_under_sym);
|
1651
1692
|
json_sym = ID2SYM(rb_intern("json")); rb_gc_register_address(&json_sym);
|
1652
1693
|
match_string_sym = ID2SYM(rb_intern("match_string")); rb_gc_register_address(&match_string_sym);
|
1653
1694
|
mode_sym = ID2SYM(rb_intern("mode")); rb_gc_register_address(&mode_sym);
|
@@ -1661,12 +1702,14 @@ Init_oj() {
|
|
1661
1702
|
oj_array_nl_sym = ID2SYM(rb_intern("array_nl")); rb_gc_register_address(&oj_array_nl_sym);
|
1662
1703
|
oj_ascii_only_sym = ID2SYM(rb_intern("ascii_only")); rb_gc_register_address(&oj_ascii_only_sym);
|
1663
1704
|
oj_create_additions_sym = ID2SYM(rb_intern("create_additions"));rb_gc_register_address(&oj_create_additions_sym);
|
1705
|
+
oj_decimal_class_sym = ID2SYM(rb_intern("decimal_class")); rb_gc_register_address(&oj_decimal_class_sym);
|
1664
1706
|
oj_hash_class_sym = ID2SYM(rb_intern("hash_class")); rb_gc_register_address(&oj_hash_class_sym);
|
1665
1707
|
oj_indent_sym = ID2SYM(rb_intern("indent")); rb_gc_register_address(&oj_indent_sym);
|
1666
1708
|
oj_max_nesting_sym = ID2SYM(rb_intern("max_nesting")); rb_gc_register_address(&oj_max_nesting_sym);
|
1667
1709
|
oj_object_class_sym = ID2SYM(rb_intern("object_class")); rb_gc_register_address(&oj_object_class_sym);
|
1668
1710
|
oj_object_nl_sym = ID2SYM(rb_intern("object_nl")); rb_gc_register_address(&oj_object_nl_sym);
|
1669
1711
|
oj_quirks_mode_sym = ID2SYM(rb_intern("quirks_mode")); rb_gc_register_address(&oj_quirks_mode_sym);
|
1712
|
+
oj_safe_sym = ID2SYM(rb_intern("safe")); rb_gc_register_address(&oj_safe_sym);
|
1670
1713
|
oj_space_before_sym = ID2SYM(rb_intern("space_before")); rb_gc_register_address(&oj_space_before_sym);
|
1671
1714
|
oj_space_sym = ID2SYM(rb_intern("space")); rb_gc_register_address(&oj_space_sym);
|
1672
1715
|
oj_trace_sym = ID2SYM(rb_intern("trace")); rb_gc_register_address(&oj_trace_sym);
|
@@ -1682,6 +1725,7 @@ Init_oj() {
|
|
1682
1725
|
unix_sym = ID2SYM(rb_intern("unix")); rb_gc_register_address(&unix_sym);
|
1683
1726
|
unix_zone_sym = ID2SYM(rb_intern("unix_zone")); rb_gc_register_address(&unix_zone_sym);
|
1684
1727
|
use_as_json_sym = ID2SYM(rb_intern("use_as_json")); rb_gc_register_address(&use_as_json_sym);
|
1728
|
+
use_raw_json_sym = ID2SYM(rb_intern("use_raw_json")); rb_gc_register_address(&use_raw_json_sym);
|
1685
1729
|
use_to_hash_sym = ID2SYM(rb_intern("use_to_hash")); rb_gc_register_address(&use_to_hash_sym);
|
1686
1730
|
use_to_json_sym = ID2SYM(rb_intern("use_to_json")); rb_gc_register_address(&use_to_json_sym);
|
1687
1731
|
wab_sym = ID2SYM(rb_intern("wab")); rb_gc_register_address(&wab_sym);
|
@@ -1698,8 +1742,10 @@ Init_oj() {
|
|
1698
1742
|
oj_odd_init();
|
1699
1743
|
oj_mimic_rails_init();
|
1700
1744
|
|
1701
|
-
#
|
1702
|
-
pthread_mutex_init(&oj_cache_mutex, 0)
|
1745
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
1746
|
+
if (0 != (err = pthread_mutex_init(&oj_cache_mutex, 0))) {
|
1747
|
+
rb_raise(rb_eException, "failed to initialize a mutex. %s", strerror(err));
|
1748
|
+
}
|
1703
1749
|
#else
|
1704
1750
|
oj_cache_mutex = rb_mutex_new();
|
1705
1751
|
rb_gc_register_address(&oj_cache_mutex);
|