oj 3.13.9 → 3.16.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +101 -0
- data/README.md +13 -2
- data/ext/oj/buf.h +11 -6
- data/ext/oj/cache.c +25 -24
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +8 -6
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +19 -33
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +20 -60
- data/ext/oj/custom.c +76 -155
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +203 -213
- data/ext/oj/dump.h +26 -12
- data/ext/oj/dump_compat.c +565 -642
- data/ext/oj/dump_leaf.c +17 -63
- data/ext/oj/dump_object.c +59 -181
- data/ext/oj/dump_strict.c +24 -48
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +18 -7
- data/ext/oj/fast.c +83 -108
- data/ext/oj/intern.c +52 -50
- data/ext/oj/intern.h +4 -8
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +104 -81
- data/ext/oj/object.c +50 -67
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +171 -106
- data/ext/oj/oj.h +96 -74
- data/ext/oj/parse.c +169 -189
- data/ext/oj/parse.h +23 -24
- data/ext/oj/parser.c +89 -34
- data/ext/oj/parser.h +20 -9
- data/ext/oj/rails.c +86 -151
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +12 -15
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +21 -32
- data/ext/oj/saj2.c +329 -93
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +26 -70
- data/ext/oj/stream_writer.c +12 -22
- data/ext/oj/strict.c +20 -52
- data/ext/oj/string_writer.c +21 -22
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +105 -150
- data/ext/oj/usual.h +68 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +32 -69
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +0 -1
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +6 -2
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +9 -6
- 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 +6 -3
- data/pages/Options.md +10 -0
- data/pages/Rails.md +12 -0
- 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 +5 -6
- 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 +20 -34
- 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 +15 -15
- data/test/helper.rb +11 -8
- 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 +49 -37
- 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 +7 -3
- data/test/mem.rb +13 -12
- data/test/perf.rb +21 -26
- 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 +12 -11
- data/test/perf_parser.rb +42 -48
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +3 -3
- 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 +95 -43
- data/test/test_custom.rb +72 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +102 -87
- data/test/test_file.rb +41 -30
- data/test/test_gc.rb +16 -5
- data/test/test_generate.rb +5 -5
- data/test/test_hash.rb +4 -4
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +85 -96
- data/test/test_parser.rb +6 -22
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +115 -23
- data/test/test_parser_usual.rb +6 -6
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +37 -39
- data/test/test_strict.rb +40 -32
- data/test/test_various.rb +163 -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 +34 -144
- 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 -16
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/oj.c
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
#include "dump.h"
|
15
15
|
#include "encode.h"
|
16
16
|
#include "intern.h"
|
17
|
+
#include "mem.h"
|
17
18
|
#include "odd.h"
|
18
19
|
#include "parse.h"
|
19
20
|
#include "rails.h"
|
@@ -21,7 +22,7 @@
|
|
21
22
|
typedef struct _yesNoOpt {
|
22
23
|
VALUE sym;
|
23
24
|
char *attr;
|
24
|
-
} *
|
25
|
+
} *YesNoOpt;
|
25
26
|
|
26
27
|
void Init_oj();
|
27
28
|
|
@@ -32,6 +33,7 @@ ID oj_array_append_id;
|
|
32
33
|
ID oj_array_end_id;
|
33
34
|
ID oj_array_start_id;
|
34
35
|
ID oj_as_json_id;
|
36
|
+
ID oj_at_id;
|
35
37
|
ID oj_begin_id;
|
36
38
|
ID oj_bigdecimal_id;
|
37
39
|
ID oj_end_id;
|
@@ -45,7 +47,6 @@ ID oj_hash_key_id;
|
|
45
47
|
ID oj_hash_set_id;
|
46
48
|
ID oj_hash_start_id;
|
47
49
|
ID oj_iconv_id;
|
48
|
-
ID oj_instance_variables_id;
|
49
50
|
ID oj_json_create_id;
|
50
51
|
ID oj_length_id;
|
51
52
|
ID oj_new_id;
|
@@ -90,7 +91,9 @@ VALUE oj_array_class_sym;
|
|
90
91
|
VALUE oj_create_additions_sym;
|
91
92
|
VALUE oj_decimal_class_sym;
|
92
93
|
VALUE oj_hash_class_sym;
|
94
|
+
VALUE oj_in_sym;
|
93
95
|
VALUE oj_indent_sym;
|
96
|
+
VALUE oj_nanosecond_sym;
|
94
97
|
VALUE oj_object_class_sym;
|
95
98
|
VALUE oj_quirks_mode_sym;
|
96
99
|
VALUE oj_safe_sym;
|
@@ -120,6 +123,7 @@ static VALUE escape_mode_sym;
|
|
120
123
|
static VALUE integer_range_sym;
|
121
124
|
static VALUE fast_sym;
|
122
125
|
static VALUE float_prec_sym;
|
126
|
+
static VALUE float_format_sym;
|
123
127
|
static VALUE float_sym;
|
124
128
|
static VALUE huge_sym;
|
125
129
|
static VALUE ignore_sym;
|
@@ -132,11 +136,13 @@ static VALUE newline_sym;
|
|
132
136
|
static VALUE nilnil_sym;
|
133
137
|
static VALUE null_sym;
|
134
138
|
static VALUE object_sym;
|
139
|
+
static VALUE omit_null_byte_sym;
|
135
140
|
static VALUE omit_nil_sym;
|
136
141
|
static VALUE rails_sym;
|
137
142
|
static VALUE raise_sym;
|
138
143
|
static VALUE ruby_sym;
|
139
144
|
static VALUE sec_prec_sym;
|
145
|
+
static VALUE slash_sym;
|
140
146
|
static VALUE strict_sym;
|
141
147
|
static VALUE symbol_keys_sym;
|
142
148
|
static VALUE time_format_sym;
|
@@ -152,7 +158,8 @@ static VALUE word_sym;
|
|
152
158
|
static VALUE xmlschema_sym;
|
153
159
|
static VALUE xss_safe_sym;
|
154
160
|
|
155
|
-
rb_encoding *oj_utf8_encoding
|
161
|
+
rb_encoding *oj_utf8_encoding = 0;
|
162
|
+
int oj_utf8_encoding_index = 0;
|
156
163
|
|
157
164
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
158
165
|
pthread_mutex_t oj_cache_mutex;
|
@@ -217,6 +224,7 @@ struct _options oj_default_options = {
|
|
217
224
|
0, // array_size
|
218
225
|
AutoNan, // nan_dump
|
219
226
|
false, // omit_nil
|
227
|
+
false, // omit_null_byte
|
220
228
|
MAX_DEPTH, // max_depth
|
221
229
|
},
|
222
230
|
{
|
@@ -225,7 +233,7 @@ struct _options oj_default_options = {
|
|
225
233
|
NULL, // tail
|
226
234
|
{'\0'}, // err
|
227
235
|
},
|
228
|
-
NULL,
|
236
|
+
NULL,
|
229
237
|
};
|
230
238
|
|
231
239
|
/* Document-method: default_options()
|
@@ -239,7 +247,7 @@ struct _options oj_default_options = {
|
|
239
247
|
*references
|
240
248
|
* - *:auto_define* [_Boolean_|_nil_] automatically define classes if they do not exist
|
241
249
|
* - *:symbol_keys* [_Boolean_|_nil_] use symbols instead of strings for hash keys
|
242
|
-
* - *:escape_mode* [_:newline_|_:json_|_:xss_safe_|_:ascii_|
|
250
|
+
* - *:escape_mode* [_:newline_|_:json_|_:slash_|_:xss_safe_|_:ascii_|_:unicode_xss_|_nil_] determines the
|
243
251
|
*characters to escape
|
244
252
|
* - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing (if dynamically modifying
|
245
253
|
*classes or reloading classes then don't use this)
|
@@ -247,7 +255,7 @@ struct _options oj_default_options = {
|
|
247
255
|
*to use for JSON
|
248
256
|
* - *:time_format* [_:unix_|_:unix_zone_|_:xmlschema_|_:ruby_] time format when dumping
|
249
257
|
* - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a String
|
250
|
-
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_] load decimals as BigDecimal instead
|
258
|
+
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_|_:ruby_] load decimals as BigDecimal instead
|
251
259
|
*of as a Float. :auto pick the most precise for the number of digits. :float should be the same as
|
252
260
|
*ruby. :fast may require rounding but is must faster.
|
253
261
|
* - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float when in
|
@@ -260,6 +268,8 @@ struct _options oj_default_options = {
|
|
260
268
|
*seconds portion of time
|
261
269
|
* - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping floats, 0
|
262
270
|
*indicates use Ruby
|
271
|
+
* - *:float_format* [_String_] the C printf format string for printing floats. Default follows
|
272
|
+
* the float_precision and will be changed if float_precision is changed. The string can be no more than 6 bytes.
|
263
273
|
* - *:use_to_json* [_Boolean_|_nil_] call to_json() methods on dump, default is false
|
264
274
|
* - *:use_as_json* [_Boolean_|_nil_] call as_json() methods on dump, default is false
|
265
275
|
* - *:use_raw_json* [_Boolean_|_nil_] call raw_json() methods on dump, default is false
|
@@ -286,6 +296,7 @@ struct _options oj_default_options = {
|
|
286
296
|
*used
|
287
297
|
* - *:array_class* [_Class_|_nil_] Class to use instead of Array on load
|
288
298
|
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted
|
299
|
+
* - *:omit_null_byte* [_true_|_false_] if true null bytes in strings will be omitted when dumping
|
289
300
|
* - *:ignore* [_nil_|_Array_] either nil or an Array of classes to ignore when dumping
|
290
301
|
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when dumping in
|
291
302
|
*object or custom mode.
|
@@ -370,6 +381,7 @@ static VALUE get_def_opts(VALUE self) {
|
|
370
381
|
oj_safe_sym,
|
371
382
|
(Yes == oj_default_options.safe) ? Qtrue : ((No == oj_default_options.safe) ? Qfalse : Qnil));
|
372
383
|
rb_hash_aset(opts, float_prec_sym, INT2FIX(oj_default_options.float_prec));
|
384
|
+
rb_hash_aset(opts, float_format_sym, rb_str_new_cstr(oj_default_options.float_fmt));
|
373
385
|
rb_hash_aset(opts, cache_str_sym, INT2FIX(oj_default_options.cache_str));
|
374
386
|
rb_hash_aset(
|
375
387
|
opts,
|
@@ -379,6 +391,7 @@ static VALUE get_def_opts(VALUE self) {
|
|
379
391
|
opts,
|
380
392
|
cache_keys_sym,
|
381
393
|
(Yes == oj_default_options.cache_keys) ? Qtrue : ((No == oj_default_options.cache_keys) ? Qfalse : Qnil));
|
394
|
+
|
382
395
|
switch (oj_default_options.mode) {
|
383
396
|
case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
|
384
397
|
case CompatMode: rb_hash_aset(opts, mode_sym, compat_sym); break;
|
@@ -404,6 +417,7 @@ static VALUE get_def_opts(VALUE self) {
|
|
404
417
|
switch (oj_default_options.escape_mode) {
|
405
418
|
case NLEsc: rb_hash_aset(opts, escape_mode_sym, newline_sym); break;
|
406
419
|
case JSONEsc: rb_hash_aset(opts, escape_mode_sym, json_sym); break;
|
420
|
+
case SlashEsc: rb_hash_aset(opts, escape_mode_sym, slash_sym); break;
|
407
421
|
case XSSEsc: rb_hash_aset(opts, escape_mode_sym, xss_safe_sym); break;
|
408
422
|
case ASCIIEsc: rb_hash_aset(opts, escape_mode_sym, ascii_sym); break;
|
409
423
|
case JXEsc: rb_hash_aset(opts, escape_mode_sym, unicode_xss_sym); break;
|
@@ -453,13 +467,14 @@ static VALUE get_def_opts(VALUE self) {
|
|
453
467
|
default: rb_hash_aset(opts, nan_sym, auto_sym); break;
|
454
468
|
}
|
455
469
|
rb_hash_aset(opts, omit_nil_sym, oj_default_options.dump_opts.omit_nil ? Qtrue : Qfalse);
|
470
|
+
rb_hash_aset(opts, omit_null_byte_sym, oj_default_options.dump_opts.omit_null_byte ? Qtrue : Qfalse);
|
456
471
|
rb_hash_aset(opts, oj_hash_class_sym, oj_default_options.hash_class);
|
457
472
|
rb_hash_aset(opts, oj_array_class_sym, oj_default_options.array_class);
|
458
473
|
|
459
474
|
if (NULL == oj_default_options.ignore) {
|
460
475
|
rb_hash_aset(opts, ignore_sym, Qnil);
|
461
476
|
} else {
|
462
|
-
VALUE
|
477
|
+
VALUE *vp;
|
463
478
|
volatile VALUE a = rb_ary_new();
|
464
479
|
|
465
480
|
for (vp = oj_default_options.ignore; Qnil != *vp; vp++) {
|
@@ -508,6 +523,8 @@ static VALUE get_def_opts(VALUE self) {
|
|
508
523
|
*load.
|
509
524
|
* - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal when dumping the
|
510
525
|
*seconds portion of time.
|
526
|
+
* - *:float_format* [_String_] the C printf format string for printing floats. Default follows
|
527
|
+
* the float_precision and will be changed if float_precision is changed. The string can be no more than 6 bytes.
|
511
528
|
* - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping floats, 0
|
512
529
|
*indicates use Ruby.
|
513
530
|
* - *:use_to_json* [_Boolean_|_nil_] call to_json() methods on dump, default is false.
|
@@ -606,7 +623,6 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
606
623
|
if (set_yesno_options(k, v, copts)) {
|
607
624
|
return ST_CONTINUE;
|
608
625
|
}
|
609
|
-
|
610
626
|
if (oj_indent_sym == k) {
|
611
627
|
switch (rb_type(v)) {
|
612
628
|
case T_NIL:
|
@@ -634,15 +650,9 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
634
650
|
} else if (float_prec_sym == k) {
|
635
651
|
int n;
|
636
652
|
|
637
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
638
653
|
if (rb_cInteger != rb_obj_class(v)) {
|
639
654
|
rb_raise(rb_eArgError, ":float_precision must be a Integer.");
|
640
655
|
}
|
641
|
-
#else
|
642
|
-
if (T_FIXNUM != rb_type(v)) {
|
643
|
-
rb_raise(rb_eArgError, ":float_precision must be a Fixnum.");
|
644
|
-
}
|
645
|
-
#endif
|
646
656
|
n = FIX2INT(v);
|
647
657
|
if (0 >= n) {
|
648
658
|
*copts->float_fmt = '\0';
|
@@ -657,15 +667,9 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
657
667
|
} else if (cache_str_sym == k || cache_string_sym == k) {
|
658
668
|
int n;
|
659
669
|
|
660
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
661
670
|
if (rb_cInteger != rb_obj_class(v)) {
|
662
671
|
rb_raise(rb_eArgError, ":cache_str must be a Integer.");
|
663
672
|
}
|
664
|
-
#else
|
665
|
-
if (T_FIXNUM != rb_type(v)) {
|
666
|
-
rb_raise(rb_eArgError, ":cache_str must be a Fixnum.");
|
667
|
-
}
|
668
|
-
#endif
|
669
673
|
n = FIX2INT(v);
|
670
674
|
if (0 >= n) {
|
671
675
|
copts->cache_str = 0;
|
@@ -678,15 +682,9 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
678
682
|
} else if (sec_prec_sym == k) {
|
679
683
|
int n;
|
680
684
|
|
681
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
682
685
|
if (rb_cInteger != rb_obj_class(v)) {
|
683
686
|
rb_raise(rb_eArgError, ":second_precision must be a Integer.");
|
684
687
|
}
|
685
|
-
#else
|
686
|
-
if (T_FIXNUM != rb_type(v)) {
|
687
|
-
rb_raise(rb_eArgError, ":second_precision must be a Fixnum.");
|
688
|
-
}
|
689
|
-
#endif
|
690
688
|
n = NUM2INT(v);
|
691
689
|
if (0 > n) {
|
692
690
|
n = 0;
|
@@ -733,6 +731,8 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
733
731
|
copts->escape_mode = NLEsc;
|
734
732
|
} else if (json_sym == v) {
|
735
733
|
copts->escape_mode = JSONEsc;
|
734
|
+
} else if (slash_sym == v) {
|
735
|
+
copts->escape_mode = SlashEsc;
|
736
736
|
} else if (xss_safe_sym == v) {
|
737
737
|
copts->escape_mode = XSSEsc;
|
738
738
|
} else if (ascii_sym == v) {
|
@@ -762,7 +762,6 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
762
762
|
if (Qnil == v) {
|
763
763
|
return ST_CONTINUE;
|
764
764
|
}
|
765
|
-
|
766
765
|
copts->compat_bigdec = (Qtrue == v);
|
767
766
|
} else if (oj_decimal_class_sym == k) {
|
768
767
|
if (rb_cFloat == v) {
|
@@ -775,7 +774,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
775
774
|
} else if (create_id_sym == k) {
|
776
775
|
if (Qnil == v) {
|
777
776
|
if (oj_json_class != oj_default_options.create_id && NULL != copts->create_id) {
|
778
|
-
|
777
|
+
OJ_R_FREE((char *)oj_default_options.create_id);
|
779
778
|
}
|
780
779
|
copts->create_id = NULL;
|
781
780
|
copts->create_id_len = 0;
|
@@ -784,7 +783,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
784
783
|
|
785
784
|
len = RSTRING_LEN(v);
|
786
785
|
if (len != copts->create_id_len || 0 != strcmp(copts->create_id, str)) {
|
787
|
-
copts->create_id =
|
786
|
+
copts->create_id = OJ_R_ALLOC_N(char, len + 1);
|
788
787
|
strcpy((char *)copts->create_id, str);
|
789
788
|
copts->create_id_len = len;
|
790
789
|
}
|
@@ -875,6 +874,17 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
875
874
|
} else {
|
876
875
|
rb_raise(rb_eArgError, ":omit_nil must be true or false.");
|
877
876
|
}
|
877
|
+
} else if (omit_null_byte_sym == k) {
|
878
|
+
if (Qnil == v) {
|
879
|
+
return ST_CONTINUE;
|
880
|
+
}
|
881
|
+
if (Qtrue == v) {
|
882
|
+
copts->dump_opts.omit_null_byte = true;
|
883
|
+
} else if (Qfalse == v) {
|
884
|
+
copts->dump_opts.omit_null_byte = false;
|
885
|
+
} else {
|
886
|
+
rb_raise(rb_eArgError, ":omit_null_byte must be true or false.");
|
887
|
+
}
|
878
888
|
} else if (oj_ascii_only_sym == k) {
|
879
889
|
// This is here only for backwards compatibility with the original Oj.
|
880
890
|
if (Qtrue == v) {
|
@@ -904,7 +914,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
904
914
|
copts->array_class = v;
|
905
915
|
}
|
906
916
|
} else if (ignore_sym == k) {
|
907
|
-
|
917
|
+
OJ_R_FREE(copts->ignore);
|
908
918
|
copts->ignore = NULL;
|
909
919
|
if (Qnil != v) {
|
910
920
|
int cnt;
|
@@ -914,9 +924,9 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
914
924
|
if (0 < cnt) {
|
915
925
|
int i;
|
916
926
|
|
917
|
-
copts->ignore =
|
927
|
+
copts->ignore = OJ_R_ALLOC_N(VALUE, cnt + 1);
|
918
928
|
for (i = 0; i < cnt; i++) {
|
919
|
-
copts->ignore[i] =
|
929
|
+
copts->ignore[i] = RARRAY_AREF(v, i);
|
920
930
|
}
|
921
931
|
copts->ignore[i] = Qnil;
|
922
932
|
}
|
@@ -925,7 +935,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
925
935
|
if (Qnil == v) {
|
926
936
|
return ST_CONTINUE;
|
927
937
|
}
|
928
|
-
if (
|
938
|
+
if (rb_obj_class(v) == rb_cRange) {
|
929
939
|
VALUE min = rb_funcall(v, oj_begin_id, 0);
|
930
940
|
VALUE max = rb_funcall(v, oj_end_id, 0);
|
931
941
|
|
@@ -942,7 +952,26 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
942
952
|
if (Qnil == v) {
|
943
953
|
return ST_CONTINUE;
|
944
954
|
}
|
945
|
-
|
955
|
+
copts->sym_key = (Qtrue == v) ? Yes : No;
|
956
|
+
|
957
|
+
} else if (oj_max_nesting_sym == k) {
|
958
|
+
if (Qtrue == v) {
|
959
|
+
copts->dump_opts.max_depth = 100;
|
960
|
+
} else if (Qfalse == v || Qnil == v) {
|
961
|
+
copts->dump_opts.max_depth = MAX_DEPTH;
|
962
|
+
} else if (T_FIXNUM == rb_type(v)) {
|
963
|
+
copts->dump_opts.max_depth = NUM2INT(v);
|
964
|
+
if (0 >= copts->dump_opts.max_depth) {
|
965
|
+
copts->dump_opts.max_depth = MAX_DEPTH;
|
966
|
+
}
|
967
|
+
}
|
968
|
+
} else if (float_format_sym == k) {
|
969
|
+
rb_check_type(v, T_STRING);
|
970
|
+
if (6 < (int)RSTRING_LEN(v)) {
|
971
|
+
rb_raise(rb_eArgError, ":float_format must be 6 bytes or less.");
|
972
|
+
}
|
973
|
+
strncpy(copts->float_fmt, RSTRING_PTR(v), (size_t)RSTRING_LEN(v));
|
974
|
+
copts->float_fmt[RSTRING_LEN(v)] = '\0';
|
946
975
|
}
|
947
976
|
return ST_CONTINUE;
|
948
977
|
}
|
@@ -951,7 +980,6 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
951
980
|
if (T_HASH != rb_type(ropts)) {
|
952
981
|
return;
|
953
982
|
}
|
954
|
-
|
955
983
|
rb_hash_foreach(ropts, parse_options_cb, (VALUE)copts);
|
956
984
|
oj_parse_opt_match_string(&copts->str_rx, ropts);
|
957
985
|
|
@@ -1107,7 +1135,7 @@ static VALUE load(int argc, VALUE *argv, VALUE self) {
|
|
1107
1135
|
* Returns [_Object_|_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_]
|
1108
1136
|
*/
|
1109
1137
|
static VALUE load_file(int argc, VALUE *argv, VALUE self) {
|
1110
|
-
char
|
1138
|
+
char *path;
|
1111
1139
|
int fd;
|
1112
1140
|
Mode mode = oj_default_options.mode;
|
1113
1141
|
struct _parseInfo pi;
|
@@ -1115,7 +1143,7 @@ static VALUE load_file(int argc, VALUE *argv, VALUE self) {
|
|
1115
1143
|
if (1 > argc) {
|
1116
1144
|
rb_raise(rb_eArgError, "Wrong number of arguments to load().");
|
1117
1145
|
}
|
1118
|
-
|
1146
|
+
path = StringValuePtr(*argv);
|
1119
1147
|
parse_info_init(&pi);
|
1120
1148
|
pi.options = oj_default_options;
|
1121
1149
|
pi.handler = Qnil;
|
@@ -1146,8 +1174,17 @@ static VALUE load_file(int argc, VALUE *argv, VALUE self) {
|
|
1146
1174
|
}
|
1147
1175
|
}
|
1148
1176
|
}
|
1149
|
-
|
1150
|
-
|
1177
|
+
#ifdef _WIN32
|
1178
|
+
{
|
1179
|
+
WCHAR *wide_path;
|
1180
|
+
wide_path = rb_w32_mbstr_to_wstr(CP_UTF8, path, -1, NULL);
|
1181
|
+
fd = rb_w32_wopen(wide_path, O_RDONLY);
|
1182
|
+
OJ_FREE(wide_path);
|
1183
|
+
}
|
1184
|
+
#else
|
1185
|
+
fd = open(path, O_RDONLY);
|
1186
|
+
#endif
|
1187
|
+
if (0 == fd) {
|
1151
1188
|
rb_raise(rb_eIOError, "%s", strerror(errno));
|
1152
1189
|
}
|
1153
1190
|
switch (mode) {
|
@@ -1220,10 +1257,10 @@ static VALUE safe_load(VALUE self, VALUE doc) {
|
|
1220
1257
|
*/
|
1221
1258
|
|
1222
1259
|
struct dump_arg {
|
1223
|
-
struct _out
|
1260
|
+
struct _out *out;
|
1224
1261
|
struct _options *copts;
|
1225
1262
|
int argc;
|
1226
|
-
VALUE
|
1263
|
+
VALUE *argv;
|
1227
1264
|
};
|
1228
1265
|
|
1229
1266
|
static VALUE dump_body(VALUE a) {
|
@@ -1243,9 +1280,8 @@ static VALUE dump_body(VALUE a) {
|
|
1243
1280
|
static VALUE dump_ensure(VALUE a) {
|
1244
1281
|
volatile struct dump_arg *arg = (void *)a;
|
1245
1282
|
|
1246
|
-
|
1247
|
-
|
1248
|
-
}
|
1283
|
+
oj_out_free(arg->out);
|
1284
|
+
|
1249
1285
|
return Qnil;
|
1250
1286
|
}
|
1251
1287
|
|
@@ -1257,7 +1293,6 @@ static VALUE dump_ensure(VALUE a) {
|
|
1257
1293
|
* - *options* [_Hash_] same as default_options
|
1258
1294
|
*/
|
1259
1295
|
static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
1260
|
-
char buf[4096];
|
1261
1296
|
struct dump_arg arg;
|
1262
1297
|
struct _out out;
|
1263
1298
|
struct _options copts = oj_default_options;
|
@@ -1279,11 +1314,10 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1279
1314
|
arg.argc = argc;
|
1280
1315
|
arg.argv = argv;
|
1281
1316
|
|
1282
|
-
arg.out
|
1283
|
-
|
1284
|
-
arg.out->
|
1285
|
-
arg.out->
|
1286
|
-
arg.out->caller = CALLER_DUMP;
|
1317
|
+
oj_out_init(arg.out);
|
1318
|
+
|
1319
|
+
arg.out->omit_nil = copts.dump_opts.omit_nil;
|
1320
|
+
arg.out->omit_null_byte = copts.dump_opts.omit_null_byte;
|
1287
1321
|
|
1288
1322
|
return rb_ensure(dump_body, (VALUE)&arg, dump_ensure, (VALUE)&arg);
|
1289
1323
|
}
|
@@ -1295,8 +1329,9 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1295
1329
|
* will be called. The mode is set to :compat.
|
1296
1330
|
* - *obj* [_Object_] Object to serialize as an JSON document String
|
1297
1331
|
* - *options* [_Hash_]
|
1298
|
-
* - *:max_nesting* [_boolean_] It true nesting is limited to 100.
|
1299
|
-
*
|
1332
|
+
* - *:max_nesting* [_Fixnum_|_boolean_] It true nesting is limited to 100. If a Fixnum nesting
|
1333
|
+
* is set to the provided value. The option to detect circular references is available but is not
|
1334
|
+
* compatible with the json gem., default is false or unlimited.
|
1300
1335
|
* - *:allow_nan* [_boolean_] If true non JSON compliant words such as Nan and Infinity will be
|
1301
1336
|
* used as appropriate, default is true.
|
1302
1337
|
* - *:quirks_mode* [_boolean_] Allow single JSON values instead of documents, default is true
|
@@ -1313,7 +1348,6 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1313
1348
|
* Returns [_String_] the encoded JSON.
|
1314
1349
|
*/
|
1315
1350
|
static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
1316
|
-
char buf[4096];
|
1317
1351
|
struct _out out;
|
1318
1352
|
struct _options copts = oj_default_options;
|
1319
1353
|
VALUE rstr;
|
@@ -1328,10 +1362,11 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
|
1328
1362
|
}
|
1329
1363
|
copts.mode = CompatMode;
|
1330
1364
|
copts.to_json = Yes;
|
1331
|
-
|
1332
|
-
out
|
1333
|
-
|
1334
|
-
out.omit_nil
|
1365
|
+
|
1366
|
+
oj_out_init(&out);
|
1367
|
+
|
1368
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
1369
|
+
out.omit_null_byte = copts.dump_opts.omit_null_byte;
|
1335
1370
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
1336
1371
|
// it is.
|
1337
1372
|
oj_dump_obj_to_json_using_params(*argv, &copts, &out, argc - 1, argv + 1);
|
@@ -1341,9 +1376,9 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
|
1341
1376
|
}
|
1342
1377
|
rstr = rb_str_new2(out.buf);
|
1343
1378
|
rstr = oj_encode(rstr);
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1379
|
+
|
1380
|
+
oj_out_free(&out);
|
1381
|
+
|
1347
1382
|
return rstr;
|
1348
1383
|
}
|
1349
1384
|
|
@@ -1363,7 +1398,6 @@ static VALUE to_file(int argc, VALUE *argv, VALUE self) {
|
|
1363
1398
|
if (3 == argc) {
|
1364
1399
|
oj_parse_options(argv[2], &copts);
|
1365
1400
|
}
|
1366
|
-
Check_Type(*argv, T_STRING);
|
1367
1401
|
oj_write_obj_to_file(argv[1], StringValuePtr(*argv), &copts);
|
1368
1402
|
|
1369
1403
|
return Qnil;
|
@@ -1703,6 +1737,18 @@ static VALUE protect_require(VALUE x) {
|
|
1703
1737
|
return Qnil;
|
1704
1738
|
}
|
1705
1739
|
|
1740
|
+
extern void print_all_odds(const char *label);
|
1741
|
+
|
1742
|
+
static VALUE debug_odd(VALUE self, VALUE label) {
|
1743
|
+
print_all_odds(RSTRING_PTR(label));
|
1744
|
+
return Qnil;
|
1745
|
+
}
|
1746
|
+
|
1747
|
+
static VALUE mem_report(VALUE self) {
|
1748
|
+
oj_mem_report();
|
1749
|
+
return Qnil;
|
1750
|
+
}
|
1751
|
+
|
1706
1752
|
/* Document-module: Oj
|
1707
1753
|
*
|
1708
1754
|
* Optimized JSON (Oj), as the name implies was written to provide speed
|
@@ -1731,15 +1777,19 @@ static VALUE protect_require(VALUE x) {
|
|
1731
1777
|
*
|
1732
1778
|
* - *:wab* specifically for WAB data exchange.
|
1733
1779
|
*/
|
1734
|
-
void Init_oj() {
|
1780
|
+
void Init_oj(void) {
|
1735
1781
|
int err = 0;
|
1736
1782
|
|
1737
1783
|
#if HAVE_RB_EXT_RACTOR_SAFE
|
1738
1784
|
rb_ext_ractor_safe(true);
|
1739
1785
|
#endif
|
1740
1786
|
Oj = rb_define_module("Oj");
|
1787
|
+
rb_gc_register_address(&Oj);
|
1741
1788
|
|
1742
1789
|
oj_cstack_class = rb_define_class_under(Oj, "CStack", rb_cObject);
|
1790
|
+
rb_gc_register_address(&oj_cstack_class);
|
1791
|
+
|
1792
|
+
rb_undef_alloc_func(oj_cstack_class);
|
1743
1793
|
|
1744
1794
|
oj_string_writer_init();
|
1745
1795
|
oj_stream_writer_init();
|
@@ -1748,9 +1798,11 @@ void Init_oj() {
|
|
1748
1798
|
// On Rubinius the require fails but can be done from a ruby file.
|
1749
1799
|
rb_protect(protect_require, Qnil, &err);
|
1750
1800
|
rb_require("stringio");
|
1751
|
-
|
1801
|
+
oj_utf8_encoding_index = rb_enc_find_index("UTF-8");
|
1802
|
+
oj_utf8_encoding = rb_enc_from_index(oj_utf8_encoding_index);
|
1752
1803
|
|
1753
1804
|
// rb_define_module_function(Oj, "hash_test", hash_test, 0);
|
1805
|
+
rb_define_module_function(Oj, "debug_odd", debug_odd, 1);
|
1754
1806
|
|
1755
1807
|
rb_define_module_function(Oj, "default_options", get_def_opts, 0);
|
1756
1808
|
rb_define_module_function(Oj, "default_options=", set_def_opts, 1);
|
@@ -1784,49 +1836,51 @@ void Init_oj() {
|
|
1784
1836
|
|
1785
1837
|
rb_define_module_function(Oj, "optimize_rails", oj_optimize_rails, 0);
|
1786
1838
|
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1839
|
+
rb_define_module_function(Oj, "mem_report", mem_report, 0);
|
1840
|
+
|
1841
|
+
oj_add_value_id = rb_intern("add_value");
|
1842
|
+
oj_array_append_id = rb_intern("array_append");
|
1843
|
+
oj_array_end_id = rb_intern("array_end");
|
1844
|
+
oj_array_start_id = rb_intern("array_start");
|
1845
|
+
oj_as_json_id = rb_intern("as_json");
|
1846
|
+
oj_at_id = rb_intern("at");
|
1847
|
+
oj_begin_id = rb_intern("begin");
|
1848
|
+
oj_bigdecimal_id = rb_intern("BigDecimal");
|
1849
|
+
oj_end_id = rb_intern("end");
|
1850
|
+
oj_error_id = rb_intern("error");
|
1851
|
+
oj_exclude_end_id = rb_intern("exclude_end?");
|
1852
|
+
oj_file_id = rb_intern("file?");
|
1853
|
+
oj_fileno_id = rb_intern("fileno");
|
1854
|
+
oj_ftype_id = rb_intern("ftype");
|
1855
|
+
oj_hash_end_id = rb_intern("hash_end");
|
1856
|
+
oj_hash_key_id = rb_intern("hash_key");
|
1857
|
+
oj_hash_set_id = rb_intern("hash_set");
|
1858
|
+
oj_hash_start_id = rb_intern("hash_start");
|
1859
|
+
oj_iconv_id = rb_intern("iconv");
|
1860
|
+
oj_json_create_id = rb_intern("json_create");
|
1861
|
+
oj_length_id = rb_intern("length");
|
1862
|
+
oj_new_id = rb_intern("new");
|
1863
|
+
oj_parse_id = rb_intern("parse");
|
1864
|
+
oj_pos_id = rb_intern("pos");
|
1865
|
+
oj_raw_json_id = rb_intern("raw_json");
|
1866
|
+
oj_read_id = rb_intern("read");
|
1867
|
+
oj_readpartial_id = rb_intern("readpartial");
|
1868
|
+
oj_replace_id = rb_intern("replace");
|
1869
|
+
oj_stat_id = rb_intern("stat");
|
1870
|
+
oj_string_id = rb_intern("string");
|
1871
|
+
oj_to_h_id = rb_intern("to_h");
|
1872
|
+
oj_to_hash_id = rb_intern("to_hash");
|
1873
|
+
oj_to_json_id = rb_intern("to_json");
|
1874
|
+
oj_to_s_id = rb_intern("to_s");
|
1875
|
+
oj_to_sym_id = rb_intern("to_sym");
|
1876
|
+
oj_to_time_id = rb_intern("to_time");
|
1877
|
+
oj_tv_nsec_id = rb_intern("tv_nsec");
|
1878
|
+
oj_tv_sec_id = rb_intern("tv_sec");
|
1879
|
+
oj_tv_usec_id = rb_intern("tv_usec");
|
1880
|
+
oj_utc_id = rb_intern("utc");
|
1881
|
+
oj_utc_offset_id = rb_intern("utc_offset");
|
1882
|
+
oj_utcq_id = rb_intern("utc?");
|
1883
|
+
oj_write_id = rb_intern("write");
|
1830
1884
|
|
1831
1885
|
rb_require("oj/bag");
|
1832
1886
|
rb_require("oj/error");
|
@@ -1897,6 +1951,8 @@ void Init_oj() {
|
|
1897
1951
|
rb_gc_register_address(&integer_range_sym);
|
1898
1952
|
fast_sym = ID2SYM(rb_intern("fast"));
|
1899
1953
|
rb_gc_register_address(&fast_sym);
|
1954
|
+
float_format_sym = ID2SYM(rb_intern("float_format"));
|
1955
|
+
rb_gc_register_address(&float_format_sym);
|
1900
1956
|
float_prec_sym = ID2SYM(rb_intern("float_precision"));
|
1901
1957
|
rb_gc_register_address(&float_prec_sym);
|
1902
1958
|
float_sym = ID2SYM(rb_intern("float"));
|
@@ -1937,10 +1993,14 @@ void Init_oj() {
|
|
1937
1993
|
rb_gc_register_address(&oj_decimal_class_sym);
|
1938
1994
|
oj_hash_class_sym = ID2SYM(rb_intern("hash_class"));
|
1939
1995
|
rb_gc_register_address(&oj_hash_class_sym);
|
1996
|
+
oj_in_sym = ID2SYM(rb_intern("in"));
|
1997
|
+
rb_gc_register_address(&oj_in_sym);
|
1940
1998
|
oj_indent_sym = ID2SYM(rb_intern("indent"));
|
1941
1999
|
rb_gc_register_address(&oj_indent_sym);
|
1942
2000
|
oj_max_nesting_sym = ID2SYM(rb_intern("max_nesting"));
|
1943
2001
|
rb_gc_register_address(&oj_max_nesting_sym);
|
2002
|
+
oj_nanosecond_sym = ID2SYM(rb_intern("nanosecond"));
|
2003
|
+
rb_gc_register_address(&oj_nanosecond_sym);
|
1944
2004
|
oj_object_class_sym = ID2SYM(rb_intern("object_class"));
|
1945
2005
|
rb_gc_register_address(&oj_object_class_sym);
|
1946
2006
|
oj_object_nl_sym = ID2SYM(rb_intern("object_nl"));
|
@@ -1949,6 +2009,8 @@ void Init_oj() {
|
|
1949
2009
|
rb_gc_register_address(&oj_quirks_mode_sym);
|
1950
2010
|
oj_safe_sym = ID2SYM(rb_intern("safe"));
|
1951
2011
|
rb_gc_register_address(&oj_safe_sym);
|
2012
|
+
omit_null_byte_sym = ID2SYM(rb_intern("omit_null_byte"));
|
2013
|
+
rb_gc_register_address(&omit_null_byte_sym);
|
1952
2014
|
oj_space_before_sym = ID2SYM(rb_intern("space_before"));
|
1953
2015
|
rb_gc_register_address(&oj_space_before_sym);
|
1954
2016
|
oj_space_sym = ID2SYM(rb_intern("space"));
|
@@ -1965,6 +2027,8 @@ void Init_oj() {
|
|
1965
2027
|
rb_gc_register_address(&ruby_sym);
|
1966
2028
|
sec_prec_sym = ID2SYM(rb_intern("second_precision"));
|
1967
2029
|
rb_gc_register_address(&sec_prec_sym);
|
2030
|
+
slash_sym = ID2SYM(rb_intern("slash"));
|
2031
|
+
rb_gc_register_address(&slash_sym);
|
1968
2032
|
strict_sym = ID2SYM(rb_intern("strict"));
|
1969
2033
|
rb_gc_register_address(&strict_sym);
|
1970
2034
|
symbol_keys_sym = ID2SYM(rb_intern("symbol_keys"));
|
@@ -2017,4 +2081,5 @@ void Init_oj() {
|
|
2017
2081
|
oj_init_doc();
|
2018
2082
|
|
2019
2083
|
oj_parser_init();
|
2084
|
+
oj_scanner_init();
|
2020
2085
|
}
|