oj 3.14.2 → 3.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +0 -1
  4. data/ext/oj/buf.h +2 -2
  5. data/ext/oj/cache.c +16 -16
  6. data/ext/oj/cache8.c +7 -7
  7. data/ext/oj/circarray.c +2 -1
  8. data/ext/oj/circarray.h +2 -2
  9. data/ext/oj/code.c +2 -2
  10. data/ext/oj/code.h +2 -2
  11. data/ext/oj/compat.c +6 -14
  12. data/ext/oj/custom.c +6 -16
  13. data/ext/oj/debug.c +3 -9
  14. data/ext/oj/dump.c +43 -18
  15. data/ext/oj/dump_compat.c +551 -576
  16. data/ext/oj/dump_leaf.c +3 -5
  17. data/ext/oj/dump_object.c +35 -36
  18. data/ext/oj/dump_strict.c +2 -4
  19. data/ext/oj/encoder.c +1 -1
  20. data/ext/oj/err.c +2 -13
  21. data/ext/oj/err.h +9 -12
  22. data/ext/oj/extconf.rb +1 -1
  23. data/ext/oj/fast.c +24 -38
  24. data/ext/oj/intern.c +38 -42
  25. data/ext/oj/intern.h +3 -7
  26. data/ext/oj/mem.c +211 -217
  27. data/ext/oj/mem.h +10 -10
  28. data/ext/oj/mimic_json.c +39 -24
  29. data/ext/oj/object.c +12 -26
  30. data/ext/oj/odd.c +2 -1
  31. data/ext/oj/odd.h +4 -4
  32. data/ext/oj/oj.c +80 -81
  33. data/ext/oj/oj.h +56 -54
  34. data/ext/oj/parse.c +55 -118
  35. data/ext/oj/parse.h +5 -10
  36. data/ext/oj/parser.c +7 -8
  37. data/ext/oj/parser.h +7 -8
  38. data/ext/oj/rails.c +28 -59
  39. data/ext/oj/reader.c +5 -9
  40. data/ext/oj/reader.h +1 -1
  41. data/ext/oj/resolve.c +3 -4
  42. data/ext/oj/rxclass.c +1 -1
  43. data/ext/oj/rxclass.h +1 -1
  44. data/ext/oj/saj.c +4 -4
  45. data/ext/oj/saj2.c +32 -49
  46. data/ext/oj/saj2.h +1 -1
  47. data/ext/oj/scp.c +3 -14
  48. data/ext/oj/sparse.c +18 -67
  49. data/ext/oj/stream_writer.c +5 -18
  50. data/ext/oj/strict.c +16 -40
  51. data/ext/oj/string_writer.c +6 -14
  52. data/ext/oj/trace.h +27 -16
  53. data/ext/oj/usual.c +62 -61
  54. data/ext/oj/usual.h +6 -6
  55. data/ext/oj/util.h +1 -1
  56. data/ext/oj/val_stack.h +4 -4
  57. data/ext/oj/wab.c +16 -36
  58. data/lib/oj/active_support_helper.rb +0 -1
  59. data/lib/oj/bag.rb +7 -1
  60. data/lib/oj/easy_hash.rb +4 -5
  61. data/lib/oj/error.rb +0 -1
  62. data/lib/oj/json.rb +4 -2
  63. data/lib/oj/mimic.rb +4 -2
  64. data/lib/oj/state.rb +8 -5
  65. data/lib/oj/version.rb +1 -2
  66. data/lib/oj.rb +2 -0
  67. data/pages/Options.md +4 -0
  68. data/test/_test_active.rb +8 -9
  69. data/test/_test_active_mimic.rb +7 -8
  70. data/test/_test_mimic_rails.rb +17 -20
  71. data/test/activerecord/result_test.rb +5 -6
  72. data/test/files.rb +15 -15
  73. data/test/foo.rb +9 -52
  74. data/test/helper.rb +5 -8
  75. data/test/isolated/shared.rb +3 -2
  76. data/test/json_gem/json_addition_test.rb +2 -2
  77. data/test/json_gem/json_common_interface_test.rb +4 -4
  78. data/test/json_gem/json_encoding_test.rb +0 -0
  79. data/test/json_gem/json_ext_parser_test.rb +1 -0
  80. data/test/json_gem/json_fixtures_test.rb +3 -2
  81. data/test/json_gem/json_generator_test.rb +43 -32
  82. data/test/json_gem/json_generic_object_test.rb +11 -11
  83. data/test/json_gem/json_parser_test.rb +46 -46
  84. data/test/json_gem/json_string_matching_test.rb +9 -9
  85. data/test/mem.rb +13 -12
  86. data/test/perf.rb +21 -26
  87. data/test/perf_compat.rb +31 -33
  88. data/test/perf_dump.rb +25 -25
  89. data/test/perf_fast.rb +80 -82
  90. data/test/perf_file.rb +27 -29
  91. data/test/perf_object.rb +65 -69
  92. data/test/perf_once.rb +12 -11
  93. data/test/perf_parser.rb +41 -48
  94. data/test/perf_saj.rb +46 -54
  95. data/test/perf_scp.rb +57 -69
  96. data/test/perf_simple.rb +41 -39
  97. data/test/perf_strict.rb +68 -70
  98. data/test/perf_wab.rb +67 -69
  99. data/test/prec.rb +3 -3
  100. data/test/sample/change.rb +0 -1
  101. data/test/sample/dir.rb +0 -1
  102. data/test/sample/doc.rb +0 -1
  103. data/test/sample/file.rb +0 -1
  104. data/test/sample/group.rb +0 -1
  105. data/test/sample/hasprops.rb +0 -1
  106. data/test/sample/layer.rb +0 -1
  107. data/test/sample/rect.rb +0 -1
  108. data/test/sample/shape.rb +0 -1
  109. data/test/sample/text.rb +0 -1
  110. data/test/sample.rb +16 -16
  111. data/test/sample_json.rb +8 -8
  112. data/test/test_compat.rb +52 -52
  113. data/test/test_custom.rb +61 -51
  114. data/test/test_debian.rb +7 -10
  115. data/test/test_fast.rb +86 -90
  116. data/test/test_file.rb +24 -29
  117. data/test/test_gc.rb +5 -5
  118. data/test/test_generate.rb +5 -5
  119. data/test/test_hash.rb +4 -4
  120. data/test/test_integer_range.rb +9 -9
  121. data/test/test_null.rb +20 -20
  122. data/test/test_object.rb +78 -87
  123. data/test/test_parser.rb +4 -4
  124. data/test/test_parser_debug.rb +4 -4
  125. data/test/test_parser_saj.rb +27 -25
  126. data/test/test_parser_usual.rb +6 -6
  127. data/test/test_rails.rb +2 -2
  128. data/test/test_saj.rb +10 -8
  129. data/test/test_scp.rb +35 -35
  130. data/test/test_strict.rb +28 -32
  131. data/test/test_various.rb +140 -97
  132. data/test/test_wab.rb +46 -44
  133. data/test/test_writer.rb +47 -47
  134. data/test/tests.rb +7 -7
  135. data/test/tests_mimic.rb +6 -6
  136. data/test/tests_mimic_addition.rb +6 -6
  137. metadata +18 -30
  138. data/test/activesupport4/decoding_test.rb +0 -108
  139. data/test/activesupport4/encoding_test.rb +0 -531
  140. data/test/activesupport4/test_helper.rb +0 -41
  141. data/test/activesupport5/abstract_unit.rb +0 -45
  142. data/test/activesupport5/decoding_test.rb +0 -133
  143. data/test/activesupport5/encoding_test.rb +0 -500
  144. data/test/activesupport5/encoding_test_cases.rb +0 -98
  145. data/test/activesupport5/test_helper.rb +0 -72
  146. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  147. data/test/bar.rb +0 -11
  148. data/test/baz.rb +0 -16
  149. data/test/bug.rb +0 -16
  150. 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
- } else if (T_STRING == rb_type(*argv)) {
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 Qnil;
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 = copts->dump_opts.omit_nil;
372
- out.caller = CALLER_GENERATE;
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
- "Oj::Rails.mimic_JSON was called implicitly. "
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
- "Oj::Rails.mimic_JSON was called implicitly. "
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
- size_t len = RSTRING_LEN(id) + 1;
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, StringValuePtr(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 = copts.dump_opts.omit_nil;
767
- copts.mode = CompatMode;
768
- copts.to_json = No;
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 = ni->i;
274
- ts.tv_nsec = 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
- parent->val = rb_class_new_instance(len - 1, RARRAY_CONST_PTR(value) + 1, rb_cRange);
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
- slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
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
- 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) {
@@ -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 len = RARRAY_LEN(value);
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
- 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/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 * classname;
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 * attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
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
- } * Odd;
28
+ } *Odd;
29
29
 
30
30
  typedef struct _oddArgs {
31
31
  Odd odd;
32
32
  VALUE args[MAX_ODD_ARGS];
33
- } * OddArgs;
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
- } * YesNoOpt;
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 = 0;
160
- int oj_utf8_encoding_index = 0;
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 * vp;
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
- copts->sym_key = (Qtrue == v) ? Yes : No;
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 * path;
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
- Check_Type(*argv, T_STRING);
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 = rb_w32_wopen(wide_path, O_RDONLY);
1159
+ fd = rb_w32_wopen(wide_path, O_RDONLY);
1163
1160
  OJ_FREE(wide_path);
1164
1161
  }
1165
1162
  #else
1166
- fd = open(path, O_RDONLY);
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 * out;
1238
+ struct _out *out;
1242
1239
  struct _options *copts;
1243
1240
  int argc;
1244
- VALUE * argv;
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 = copts.dump_opts.omit_nil;
1301
- arg.out->caller = CALLER_DUMP;
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 = copts.dump_opts.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 = rb_enc_from_index(oj_utf8_encoding_index);
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 = rb_intern("add_value");
1823
- oj_array_append_id = rb_intern("array_append");
1824
- oj_array_end_id = rb_intern("array_end");
1825
- oj_array_start_id = rb_intern("array_start");
1826
- oj_as_json_id = rb_intern("as_json");
1827
- oj_at_id = rb_intern("at");
1828
- oj_begin_id = rb_intern("begin");
1829
- oj_bigdecimal_id = rb_intern("BigDecimal");
1830
- oj_end_id = rb_intern("end");
1831
- oj_error_id = rb_intern("error");
1832
- oj_exclude_end_id = rb_intern("exclude_end?");
1833
- oj_file_id = rb_intern("file?");
1834
- oj_fileno_id = rb_intern("fileno");
1835
- oj_ftype_id = rb_intern("ftype");
1836
- oj_hash_end_id = rb_intern("hash_end");
1837
- oj_hash_key_id = rb_intern("hash_key");
1838
- oj_hash_set_id = rb_intern("hash_set");
1839
- oj_hash_start_id = rb_intern("hash_start");
1840
- oj_iconv_id = rb_intern("iconv");
1841
- oj_json_create_id = rb_intern("json_create");
1842
- oj_length_id = rb_intern("length");
1843
- oj_new_id = rb_intern("new");
1844
- oj_parse_id = rb_intern("parse");
1845
- oj_pos_id = rb_intern("pos");
1846
- oj_raw_json_id = rb_intern("raw_json");
1847
- oj_read_id = rb_intern("read");
1848
- oj_readpartial_id = rb_intern("readpartial");
1849
- oj_replace_id = rb_intern("replace");
1850
- oj_stat_id = rb_intern("stat");
1851
- oj_string_id = rb_intern("string");
1852
- oj_to_h_id = rb_intern("to_h");
1853
- oj_to_hash_id = rb_intern("to_hash");
1854
- oj_to_json_id = rb_intern("to_json");
1855
- oj_to_s_id = rb_intern("to_s");
1856
- oj_to_sym_id = rb_intern("to_sym");
1857
- oj_to_time_id = rb_intern("to_time");
1858
- oj_tv_nsec_id = rb_intern("tv_nsec");
1859
- oj_tv_sec_id = rb_intern("tv_sec");
1860
- oj_tv_usec_id = rb_intern("tv_usec");
1861
- oj_utc_id = rb_intern("utc");
1862
- oj_utc_offset_id = rb_intern("utc_offset");
1863
- oj_utcq_id = rb_intern("utc?");
1864
- oj_write_id = rb_intern("write");
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"));