oj 3.14.3 → 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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/ext/oj/custom.c +5 -15
  4. data/ext/oj/dump.c +27 -2
  5. data/ext/oj/mimic_json.c +21 -0
  6. data/ext/oj/object.c +7 -21
  7. data/ext/oj/oj.c +20 -0
  8. data/ext/oj/oj.h +3 -0
  9. data/ext/oj/strict.c +9 -27
  10. data/ext/oj/wab.c +9 -27
  11. data/lib/oj/version.rb +1 -1
  12. data/lib/oj.rb +3 -0
  13. data/pages/Options.md +4 -0
  14. data/test/_test_active.rb +8 -8
  15. data/test/_test_active_mimic.rb +7 -7
  16. data/test/_test_mimic_rails.rb +17 -19
  17. data/test/files.rb +14 -14
  18. data/test/foo.rb +5 -5
  19. data/test/helper.rb +4 -4
  20. data/test/mem.rb +8 -7
  21. data/test/perf.rb +21 -26
  22. data/test/perf_compat.rb +30 -32
  23. data/test/perf_dump.rb +25 -25
  24. data/test/perf_fast.rb +80 -82
  25. data/test/perf_file.rb +27 -29
  26. data/test/perf_object.rb +65 -68
  27. data/test/perf_once.rb +8 -7
  28. data/test/perf_parser.rb +40 -46
  29. data/test/perf_saj.rb +46 -53
  30. data/test/perf_scp.rb +57 -69
  31. data/test/perf_simple.rb +40 -38
  32. data/test/perf_strict.rb +68 -70
  33. data/test/perf_wab.rb +67 -69
  34. data/test/prec.rb +3 -3
  35. data/test/sample.rb +16 -15
  36. data/test/sample_json.rb +8 -7
  37. data/test/test_compat.rb +44 -46
  38. data/test/test_custom.rb +56 -42
  39. data/test/test_debian.rb +6 -9
  40. data/test/test_fast.rb +78 -72
  41. data/test/test_file.rb +16 -21
  42. data/test/test_gc.rb +5 -5
  43. data/test/test_generate.rb +5 -5
  44. data/test/test_hash.rb +4 -4
  45. data/test/test_integer_range.rb +9 -9
  46. data/test/test_null.rb +18 -20
  47. data/test/test_object.rb +76 -86
  48. data/test/test_parser.rb +4 -4
  49. data/test/test_parser_debug.rb +4 -4
  50. data/test/test_parser_saj.rb +31 -31
  51. data/test/test_parser_usual.rb +3 -3
  52. data/test/test_rails.rb +2 -2
  53. data/test/test_saj.rb +8 -8
  54. data/test/test_scp.rb +29 -29
  55. data/test/test_strict.rb +25 -31
  56. data/test/test_various.rb +121 -75
  57. data/test/test_wab.rb +43 -42
  58. data/test/test_writer.rb +46 -46
  59. data/test/tests.rb +7 -7
  60. data/test/tests_mimic.rb +6 -6
  61. data/test/tests_mimic_addition.rb +6 -6
  62. metadata +3 -6
  63. data/test/bar.rb +0 -11
  64. data/test/baz.rb +0 -16
  65. data/test/bug.rb +0 -16
  66. data/test/zoo.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce52cbfa0a36f659877cda70d0376fdc19264f96ff8ff1f8085e8cb3560c8bae
4
- data.tar.gz: 44b94e3e4174f1464dd7b4f025e28110dc273a353c42a4d8460c6e45846d1fab
3
+ metadata.gz: 929e5766d8a556ed9590574901fe8268979fd6c165d10e1a2a8601a594dd6897
4
+ data.tar.gz: 966fedee6a16f73c004b56050474377ae48521f5858da962f0f0416b5636a4c3
5
5
  SHA512:
6
- metadata.gz: 465dd87a8c8e11b562de10d1ab60d78f8e2250c4c06f997455673ea67fb88c75e1c07dea01c01fa864ebfa39a2b0bee1371ee7551895ba6d125bee3af20975ee
7
- data.tar.gz: 430a1f0a293fe87fd03af88b2e1f27e70ffae7b7ab8a2451dea1de5891ce6b9967f5475bd33f7cb37c728a7e4ed44b2b3c5051ebeb452c76f393f543a42d5dd1
6
+ metadata.gz: f458f616c33c48d84cb0e1d2c1c45e8b677609c19251345328721fe3b7b6c4c5aa1fd4906da2234b60889a6e3bb45ee0371e7de7565bb6d1aa7d924e231e36dd
7
+ data.tar.gz: fbbf233fc1ce57739d2fe538c179a24282e4c043740c2b47cce29745e3847712afa7828d321b877a3c29ab7d2216e7185af9a85bb9c8eb96b6036f9e3e49c1d1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 3.15.0 - 2023-06-02
4
+
5
+ - Added `omit_null_byte` option when dumping.
6
+
3
7
  ## 3.14.3 - 2023-04-07
4
8
 
5
9
  - Fixed compat parse with optimized Hash when parsing a JSON::GenericObject.
data/ext/oj/custom.c CHANGED
@@ -937,9 +937,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
937
937
  break;
938
938
  default: break;
939
939
  }
940
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
941
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
942
- }
940
+ TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rstr);
943
941
  }
944
942
  }
945
943
 
@@ -998,9 +996,7 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
998
996
  break;
999
997
  default: break;
1000
998
  }
1001
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
1002
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
1003
- }
999
+ TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
1004
1000
  }
1005
1001
 
1006
1002
  static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
@@ -1011,9 +1007,7 @@ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
1011
1007
  case T_HASH: rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), value); break;
1012
1008
  default: break;
1013
1009
  }
1014
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
1015
- oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
1016
- }
1010
+ TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
1017
1011
  }
1018
1012
 
1019
1013
  static void array_append_num(ParseInfo pi, NumInfo ni) {
@@ -1021,9 +1015,7 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
1021
1015
  volatile VALUE rval = oj_num_as_value(ni);
1022
1016
 
1023
1017
  rb_ary_push(parent->val, rval);
1024
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
1025
- oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
1026
- }
1018
+ TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
1027
1019
  }
1028
1020
 
1029
1021
  static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
@@ -1038,9 +1030,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
1038
1030
  }
1039
1031
  }
1040
1032
  rb_ary_push(stack_peek(&pi->stack)->val, rstr);
1041
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
1042
- oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
1043
- }
1033
+ TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rstr);
1044
1034
  }
1045
1035
 
1046
1036
  void oj_set_custom_callbacks(ParseInfo pi) {
data/ext/oj/dump.c CHANGED
@@ -857,6 +857,9 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
857
857
  break;
858
858
  case '6': // control characters
859
859
  if (*(uint8_t *)str < 0x80) {
860
+ if (0 == (uint8_t)*str && out->opts->dump_opts.omit_null_byte) {
861
+ break;
862
+ }
860
863
  APPEND_CHARS(out->cur, "\\u00", 4);
861
864
  dump_hex((uint8_t)*str, out);
862
865
  } else {
@@ -995,6 +998,18 @@ void oj_dump_false(VALUE obj, int depth, Out out, bool as_ok) {
995
998
  *out->cur = '\0';
996
999
  }
997
1000
 
1001
+ static const char digits_table[] = "\
1002
+ 00010203040506070809\
1003
+ 10111213141516171819\
1004
+ 20212223242526272829\
1005
+ 30313233343536373839\
1006
+ 40414243444546474849\
1007
+ 50515253545556575859\
1008
+ 60616263646566676869\
1009
+ 70717273747576777879\
1010
+ 80818283848586878889\
1011
+ 90919293949596979899";
1012
+
998
1013
  void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
999
1014
  char buf[32];
1000
1015
  char *b = buf + sizeof(buf) - 1;
@@ -1017,9 +1032,19 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1017
1032
  *b-- = '"';
1018
1033
  }
1019
1034
  if (0 < num) {
1020
- for (; 0 < num; num /= 10, b--) {
1021
- *b = (num % 10) + '0';
1035
+ while (100 <= num) {
1036
+ unsigned idx = num % 100 * 2;
1037
+ *b-- = digits_table[idx + 1];
1038
+ *b-- = digits_table[idx];
1039
+ num /= 100;
1022
1040
  }
1041
+ if (num < 10) {
1042
+ *b-- = num + '0';
1043
+ } else {
1044
+ *b-- = digits_table[num * 2 + 1];
1045
+ *b-- = digits_table[num * 2];
1046
+ }
1047
+
1023
1048
  if (neg) {
1024
1049
  *b = '-';
1025
1050
  } else {
data/ext/oj/mimic_json.c CHANGED
@@ -738,6 +738,7 @@ static struct _options mimic_object_to_json_options = {0, // indent
738
738
  0, // array_size
739
739
  RaiseNan, // nan_dump
740
740
  false, // omit_nil
741
+ false, // omit_null_byte
741
742
  100, // max_depth
742
743
  },
743
744
  {
@@ -791,28 +792,48 @@ void oj_mimic_json_methods(VALUE json) {
791
792
  VALUE json_error;
792
793
  VALUE generator;
793
794
  VALUE ext;
795
+ VALUE verbose;
794
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);
801
+
802
+ rb_undef_method(json, "create_id=");
795
803
  rb_define_module_function(json, "create_id=", mimic_set_create_id, 1);
804
+ rb_undef_method(json, "create_id");
796
805
  rb_define_module_function(json, "create_id", mimic_create_id, 0);
797
806
 
807
+ rb_undef_method(json, "dump");
798
808
  rb_define_module_function(json, "dump", mimic_dump, -1);
809
+ rb_undef_method(json, "load");
799
810
  rb_define_module_function(json, "load", mimic_load, -1);
800
811
  rb_define_module_function(json, "restore", mimic_load, -1);
812
+ rb_undef_method(json, "recurse_proc");
801
813
  rb_define_module_function(json, "recurse_proc", mimic_recurse_proc, 1);
814
+ rb_undef_method(json, "[]");
802
815
  rb_define_module_function(json, "[]", mimic_dump_load, -1);
803
816
 
817
+ rb_undef_method(json, "generate");
804
818
  rb_define_module_function(json, "generate", oj_mimic_generate, -1);
819
+ rb_undef_method(json, "fast_generate");
805
820
  rb_define_module_function(json, "fast_generate", oj_mimic_generate, -1);
821
+ rb_undef_method(json, "pretty_generate");
806
822
  rb_define_module_function(json, "pretty_generate", oj_mimic_pretty_generate, -1);
807
823
  // For older versions of JSON, the deprecated unparse methods.
824
+ rb_undef_method(json, "unparse");
808
825
  rb_define_module_function(json, "unparse", oj_mimic_generate, -1);
809
826
  rb_define_module_function(json, "fast_unparse", oj_mimic_generate, -1);
810
827
  rb_define_module_function(json, "pretty_unparse", oj_mimic_pretty_generate, -1);
811
828
 
829
+ rb_undef_method(json, "parse");
812
830
  rb_define_module_function(json, "parse", oj_mimic_parse, -1);
831
+ rb_undef_method(json, "parse!");
813
832
  rb_define_module_function(json, "parse!", mimic_parse_bang, -1);
814
833
 
834
+ rb_undef_method(json, "state");
815
835
  rb_define_module_function(json, "state", mimic_state, 0);
836
+ rb_gv_set("$VERBOSE", verbose);
816
837
 
817
838
  if (rb_const_defined_at(json, rb_intern("JSONError"))) {
818
839
  json_error = rb_const_get(json, rb_intern("JSONError"));
data/ext/oj/object.c CHANGED
@@ -446,9 +446,7 @@ WHICH_TYPE:
446
446
  rb_class2name(rb_obj_class(parent->val)));
447
447
  return;
448
448
  }
449
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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) {
@@ -603,9 +599,7 @@ WHICH_TYPE:
603
599
  rb_class2name(rb_obj_class(parent->val)));
604
600
  return;
605
601
  }
606
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
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/oj.c CHANGED
@@ -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;
@@ -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,6 +463,7 @@ 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
 
@@ -865,6 +870,17 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
865
870
  } else {
866
871
  rb_raise(rb_eArgError, ":omit_nil must be true or false.");
867
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
+ }
868
884
  } else if (oj_ascii_only_sym == k) {
869
885
  // This is here only for backwards compatibility with the original Oj.
870
886
  if (Qtrue == v) {
@@ -1279,6 +1295,7 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
1279
1295
  oj_out_init(arg.out);
1280
1296
 
1281
1297
  arg.out->omit_nil = copts.dump_opts.omit_nil;
1298
+ arg.out->omit_null_byte = copts.dump_opts.omit_null_byte;
1282
1299
  arg.out->caller = CALLER_DUMP;
1283
1300
 
1284
1301
  return rb_ensure(dump_body, (VALUE)&arg, dump_ensure, (VALUE)&arg);
@@ -1327,6 +1344,7 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
1327
1344
  oj_out_init(&out);
1328
1345
 
1329
1346
  out.omit_nil = copts.dump_opts.omit_nil;
1347
+ out.omit_null_byte = copts.dump_opts.omit_null_byte;
1330
1348
  // For obj.to_json or generate nan is not allowed but if called from dump
1331
1349
  // it is.
1332
1350
  oj_dump_obj_to_json_using_params(*argv, &copts, &out, argc - 1, argv + 1);
@@ -1967,6 +1985,8 @@ void Init_oj(void) {
1967
1985
  rb_gc_register_address(&oj_quirks_mode_sym);
1968
1986
  oj_safe_sym = ID2SYM(rb_intern("safe"));
1969
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);
1970
1990
  oj_space_before_sym = ID2SYM(rb_intern("space_before"));
1971
1991
  rb_gc_register_address(&oj_space_before_sym);
1972
1992
  oj_space_sym = ID2SYM(rb_intern("space"));
data/ext/oj/oj.h CHANGED
@@ -124,6 +124,7 @@ typedef struct _dumpOpts {
124
124
  uint8_t array_size;
125
125
  char nan_dump; // NanDump
126
126
  bool omit_nil;
127
+ bool omit_null_byte;
127
128
  int max_depth;
128
129
  } *DumpOpts;
129
130
 
@@ -199,6 +200,7 @@ typedef struct _out {
199
200
  uint32_t hash_cnt;
200
201
  bool allocated;
201
202
  bool omit_nil;
203
+ bool omit_null_byte;
202
204
  int argc;
203
205
  VALUE *argv;
204
206
  DumpCaller caller; // used for the mimic json only
@@ -323,6 +325,7 @@ extern VALUE oj_max_nesting_sym;
323
325
  extern VALUE oj_object_class_sym;
324
326
  extern VALUE oj_object_nl_sym;
325
327
  extern VALUE oj_quirks_mode_sym;
328
+ extern VALUE oj_skip_null_byte_sym;
326
329
  extern VALUE oj_space_before_sym;
327
330
  extern VALUE oj_space_sym;
328
331
  extern VALUE oj_symbolize_names_sym;
data/ext/oj/strict.c CHANGED
@@ -62,9 +62,7 @@ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
62
62
  }
63
63
 
64
64
  static void add_value(ParseInfo pi, VALUE val) {
65
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
66
- oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
67
- }
65
+ TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, val);
68
66
  pi->stack.head->val = val;
69
67
  }
70
68
 
@@ -72,9 +70,7 @@ static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig
72
70
  volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
73
71
 
74
72
  pi->stack.head->val = rstr;
75
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
76
- oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, rstr);
77
- }
73
+ TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, rstr);
78
74
  }
79
75
 
80
76
  static void add_num(ParseInfo pi, NumInfo ni) {
@@ -82,9 +78,7 @@ static void add_num(ParseInfo pi, NumInfo ni) {
82
78
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
83
79
  }
84
80
  pi->stack.head->val = oj_num_as_value(ni);
85
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
86
- oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
87
- }
81
+ TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, pi->stack.head->val);
88
82
  }
89
83
 
90
84
  static VALUE start_hash(ParseInfo pi) {
@@ -99,9 +93,7 @@ static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len,
99
93
  volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
100
94
 
101
95
  rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), rstr);
102
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
103
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
104
- }
96
+ TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rstr);
105
97
  }
106
98
 
107
99
  static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
@@ -112,16 +104,12 @@ static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
112
104
  }
113
105
  v = oj_num_as_value(ni);
114
106
  rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), v);
115
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
116
- oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, v);
117
- }
107
+ TRACE_PARSE_CALL(pi->options.trace, "set_number", pi, v);
118
108
  }
119
109
 
120
110
  static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
121
111
  rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), value);
122
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
123
- oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
124
- }
112
+ TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
125
113
  }
126
114
 
127
115
  static VALUE start_array(ParseInfo pi) {
@@ -133,9 +121,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
133
121
  volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
134
122
 
135
123
  rb_ary_push(stack_peek(&pi->stack)->val, rstr);
136
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
137
- oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
138
- }
124
+ TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rstr);
139
125
  }
140
126
 
141
127
  static void array_append_num(ParseInfo pi, NumInfo ni) {
@@ -146,16 +132,12 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
146
132
  }
147
133
  v = oj_num_as_value(ni);
148
134
  rb_ary_push(stack_peek(&pi->stack)->val, v);
149
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
150
- oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, v);
151
- }
135
+ TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, v);
152
136
  }
153
137
 
154
138
  static void array_append_value(ParseInfo pi, VALUE value) {
155
139
  rb_ary_push(stack_peek(&pi->stack)->val, value);
156
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
157
- oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
158
- }
140
+ TRACE_PARSE_CALL(pi->options.trace, "append_value", pi, value);
159
141
  }
160
142
 
161
143
  void oj_set_strict_callbacks(ParseInfo pi) {
data/ext/oj/wab.c CHANGED
@@ -318,9 +318,7 @@ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
318
318
  }
319
319
 
320
320
  static void add_value(ParseInfo pi, VALUE val) {
321
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
322
- oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
323
- }
321
+ TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, val);
324
322
  pi->stack.head->val = val;
325
323
  }
326
324
 
@@ -468,9 +466,7 @@ static VALUE cstr_to_rstr(ParseInfo pi, const char *str, size_t len) {
468
466
 
469
467
  static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
470
468
  pi->stack.head->val = cstr_to_rstr(pi, str, len);
471
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
472
- oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
473
- }
469
+ TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, pi->stack.head->val);
474
470
  }
475
471
 
476
472
  static void add_num(ParseInfo pi, NumInfo ni) {
@@ -478,9 +474,7 @@ static void add_num(ParseInfo pi, NumInfo ni) {
478
474
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
479
475
  }
480
476
  pi->stack.head->val = oj_num_as_value(ni);
481
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
482
- oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
483
- }
477
+ TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, pi->stack.head->val);
484
478
  }
485
479
 
486
480
  static VALUE start_hash(ParseInfo pi) {
@@ -495,9 +489,7 @@ static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len,
495
489
  volatile VALUE rval = cstr_to_rstr(pi, str, len);
496
490
 
497
491
  rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
498
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
499
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
500
- }
492
+ TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
501
493
  }
502
494
 
503
495
  static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
@@ -508,16 +500,12 @@ static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
508
500
  }
509
501
  rval = oj_num_as_value(ni);
510
502
  rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
511
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
512
- oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, rval);
513
- }
503
+ TRACE_PARSE_CALL(pi->options.trace, "set_number", pi, rval);
514
504
  }
515
505
 
516
506
  static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
517
507
  rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), value);
518
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
519
- oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
520
- }
508
+ TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
521
509
  }
522
510
 
523
511
  static VALUE start_array(ParseInfo pi) {
@@ -529,9 +517,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
529
517
  volatile VALUE rval = cstr_to_rstr(pi, str, len);
530
518
 
531
519
  rb_ary_push(stack_peek(&pi->stack)->val, rval);
532
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
533
- oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, rval);
534
- }
520
+ TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, rval);
535
521
  }
536
522
 
537
523
  static void array_append_num(ParseInfo pi, NumInfo ni) {
@@ -542,16 +528,12 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
542
528
  }
543
529
  rval = oj_num_as_value(ni);
544
530
  rb_ary_push(stack_peek(&pi->stack)->val, rval);
545
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
546
- oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
547
- }
531
+ TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
548
532
  }
549
533
 
550
534
  static void array_append_value(ParseInfo pi, VALUE value) {
551
535
  rb_ary_push(stack_peek(&pi->stack)->val, value);
552
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
553
- oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
554
- }
536
+ TRACE_PARSE_CALL(pi->options.trace, "append_value", pi, value);
555
537
  }
556
538
 
557
539
  void oj_set_wab_callbacks(ParseInfo pi) {
data/lib/oj/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Oj
2
2
  # Current version of the module.
3
- VERSION = '3.14.3'
3
+ VERSION = '3.15.0'
4
4
  end
data/lib/oj.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Oj module is defined in oj.c.
1
4
  module Oj
2
5
  end
3
6
 
data/pages/Options.md CHANGED
@@ -265,6 +265,10 @@ to true.
265
265
 
266
266
  The number of digits after the decimal when dumping the seconds of time.
267
267
 
268
+ ### :skip_null_byte [Boolean]
269
+
270
+ If true, null bytes in strings will be omitted when dumping.
271
+
268
272
  ### :space
269
273
 
270
274
  String inserted after the ':' character when dumping a JSON object. The
data/test/_test_active.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
- # encoding: UTF-8
2
+ # frozen_string_literal: true
3
3
 
4
- $: << File.dirname(__FILE__)
4
+ $LOAD_PATH << __dir__
5
5
  %w(lib ext test).each do |dir|
6
6
  $LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
7
7
  end
@@ -13,14 +13,14 @@ require 'sqlite3'
13
13
  require 'active_record'
14
14
  require 'oj'
15
15
 
16
- #Oj.mimic_JSON()
16
+ # Oj.mimic_JSON()
17
17
  Oj.default_options = {mode: :compat, indent: 2}
18
18
 
19
- #ActiveRecord::Base.logger = Logger.new(STDERR)
19
+ # ActiveRecord::Base.logger = Logger.new(STDERR)
20
20
 
21
21
  ActiveRecord::Base.establish_connection(
22
- :adapter => "sqlite3",
23
- :database => ":memory:"
22
+ :adapter => 'sqlite3',
23
+ :database => ':memory:'
24
24
  )
25
25
 
26
26
  ActiveRecord::Schema.define do
@@ -37,8 +37,8 @@ end
37
37
  class ActiveTest < Minitest::Test
38
38
 
39
39
  def test_active
40
- User.find_or_create_by(first_name: "John", last_name: "Smith", email: "john@example.com")
41
- User.find_or_create_by(first_name: "Joan", last_name: "Smith", email: "joan@example.com")
40
+ User.find_or_create_by(first_name: 'John', last_name: 'Smith', email: 'john@example.com')
41
+ User.find_or_create_by(first_name: 'Joan', last_name: 'Smith', email: 'joan@example.com')
42
42
 
43
43
  # Single instance.
44
44
  assert_equal(%|{
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
- # encoding: UTF-8
2
+ # frozen_string_literal: true
3
3
 
4
- $: << File.dirname(__FILE__)
4
+ $LOAD_PATH << __dir__
5
5
  %w(lib ext test).each do |dir|
6
6
  $LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
7
7
  end
@@ -16,11 +16,11 @@ require 'oj'
16
16
  Oj.mimic_JSON()
17
17
  Oj.default_options = {mode: :compat, indent: 2}
18
18
 
19
- #ActiveRecord::Base.logger = Logger.new(STDERR)
19
+ # ActiveRecord::Base.logger = Logger.new(STDERR)
20
20
 
21
21
  ActiveRecord::Base.establish_connection(
22
- :adapter => "sqlite3",
23
- :database => ":memory:"
22
+ :adapter => 'sqlite3',
23
+ :database => ':memory:'
24
24
  )
25
25
 
26
26
  ActiveRecord::Schema.define do
@@ -37,8 +37,8 @@ end
37
37
  class ActiveTest < Minitest::Test
38
38
 
39
39
  def test_active
40
- User.find_or_create_by(first_name: "John", last_name: "Smith", email: "john@example.com")
41
- User.find_or_create_by(first_name: "Joan", last_name: "Smith", email: "joan@example.com")
40
+ User.find_or_create_by(first_name: 'John', last_name: 'Smith', email: 'john@example.com')
41
+ User.find_or_create_by(first_name: 'Joan', last_name: 'Smith', email: 'joan@example.com')
42
42
 
43
43
  # Single instance.
44
44
  assert_equal(%|{