oj 3.16.9 → 3.16.11

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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/ext/oj/custom.c +10 -9
  4. data/ext/oj/dump.c +319 -20
  5. data/ext/oj/dump.h +7 -2
  6. data/ext/oj/dump_compat.c +9 -8
  7. data/ext/oj/dump_leaf.c +1 -1
  8. data/ext/oj/dump_object.c +27 -17
  9. data/ext/oj/dump_strict.c +7 -6
  10. data/ext/oj/fast.c +4 -7
  11. data/ext/oj/mimic_json.c +3 -6
  12. data/ext/oj/object.c +8 -8
  13. data/ext/oj/oj.c +12 -9
  14. data/ext/oj/parse.c +15 -5
  15. data/ext/oj/parser.c +1 -1
  16. data/ext/oj/parser.h +2 -0
  17. data/ext/oj/rails.c +20 -19
  18. data/ext/oj/saj.c +3 -6
  19. data/ext/oj/scp.c +3 -6
  20. data/ext/oj/simd.h +10 -0
  21. data/ext/oj/stream_writer.c +1 -7
  22. data/ext/oj/strict.c +2 -4
  23. data/ext/oj/string_writer.c +1 -3
  24. data/ext/oj/wab.c +4 -3
  25. data/lib/oj/version.rb +1 -1
  26. data/pages/Encoding.md +1 -1
  27. metadata +4 -98
  28. data/test/_test_active.rb +0 -75
  29. data/test/_test_active_mimic.rb +0 -95
  30. data/test/_test_mimic_rails.rb +0 -123
  31. data/test/activerecord/result_test.rb +0 -31
  32. data/test/activesupport6/abstract_unit.rb +0 -44
  33. data/test/activesupport6/decoding_test.rb +0 -133
  34. data/test/activesupport6/encoding_test.rb +0 -542
  35. data/test/activesupport6/encoding_test_cases.rb +0 -98
  36. data/test/activesupport6/test_common.rb +0 -17
  37. data/test/activesupport6/test_helper.rb +0 -163
  38. data/test/activesupport6/time_zone_test_helpers.rb +0 -39
  39. data/test/activesupport7/abstract_unit.rb +0 -52
  40. data/test/activesupport7/decoding_test.rb +0 -125
  41. data/test/activesupport7/encoding_test.rb +0 -536
  42. data/test/activesupport7/encoding_test_cases.rb +0 -104
  43. data/test/activesupport7/time_zone_test_helpers.rb +0 -47
  44. data/test/files.rb +0 -29
  45. data/test/foo.rb +0 -26
  46. data/test/helper.rb +0 -39
  47. data/test/isolated/shared.rb +0 -309
  48. data/test/isolated/test_mimic_after.rb +0 -13
  49. data/test/isolated/test_mimic_alone.rb +0 -12
  50. data/test/isolated/test_mimic_as_json.rb +0 -45
  51. data/test/isolated/test_mimic_before.rb +0 -13
  52. data/test/isolated/test_mimic_define.rb +0 -28
  53. data/test/isolated/test_mimic_rails_after.rb +0 -22
  54. data/test/isolated/test_mimic_rails_before.rb +0 -21
  55. data/test/isolated/test_mimic_redefine.rb +0 -15
  56. data/test/json_gem/json_addition_test.rb +0 -216
  57. data/test/json_gem/json_common_interface_test.rb +0 -155
  58. data/test/json_gem/json_encoding_test.rb +0 -107
  59. data/test/json_gem/json_ext_parser_test.rb +0 -21
  60. data/test/json_gem/json_fixtures_test.rb +0 -36
  61. data/test/json_gem/json_generator_test.rb +0 -413
  62. data/test/json_gem/json_generic_object_test.rb +0 -90
  63. data/test/json_gem/json_parser_test.rb +0 -477
  64. data/test/json_gem/json_string_matching_test.rb +0 -42
  65. data/test/json_gem/test_helper.rb +0 -30
  66. data/test/mem.rb +0 -34
  67. data/test/perf.rb +0 -102
  68. data/test/perf_compat.rb +0 -128
  69. data/test/perf_dump.rb +0 -50
  70. data/test/perf_fast.rb +0 -162
  71. data/test/perf_file.rb +0 -62
  72. data/test/perf_object.rb +0 -134
  73. data/test/perf_once.rb +0 -59
  74. data/test/perf_parser.rb +0 -183
  75. data/test/perf_saj.rb +0 -101
  76. data/test/perf_scp.rb +0 -140
  77. data/test/perf_simple.rb +0 -289
  78. data/test/perf_strict.rb +0 -137
  79. data/test/perf_wab.rb +0 -129
  80. data/test/prec.rb +0 -23
  81. data/test/sample/change.rb +0 -13
  82. data/test/sample/dir.rb +0 -18
  83. data/test/sample/doc.rb +0 -35
  84. data/test/sample/file.rb +0 -47
  85. data/test/sample/group.rb +0 -15
  86. data/test/sample/hasprops.rb +0 -15
  87. data/test/sample/layer.rb +0 -11
  88. data/test/sample/line.rb +0 -20
  89. data/test/sample/oval.rb +0 -10
  90. data/test/sample/rect.rb +0 -9
  91. data/test/sample/shape.rb +0 -34
  92. data/test/sample/text.rb +0 -19
  93. data/test/sample.rb +0 -54
  94. data/test/sample_json.rb +0 -37
  95. data/test/test_compat.rb +0 -567
  96. data/test/test_custom.rb +0 -555
  97. data/test/test_debian.rb +0 -50
  98. data/test/test_fast.rb +0 -526
  99. data/test/test_file.rb +0 -250
  100. data/test/test_gc.rb +0 -60
  101. data/test/test_generate.rb +0 -21
  102. data/test/test_hash.rb +0 -39
  103. data/test/test_integer_range.rb +0 -72
  104. data/test/test_null.rb +0 -376
  105. data/test/test_object.rb +0 -1030
  106. data/test/test_parser.rb +0 -11
  107. data/test/test_parser_debug.rb +0 -27
  108. data/test/test_parser_saj.rb +0 -337
  109. data/test/test_parser_usual.rb +0 -255
  110. data/test/test_rails.rb +0 -35
  111. data/test/test_saj.rb +0 -188
  112. data/test/test_scp.rb +0 -431
  113. data/test/test_strict.rb +0 -441
  114. data/test/test_various.rb +0 -801
  115. data/test/test_wab.rb +0 -311
  116. data/test/test_writer.rb +0 -396
  117. data/test/tests.rb +0 -33
  118. data/test/tests_mimic.rb +0 -23
  119. data/test/tests_mimic_addition.rb +0 -16
data/ext/oj/dump_compat.c CHANGED
@@ -103,7 +103,7 @@ static void dump_values_array(VALUE *values, int depth, Out out) {
103
103
  static void dump_to_json(VALUE obj, Out out) {
104
104
  volatile VALUE rs;
105
105
  const char *s;
106
- int len;
106
+ size_t len;
107
107
 
108
108
  TRACE(out->opts->trace, "to_json", obj, 0, TraceRubyIn);
109
109
  if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
@@ -115,7 +115,7 @@ static void dump_to_json(VALUE obj, Out out) {
115
115
 
116
116
  StringValue(rs);
117
117
  s = RSTRING_PTR(rs);
118
- len = (int)RSTRING_LEN(rs);
118
+ len = RSTRING_LEN(rs);
119
119
 
120
120
  assure_size(out, len + 1);
121
121
  APPEND_CHARS(out->cur, s, len);
@@ -124,7 +124,8 @@ static void dump_to_json(VALUE obj, Out out) {
124
124
 
125
125
  static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
126
126
  size_t size;
127
- int i, cnt;
127
+ size_t i;
128
+ size_t cnt;
128
129
  int d2 = depth + 1;
129
130
  long id = oj_check_circular(a, out);
130
131
 
@@ -136,7 +137,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
136
137
  dump_to_json(a, out);
137
138
  return;
138
139
  }
139
- cnt = (int)RARRAY_LEN(a);
140
+ cnt = RARRAY_LEN(a);
140
141
  *out->cur++ = '[';
141
142
  assure_size(out, 2);
142
143
  if (0 == cnt) {
@@ -552,7 +553,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
552
553
  char buf[64];
553
554
  char *b;
554
555
  double d = rb_num2dbl(obj);
555
- int cnt = 0;
556
+ size_t cnt = 0;
556
557
 
557
558
  if (0.0 == d) {
558
559
  b = buf;
@@ -590,7 +591,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
590
591
  volatile VALUE rstr = oj_safe_string_convert(obj);
591
592
 
592
593
  strcpy(buf, RSTRING_PTR(rstr));
593
- cnt = (int)RSTRING_LEN(rstr);
594
+ cnt = RSTRING_LEN(rstr);
594
595
  }
595
596
  assure_size(out, cnt);
596
597
  APPEND_CHARS(out->cur, buf, cnt);
@@ -800,7 +801,7 @@ static void dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
800
801
  // rb_big2str can not so unless overridden by using add_to_json(Integer)
801
802
  // this must use to_s to pass the json gem unit tests.
802
803
  volatile VALUE rs;
803
- int cnt;
804
+ size_t cnt;
804
805
  bool dump_as_string = false;
805
806
 
806
807
  if (use_bignum_alt) {
@@ -809,7 +810,7 @@ static void dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
809
810
  rs = oj_safe_string_convert(obj);
810
811
  }
811
812
  rb_check_type(rs, T_STRING);
812
- cnt = (int)RSTRING_LEN(rs);
813
+ cnt = RSTRING_LEN(rs);
813
814
 
814
815
  if (out->opts->int_range_min != 0 || out->opts->int_range_max != 0) {
815
816
  dump_as_string = true; // Bignum cannot be inside of Fixnum range
data/ext/oj/dump_leaf.c CHANGED
@@ -17,7 +17,7 @@ inline static void dump_chars(const char *s, size_t size, Out out) {
17
17
  static void dump_leaf_str(Leaf leaf, Out out) {
18
18
  switch (leaf->value_type) {
19
19
  case STR_VAL: oj_dump_cstr(leaf->str, strlen(leaf->str), 0, 0, out); break;
20
- case RUBY_VAL: oj_dump_cstr(StringValueCStr(leaf->value), (int)RSTRING_LEN(leaf->value), 0, 0, out); break;
20
+ case RUBY_VAL: oj_dump_cstr(StringValueCStr(leaf->value), RSTRING_LEN(leaf->value), 0, 0, out); break;
21
21
  case COL_VAL:
22
22
  default: rb_raise(rb_eTypeError, "Unexpected value type %02x.\n", leaf->value_type); break;
23
23
  }
data/ext/oj/dump_object.c CHANGED
@@ -33,7 +33,7 @@ static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
33
33
  if (oj_bigdecimal_class == clas) {
34
34
  volatile VALUE rstr = oj_safe_string_convert(obj);
35
35
  const char *str = RSTRING_PTR(rstr);
36
- int len = (int)RSTRING_LEN(rstr);
36
+ size_t len = RSTRING_LEN(rstr);
37
37
 
38
38
  if (No != out->opts->bigdec_as_num) {
39
39
  oj_dump_raw(str, len, out);
@@ -62,7 +62,7 @@ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
62
62
  if (oj_bigdecimal_class == clas) {
63
63
  volatile VALUE rstr = oj_safe_string_convert(obj);
64
64
  const char *str = RSTRING_PTR(rstr);
65
- int len = (int)RSTRING_LEN(rstr);
65
+ size_t len = RSTRING_LEN(rstr);
66
66
 
67
67
  if (0 == strcasecmp("Infinity", str)) {
68
68
  str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
@@ -95,7 +95,8 @@ static void dump_class(VALUE obj, int depth, Out out, bool as_ok) {
95
95
 
96
96
  static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
97
97
  size_t size;
98
- int i, cnt;
98
+ size_t i;
99
+ size_t cnt;
99
100
  int d2 = depth + 1;
100
101
  long id = oj_check_circular(a, out);
101
102
 
@@ -106,7 +107,7 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
106
107
  dump_obj_attrs(a, clas, 0, depth, out);
107
108
  return;
108
109
  }
109
- cnt = (int)RARRAY_LEN(a);
110
+ cnt = RARRAY_LEN(a);
110
111
  *out->cur++ = '[';
111
112
  if (0 < id) {
112
113
  assure_size(out, d2 * out->indent + 16);
@@ -181,7 +182,7 @@ static void dump_str_class(VALUE obj, VALUE clas, int depth, Out out) {
181
182
  dump_obj_attrs(obj, clas, 0, depth, out);
182
183
  } else {
183
184
  const char *s = RSTRING_PTR(obj);
184
- size_t len = (int)RSTRING_LEN(obj);
185
+ size_t len = RSTRING_LEN(obj);
185
186
  char s1 = s[1];
186
187
 
187
188
  oj_dump_cstr(s, len, 0, (':' == *s || ('^' == *s && ('r' == s1 || 'i' == s1))), out);
@@ -195,7 +196,7 @@ static void dump_str(VALUE obj, int depth, Out out, bool as_ok) {
195
196
  static void dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
196
197
  volatile VALUE s = rb_sym2str(obj);
197
198
 
198
- oj_dump_cstr(RSTRING_PTR(s), (int)RSTRING_LEN(s), 1, 0, out);
199
+ oj_dump_cstr(RSTRING_PTR(s), RSTRING_LEN(s), 1, 0, out);
199
200
  }
200
201
 
201
202
  static int hash_cb(VALUE key, VALUE value, VALUE ov) {
@@ -389,7 +390,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
389
390
  rb_raise(rb_eEncodingError, "Invalid type for raw JSON.");
390
391
  } else {
391
392
  const char *s = RSTRING_PTR(v);
392
- int len = (int)RSTRING_LEN(v);
393
+ size_t len = RSTRING_LEN(v);
393
394
  const char *name = rb_id2name(*odd->attrs);
394
395
  size_t nlen = strlen(name);
395
396
 
@@ -489,7 +490,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
489
490
  *out->cur++ = ',';
490
491
  fill_indent(out, d2);
491
492
  APPEND_CHARS(out->cur, "\"self\":", 7);
492
- oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
493
+ oj_dump_cstr(RSTRING_PTR(obj), RSTRING_LEN(obj), 0, 0, out);
493
494
  break;
494
495
  case T_ARRAY:
495
496
  assure_size(out, d2 * out->indent + 14);
@@ -564,11 +565,12 @@ static void dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
564
565
  static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
565
566
  VALUE clas = rb_obj_class(obj);
566
567
  const char *class_name = rb_class2name(clas);
567
- int i;
568
- int d2 = depth + 1;
569
- int d3 = d2 + 1;
570
- size_t len = strlen(class_name);
571
- size_t size = d2 * out->indent + d3 * out->indent + 10 + len;
568
+ size_t i;
569
+ int d2 = depth + 1;
570
+ int d3 = d2 + 1;
571
+ size_t len = strlen(class_name);
572
+ size_t size = d2 * out->indent + d3 * out->indent + 10 + len;
573
+ char circular = out->opts->circular;
572
574
 
573
575
  assure_size(out, size);
574
576
  *out->cur++ = '{';
@@ -577,14 +579,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
577
579
  if ('#' == *class_name) {
578
580
  VALUE ma = rb_struct_s_members(clas);
579
581
  const char *name;
580
- int cnt = (int)RARRAY_LEN(ma);
582
+ size_t cnt = RARRAY_LEN(ma);
581
583
 
582
584
  *out->cur++ = '[';
583
585
  for (i = 0; i < cnt; i++) {
584
586
  volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
585
587
 
586
588
  name = RSTRING_PTR(s);
587
- len = (int)RSTRING_LEN(s);
589
+ len = RSTRING_LEN(s);
588
590
  size = len + 3;
589
591
  assure_size(out, size);
590
592
  if (0 < i) {
@@ -607,14 +609,18 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
607
609
  {
608
610
  VALUE v;
609
611
  int cnt;
612
+
610
613
  #if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
611
614
  cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
612
615
  #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
613
616
  cnt = (int)RSTRUCT_LEN(obj);
614
617
  #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
615
618
 
616
- for (i = 0; i < cnt; i++) {
617
- v = RSTRUCT_GET(obj, i);
619
+ if (0 == strcmp(class_name, "Range")) {
620
+ out->opts->circular = 'n';
621
+ }
622
+ for (i = 0; i < (size_t)cnt; i++) {
623
+ v = RSTRUCT_GET(obj, (int)i);
618
624
  if (dump_ignore(out->opts, v)) {
619
625
  v = Qnil;
620
626
  }
@@ -630,6 +636,9 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
630
636
  // class in interpreted Ruby so length() may not be defined.
631
637
  int slen = FIX2INT(rb_funcall2(obj, oj_length_id, 0, 0));
632
638
 
639
+ if (0 == strcmp(class_name, "Range")) {
640
+ out->opts->circular = 'n';
641
+ }
633
642
  for (i = 0; i < slen; i++) {
634
643
  assure_size(out, size);
635
644
  fill_indent(out, d3);
@@ -641,6 +650,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
641
650
  }
642
651
  }
643
652
  #endif
653
+ out->opts->circular = circular;
644
654
  out->cur--;
645
655
  APPEND_CHARS(out->cur, "]}", 2);
646
656
  *out->cur = '\0';
data/ext/oj/dump_strict.c CHANGED
@@ -30,7 +30,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
30
30
  char buf[64];
31
31
  char* b;
32
32
  double d = rb_num2dbl(obj);
33
- int cnt = 0;
33
+ size_t cnt = 0;
34
34
 
35
35
  if (0.0 == d) {
36
36
  b = buf;
@@ -92,7 +92,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
92
92
  } else if (0 == out->opts->float_prec) {
93
93
  volatile VALUE rstr = oj_safe_string_convert(obj);
94
94
 
95
- cnt = (int)RSTRING_LEN(rstr);
95
+ cnt = RSTRING_LEN(rstr);
96
96
  if ((int)sizeof(buf) <= cnt) {
97
97
  cnt = sizeof(buf) - 1;
98
98
  }
@@ -109,7 +109,8 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
109
109
 
110
110
  static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
111
111
  size_t size;
112
- int i, cnt;
112
+ size_t i;
113
+ size_t cnt;
113
114
  int d2 = depth + 1;
114
115
 
115
116
  if (Yes == out->opts->circular) {
@@ -118,7 +119,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
118
119
  return;
119
120
  }
120
121
  }
121
- cnt = (int)RARRAY_LEN(a);
122
+ cnt = RARRAY_LEN(a);
122
123
  *out->cur++ = '[';
123
124
  size = 2;
124
125
  assure_size(out, size);
@@ -290,7 +291,7 @@ static void dump_data_strict(VALUE obj, int depth, Out out, bool as_ok) {
290
291
  if (oj_bigdecimal_class == clas) {
291
292
  volatile VALUE rstr = oj_safe_string_convert(obj);
292
293
 
293
- oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
294
+ oj_dump_raw(RSTRING_PTR(rstr), RSTRING_LEN(rstr), out);
294
295
  } else {
295
296
  raise_strict(obj);
296
297
  }
@@ -302,7 +303,7 @@ static void dump_data_null(VALUE obj, int depth, Out out, bool as_ok) {
302
303
  if (oj_bigdecimal_class == clas) {
303
304
  volatile VALUE rstr = oj_safe_string_convert(obj);
304
305
 
305
- oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
306
+ oj_dump_raw(RSTRING_PTR(rstr), RSTRING_LEN(rstr), out);
306
307
  } else {
307
308
  oj_dump_nil(Qnil, depth, out, false);
308
309
  }
data/ext/oj/fast.c CHANGED
@@ -193,8 +193,7 @@ static VALUE leaf_value(Doc doc, Leaf leaf) {
193
193
  case T_FIXNUM: leaf_fixnum_value(leaf); break;
194
194
  case T_FLOAT: leaf_float_value(leaf); break;
195
195
  case T_STRING:
196
- leaf->value = rb_str_new2(leaf->str);
197
- leaf->value = oj_encode(leaf->value);
196
+ leaf->value = rb_utf8_str_new_cstr(leaf->str);
198
197
  leaf->value_type = RUBY_VAL;
199
198
  break;
200
199
  case T_ARRAY: return leaf_array_value(doc, leaf); break;
@@ -309,8 +308,7 @@ static VALUE leaf_hash_value(Doc doc, Leaf leaf) {
309
308
  volatile VALUE key;
310
309
 
311
310
  do {
312
- key = rb_str_new2(e->key);
313
- key = oj_encode(key);
311
+ key = rb_utf8_str_new_cstr(e->key);
314
312
  rb_hash_aset(h, key, leaf_value(doc, e));
315
313
  e = e->next;
316
314
  } while (e != first);
@@ -1088,7 +1086,7 @@ static VALUE doc_open(VALUE clas, VALUE str) {
1088
1086
  int given = rb_block_given_p();
1089
1087
 
1090
1088
  Check_Type(str, T_STRING);
1091
- len = (int)RSTRING_LEN(str) + 1;
1089
+ len = RSTRING_LEN(str) + 1;
1092
1090
  json = OJ_R_ALLOC_N(char, len);
1093
1091
 
1094
1092
  memcpy(json, StringValuePtr(str), len);
@@ -1257,8 +1255,7 @@ static VALUE doc_local_key(VALUE self) {
1257
1255
  volatile VALUE key = Qnil;
1258
1256
 
1259
1257
  if (T_HASH == leaf->parent_type) {
1260
- key = rb_str_new2(leaf->key);
1261
- key = oj_encode(key);
1258
+ key = rb_utf8_str_new_cstr(leaf->key);
1262
1259
  } else if (T_ARRAY == leaf->parent_type) {
1263
1260
  key = LONG2NUM(leaf->index);
1264
1261
  }
data/ext/oj/mimic_json.c CHANGED
@@ -246,8 +246,7 @@ static VALUE mimic_dump(int argc, VALUE *argv, VALUE self) {
246
246
  if (0 == out.buf) {
247
247
  rb_raise(rb_eNoMemError, "Not enough memory.");
248
248
  }
249
- rstr = rb_str_new2(out.buf);
250
- rstr = oj_encode(rstr);
249
+ rstr = rb_utf8_str_new_cstr(out.buf);
251
250
  if (2 <= argc && Qnil != argv[1] && rb_respond_to(argv[1], oj_write_id)) {
252
251
  VALUE io = argv[1];
253
252
  VALUE args[1];
@@ -396,8 +395,7 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
396
395
  if (0 == out.buf) {
397
396
  rb_raise(rb_eNoMemError, "Not enough memory.");
398
397
  }
399
- rstr = rb_str_new2(out.buf);
400
- rstr = oj_encode(rstr);
398
+ rstr = rb_utf8_str_new_cstr(out.buf);
401
399
 
402
400
  oj_out_free(&out);
403
401
 
@@ -768,8 +766,7 @@ static VALUE mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
768
766
  if (NULL == out.buf) {
769
767
  rb_raise(rb_eNoMemError, "Not enough memory.");
770
768
  }
771
- rstr = rb_str_new2(out.buf);
772
- rstr = oj_encode(rstr);
769
+ rstr = rb_utf8_str_new_cstr(out.buf);
773
770
 
774
771
  oj_out_free(&out);
775
772
 
data/ext/oj/object.c CHANGED
@@ -305,7 +305,7 @@ static int hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
305
305
 
306
306
  static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, volatile VALUE value) {
307
307
  if (T_ARRAY == rb_type(value)) {
308
- int len = (int)RARRAY_LEN(value);
308
+ size_t len = RARRAY_LEN(value);
309
309
 
310
310
  if (2 == klen && 'u' == key[1]) {
311
311
  volatile VALUE sc;
@@ -321,19 +321,20 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
321
321
  if (T_ARRAY == rb_type(e1)) {
322
322
  VALUE args[1024];
323
323
  volatile VALUE rstr;
324
- int i, cnt = (int)RARRAY_LEN(e1);
324
+ size_t i;
325
+ size_t cnt = RARRAY_LEN(e1);
325
326
 
326
327
  for (i = 0; i < cnt; i++) {
327
328
  rstr = RARRAY_AREF(e1, i);
328
329
  args[i] = rb_funcall(rstr, oj_to_sym_id, 0);
329
330
  }
330
- sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
331
+ sc = rb_funcall2(rb_cStruct, oj_new_id, (int)cnt, args);
331
332
  } else {
332
333
  // If struct is not defined then we let this fail and raise an exception.
333
334
  sc = oj_name2struct(pi, *RARRAY_CONST_PTR(value), rb_eArgError);
334
335
  }
335
336
  if (sc == rb_cRange) {
336
- parent->val = rb_class_new_instance(len - 1, RARRAY_CONST_PTR(value) + 1, rb_cRange);
337
+ parent->val = rb_class_new_instance((int)(len - 1), RARRAY_CONST_PTR(value) + 1, rb_cRange);
337
338
  } else {
338
339
  // Create a properly initialized struct instance without calling the initialize method.
339
340
  parent->val = rb_obj_alloc(sc);
@@ -348,10 +349,10 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
348
349
  slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0));
349
350
  #endif
350
351
  // MRI >= 1.9
351
- if (len - 1 > slen) {
352
+ if (len - 1 > (size_t)slen) {
352
353
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
353
354
  } else {
354
- int i;
355
+ size_t i;
355
356
 
356
357
  for (i = 0; i < len - 1; i++) {
357
358
  rb_struct_aset(parent->val, INT2FIX(i), RARRAY_CONST_PTR(value)[i + 1]);
@@ -698,9 +699,8 @@ oj_object_parse(int argc, VALUE *argv, VALUE self) {
698
699
 
699
700
  if (T_STRING == rb_type(*argv)) {
700
701
  return oj_pi_parse(argc, argv, &pi, 0, 0, 1);
701
- } else {
702
- return oj_pi_sparse(argc, argv, &pi, 0);
703
702
  }
703
+ return oj_pi_sparse(argc, argv, &pi, 0);
704
704
  }
705
705
 
706
706
  VALUE
data/ext/oj/oj.c CHANGED
@@ -18,6 +18,7 @@
18
18
  #include "odd.h"
19
19
  #include "parse.h"
20
20
  #include "rails.h"
21
+ #include "simd.h"
21
22
 
22
23
  typedef struct _yesNoOpt {
23
24
  VALUE sym;
@@ -923,12 +924,12 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
923
924
  OJ_R_FREE(copts->ignore);
924
925
  copts->ignore = NULL;
925
926
  if (Qnil != v) {
926
- int cnt;
927
+ size_t cnt;
927
928
 
928
929
  rb_check_type(v, T_ARRAY);
929
- cnt = (int)RARRAY_LEN(v);
930
+ cnt = RARRAY_LEN(v);
930
931
  if (0 < cnt) {
931
- int i;
932
+ size_t i;
932
933
 
933
934
  copts->ignore = OJ_R_ALLOC_N(VALUE, cnt + 1);
934
935
  for (i = 0; i < cnt; i++) {
@@ -973,7 +974,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
973
974
  }
974
975
  } else if (float_format_sym == k) {
975
976
  rb_check_type(v, T_STRING);
976
- if (6 < (int)RSTRING_LEN(v)) {
977
+ if (6 < RSTRING_LEN(v)) {
977
978
  rb_raise(rb_eArgError, ":float_format must be 6 bytes or less.");
978
979
  }
979
980
  strncpy(copts->float_fmt, RSTRING_PTR(v), (size_t)RSTRING_LEN(v));
@@ -1188,7 +1189,7 @@ static VALUE load_file(int argc, VALUE *argv, VALUE self) {
1188
1189
  OJ_FREE(wide_path);
1189
1190
  }
1190
1191
  #else
1191
- fd = open(path, O_RDONLY);
1192
+ fd = open(path, O_RDONLY);
1192
1193
  #endif
1193
1194
  if (0 == fd) {
1194
1195
  rb_raise(rb_eIOError, "%s", strerror(errno));
@@ -1277,8 +1278,7 @@ static VALUE dump_body(VALUE a) {
1277
1278
  if (0 == arg->out->buf) {
1278
1279
  rb_raise(rb_eNoMemError, "Not enough memory.");
1279
1280
  }
1280
- rstr = rb_str_new2(arg->out->buf);
1281
- rstr = oj_encode(rstr);
1281
+ rstr = rb_utf8_str_new_cstr(arg->out->buf);
1282
1282
 
1283
1283
  return rstr;
1284
1284
  }
@@ -1378,8 +1378,7 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
1378
1378
  if (0 == out.buf) {
1379
1379
  rb_raise(rb_eNoMemError, "Not enough memory.");
1380
1380
  }
1381
- rstr = rb_str_new2(out.buf);
1382
- rstr = oj_encode(rstr);
1381
+ rstr = rb_utf8_str_new_cstr(out.buf);
1383
1382
 
1384
1383
  oj_out_free(&out);
1385
1384
 
@@ -2083,4 +2082,8 @@ void Init_oj(void) {
2083
2082
 
2084
2083
  oj_parser_init();
2085
2084
  oj_scanner_init();
2085
+
2086
+ #ifdef HAVE_SIMD_NEON
2087
+ initialize_neon();
2088
+ #endif /* HAVE_SIMD_NEON */
2086
2089
  }
data/ext/oj/parse.c CHANGED
@@ -183,9 +183,19 @@ static void unicode_to_chars(ParseInfo pi, Buf buf, uint32_t code) {
183
183
  }
184
184
  }
185
185
 
186
+ static const unsigned char end_of_scan_string[] = {
187
+ // Filled 1 at the positions of '\0', '\\', and '"'
188
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
189
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
191
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
193
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
194
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
195
+ };
186
196
  static inline const char *scan_string_noSIMD(const char *str, const char *end) {
187
- for (; '"' != *str; str++) {
188
- if (end <= str || '\0' == *str || '\\' == *str) {
197
+ for (; str < end; str++) {
198
+ if (end_of_scan_string[(unsigned char)*str]) {
189
199
  break;
190
200
  }
191
201
  }
@@ -1123,12 +1133,12 @@ CLEANUP:
1123
1133
  // The json gem requires the error message be UTF-8 encoded. In
1124
1134
  // additional the complete JSON source must be returned. There
1125
1135
  // does not seem to be a size limit.
1126
- VALUE msg = oj_encode(rb_str_new2(pi->err.msg));
1136
+ VALUE msg = rb_utf8_str_new_cstr(pi->err.msg);
1127
1137
  VALUE args[1];
1128
1138
 
1129
1139
  if (NULL != pi->json) {
1130
- msg = rb_str_append(msg, oj_encode(rb_str_new2(" in '")));
1131
- msg = rb_str_append(msg, oj_encode(rb_str_new2(pi->json)));
1140
+ msg = rb_str_append(msg, rb_utf8_str_new_cstr(" in '"));
1141
+ msg = rb_str_append(msg, rb_utf8_str_new_cstr(pi->json));
1132
1142
  }
1133
1143
  args[0] = msg;
1134
1144
  if (pi->err.clas == oj_parse_error_class) {
data/ext/oj/parser.c CHANGED
@@ -1161,7 +1161,7 @@ static void parser_mark(void *ptr) {
1161
1161
  }
1162
1162
  }
1163
1163
 
1164
- static const rb_data_type_t oj_parser_type = {
1164
+ const rb_data_type_t oj_parser_type = {
1165
1165
  "Oj/parser",
1166
1166
  {
1167
1167
  parser_mark,
data/ext/oj/parser.h CHANGED
@@ -42,6 +42,8 @@ typedef struct _num {
42
42
 
43
43
  struct _ojParser;
44
44
 
45
+ extern const rb_data_type_t oj_parser_type;
46
+
45
47
  typedef struct _funcs {
46
48
  void (*add_null)(struct _ojParser *p);
47
49
  void (*add_true)(struct _ojParser *p);
data/ext/oj/rails.c CHANGED
@@ -140,7 +140,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
140
140
  volatile VALUE v;
141
141
  int cnt;
142
142
  int i;
143
- int len;
143
+ size_t len;
144
144
  const char *name;
145
145
 
146
146
  #ifdef RSTRUCT_LEN
@@ -161,7 +161,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
161
161
  volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
162
162
 
163
163
  name = RSTRING_PTR(s);
164
- len = (int)RSTRING_LEN(s);
164
+ len = RSTRING_LEN(s);
165
165
  assure_size(out, size + sep_len + 6);
166
166
  if (0 < i) {
167
167
  *out->cur++ = ',';
@@ -205,11 +205,11 @@ static void dump_bigdecimal(VALUE obj, int depth, Out out, bool as_ok) {
205
205
  if ('I' == *str || 'N' == *str || ('-' == *str && 'I' == str[1])) {
206
206
  oj_dump_nil(Qnil, depth, out, false);
207
207
  } else if (out->opts->int_range_max != 0 || out->opts->int_range_min != 0) {
208
- oj_dump_cstr(str, (int)RSTRING_LEN(rstr), 0, 0, out);
208
+ oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
209
209
  } else if (Yes == out->opts->bigdec_as_num) {
210
- oj_dump_raw(str, (int)RSTRING_LEN(rstr), out);
210
+ oj_dump_raw(str, RSTRING_LEN(rstr), out);
211
211
  } else {
212
- oj_dump_cstr(str, (int)RSTRING_LEN(rstr), 0, 0, out);
212
+ oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
213
213
  }
214
214
  }
215
215
 
@@ -330,14 +330,14 @@ static void dump_timewithzone(VALUE obj, int depth, Out out, bool as_ok) {
330
330
  static void dump_to_s(VALUE obj, int depth, Out out, bool as_ok) {
331
331
  volatile VALUE rstr = oj_safe_string_convert(obj);
332
332
 
333
- oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
333
+ oj_dump_cstr(RSTRING_PTR(rstr), RSTRING_LEN(rstr), 0, 0, out);
334
334
  }
335
335
 
336
336
  static ID parameters_id = 0;
337
337
 
338
338
  typedef struct _strLen {
339
339
  const char *str;
340
- int len;
340
+ size_t len;
341
341
  } *StrLen;
342
342
 
343
343
  static void dump_actioncontroller_parameters(VALUE obj, int depth, Out out, bool as_ok) {
@@ -352,10 +352,10 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
352
352
  volatile VALUE v;
353
353
  StrLen cp;
354
354
  StrLen cols;
355
- int i;
356
- int cnt = (int)RARRAY_LEN(rcols);
355
+ size_t i;
356
+ size_t cnt = RARRAY_LEN(rcols);
357
357
 
358
- *ccnt = cnt;
358
+ *ccnt = (int)cnt;
359
359
  cols = OJ_R_ALLOC_N(struct _strLen, cnt);
360
360
  for (i = 0, cp = cols; i < cnt; i++, cp++) {
361
361
  v = RARRAY_AREF(rcols, i);
@@ -363,7 +363,7 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
363
363
  v = oj_safe_string_convert(v);
364
364
  }
365
365
  cp->str = StringValuePtr(v);
366
- cp->len = (int)RSTRING_LEN(v);
366
+ cp->len = RSTRING_LEN(v);
367
367
  }
368
368
  return cols;
369
369
  }
@@ -424,7 +424,8 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
424
424
  volatile VALUE rows;
425
425
  StrLen cols;
426
426
  int ccnt = 0;
427
- int i, rcnt;
427
+ size_t i;
428
+ size_t rcnt;
428
429
  size_t size;
429
430
  int d2 = depth + 1;
430
431
 
@@ -435,7 +436,7 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
435
436
  out->argc = 0;
436
437
  cols = columns_array(rb_ivar_get(obj, columns_id), &ccnt);
437
438
  rows = rb_ivar_get(obj, rows_id);
438
- rcnt = (int)RARRAY_LEN(rows);
439
+ rcnt = RARRAY_LEN(rows);
439
440
  assure_size(out, 2);
440
441
  *out->cur++ = '[';
441
442
  if (out->opts->dump_opts.use) {
@@ -933,8 +934,7 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
933
934
  if (0 == out.buf) {
934
935
  rb_raise(rb_eNoMemError, "Not enough memory.");
935
936
  }
936
- rstr = rb_str_new2(out.buf);
937
- rstr = oj_encode(rstr);
937
+ rstr = rb_utf8_str_new_cstr(out.buf);
938
938
  }
939
939
  if (Yes == copts.circular) {
940
940
  oj_cache8_delete(out.circ_cache);
@@ -1174,7 +1174,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1174
1174
  char buf[64];
1175
1175
  char *b;
1176
1176
  double d = rb_num2dbl(obj);
1177
- int cnt = 0;
1177
+ size_t cnt = 0;
1178
1178
 
1179
1179
  if (0.0 == d) {
1180
1180
  b = buf;
@@ -1195,7 +1195,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1195
1195
  volatile VALUE rstr = oj_safe_string_convert(obj);
1196
1196
 
1197
1197
  strcpy(buf, RSTRING_PTR(rstr));
1198
- cnt = (int)RSTRING_LEN(rstr);
1198
+ cnt = RSTRING_LEN(rstr);
1199
1199
  }
1200
1200
  }
1201
1201
  assure_size(out, cnt);
@@ -1207,7 +1207,8 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1207
1207
 
1208
1208
  static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
1209
1209
  size_t size;
1210
- int i, cnt;
1210
+ size_t i;
1211
+ size_t cnt;
1211
1212
  int d2 = depth + 1;
1212
1213
 
1213
1214
  if (Yes == out->opts->circular) {
@@ -1221,7 +1222,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
1221
1222
  dump_as_json(a, depth, out, false);
1222
1223
  return;
1223
1224
  }
1224
- cnt = (int)RARRAY_LEN(a);
1225
+ cnt = RARRAY_LEN(a);
1225
1226
  *out->cur++ = '[';
1226
1227
  size = 2;
1227
1228
  assure_size(out, size);