oj 3.14.2 → 3.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/README.md +0 -1
- data/ext/oj/buf.h +2 -2
- data/ext/oj/cache.c +16 -16
- data/ext/oj/cache8.c +7 -7
- data/ext/oj/circarray.c +2 -1
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +2 -2
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +6 -14
- data/ext/oj/custom.c +6 -16
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +43 -18
- data/ext/oj/dump_compat.c +551 -576
- data/ext/oj/dump_leaf.c +3 -5
- data/ext/oj/dump_object.c +35 -36
- data/ext/oj/dump_strict.c +2 -4
- data/ext/oj/encoder.c +1 -1
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +1 -1
- data/ext/oj/fast.c +24 -38
- data/ext/oj/intern.c +38 -42
- data/ext/oj/intern.h +3 -7
- data/ext/oj/mem.c +211 -217
- data/ext/oj/mem.h +10 -10
- data/ext/oj/mimic_json.c +39 -24
- data/ext/oj/object.c +12 -26
- data/ext/oj/odd.c +2 -1
- data/ext/oj/odd.h +4 -4
- data/ext/oj/oj.c +80 -81
- data/ext/oj/oj.h +56 -54
- data/ext/oj/parse.c +55 -118
- data/ext/oj/parse.h +5 -10
- data/ext/oj/parser.c +7 -8
- data/ext/oj/parser.h +7 -8
- data/ext/oj/rails.c +28 -59
- data/ext/oj/reader.c +5 -9
- data/ext/oj/reader.h +1 -1
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +1 -1
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +4 -4
- data/ext/oj/saj2.c +32 -49
- data/ext/oj/saj2.h +1 -1
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +18 -67
- data/ext/oj/stream_writer.c +5 -18
- data/ext/oj/strict.c +16 -40
- data/ext/oj/string_writer.c +6 -14
- data/ext/oj/trace.h +27 -16
- data/ext/oj/usual.c +62 -61
- data/ext/oj/usual.h +6 -6
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.h +4 -4
- data/ext/oj/wab.c +16 -36
- data/lib/oj/active_support_helper.rb +0 -1
- 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 +4 -2
- data/lib/oj/mimic.rb +4 -2
- data/lib/oj/state.rb +8 -5
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/Options.md +4 -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/files.rb +15 -15
- data/test/foo.rb +9 -52
- data/test/helper.rb +5 -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 +4 -4
- 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 +43 -32
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +46 -46
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/mem.rb +13 -12
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +25 -25
- 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 +41 -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 +52 -52
- data/test/test_custom.rb +61 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +86 -90
- data/test/test_file.rb +24 -29
- data/test/test_gc.rb +5 -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 +78 -87
- data/test/test_parser.rb +4 -4
- data/test/test_parser_debug.rb +4 -4
- data/test/test_parser_saj.rb +27 -25
- 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 +35 -35
- data/test/test_strict.rb +28 -32
- data/test/test_various.rb +140 -97
- data/test/test_wab.rb +46 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +7 -7
- data/test/tests_mimic.rb +6 -6
- data/test/tests_mimic_addition.rb +6 -6
- metadata +18 -30
- 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/abstract_unit.rb +0 -45
- data/test/activesupport5/decoding_test.rb +0 -133
- data/test/activesupport5/encoding_test.rb +0 -500
- data/test/activesupport5/encoding_test_cases.rb +0 -98
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/activesupport5/time_zone_test_helpers.rb +0 -39
- data/test/bar.rb +0 -11
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/mimic_json.c
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
// Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
|
2
2
|
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
3
3
|
|
4
|
-
#include "mem.h"
|
5
4
|
#include "dump.h"
|
6
5
|
#include "encode.h"
|
6
|
+
#include "mem.h"
|
7
7
|
#include "oj.h"
|
8
8
|
#include "parse.h"
|
9
9
|
|
@@ -349,12 +349,11 @@ static VALUE mimic_load(int argc, VALUE *argv, VALUE self) {
|
|
349
349
|
static VALUE mimic_dump_load(int argc, VALUE *argv, VALUE self) {
|
350
350
|
if (1 > argc) {
|
351
351
|
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
|
352
|
-
}
|
352
|
+
}
|
353
|
+
if (T_STRING == rb_type(*argv)) {
|
353
354
|
return mimic_load(argc, argv, self);
|
354
|
-
} else {
|
355
|
-
return mimic_dump(argc, argv, self);
|
356
355
|
}
|
357
|
-
return
|
356
|
+
return mimic_dump(argc, argv, self);
|
358
357
|
}
|
359
358
|
|
360
359
|
static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
@@ -368,8 +367,8 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
|
368
367
|
|
369
368
|
oj_out_init(&out);
|
370
369
|
|
371
|
-
out.omit_nil
|
372
|
-
out.caller
|
370
|
+
out.omit_nil = copts->dump_opts.omit_nil;
|
371
|
+
out.caller = CALLER_GENERATE;
|
373
372
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
374
373
|
// it is.
|
375
374
|
copts->dump_opts.nan_dump = RaiseNan;
|
@@ -389,10 +388,8 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
|
389
388
|
VALUE active_hack[1];
|
390
389
|
|
391
390
|
if (Qundef == state_class) {
|
392
|
-
rb_warn(
|
393
|
-
|
394
|
-
"Call it explicitly beforehand if you want to remove this warning."
|
395
|
-
);
|
391
|
+
rb_warn("Oj::Rails.mimic_JSON was called implicitly. "
|
392
|
+
"Call it explicitly beforehand if you want to remove this warning.");
|
396
393
|
oj_define_mimic_json(0, NULL, Qnil);
|
397
394
|
}
|
398
395
|
active_hack[0] = rb_funcall(state_class, oj_new_id, 0);
|
@@ -467,7 +464,7 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
|
467
464
|
}
|
468
465
|
if (1 == argc || Qnil == argv[1]) {
|
469
466
|
h = rb_hash_new();
|
470
|
-
} else
|
467
|
+
} else {
|
471
468
|
h = argv[1];
|
472
469
|
}
|
473
470
|
if (!oj_hash_has_key(h, oj_indent_sym)) {
|
@@ -486,10 +483,8 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
|
486
483
|
rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
|
487
484
|
}
|
488
485
|
if (Qundef == state_class) {
|
489
|
-
rb_warn(
|
490
|
-
|
491
|
-
"Call it explicitly beforehand if you want to remove this warning."
|
492
|
-
);
|
486
|
+
rb_warn("Oj::Rails.mimic_JSON was called implicitly. "
|
487
|
+
"Call it explicitly beforehand if you want to remove this warning.");
|
493
488
|
oj_define_mimic_json(0, NULL, Qnil);
|
494
489
|
}
|
495
490
|
rargs[1] = rb_funcall(state_class, oj_new_id, 1, h);
|
@@ -658,11 +653,9 @@ static VALUE mimic_recurse_proc(VALUE self, VALUE obj) {
|
|
658
653
|
*
|
659
654
|
* - *id* [_nil_|String] new create_id
|
660
655
|
*
|
661
|
-
* Returns [_String_] the id.
|
656
|
+
* Returns [_nil_|_String_] the id.
|
662
657
|
*/
|
663
658
|
static VALUE mimic_set_create_id(VALUE self, VALUE id) {
|
664
|
-
Check_Type(id, T_STRING);
|
665
|
-
|
666
659
|
if (NULL != oj_default_options.create_id) {
|
667
660
|
if (oj_json_class != oj_default_options.create_id) {
|
668
661
|
OJ_R_FREE((char *)oj_default_options.create_id);
|
@@ -671,10 +664,11 @@ static VALUE mimic_set_create_id(VALUE self, VALUE id) {
|
|
671
664
|
oj_default_options.create_id_len = 0;
|
672
665
|
}
|
673
666
|
if (Qnil != id) {
|
674
|
-
|
667
|
+
const char *ptr = StringValueCStr(id);
|
668
|
+
size_t len = RSTRING_LEN(id) + 1;
|
675
669
|
|
676
670
|
oj_default_options.create_id = OJ_R_ALLOC_N(char, len);
|
677
|
-
strcpy((char *)oj_default_options.create_id,
|
671
|
+
strcpy((char *)oj_default_options.create_id, ptr);
|
678
672
|
oj_default_options.create_id_len = len - 1;
|
679
673
|
}
|
680
674
|
return id;
|
@@ -744,6 +738,7 @@ static struct _options mimic_object_to_json_options = {0, // indent
|
|
744
738
|
0, // array_size
|
745
739
|
RaiseNan, // nan_dump
|
746
740
|
false, // omit_nil
|
741
|
+
false, // omit_null_byte
|
747
742
|
100, // max_depth
|
748
743
|
},
|
749
744
|
{
|
@@ -763,9 +758,9 @@ static VALUE mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
|
|
763
758
|
|
764
759
|
oj_out_init(&out);
|
765
760
|
|
766
|
-
out.omit_nil
|
767
|
-
copts.mode
|
768
|
-
copts.to_json
|
761
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
762
|
+
copts.mode = CompatMode;
|
763
|
+
copts.to_json = No;
|
769
764
|
if (1 <= argc && Qnil != argv[0]) {
|
770
765
|
oj_parse_mimic_dump_options(argv[0], &copts);
|
771
766
|
}
|
@@ -797,28 +792,48 @@ void oj_mimic_json_methods(VALUE json) {
|
|
797
792
|
VALUE json_error;
|
798
793
|
VALUE generator;
|
799
794
|
VALUE ext;
|
795
|
+
VALUE verbose;
|
796
|
+
|
797
|
+
// rb_undef_method doesn't work for modules or maybe sometimes
|
798
|
+
// doesn't. Anyway setting verbose should hide the warning.
|
799
|
+
verbose = rb_gv_get("$VERBOSE");
|
800
|
+
rb_gv_set("$VERBOSE", Qfalse);
|
800
801
|
|
802
|
+
rb_undef_method(json, "create_id=");
|
801
803
|
rb_define_module_function(json, "create_id=", mimic_set_create_id, 1);
|
804
|
+
rb_undef_method(json, "create_id");
|
802
805
|
rb_define_module_function(json, "create_id", mimic_create_id, 0);
|
803
806
|
|
807
|
+
rb_undef_method(json, "dump");
|
804
808
|
rb_define_module_function(json, "dump", mimic_dump, -1);
|
809
|
+
rb_undef_method(json, "load");
|
805
810
|
rb_define_module_function(json, "load", mimic_load, -1);
|
806
811
|
rb_define_module_function(json, "restore", mimic_load, -1);
|
812
|
+
rb_undef_method(json, "recurse_proc");
|
807
813
|
rb_define_module_function(json, "recurse_proc", mimic_recurse_proc, 1);
|
814
|
+
rb_undef_method(json, "[]");
|
808
815
|
rb_define_module_function(json, "[]", mimic_dump_load, -1);
|
809
816
|
|
817
|
+
rb_undef_method(json, "generate");
|
810
818
|
rb_define_module_function(json, "generate", oj_mimic_generate, -1);
|
819
|
+
rb_undef_method(json, "fast_generate");
|
811
820
|
rb_define_module_function(json, "fast_generate", oj_mimic_generate, -1);
|
821
|
+
rb_undef_method(json, "pretty_generate");
|
812
822
|
rb_define_module_function(json, "pretty_generate", oj_mimic_pretty_generate, -1);
|
813
823
|
// For older versions of JSON, the deprecated unparse methods.
|
824
|
+
rb_undef_method(json, "unparse");
|
814
825
|
rb_define_module_function(json, "unparse", oj_mimic_generate, -1);
|
815
826
|
rb_define_module_function(json, "fast_unparse", oj_mimic_generate, -1);
|
816
827
|
rb_define_module_function(json, "pretty_unparse", oj_mimic_pretty_generate, -1);
|
817
828
|
|
829
|
+
rb_undef_method(json, "parse");
|
818
830
|
rb_define_module_function(json, "parse", oj_mimic_parse, -1);
|
831
|
+
rb_undef_method(json, "parse!");
|
819
832
|
rb_define_module_function(json, "parse!", mimic_parse_bang, -1);
|
820
833
|
|
834
|
+
rb_undef_method(json, "state");
|
821
835
|
rb_define_module_function(json, "state", mimic_state, 0);
|
836
|
+
rb_gv_set("$VERBOSE", verbose);
|
822
837
|
|
823
838
|
if (rb_const_defined_at(json, rb_intern("JSONError"))) {
|
824
839
|
json_error = rb_const_get(json, rb_intern("JSONError"));
|
data/ext/oj/object.c
CHANGED
@@ -270,8 +270,8 @@ static int hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
|
|
270
270
|
parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
|
271
271
|
} else if (ni->has_exp) {
|
272
272
|
struct timespec ts;
|
273
|
-
ts.tv_sec
|
274
|
-
ts.tv_nsec
|
273
|
+
ts.tv_sec = ni->i;
|
274
|
+
ts.tv_nsec = nsec;
|
275
275
|
parent->val = rb_time_timespec_new(&ts, (int)ni->exp);
|
276
276
|
} else {
|
277
277
|
parent->val = rb_time_nano_new(ni->i, (long)nsec);
|
@@ -325,14 +325,14 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
325
325
|
sc = oj_name2struct(pi, *RARRAY_CONST_PTR(value), rb_eArgError);
|
326
326
|
}
|
327
327
|
if (sc == rb_cRange) {
|
328
|
-
|
328
|
+
parent->val = rb_class_new_instance(len - 1, RARRAY_CONST_PTR(value) + 1, rb_cRange);
|
329
329
|
} else {
|
330
330
|
// Create a properly initialized struct instance without calling the initialize method.
|
331
331
|
parent->val = rb_obj_alloc(sc);
|
332
332
|
// If the JSON array has more entries than the struct class allows, we record an error.
|
333
333
|
#ifdef RSTRUCT_LEN
|
334
334
|
#if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
335
|
-
|
335
|
+
slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
|
336
336
|
#else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
337
337
|
slen = (int)RSTRUCT_LEN(parent->val);
|
338
338
|
#endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
@@ -446,9 +446,7 @@ WHICH_TYPE:
|
|
446
446
|
rb_class2name(rb_obj_class(parent->val)));
|
447
447
|
return;
|
448
448
|
}
|
449
|
-
|
450
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
|
451
|
-
}
|
449
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
|
452
450
|
}
|
453
451
|
|
454
452
|
static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
@@ -517,9 +515,7 @@ WHICH_TYPE:
|
|
517
515
|
rb_class2name(rb_obj_class(parent->val)));
|
518
516
|
return;
|
519
517
|
}
|
520
|
-
|
521
|
-
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, rval);
|
522
|
-
}
|
518
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, rval);
|
523
519
|
}
|
524
520
|
|
525
521
|
static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
@@ -545,7 +541,7 @@ WHICH_TYPE:
|
|
545
541
|
}
|
546
542
|
} else {
|
547
543
|
if (3 <= klen && '^' == *key && '#' == key[1] && T_ARRAY == rb_type(value)) {
|
548
|
-
long
|
544
|
+
long len = RARRAY_LEN(value);
|
549
545
|
volatile const VALUE *a = RARRAY_CONST_PTR(value);
|
550
546
|
|
551
547
|
if (2 != len) {
|
@@ -603,9 +599,7 @@ WHICH_TYPE:
|
|
603
599
|
rb_class2name(rb_obj_class(parent->val)));
|
604
600
|
return;
|
605
601
|
}
|
606
|
-
|
607
|
-
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, value);
|
608
|
-
}
|
602
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, value);
|
609
603
|
}
|
610
604
|
|
611
605
|
static VALUE start_hash(ParseInfo pi) {
|
@@ -651,32 +645,24 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
651
645
|
}
|
652
646
|
rval = str_to_value(pi, str, len, orig);
|
653
647
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
654
|
-
|
655
|
-
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rval);
|
656
|
-
}
|
648
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rval);
|
657
649
|
}
|
658
650
|
|
659
651
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
660
652
|
volatile VALUE rval = oj_num_as_value(ni);
|
661
653
|
|
662
654
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
663
|
-
|
664
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
665
|
-
}
|
655
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
|
666
656
|
}
|
667
657
|
|
668
658
|
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
669
659
|
pi->stack.head->val = str_to_value(pi, str, len, orig);
|
670
|
-
|
671
|
-
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
|
672
|
-
}
|
660
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, pi->stack.head->val);
|
673
661
|
}
|
674
662
|
|
675
663
|
static void add_num(ParseInfo pi, NumInfo ni) {
|
676
664
|
pi->stack.head->val = oj_num_as_value(ni);
|
677
|
-
|
678
|
-
oj_trace_parse_call("add_num", pi, __FILE__, __LINE__, pi->stack.head->val);
|
679
|
-
}
|
665
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_num", pi, pi->stack.head->val);
|
680
666
|
}
|
681
667
|
|
682
668
|
void oj_set_object_callbacks(ParseInfo pi) {
|
data/ext/oj/odd.c
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
2
2
|
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
3
3
|
|
4
|
-
#include "mem.h"
|
5
4
|
#include "odd.h"
|
6
5
|
|
7
6
|
#include <string.h>
|
8
7
|
|
8
|
+
#include "mem.h"
|
9
|
+
|
9
10
|
static Odd odds = NULL;
|
10
11
|
static ID sec_id;
|
11
12
|
static ID sec_fraction_id;
|
data/ext/oj/odd.h
CHANGED
@@ -14,7 +14,7 @@ typedef VALUE (*AttrGetFunc)(VALUE obj);
|
|
14
14
|
|
15
15
|
typedef struct _odd {
|
16
16
|
struct _odd *next;
|
17
|
-
const char
|
17
|
+
const char *classname;
|
18
18
|
size_t clen;
|
19
19
|
VALUE clas; // Ruby class or module
|
20
20
|
VALUE create_obj;
|
@@ -22,15 +22,15 @@ typedef struct _odd {
|
|
22
22
|
int attr_cnt;
|
23
23
|
bool is_module;
|
24
24
|
bool raw;
|
25
|
-
const char
|
25
|
+
const char *attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
|
26
26
|
ID attrs[MAX_ODD_ARGS]; // 0 terminated attr IDs
|
27
27
|
AttrGetFunc attrFuncs[MAX_ODD_ARGS];
|
28
|
-
} *
|
28
|
+
} *Odd;
|
29
29
|
|
30
30
|
typedef struct _oddArgs {
|
31
31
|
Odd odd;
|
32
32
|
VALUE args[MAX_ODD_ARGS];
|
33
|
-
} *
|
33
|
+
} *OddArgs;
|
34
34
|
|
35
35
|
extern void oj_odd_init(void);
|
36
36
|
extern Odd oj_get_odd(VALUE clas);
|
data/ext/oj/oj.c
CHANGED
@@ -11,10 +11,10 @@
|
|
11
11
|
#include <sys/types.h>
|
12
12
|
#include <unistd.h>
|
13
13
|
|
14
|
-
#include "mem.h"
|
15
14
|
#include "dump.h"
|
16
15
|
#include "encode.h"
|
17
16
|
#include "intern.h"
|
17
|
+
#include "mem.h"
|
18
18
|
#include "odd.h"
|
19
19
|
#include "parse.h"
|
20
20
|
#include "rails.h"
|
@@ -22,7 +22,7 @@
|
|
22
22
|
typedef struct _yesNoOpt {
|
23
23
|
VALUE sym;
|
24
24
|
char *attr;
|
25
|
-
} *
|
25
|
+
} *YesNoOpt;
|
26
26
|
|
27
27
|
void Init_oj();
|
28
28
|
|
@@ -135,6 +135,7 @@ static VALUE newline_sym;
|
|
135
135
|
static VALUE nilnil_sym;
|
136
136
|
static VALUE null_sym;
|
137
137
|
static VALUE object_sym;
|
138
|
+
static VALUE omit_null_byte_sym;
|
138
139
|
static VALUE omit_nil_sym;
|
139
140
|
static VALUE rails_sym;
|
140
141
|
static VALUE raise_sym;
|
@@ -156,8 +157,8 @@ static VALUE word_sym;
|
|
156
157
|
static VALUE xmlschema_sym;
|
157
158
|
static VALUE xss_safe_sym;
|
158
159
|
|
159
|
-
rb_encoding *oj_utf8_encoding
|
160
|
-
int
|
160
|
+
rb_encoding *oj_utf8_encoding = 0;
|
161
|
+
int oj_utf8_encoding_index = 0;
|
161
162
|
|
162
163
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
163
164
|
pthread_mutex_t oj_cache_mutex;
|
@@ -222,6 +223,7 @@ struct _options oj_default_options = {
|
|
222
223
|
0, // array_size
|
223
224
|
AutoNan, // nan_dump
|
224
225
|
false, // omit_nil
|
226
|
+
false, // omit_null_byte
|
225
227
|
MAX_DEPTH, // max_depth
|
226
228
|
},
|
227
229
|
{
|
@@ -291,6 +293,7 @@ struct _options oj_default_options = {
|
|
291
293
|
*used
|
292
294
|
* - *:array_class* [_Class_|_nil_] Class to use instead of Array on load
|
293
295
|
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted
|
296
|
+
* - *:omit_null_byte* [_true_|_false_] if true null bytes in strings will be omitted when dumping
|
294
297
|
* - *:ignore* [_nil_|_Array_] either nil or an Array of classes to ignore when dumping
|
295
298
|
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when dumping in
|
296
299
|
*object or custom mode.
|
@@ -384,6 +387,7 @@ static VALUE get_def_opts(VALUE self) {
|
|
384
387
|
opts,
|
385
388
|
cache_keys_sym,
|
386
389
|
(Yes == oj_default_options.cache_keys) ? Qtrue : ((No == oj_default_options.cache_keys) ? Qfalse : Qnil));
|
390
|
+
|
387
391
|
switch (oj_default_options.mode) {
|
388
392
|
case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
|
389
393
|
case CompatMode: rb_hash_aset(opts, mode_sym, compat_sym); break;
|
@@ -459,13 +463,14 @@ static VALUE get_def_opts(VALUE self) {
|
|
459
463
|
default: rb_hash_aset(opts, nan_sym, auto_sym); break;
|
460
464
|
}
|
461
465
|
rb_hash_aset(opts, omit_nil_sym, oj_default_options.dump_opts.omit_nil ? Qtrue : Qfalse);
|
466
|
+
rb_hash_aset(opts, omit_null_byte_sym, oj_default_options.dump_opts.omit_null_byte ? Qtrue : Qfalse);
|
462
467
|
rb_hash_aset(opts, oj_hash_class_sym, oj_default_options.hash_class);
|
463
468
|
rb_hash_aset(opts, oj_array_class_sym, oj_default_options.array_class);
|
464
469
|
|
465
470
|
if (NULL == oj_default_options.ignore) {
|
466
471
|
rb_hash_aset(opts, ignore_sym, Qnil);
|
467
472
|
} else {
|
468
|
-
VALUE
|
473
|
+
VALUE *vp;
|
469
474
|
volatile VALUE a = rb_ary_new();
|
470
475
|
|
471
476
|
for (vp = oj_default_options.ignore; Qnil != *vp; vp++) {
|
@@ -640,15 +645,9 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
640
645
|
} else if (float_prec_sym == k) {
|
641
646
|
int n;
|
642
647
|
|
643
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
644
648
|
if (rb_cInteger != rb_obj_class(v)) {
|
645
649
|
rb_raise(rb_eArgError, ":float_precision must be a Integer.");
|
646
650
|
}
|
647
|
-
#else
|
648
|
-
if (T_FIXNUM != rb_type(v)) {
|
649
|
-
rb_raise(rb_eArgError, ":float_precision must be a Fixnum.");
|
650
|
-
}
|
651
|
-
#endif
|
652
651
|
n = FIX2INT(v);
|
653
652
|
if (0 >= n) {
|
654
653
|
*copts->float_fmt = '\0';
|
@@ -663,15 +662,9 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
663
662
|
} else if (cache_str_sym == k || cache_string_sym == k) {
|
664
663
|
int n;
|
665
664
|
|
666
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
667
665
|
if (rb_cInteger != rb_obj_class(v)) {
|
668
666
|
rb_raise(rb_eArgError, ":cache_str must be a Integer.");
|
669
667
|
}
|
670
|
-
#else
|
671
|
-
if (T_FIXNUM != rb_type(v)) {
|
672
|
-
rb_raise(rb_eArgError, ":cache_str must be a Fixnum.");
|
673
|
-
}
|
674
|
-
#endif
|
675
668
|
n = FIX2INT(v);
|
676
669
|
if (0 >= n) {
|
677
670
|
copts->cache_str = 0;
|
@@ -684,15 +677,9 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
684
677
|
} else if (sec_prec_sym == k) {
|
685
678
|
int n;
|
686
679
|
|
687
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
688
680
|
if (rb_cInteger != rb_obj_class(v)) {
|
689
681
|
rb_raise(rb_eArgError, ":second_precision must be a Integer.");
|
690
682
|
}
|
691
|
-
#else
|
692
|
-
if (T_FIXNUM != rb_type(v)) {
|
693
|
-
rb_raise(rb_eArgError, ":second_precision must be a Fixnum.");
|
694
|
-
}
|
695
|
-
#endif
|
696
683
|
n = NUM2INT(v);
|
697
684
|
if (0 > n) {
|
698
685
|
n = 0;
|
@@ -883,6 +870,17 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
883
870
|
} else {
|
884
871
|
rb_raise(rb_eArgError, ":omit_nil must be true or false.");
|
885
872
|
}
|
873
|
+
} else if (omit_null_byte_sym == k) {
|
874
|
+
if (Qnil == v) {
|
875
|
+
return ST_CONTINUE;
|
876
|
+
}
|
877
|
+
if (Qtrue == v) {
|
878
|
+
copts->dump_opts.omit_null_byte = true;
|
879
|
+
} else if (Qfalse == v) {
|
880
|
+
copts->dump_opts.omit_null_byte = false;
|
881
|
+
} else {
|
882
|
+
rb_raise(rb_eArgError, ":omit_null_byte must be true or false.");
|
883
|
+
}
|
886
884
|
} else if (oj_ascii_only_sym == k) {
|
887
885
|
// This is here only for backwards compatibility with the original Oj.
|
888
886
|
if (Qtrue == v) {
|
@@ -950,7 +948,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
950
948
|
if (Qnil == v) {
|
951
949
|
return ST_CONTINUE;
|
952
950
|
}
|
953
|
-
|
951
|
+
copts->sym_key = (Qtrue == v) ? Yes : No;
|
954
952
|
}
|
955
953
|
return ST_CONTINUE;
|
956
954
|
}
|
@@ -1115,7 +1113,7 @@ static VALUE load(int argc, VALUE *argv, VALUE self) {
|
|
1115
1113
|
* Returns [_Object_|_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_]
|
1116
1114
|
*/
|
1117
1115
|
static VALUE load_file(int argc, VALUE *argv, VALUE self) {
|
1118
|
-
char
|
1116
|
+
char *path;
|
1119
1117
|
int fd;
|
1120
1118
|
Mode mode = oj_default_options.mode;
|
1121
1119
|
struct _parseInfo pi;
|
@@ -1123,7 +1121,7 @@ static VALUE load_file(int argc, VALUE *argv, VALUE self) {
|
|
1123
1121
|
if (1 > argc) {
|
1124
1122
|
rb_raise(rb_eArgError, "Wrong number of arguments to load().");
|
1125
1123
|
}
|
1126
|
-
|
1124
|
+
path = StringValuePtr(*argv);
|
1127
1125
|
parse_info_init(&pi);
|
1128
1126
|
pi.options = oj_default_options;
|
1129
1127
|
pi.handler = Qnil;
|
@@ -1154,16 +1152,15 @@ static VALUE load_file(int argc, VALUE *argv, VALUE self) {
|
|
1154
1152
|
}
|
1155
1153
|
}
|
1156
1154
|
}
|
1157
|
-
path = StringValuePtr(*argv);
|
1158
1155
|
#ifdef _WIN32
|
1159
1156
|
{
|
1160
1157
|
WCHAR *wide_path;
|
1161
1158
|
wide_path = rb_w32_mbstr_to_wstr(CP_UTF8, path, -1, NULL);
|
1162
|
-
fd
|
1159
|
+
fd = rb_w32_wopen(wide_path, O_RDONLY);
|
1163
1160
|
OJ_FREE(wide_path);
|
1164
1161
|
}
|
1165
1162
|
#else
|
1166
|
-
fd
|
1163
|
+
fd = open(path, O_RDONLY);
|
1167
1164
|
#endif
|
1168
1165
|
if (0 == fd) {
|
1169
1166
|
rb_raise(rb_eIOError, "%s", strerror(errno));
|
@@ -1238,10 +1235,10 @@ static VALUE safe_load(VALUE self, VALUE doc) {
|
|
1238
1235
|
*/
|
1239
1236
|
|
1240
1237
|
struct dump_arg {
|
1241
|
-
struct _out
|
1238
|
+
struct _out *out;
|
1242
1239
|
struct _options *copts;
|
1243
1240
|
int argc;
|
1244
|
-
VALUE
|
1241
|
+
VALUE *argv;
|
1245
1242
|
};
|
1246
1243
|
|
1247
1244
|
static VALUE dump_body(VALUE a) {
|
@@ -1297,8 +1294,9 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1297
1294
|
|
1298
1295
|
oj_out_init(arg.out);
|
1299
1296
|
|
1300
|
-
arg.out->omit_nil
|
1301
|
-
arg.out->
|
1297
|
+
arg.out->omit_nil = copts.dump_opts.omit_nil;
|
1298
|
+
arg.out->omit_null_byte = copts.dump_opts.omit_null_byte;
|
1299
|
+
arg.out->caller = CALLER_DUMP;
|
1302
1300
|
|
1303
1301
|
return rb_ensure(dump_body, (VALUE)&arg, dump_ensure, (VALUE)&arg);
|
1304
1302
|
}
|
@@ -1345,7 +1343,8 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
|
1345
1343
|
|
1346
1344
|
oj_out_init(&out);
|
1347
1345
|
|
1348
|
-
out.omit_nil
|
1346
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
1347
|
+
out.omit_null_byte = copts.dump_opts.omit_null_byte;
|
1349
1348
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
1350
1349
|
// it is.
|
1351
1350
|
oj_dump_obj_to_json_using_params(*argv, &copts, &out, argc - 1, argv + 1);
|
@@ -1377,7 +1376,6 @@ static VALUE to_file(int argc, VALUE *argv, VALUE self) {
|
|
1377
1376
|
if (3 == argc) {
|
1378
1377
|
oj_parse_options(argv[2], &copts);
|
1379
1378
|
}
|
1380
|
-
Check_Type(*argv, T_STRING);
|
1381
1379
|
oj_write_obj_to_file(argv[1], StringValuePtr(*argv), &copts);
|
1382
1380
|
|
1383
1381
|
return Qnil;
|
@@ -1719,8 +1717,7 @@ static VALUE protect_require(VALUE x) {
|
|
1719
1717
|
|
1720
1718
|
extern void print_all_odds(const char *label);
|
1721
1719
|
|
1722
|
-
static VALUE
|
1723
|
-
debug_odd(VALUE self, VALUE label) {
|
1720
|
+
static VALUE debug_odd(VALUE self, VALUE label) {
|
1724
1721
|
print_all_odds(RSTRING_PTR(label));
|
1725
1722
|
return Qnil;
|
1726
1723
|
}
|
@@ -1780,7 +1777,7 @@ void Init_oj(void) {
|
|
1780
1777
|
rb_protect(protect_require, Qnil, &err);
|
1781
1778
|
rb_require("stringio");
|
1782
1779
|
oj_utf8_encoding_index = rb_enc_find_index("UTF-8");
|
1783
|
-
oj_utf8_encoding
|
1780
|
+
oj_utf8_encoding = rb_enc_from_index(oj_utf8_encoding_index);
|
1784
1781
|
|
1785
1782
|
// rb_define_module_function(Oj, "hash_test", hash_test, 0);
|
1786
1783
|
rb_define_module_function(Oj, "debug_odd", debug_odd, 1);
|
@@ -1819,49 +1816,49 @@ void Init_oj(void) {
|
|
1819
1816
|
|
1820
1817
|
rb_define_module_function(Oj, "mem_report", mem_report, 0);
|
1821
1818
|
|
1822
|
-
oj_add_value_id
|
1823
|
-
oj_array_append_id
|
1824
|
-
oj_array_end_id
|
1825
|
-
oj_array_start_id
|
1826
|
-
oj_as_json_id
|
1827
|
-
oj_at_id
|
1828
|
-
oj_begin_id
|
1829
|
-
oj_bigdecimal_id
|
1830
|
-
oj_end_id
|
1831
|
-
oj_error_id
|
1832
|
-
oj_exclude_end_id
|
1833
|
-
oj_file_id
|
1834
|
-
oj_fileno_id
|
1835
|
-
oj_ftype_id
|
1836
|
-
oj_hash_end_id
|
1837
|
-
oj_hash_key_id
|
1838
|
-
oj_hash_set_id
|
1839
|
-
oj_hash_start_id
|
1840
|
-
oj_iconv_id
|
1841
|
-
oj_json_create_id
|
1842
|
-
oj_length_id
|
1843
|
-
oj_new_id
|
1844
|
-
oj_parse_id
|
1845
|
-
oj_pos_id
|
1846
|
-
oj_raw_json_id
|
1847
|
-
oj_read_id
|
1848
|
-
oj_readpartial_id
|
1849
|
-
oj_replace_id
|
1850
|
-
oj_stat_id
|
1851
|
-
oj_string_id
|
1852
|
-
oj_to_h_id
|
1853
|
-
oj_to_hash_id
|
1854
|
-
oj_to_json_id
|
1855
|
-
oj_to_s_id
|
1856
|
-
oj_to_sym_id
|
1857
|
-
oj_to_time_id
|
1858
|
-
oj_tv_nsec_id
|
1859
|
-
oj_tv_sec_id
|
1860
|
-
oj_tv_usec_id
|
1861
|
-
oj_utc_id
|
1862
|
-
oj_utc_offset_id
|
1863
|
-
oj_utcq_id
|
1864
|
-
oj_write_id
|
1819
|
+
oj_add_value_id = rb_intern("add_value");
|
1820
|
+
oj_array_append_id = rb_intern("array_append");
|
1821
|
+
oj_array_end_id = rb_intern("array_end");
|
1822
|
+
oj_array_start_id = rb_intern("array_start");
|
1823
|
+
oj_as_json_id = rb_intern("as_json");
|
1824
|
+
oj_at_id = rb_intern("at");
|
1825
|
+
oj_begin_id = rb_intern("begin");
|
1826
|
+
oj_bigdecimal_id = rb_intern("BigDecimal");
|
1827
|
+
oj_end_id = rb_intern("end");
|
1828
|
+
oj_error_id = rb_intern("error");
|
1829
|
+
oj_exclude_end_id = rb_intern("exclude_end?");
|
1830
|
+
oj_file_id = rb_intern("file?");
|
1831
|
+
oj_fileno_id = rb_intern("fileno");
|
1832
|
+
oj_ftype_id = rb_intern("ftype");
|
1833
|
+
oj_hash_end_id = rb_intern("hash_end");
|
1834
|
+
oj_hash_key_id = rb_intern("hash_key");
|
1835
|
+
oj_hash_set_id = rb_intern("hash_set");
|
1836
|
+
oj_hash_start_id = rb_intern("hash_start");
|
1837
|
+
oj_iconv_id = rb_intern("iconv");
|
1838
|
+
oj_json_create_id = rb_intern("json_create");
|
1839
|
+
oj_length_id = rb_intern("length");
|
1840
|
+
oj_new_id = rb_intern("new");
|
1841
|
+
oj_parse_id = rb_intern("parse");
|
1842
|
+
oj_pos_id = rb_intern("pos");
|
1843
|
+
oj_raw_json_id = rb_intern("raw_json");
|
1844
|
+
oj_read_id = rb_intern("read");
|
1845
|
+
oj_readpartial_id = rb_intern("readpartial");
|
1846
|
+
oj_replace_id = rb_intern("replace");
|
1847
|
+
oj_stat_id = rb_intern("stat");
|
1848
|
+
oj_string_id = rb_intern("string");
|
1849
|
+
oj_to_h_id = rb_intern("to_h");
|
1850
|
+
oj_to_hash_id = rb_intern("to_hash");
|
1851
|
+
oj_to_json_id = rb_intern("to_json");
|
1852
|
+
oj_to_s_id = rb_intern("to_s");
|
1853
|
+
oj_to_sym_id = rb_intern("to_sym");
|
1854
|
+
oj_to_time_id = rb_intern("to_time");
|
1855
|
+
oj_tv_nsec_id = rb_intern("tv_nsec");
|
1856
|
+
oj_tv_sec_id = rb_intern("tv_sec");
|
1857
|
+
oj_tv_usec_id = rb_intern("tv_usec");
|
1858
|
+
oj_utc_id = rb_intern("utc");
|
1859
|
+
oj_utc_offset_id = rb_intern("utc_offset");
|
1860
|
+
oj_utcq_id = rb_intern("utc?");
|
1861
|
+
oj_write_id = rb_intern("write");
|
1865
1862
|
|
1866
1863
|
rb_require("oj/bag");
|
1867
1864
|
rb_require("oj/error");
|
@@ -1988,6 +1985,8 @@ void Init_oj(void) {
|
|
1988
1985
|
rb_gc_register_address(&oj_quirks_mode_sym);
|
1989
1986
|
oj_safe_sym = ID2SYM(rb_intern("safe"));
|
1990
1987
|
rb_gc_register_address(&oj_safe_sym);
|
1988
|
+
omit_null_byte_sym = ID2SYM(rb_intern("omit_null_byte"));
|
1989
|
+
rb_gc_register_address(&omit_null_byte_sym);
|
1991
1990
|
oj_space_before_sym = ID2SYM(rb_intern("space_before"));
|
1992
1991
|
rb_gc_register_address(&oj_space_before_sym);
|
1993
1992
|
oj_space_sym = ID2SYM(rb_intern("space"));
|