oj 3.12.3 → 3.13.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -3
  3. data/ext/oj/buf.h +9 -0
  4. data/ext/oj/cache.c +341 -0
  5. data/ext/oj/cache.h +21 -0
  6. data/ext/oj/compat.c +7 -22
  7. data/ext/oj/custom.c +15 -17
  8. data/ext/oj/debug.c +132 -0
  9. data/ext/oj/dump.c +12 -15
  10. data/ext/oj/dump_compat.c +3 -3
  11. data/ext/oj/dump_object.c +9 -9
  12. data/ext/oj/dump_strict.c +3 -3
  13. data/ext/oj/err.h +19 -0
  14. data/ext/oj/extconf.rb +5 -0
  15. data/ext/oj/fast.c +7 -18
  16. data/ext/oj/intern.c +281 -0
  17. data/ext/oj/intern.h +26 -0
  18. data/ext/oj/mimic_json.c +2 -2
  19. data/ext/oj/object.c +15 -92
  20. data/ext/oj/odd.c +1 -1
  21. data/ext/oj/oj.c +117 -94
  22. data/ext/oj/oj.h +1 -1
  23. data/ext/oj/parse.c +5 -5
  24. data/ext/oj/parser.c +1483 -0
  25. data/ext/oj/parser.h +90 -0
  26. data/ext/oj/rails.c +5 -5
  27. data/ext/oj/resolve.c +2 -20
  28. data/ext/oj/rxclass.c +1 -1
  29. data/ext/oj/saj.c +1 -1
  30. data/ext/oj/saj2.c +348 -0
  31. data/ext/oj/scp.c +1 -1
  32. data/ext/oj/sparse.c +2 -2
  33. data/ext/oj/stream_writer.c +4 -4
  34. data/ext/oj/strict.c +9 -27
  35. data/ext/oj/string_writer.c +2 -2
  36. data/ext/oj/usual.c +1252 -0
  37. data/ext/oj/validate.c +51 -0
  38. data/ext/oj/wab.c +14 -19
  39. data/lib/oj/error.rb +1 -1
  40. data/lib/oj/state.rb +8 -7
  41. data/lib/oj/version.rb +1 -1
  42. data/pages/Options.md +1 -1
  43. data/pages/Parser.md +309 -0
  44. data/pages/Rails.md +2 -2
  45. data/test/json_gem/json_generator_test.rb +1 -1
  46. data/test/mem.rb +33 -0
  47. data/test/perf_once.rb +58 -0
  48. data/test/perf_parser.rb +189 -0
  49. data/test/test_hash.rb +1 -1
  50. data/test/test_parser.rb +27 -0
  51. data/test/test_parser_saj.rb +245 -0
  52. data/test/test_parser_usual.rb +213 -0
  53. metadata +26 -5
  54. data/ext/oj/hash.c +0 -168
  55. data/ext/oj/hash.h +0 -21
  56. data/ext/oj/hash_test.c +0 -491
data/ext/oj/odd.c CHANGED
@@ -206,7 +206,7 @@ void oj_reg_odd(VALUE clas,
206
206
  *fp = 0;
207
207
  switch (rb_type(*members)) {
208
208
  case T_STRING:
209
- if (NULL == (*np = strdup(rb_string_value_ptr(members)))) {
209
+ if (NULL == (*np = strdup(RSTRING_PTR(*members)))) {
210
210
  rb_raise(rb_eNoMemError, "for attribute name.");
211
211
  }
212
212
  break;
data/ext/oj/oj.c CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  #include "dump.h"
15
15
  #include "encode.h"
16
- #include "hash.h"
16
+ #include "intern.h"
17
17
  #include "odd.h"
18
18
  #include "parse.h"
19
19
  #include "rails.h"
@@ -158,6 +158,8 @@ pthread_mutex_t oj_cache_mutex;
158
158
  VALUE oj_cache_mutex = Qnil;
159
159
  #endif
160
160
 
161
+ extern void oj_parser_init();
162
+
161
163
  const char oj_json_class[] = "json_class";
162
164
 
163
165
  struct _options oj_default_options = {
@@ -188,7 +190,7 @@ struct _options oj_default_options = {
188
190
  false, // sec_prec_set
189
191
  No, // ignore_under
190
192
  Yes, // cache_keys
191
- 3, // cache_str
193
+ 0, // cache_str
192
194
  0, // int_range_min
193
195
  0, // int_range_max
194
196
  oj_json_class, // create_id
@@ -286,7 +288,7 @@ struct _options oj_default_options = {
286
288
  * - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when dumping in
287
289
  *object or custom mode.
288
290
  * - *:cache_keys* [_Boolean_] if true then hash keys are cached
289
- * - *:cache_str* [_Fixnum_] maximum string value length to cache
291
+ * - *:cache_str* [_Fixnum_] maximum string value length to cache (strings less than this are cached)
290
292
  * - *:integer_range* [_Range_] Dump integers outside range as strings.
291
293
  * - *:trace* [_true,_|_false_] Trace all load and dump calls, default is false (trace is off)
292
294
  * - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default is false (safe is
@@ -507,7 +509,7 @@ static VALUE get_def_opts(VALUE self) {
507
509
  * Sets the default options for load and dump.
508
510
  * - *opts* [_Hash_] options to change
509
511
  * - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element in a JSON
510
- *document or the String to use for identation.
512
+ *document or the String to use for indentation.
511
513
  * - :circular [_Boolean_|_nil_] support circular references while dumping.
512
514
  * - *:auto_define* [_Boolean_|_nil_] automatically define classes if they do not exist.
513
515
  * - *:symbol_keys* [_Boolean_|_nil_] convert hash keys to symbols.
@@ -569,7 +571,7 @@ static VALUE get_def_opts(VALUE self) {
569
571
  * - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when
570
572
  *dumping in object or custom mode.
571
573
  * - *:cache_keys* [_Boolean_] if true then hash keys are cached
572
- * - *:cache_str* [_Fixnum_] maximum string vsalue length to cache
574
+ * - *:cache_str* [_Fixnum_] maximum string value length to cache (strings less than this are cached)
573
575
  * - *:integer_range* [_Range_] Dump integers outside range as strings.
574
576
  * - *:trace* [_Boolean_] turn trace on or off.
575
577
  * - *:safe* [_Boolean_] turn safe mimic on or off.
@@ -589,7 +591,8 @@ bool oj_hash_has_key(VALUE hash, VALUE key)
589
591
  return true;
590
592
  }
591
593
 
592
- void oj_parse_options(VALUE ropts, Options copts) {
594
+ bool set_yesno_options(VALUE key, VALUE value, Options copts)
595
+ {
593
596
  struct _yesNoOpt ynos[] = {{circular_sym, &copts->circular},
594
597
  {auto_define_sym, &copts->auto_define},
595
598
  {symbol_keys_sym, &copts->sym_key},
@@ -612,15 +615,37 @@ void oj_parse_options(VALUE ropts, Options copts) {
612
615
  {oj_create_additions_sym, &copts->create_ok},
613
616
  {cache_keys_sym, &copts->cache_keys},
614
617
  {Qnil, 0}};
615
- YesNoOpt o;
616
- volatile VALUE v;
617
- size_t len;
618
+ YesNoOpt o;
619
+
620
+ for (o = ynos; 0 != o->attr; o++) {
621
+ if (key == o->sym) {
622
+ if (Qnil == value) {
623
+ *o->attr = NotSet;
624
+ } else if (Qtrue == value) {
625
+ *o->attr = Yes;
626
+ } else if (Qfalse == value) {
627
+ *o->attr = No;
628
+ } else {
629
+ rb_raise(rb_eArgError,
630
+ "%s must be true, false, or nil.",
631
+ rb_id2name(key));
632
+ }
633
+ return true;
634
+ }
635
+ }
636
+ return false;
637
+ }
618
638
 
619
- if (T_HASH != rb_type(ropts)) {
620
- return;
639
+ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
640
+ {
641
+ Options copts = (Options)opts;
642
+ size_t len;
643
+
644
+ if (set_yesno_options(k, v, copts)) {
645
+ return ST_CONTINUE;
621
646
  }
622
- if (oj_hash_has_key(ropts, oj_indent_sym)) {
623
- v = rb_hash_lookup(ropts, oj_indent_sym);
647
+
648
+ if (oj_indent_sym == k) {
624
649
  switch (rb_type(v)) {
625
650
  case T_NIL:
626
651
  copts->dump_opts.indent_size = 0;
@@ -644,8 +669,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
644
669
  break;
645
670
  default: rb_raise(rb_eTypeError, "indent must be a Fixnum, String, or nil."); break;
646
671
  }
647
- }
648
- if (Qnil != (v = rb_hash_lookup(ropts, float_prec_sym))) {
672
+ } else if (float_prec_sym == k) {
649
673
  int n;
650
674
 
651
675
  #ifdef RUBY_INTEGER_UNIFICATION
@@ -668,8 +692,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
668
692
  sprintf(copts->float_fmt, "%%0.%dg", n);
669
693
  copts->float_prec = n;
670
694
  }
671
- }
672
- if (Qnil != (v = rb_hash_lookup(ropts, cache_str_sym))) {
695
+ } else if (cache_str_sym == k) {
673
696
  int n;
674
697
 
675
698
  #ifdef RUBY_INTEGER_UNIFICATION
@@ -690,8 +713,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
690
713
  }
691
714
  copts->cache_str = (char)n;
692
715
  }
693
- }
694
- if (Qnil != (v = rb_hash_lookup(ropts, sec_prec_sym))) {
716
+ } else if (sec_prec_sym == k) {
695
717
  int n;
696
718
 
697
719
  #ifdef RUBY_INTEGER_UNIFICATION
@@ -714,8 +736,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
714
736
  copts->sec_prec_set = true;
715
737
  }
716
738
  copts->sec_prec = n;
717
- }
718
- if (Qnil != (v = rb_hash_lookup(ropts, mode_sym))) {
739
+ } else if (mode_sym == k) {
719
740
  if (wab_sym == v) {
720
741
  copts->mode = WabMode;
721
742
  } else if (object_sym == v) {
@@ -734,8 +755,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
734
755
  rb_raise(rb_eArgError,
735
756
  ":mode must be :object, :strict, :compat, :null, :custom, :rails, or :wab.");
736
757
  }
737
- }
738
- if (Qnil != (v = rb_hash_lookup(ropts, time_format_sym))) {
758
+ } else if (time_format_sym == k) {
739
759
  if (unix_sym == v) {
740
760
  copts->time_format = UnixTime;
741
761
  } else if (unix_zone_sym == v) {
@@ -747,8 +767,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
747
767
  } else {
748
768
  rb_raise(rb_eArgError, ":time_format must be :unix, :unix_zone, :xmlschema, or :ruby.");
749
769
  }
750
- }
751
- if (Qnil != (v = rb_hash_lookup(ropts, escape_mode_sym))) {
770
+ } else if (escape_mode_sym == k) {
752
771
  if (newline_sym == v) {
753
772
  copts->escape_mode = NLEsc;
754
773
  } else if (json_sym == v) {
@@ -763,8 +782,11 @@ void oj_parse_options(VALUE ropts, Options copts) {
763
782
  rb_raise(rb_eArgError,
764
783
  ":encoding must be :newline, :json, :xss_safe, :unicode_xss, or :ascii.");
765
784
  }
766
- }
767
- if (Qnil != (v = rb_hash_lookup(ropts, bigdecimal_load_sym))) {
785
+ } else if (bigdecimal_load_sym == k) {
786
+ if (Qnil == v) {
787
+ return ST_CONTINUE;
788
+ }
789
+
768
790
  if (bigdecimal_sym == v || Qtrue == v) {
769
791
  copts->bigdec_load = BigDec;
770
792
  } else if (float_sym == v) {
@@ -776,12 +798,13 @@ void oj_parse_options(VALUE ropts, Options copts) {
776
798
  } else {
777
799
  rb_raise(rb_eArgError, ":bigdecimal_load must be :bigdecimal, :float, or :auto.");
778
800
  }
779
- }
780
- if (Qnil != (v = rb_hash_lookup(ropts, compat_bigdecimal_sym))) {
801
+ } else if (compat_bigdecimal_sym == k) {
802
+ if (Qnil == v) {
803
+ return ST_CONTINUE;
804
+ }
805
+
781
806
  copts->compat_bigdec = (Qtrue == v);
782
- }
783
- if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
784
- v = rb_hash_lookup(ropts, oj_decimal_class_sym);
807
+ } else if (oj_decimal_class_sym == k) {
785
808
  if (rb_cFloat == v) {
786
809
  copts->compat_bigdec = false;
787
810
  } else if (oj_bigdecimal_class == v) {
@@ -789,9 +812,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
789
812
  } else {
790
813
  rb_raise(rb_eArgError, ":decimal_class must be BigDecimal or Float.");
791
814
  }
792
- }
793
- if (oj_hash_has_key(ropts, create_id_sym)) {
794
- v = rb_hash_lookup(ropts, create_id_sym);
815
+ } else if (create_id_sym == k) {
795
816
  if (Qnil == v) {
796
817
  if (oj_json_class != oj_default_options.create_id && NULL != copts->create_id) {
797
818
  xfree((char *)oj_default_options.create_id);
@@ -810,25 +831,8 @@ void oj_parse_options(VALUE ropts, Options copts) {
810
831
  } else {
811
832
  rb_raise(rb_eArgError, ":create_id must be string.");
812
833
  }
813
- }
814
- for (o = ynos; 0 != o->attr; o++) {
815
- if (oj_hash_has_key(ropts, o->sym)) {
816
- v = rb_hash_lookup(ropts, o->sym);
817
- if (Qnil == v) {
818
- *o->attr = NotSet;
819
- } else if (Qtrue == v) {
820
- *o->attr = Yes;
821
- } else if (Qfalse == v) {
822
- *o->attr = No;
823
- } else {
824
- rb_raise(rb_eArgError,
825
- "%s must be true, false, or nil.",
826
- rb_id2name(SYM2ID(o->sym)));
827
- }
828
- }
829
- }
830
- if (oj_hash_has_key(ropts, oj_space_sym)) {
831
- if (Qnil == (v = rb_hash_lookup(ropts, oj_space_sym))) {
834
+ } else if (oj_space_sym == k) {
835
+ if (Qnil == v) {
832
836
  copts->dump_opts.after_size = 0;
833
837
  *copts->dump_opts.after_sep = '\0';
834
838
  } else {
@@ -841,9 +845,8 @@ void oj_parse_options(VALUE ropts, Options copts) {
841
845
  strcpy(copts->dump_opts.after_sep, StringValuePtr(v));
842
846
  copts->dump_opts.after_size = (uint8_t)len;
843
847
  }
844
- }
845
- if (oj_hash_has_key(ropts, oj_space_before_sym)) {
846
- if (Qnil == (v = rb_hash_lookup(ropts, oj_space_before_sym))) {
848
+ } else if (oj_space_before_sym == k) {
849
+ if (Qnil == v) {
847
850
  copts->dump_opts.before_size = 0;
848
851
  *copts->dump_opts.before_sep = '\0';
849
852
  } else {
@@ -856,9 +859,8 @@ void oj_parse_options(VALUE ropts, Options copts) {
856
859
  strcpy(copts->dump_opts.before_sep, StringValuePtr(v));
857
860
  copts->dump_opts.before_size = (uint8_t)len;
858
861
  }
859
- }
860
- if (oj_hash_has_key(ropts, oj_object_nl_sym)) {
861
- if (Qnil == (v = rb_hash_lookup(ropts, oj_object_nl_sym))) {
862
+ } else if (oj_object_nl_sym == k) {
863
+ if (Qnil == v) {
862
864
  copts->dump_opts.hash_size = 0;
863
865
  *copts->dump_opts.hash_nl = '\0';
864
866
  } else {
@@ -871,9 +873,8 @@ void oj_parse_options(VALUE ropts, Options copts) {
871
873
  strcpy(copts->dump_opts.hash_nl, StringValuePtr(v));
872
874
  copts->dump_opts.hash_size = (uint8_t)len;
873
875
  }
874
- }
875
- if (oj_hash_has_key(ropts, oj_array_nl_sym)) {
876
- if (Qnil == (v = rb_hash_lookup(ropts, oj_array_nl_sym))) {
876
+ } else if (oj_array_nl_sym == k) {
877
+ if (Qnil == v) {
877
878
  copts->dump_opts.array_size = 0;
878
879
  *copts->dump_opts.array_nl = '\0';
879
880
  } else {
@@ -886,8 +887,11 @@ void oj_parse_options(VALUE ropts, Options copts) {
886
887
  strcpy(copts->dump_opts.array_nl, StringValuePtr(v));
887
888
  copts->dump_opts.array_size = (uint8_t)len;
888
889
  }
889
- }
890
- if (Qnil != (v = rb_hash_lookup(ropts, nan_sym))) {
890
+ } else if (nan_sym == k) {
891
+ if (Qnil == v) {
892
+ return ST_CONTINUE;
893
+ }
894
+
891
895
  if (null_sym == v) {
892
896
  copts->dump_opts.nan_dump = NullNan;
893
897
  } else if (huge_sym == v) {
@@ -901,11 +905,11 @@ void oj_parse_options(VALUE ropts, Options copts) {
901
905
  } else {
902
906
  rb_raise(rb_eArgError, ":nan must be :null, :huge, :word, :raise, or :auto.");
903
907
  }
904
- }
905
- copts->dump_opts.use = (0 < copts->dump_opts.indent_size || 0 < copts->dump_opts.after_size ||
906
- 0 < copts->dump_opts.before_size || 0 < copts->dump_opts.hash_size ||
907
- 0 < copts->dump_opts.array_size);
908
- if (Qnil != (v = rb_hash_lookup(ropts, omit_nil_sym))) {
908
+ } else if (omit_nil_sym == k) {
909
+ if (Qnil == v) {
910
+ return ST_CONTINUE;
911
+ }
912
+
909
913
  if (Qtrue == v) {
910
914
  copts->dump_opts.omit_nil = true;
911
915
  } else if (Qfalse == v) {
@@ -913,43 +917,38 @@ void oj_parse_options(VALUE ropts, Options copts) {
913
917
  } else {
914
918
  rb_raise(rb_eArgError, ":omit_nil must be true or false.");
915
919
  }
916
- }
917
- // This is here only for backwards compatibility with the original Oj.
918
- v = rb_hash_lookup(ropts, oj_ascii_only_sym);
919
- if (Qtrue == v) {
920
- copts->escape_mode = ASCIIEsc;
921
- } else if (Qfalse == v) {
922
- copts->escape_mode = JSONEsc;
923
- }
924
- if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
925
- if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
920
+ } else if(oj_ascii_only_sym == k) {
921
+ // This is here only for backwards compatibility with the original Oj.
922
+ if (Qtrue == v) {
923
+ copts->escape_mode = ASCIIEsc;
924
+ } else if (Qfalse == v) {
925
+ copts->escape_mode = JSONEsc;
926
+ }
927
+ } else if (oj_hash_class_sym == k) {
928
+ if (Qnil == v) {
926
929
  copts->hash_class = Qnil;
927
930
  } else {
928
931
  rb_check_type(v, T_CLASS);
929
932
  copts->hash_class = v;
930
933
  }
931
- }
932
- if (oj_hash_has_key(ropts, oj_object_class_sym)) {
933
- if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
934
+ } else if (oj_object_class_sym == k) {
935
+ if (Qnil == v) {
934
936
  copts->hash_class = Qnil;
935
937
  } else {
936
938
  rb_check_type(v, T_CLASS);
937
939
  copts->hash_class = v;
938
940
  }
939
- }
940
- if (oj_hash_has_key(ropts, oj_array_class_sym)) {
941
- if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
941
+ } else if (oj_array_class_sym == k) {
942
+ if (Qnil == v) {
942
943
  copts->array_class = Qnil;
943
944
  } else {
944
945
  rb_check_type(v, T_CLASS);
945
946
  copts->array_class = v;
946
947
  }
947
- }
948
- oj_parse_opt_match_string(&copts->str_rx, ropts);
949
- if (oj_hash_has_key(ropts, ignore_sym)) {
948
+ } else if (ignore_sym == k) {
950
949
  xfree(copts->ignore);
951
950
  copts->ignore = NULL;
952
- if (Qnil != (v = rb_hash_lookup(ropts, ignore_sym))) {
951
+ if (Qnil != v) {
953
952
  int cnt;
954
953
 
955
954
  rb_check_type(v, T_ARRAY);
@@ -964,8 +963,11 @@ void oj_parse_options(VALUE ropts, Options copts) {
964
963
  copts->ignore[i] = Qnil;
965
964
  }
966
965
  }
967
- }
968
- if (Qnil != (v = rb_hash_lookup(ropts, integer_range_sym))) {
966
+ } else if (integer_range_sym == k) {
967
+ if (Qnil == v) {
968
+ return ST_CONTINUE;
969
+ }
970
+
969
971
  if (TYPE(v) == T_STRUCT && rb_obj_class(v) == rb_cRange) {
970
972
  VALUE min = rb_funcall(v, oj_begin_id, 0);
971
973
  VALUE max = rb_funcall(v, oj_end_id, 0);
@@ -980,6 +982,22 @@ void oj_parse_options(VALUE ropts, Options copts) {
980
982
  rb_raise(rb_eArgError, ":integer_range must be a range of Fixnum.");
981
983
  }
982
984
  }
985
+
986
+ return ST_CONTINUE;
987
+ }
988
+
989
+ void oj_parse_options(VALUE ropts, Options copts) {
990
+ if (T_HASH != rb_type(ropts)) {
991
+ return;
992
+ }
993
+
994
+ rb_hash_foreach(ropts, parse_options_cb, (VALUE)copts);
995
+ oj_parse_opt_match_string(&copts->str_rx, ropts);
996
+
997
+ copts->dump_opts.use = (0 < copts->dump_opts.indent_size || 0 < copts->dump_opts.after_size ||
998
+ 0 < copts->dump_opts.before_size || 0 < copts->dump_opts.hash_size ||
999
+ 0 < copts->dump_opts.array_size);
1000
+ return;
983
1001
  }
984
1002
 
985
1003
  static int match_string_cb(VALUE key, VALUE value, VALUE rx) {
@@ -1380,7 +1398,7 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
1380
1398
  * Dumps an Object to the specified file.
1381
1399
  * - *file* [_String_] _path file path to write the JSON document to
1382
1400
  * - *obj* [_Object_] Object to serialize as an JSON document String
1383
- * - *options* [_Hash_] formating options
1401
+ * - *options* [_Hash_] formatting options
1384
1402
  * - *:indent* [_Fixnum_] format expected
1385
1403
  * - *:circular* [_Boolean_] allow circular references, default: false
1386
1404
  */
@@ -1402,7 +1420,7 @@ static VALUE to_file(int argc, VALUE *argv, VALUE self) {
1402
1420
  * Dumps an Object to the specified IO stream.
1403
1421
  * - *io* [_IO_] IO stream to write the JSON document to
1404
1422
  * - *obj* [_Object_] Object to serialize as an JSON document String
1405
- * - *options* [_Hash_] formating options
1423
+ * - *options* [_Hash_] formatting options
1406
1424
  * - *:indent* [_Fixnum_] format expected
1407
1425
  * - *:circular* [_Boolean_] allow circular references, default: false
1408
1426
  */
@@ -1761,6 +1779,9 @@ static VALUE protect_require(VALUE x) {
1761
1779
  void Init_oj() {
1762
1780
  int err = 0;
1763
1781
 
1782
+ #if HAVE_RB_EXT_RACTOR_SAFE
1783
+ rb_ext_ractor_safe(true);
1784
+ #endif
1764
1785
  Oj = rb_define_module("Oj");
1765
1786
 
1766
1787
  oj_cstack_class = rb_define_class_under(Oj, "CStack", rb_cObject);
@@ -2035,4 +2056,6 @@ void Init_oj() {
2035
2056
  rb_gc_register_address(&oj_cache_mutex);
2036
2057
  #endif
2037
2058
  oj_init_doc();
2059
+
2060
+ oj_parser_init();
2038
2061
  }
data/ext/oj/oj.h CHANGED
@@ -143,7 +143,7 @@ typedef struct _options {
143
143
  char safe; // YesNo
144
144
  char sec_prec_set; // boolean (0 or 1)
145
145
  char ignore_under; // YesNo - ignore attrs starting with _ if true in object and custom modes
146
- char cache_keys; // YexNo
146
+ char cache_keys; // YesNo
147
147
  char cache_str; // string short than or equal to this are cache
148
148
  int64_t int_range_min; // dump numbers below as string
149
149
  int64_t int_range_max; // dump numbers above as string
data/ext/oj/parse.c CHANGED
@@ -489,7 +489,7 @@ static void read_num(ParseInfo pi) {
489
489
  if ('.' == *pi->cur) {
490
490
  pi->cur++;
491
491
  // A trailing . is not a valid decimal but if encountered allow it
492
- // except when mimicing the JSON gem or in strict mode.
492
+ // except when mimicking the JSON gem or in strict mode.
493
493
  if (StrictMode == pi->options.mode || CompatMode == pi->options.mode) {
494
494
  int pos = (int)(pi->cur - ni.str);
495
495
 
@@ -964,12 +964,12 @@ static VALUE protect_parse(VALUE pip) {
964
964
  extern int oj_utf8_index;
965
965
 
966
966
  static void oj_pi_set_input_str(ParseInfo pi, volatile VALUE *inputp) {
967
- rb_encoding *enc = rb_to_encoding(rb_obj_encoding(*inputp));
967
+ rb_encoding *enc = rb_enc_get(*inputp);
968
968
 
969
- if (rb_utf8_encoding() != enc) {
970
- *inputp = rb_str_conv_enc(*inputp, enc, rb_utf8_encoding());
969
+ if (oj_utf8_encoding != enc) {
970
+ *inputp = rb_str_conv_enc(*inputp, enc, oj_utf8_encoding);
971
971
  }
972
- pi->json = rb_string_value_ptr((VALUE *)inputp);
972
+ pi->json = RSTRING_PTR(*inputp);
973
973
  pi->end = pi->json + RSTRING_LEN(*inputp);
974
974
  }
975
975