oj 3.14.3 → 3.15.0

Sign up to get free protection for your applications and to get access to all the features.
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(%|{