oj 3.13.9 → 3.16.1
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 +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
|
}
|