oj 3.14.2 → 3.15.0
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 +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"));
|