oj 3.13.9 → 3.13.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 646e1253e68f33e284b1efa4ec5f6c3ad9de2e52a1f4ddfbb37435ceb5e23bd0
4
- data.tar.gz: 775d9f0169d77a6f06990cf0d1f0e1904a530567d0939471f326e7ec5ee24c37
3
+ metadata.gz: e4f2c04b24ed0dc8c781036c17371378649d1aad9b927b402b2b0f3d67f9f94b
4
+ data.tar.gz: 65b50beb64e09569e7bcdcff9675a60b146de5ed78027b90de5def8eb6b57aa8
5
5
  SHA512:
6
- metadata.gz: f15a8a5dabfece0fb92ebfd2be99d567890441a2774c361646fc0ab03eba1de0070106cdc0addcc6fa75cf797dcd568b2f0129954c5debbe9ffa334ea8aa7fc4
7
- data.tar.gz: 9d3d0d399610c5209a6819df7583368c14250311249ff3f42a67c868057b96fb8f89c12657aeaf36f1ef545793038aece84f8a7524f40f77ed8636fe6d9e09f5
6
+ metadata.gz: 62a4e36ea67596152899cf389502a69f4f19b354dc5980c66b31ad5163b932245030bfd338ad582ec101572b56fd280c0e784b1d20567f830933627274506503
7
+ data.tar.gz: 671d6a7066b4f74c164ce4af83acbab38fcb0743c97c13985ad4f8e7f1431f67288d1bb80f74b7e55d90d6c5e727e01dc72b138b7dfda3220cbc55ae3ebf2856
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## 3.13.10 - 2021-12-12
5
+
6
+ - Fixed Oj::Doc re-entrant issue with each_child.
7
+ - Fixed each_child on empty Oj::Doc.
8
+
4
9
  ## 3.13.9 - 2021-10-06
5
10
 
6
11
  - Fix mimic JSON load so that it honors the `:symbolize_names` option.
data/README.md CHANGED
@@ -43,6 +43,15 @@ or in Bundler:
43
43
  gem 'oj'
44
44
  ```
45
45
 
46
+ ## Rails and json quickstart
47
+
48
+ See the Quickstart sections of the [Rails](pages/Rails.md) and [json](pages/JsonGem.md) docs.
49
+
50
+ ## multi_json
51
+
52
+ Code which uses [multi_json](https://github.com/intridea/multi_json)
53
+ will automatically prefer Oj if it is installed.
54
+
46
55
  ## Support
47
56
 
48
57
  [Get supported Oj with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security).
data/ext/oj/custom.c CHANGED
@@ -282,7 +282,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
282
282
  Out out = (Out)ov;
283
283
  int depth = out->depth;
284
284
 
285
- if (oj_dump_ignore(out->opts, value)) {
285
+ if (dump_ignore(out->opts, value)) {
286
286
  return ST_CONTINUE;
287
287
  }
288
288
  if (out->omit_nil && Qnil == value) {
@@ -577,7 +577,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
577
577
  size_t size;
578
578
  const char *attr;
579
579
 
580
- if (oj_dump_ignore(out->opts, value)) {
580
+ if (dump_ignore(out->opts, value)) {
581
581
  return ST_CONTINUE;
582
582
  }
583
583
  if (out->omit_nil && Qnil == value) {
@@ -749,7 +749,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
749
749
  } else {
750
750
  fill_indent(out, d2);
751
751
  }
752
- oj_dump_custom_val(rb_ary_entry(a, i), d2, out, true);
752
+ oj_dump_custom_val(RARRAY_AREF(a, i), d2, out, true);
753
753
  if (i < cnt) {
754
754
  *out->cur++ = ',';
755
755
  }
@@ -833,7 +833,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
833
833
  v = rb_struct_aref(obj, INT2FIX(i));
834
834
  #endif
835
835
  if (ma != Qnil) {
836
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
836
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
837
837
 
838
838
  name = RSTRING_PTR(s);
839
839
  len = (int)RSTRING_LEN(s);
data/ext/oj/dump.c CHANGED
@@ -1225,17 +1225,3 @@ int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char
1225
1225
  }
1226
1226
  return cnt;
1227
1227
  }
1228
-
1229
- bool oj_dump_ignore(Options opts, VALUE obj) {
1230
- if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
1231
- VALUE *vp = opts->ignore;
1232
- VALUE clas = rb_obj_class(obj);
1233
-
1234
- for (; Qnil != *vp; vp++) {
1235
- if (clas == *vp) {
1236
- return true;
1237
- }
1238
- }
1239
- }
1240
- return false;
1241
- }
data/ext/oj/dump.h CHANGED
@@ -50,7 +50,6 @@ extern VALUE oj_remove_to_json(int argc, VALUE *argv, VALUE self);
50
50
 
51
51
  extern int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char *format);
52
52
 
53
- extern bool oj_dump_ignore(Options opts, VALUE obj);
54
53
  extern time_t oj_sec_from_time_hard_way(VALUE obj);
55
54
 
56
55
  inline static void assure_size(Out out, size_t len) {
@@ -69,6 +68,20 @@ inline static void fill_indent(Out out, int cnt) {
69
68
  }
70
69
  }
71
70
 
71
+ inline static bool dump_ignore(Options opts, VALUE obj) {
72
+ if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
73
+ VALUE *vp = opts->ignore;
74
+ VALUE clas = rb_obj_class(obj);
75
+
76
+ for (; Qnil != *vp; vp++) {
77
+ if (clas == *vp) {
78
+ return true;
79
+ }
80
+ }
81
+ }
82
+ return false;
83
+ }
84
+
72
85
  inline static void dump_ulong(unsigned long num, Out out) {
73
86
  char buf[32];
74
87
  char *b = buf + sizeof(buf) - 1;
data/ext/oj/dump_compat.c CHANGED
@@ -182,7 +182,7 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
182
182
  } else {
183
183
  fill_indent(out, d2);
184
184
  }
185
- oj_dump_compat_val(rb_ary_entry(a, i), d2, out, true);
185
+ oj_dump_compat_val(RARRAY_AREF(a, i), d2, out, true);
186
186
  if (i < cnt) {
187
187
  *out->cur++ = ',';
188
188
  }
data/ext/oj/dump_object.c CHANGED
@@ -157,7 +157,7 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
157
157
  } else {
158
158
  fill_indent(out, d2);
159
159
  }
160
- oj_dump_obj_val(rb_ary_entry(a, i), d2, out);
160
+ oj_dump_obj_val(RARRAY_AREF(a, i), d2, out);
161
161
  if (i < cnt) {
162
162
  *out->cur++ = ',';
163
163
  }
@@ -218,7 +218,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
218
218
  int depth = out->depth;
219
219
  long size = depth * out->indent + 1;
220
220
 
221
- if (oj_dump_ignore(out->opts, value)) {
221
+ if (dump_ignore(out->opts, value)) {
222
222
  return ST_CONTINUE;
223
223
  }
224
224
  if (out->omit_nil && Qnil == value) {
@@ -226,47 +226,54 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
226
226
  }
227
227
  assure_size(out, size);
228
228
  fill_indent(out, depth);
229
- if (rb_type(key) == T_STRING) {
229
+ switch (rb_type(key)) {
230
+ case T_STRING:
230
231
  dump_str_class(key, Qundef, depth, out);
231
232
  *out->cur++ = ':';
232
233
  oj_dump_obj_val(value, depth, out);
233
- } else if (rb_type(key) == T_SYMBOL) {
234
+ break;
235
+
236
+ case T_SYMBOL:
234
237
  dump_sym(key, 0, out, false);
235
238
  *out->cur++ = ':';
236
239
  oj_dump_obj_val(value, depth, out);
237
- } else {
238
- int d2 = depth + 1;
239
- long s2 = size + out->indent + 1;
240
- int i;
241
- int started = 0;
242
- uint8_t b;
240
+ break;
243
241
 
244
- assure_size(out, s2 + 15);
245
- *out->cur++ = '"';
246
- *out->cur++ = '^';
247
- *out->cur++ = '#';
248
- out->hash_cnt++;
249
- for (i = 28; 0 <= i; i -= 4) {
250
- b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
251
- if ('\0' != b) {
252
- started = 1;
253
- }
254
- if (started) {
255
- *out->cur++ = hex_chars[b];
242
+ default:
243
+ {
244
+ int d2 = depth + 1;
245
+ long s2 = size + out->indent + 1;
246
+ int i;
247
+ int started = 0;
248
+ uint8_t b;
249
+
250
+ assure_size(out, s2 + 15);
251
+ *out->cur++ = '"';
252
+ *out->cur++ = '^';
253
+ *out->cur++ = '#';
254
+ out->hash_cnt++;
255
+ for (i = 28; 0 <= i; i -= 4) {
256
+ b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
257
+ if ('\0' != b) {
258
+ started = 1;
259
+ }
260
+ if (started) {
261
+ *out->cur++ = hex_chars[b];
262
+ }
256
263
  }
264
+ *out->cur++ = '"';
265
+ *out->cur++ = ':';
266
+ *out->cur++ = '[';
267
+ fill_indent(out, d2);
268
+ oj_dump_obj_val(key, d2, out);
269
+ assure_size(out, s2);
270
+ *out->cur++ = ',';
271
+ fill_indent(out, d2);
272
+ oj_dump_obj_val(value, d2, out);
273
+ assure_size(out, size);
274
+ fill_indent(out, depth);
275
+ *out->cur++ = ']';
257
276
  }
258
- *out->cur++ = '"';
259
- *out->cur++ = ':';
260
- *out->cur++ = '[';
261
- fill_indent(out, d2);
262
- oj_dump_obj_val(key, d2, out);
263
- assure_size(out, s2);
264
- *out->cur++ = ',';
265
- fill_indent(out, d2);
266
- oj_dump_obj_val(value, d2, out);
267
- assure_size(out, size);
268
- fill_indent(out, depth);
269
- *out->cur++ = ']';
270
277
  }
271
278
  out->depth = depth;
272
279
  *out->cur++ = ',';
@@ -342,7 +349,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
342
349
  size_t size = depth * out->indent + 1;
343
350
  const char *attr = rb_id2name(key);
344
351
 
345
- if (oj_dump_ignore(out->opts, value)) {
352
+ if (dump_ignore(out->opts, value)) {
346
353
  return ST_CONTINUE;
347
354
  }
348
355
  if (out->omit_nil && Qnil == value) {
@@ -605,7 +612,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
605
612
  }
606
613
  value = rb_ivar_get(obj, vid);
607
614
 
608
- if (oj_dump_ignore(out->opts, value)) {
615
+ if (dump_ignore(out->opts, value)) {
609
616
  continue;
610
617
  }
611
618
  if (out->omit_nil && Qnil == value) {
@@ -694,7 +701,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
694
701
 
695
702
  *out->cur++ = '[';
696
703
  for (i = 0; i < cnt; i++) {
697
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
704
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
698
705
 
699
706
  name = RSTRING_PTR(s);
700
707
  len = (int)RSTRING_LEN(s);
@@ -730,7 +737,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
730
737
 
731
738
  for (i = 0; i < cnt; i++) {
732
739
  v = RSTRUCT_GET(obj, i);
733
- if (oj_dump_ignore(out->opts, v)) {
740
+ if (dump_ignore(out->opts, v)) {
734
741
  v = Qnil;
735
742
  }
736
743
  assure_size(out, size);
@@ -748,7 +755,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
748
755
  for (i = 0; i < slen; i++) {
749
756
  assure_size(out, size);
750
757
  fill_indent(out, d3);
751
- if (oj_dump_ignore(out->opts, v)) {
758
+ if (dump_ignore(out->opts, v)) {
752
759
  v = Qnil;
753
760
  }
754
761
  oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
data/ext/oj/dump_strict.c CHANGED
@@ -153,9 +153,9 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
153
153
  fill_indent(out, d2);
154
154
  }
155
155
  if (NullMode == out->opts->mode) {
156
- oj_dump_null_val(rb_ary_entry(a, i), d2, out);
156
+ oj_dump_null_val(RARRAY_AREF(a, i), d2, out);
157
157
  } else {
158
- oj_dump_strict_val(rb_ary_entry(a, i), d2, out);
158
+ oj_dump_strict_val(RARRAY_AREF(a, i), d2, out);
159
159
  }
160
160
  if (i < cnt) {
161
161
  *out->cur++ = ',';
data/ext/oj/fast.c CHANGED
@@ -771,7 +771,7 @@ static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) {
771
771
  pi.doc = doc;
772
772
  #if IS_WINDOWS
773
773
  // assume a 1M stack and give half to ruby
774
- pi.stack_min = (void*)((char*)&pi - (512 * 1024));
774
+ pi.stack_min = (void *)((char *)&pi - (512 * 1024));
775
775
  #else
776
776
  {
777
777
  struct rlimit lim;
@@ -1492,6 +1492,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1492
1492
  Doc doc = self_doc(self);
1493
1493
  const char *path = 0;
1494
1494
  size_t wlen;
1495
+ Leaf * where_orig = doc->where;
1495
1496
 
1496
1497
  wlen = doc->where - doc->where_path;
1497
1498
  if (0 < wlen) {
@@ -1508,9 +1509,13 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1508
1509
  if (0 < wlen) {
1509
1510
  memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
1510
1511
  }
1512
+ doc->where = where_orig;
1511
1513
  return Qnil;
1512
1514
  }
1513
1515
  }
1516
+ if (NULL == doc->where || NULL == *doc->where) {
1517
+ return Qnil;
1518
+ }
1514
1519
  if (COL_VAL == (*doc->where)->value_type && 0 != (*doc->where)->elements) {
1515
1520
  Leaf first = (*doc->where)->elements->next;
1516
1521
  Leaf e = first;
@@ -1525,6 +1530,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1525
1530
  if (0 < wlen) {
1526
1531
  memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
1527
1532
  }
1533
+ doc->where = where_orig;
1528
1534
  }
1529
1535
  return Qnil;
1530
1536
  }
data/ext/oj/mimic_json.c CHANGED
@@ -272,7 +272,7 @@ static int mimic_walk(VALUE key, VALUE obj, VALUE proc) {
272
272
  size_t i;
273
273
 
274
274
  for (i = 0; i < cnt; i++) {
275
- mimic_walk(Qnil, rb_ary_entry(obj, i), proc);
275
+ mimic_walk(Qnil, RARRAY_AREF(obj, i), proc);
276
276
  }
277
277
  break;
278
278
  }
@@ -499,6 +499,52 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
499
499
  return mimic_generate_core(2, rargs, &copts);
500
500
  }
501
501
 
502
+ static int parse_options_cb(VALUE k, VALUE v, VALUE info) {
503
+ struct _parseInfo *pi = (struct _parseInfo *)info;
504
+
505
+ if (oj_symbolize_names_sym == k) {
506
+ pi->options.sym_key = (Qtrue == v) ? Yes : No;
507
+ } else if (oj_quirks_mode_sym == k) {
508
+ pi->options.quirks_mode = (Qtrue == v) ? Yes : No;
509
+ } else if (oj_create_additions_sym == k) {
510
+ pi->options.create_ok = (Qtrue == v) ? Yes : No;
511
+ } else if (oj_allow_nan_sym == k) {
512
+ pi->options.allow_nan = (Qtrue == v) ? Yes : No;
513
+ } else if (oj_hash_class_sym == k) {
514
+ if (Qnil == v) {
515
+ pi->options.hash_class = Qnil;
516
+ } else {
517
+ rb_check_type(v, T_CLASS);
518
+ pi->options.hash_class = v;
519
+ }
520
+ } else if (oj_object_class_sym == k) {
521
+ if (Qnil == v) {
522
+ pi->options.hash_class = Qnil;
523
+ } else {
524
+ rb_check_type(v, T_CLASS);
525
+ pi->options.hash_class = v;
526
+ }
527
+ } else if (oj_array_class_sym == k) {
528
+ if (Qnil == v) {
529
+ pi->options.array_class = Qnil;
530
+ } else {
531
+ rb_check_type(v, T_CLASS);
532
+ pi->options.array_class = v;
533
+ }
534
+ } else if (oj_decimal_class_sym == k) {
535
+ pi->options.compat_bigdec = (oj_bigdecimal_class == v);
536
+ } else if (oj_max_nesting_sym == k) {
537
+ if (Qtrue == v) {
538
+ pi->max_depth = 100;
539
+ } else if (Qfalse == v || Qnil == v) {
540
+ pi->max_depth = 0;
541
+ } else if (T_FIXNUM == rb_type(v)) {
542
+ pi->max_depth = NUM2INT(v);
543
+ }
544
+ }
545
+ return ST_CONTINUE;
546
+ }
547
+
502
548
  static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
503
549
  struct _parseInfo pi;
504
550
  VALUE ropts;
@@ -524,59 +570,11 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
524
570
  pi.max_depth = 100;
525
571
 
526
572
  if (Qnil != ropts) {
527
- VALUE v;
528
-
529
573
  if (T_HASH != rb_type(ropts)) {
530
574
  rb_raise(rb_eArgError, "options must be a hash.");
531
575
  }
532
- if (Qnil != (v = rb_hash_lookup(ropts, oj_symbolize_names_sym))) {
533
- pi.options.sym_key = (Qtrue == v) ? Yes : No;
534
- }
535
- if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
536
- pi.options.quirks_mode = (Qtrue == v) ? Yes : No;
537
- }
538
- if (Qnil != (v = rb_hash_lookup(ropts, oj_create_additions_sym))) {
539
- pi.options.create_ok = (Qtrue == v) ? Yes : No;
540
- }
541
- if (Qnil != (v = rb_hash_lookup(ropts, oj_allow_nan_sym))) {
542
- pi.options.allow_nan = (Qtrue == v) ? Yes : No;
543
- }
544
576
 
545
- if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
546
- if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
547
- pi.options.hash_class = Qnil;
548
- } else {
549
- rb_check_type(v, T_CLASS);
550
- pi.options.hash_class = v;
551
- }
552
- }
553
- if (oj_hash_has_key(ropts, oj_object_class_sym)) {
554
- if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
555
- pi.options.hash_class = Qnil;
556
- } else {
557
- rb_check_type(v, T_CLASS);
558
- pi.options.hash_class = v;
559
- }
560
- }
561
- if (oj_hash_has_key(ropts, oj_array_class_sym)) {
562
- if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
563
- pi.options.array_class = Qnil;
564
- } else {
565
- rb_check_type(v, T_CLASS);
566
- pi.options.array_class = v;
567
- }
568
- }
569
- if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
570
- pi.options.compat_bigdec = (oj_bigdecimal_class == rb_hash_lookup(ropts, oj_decimal_class_sym));
571
- }
572
- v = rb_hash_lookup(ropts, oj_max_nesting_sym);
573
- if (Qtrue == v) {
574
- pi.max_depth = 100;
575
- } else if (Qfalse == v || Qnil == v) {
576
- pi.max_depth = 0;
577
- } else if (T_FIXNUM == rb_type(v)) {
578
- pi.max_depth = NUM2INT(v);
579
- }
577
+ rb_hash_foreach(ropts, parse_options_cb, (VALUE)&pi);
580
578
  oj_parse_opt_match_string(&pi.options.str_rx, ropts);
581
579
  if (Yes == pi.options.create_ok && Yes == pi.options.sym_key) {
582
580
  rb_raise(rb_eArgError, ":symbolize_names and :create_additions can not both be true.");
data/ext/oj/object.c CHANGED
@@ -325,7 +325,7 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
325
325
  int i, cnt = (int)RARRAY_LEN(e1);
326
326
 
327
327
  for (i = 0; i < cnt; i++) {
328
- rstr = rb_ary_entry(e1, i);
328
+ rstr = RARRAY_AREF(e1, i);
329
329
  args[i] = rb_funcall(rstr, oj_to_sym_id, 0);
330
330
  }
331
331
  sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
data/ext/oj/oj.c CHANGED
@@ -916,7 +916,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
916
916
 
917
917
  copts->ignore = ALLOC_N(VALUE, cnt + 1);
918
918
  for (i = 0; i < cnt; i++) {
919
- copts->ignore[i] = rb_ary_entry(v, i);
919
+ copts->ignore[i] = RARRAY_AREF(v, i);
920
920
  }
921
921
  copts->ignore[i] = Qnil;
922
922
  }
data/ext/oj/rails.c CHANGED
@@ -157,7 +157,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
157
157
  assure_size(out, 2);
158
158
  *out->cur++ = '{';
159
159
  for (i = 0; i < cnt; i++) {
160
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
160
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
161
161
 
162
162
  name = RSTRING_PTR(s);
163
163
  len = (int)RSTRING_LEN(s);
@@ -383,7 +383,7 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
383
383
  *ccnt = cnt;
384
384
  cols = ALLOC_N(struct _strLen, cnt);
385
385
  for (i = 0, cp = cols; i < cnt; i++, cp++) {
386
- v = rb_ary_entry(rcols, i);
386
+ v = RARRAY_AREF(rcols, i);
387
387
  if (T_STRING != rb_type(v)) {
388
388
  v = rb_funcall(v, oj_to_s_id, 0);
389
389
  }
@@ -420,7 +420,7 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
420
420
  }
421
421
  oj_dump_cstr(cols->str, cols->len, 0, 0, out);
422
422
  *out->cur++ = ':';
423
- dump_rails_val(rb_ary_entry(row, i), depth, out, true);
423
+ dump_rails_val(RARRAY_AREF(row, i), depth, out, true);
424
424
  if (i < ccnt - 1) {
425
425
  *out->cur++ = ',';
426
426
  }
@@ -490,7 +490,7 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
490
490
  } else {
491
491
  fill_indent(out, d2);
492
492
  }
493
- dump_row(rb_ary_entry(rows, i), cols, ccnt, d2, out);
493
+ dump_row(RARRAY_AREF(rows, i), cols, ccnt, d2, out);
494
494
  if (i < rcnt - 1) {
495
495
  *out->cur++ = ',';
496
496
  }
@@ -1281,7 +1281,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
1281
1281
  } else {
1282
1282
  fill_indent(out, d2);
1283
1283
  }
1284
- dump_rails_val(rb_ary_entry(a, i), d2, out, true);
1284
+ dump_rails_val(RARRAY_AREF(a, i), d2, out, true);
1285
1285
  if (i < cnt) {
1286
1286
  *out->cur++ = ',';
1287
1287
  }
data/ext/oj/wab.c CHANGED
@@ -128,7 +128,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
128
128
  for (i = 0; i <= cnt; i++) {
129
129
  assure_size(out, size);
130
130
  fill_indent(out, d2);
131
- oj_dump_wab_val(rb_ary_entry(a, i), d2, out);
131
+ oj_dump_wab_val(RARRAY_AREF(a, i), d2, out);
132
132
  if (i < cnt) {
133
133
  *out->cur++ = ',';
134
134
  }
data/lib/oj/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '3.13.9'
4
+ VERSION = '3.13.10'
5
5
  end
data/pages/JsonGem.md CHANGED
@@ -1,3 +1,18 @@
1
+ # JSON Quickstart
2
+
3
+ To have Oj universally "take over" many methods on the JSON constant (`load`, `parse`, etc.) with
4
+ their faster Oj counterparts, in a mode that is compatible with the json gem:
5
+
6
+ ```ruby
7
+ Oj.mimic_JSON()
8
+ ```
9
+
10
+ If the project does not already use the json gem, `JSON` will become available.
11
+ If the project does require the json gem, `Oj.mimic_JSON()` should be invoked after the
12
+ json gem has been required.
13
+
14
+ For more details and options, read on...
15
+
1
16
  # Oj JSON Gem Compatibility
2
17
 
3
18
  The `:compat` mode mimics the json gem. The json gem is built around the use
data/pages/Modes.md CHANGED
@@ -39,7 +39,8 @@ if a non-native type is encountered instead of raising an Exception.
39
39
  The `:compat` mode mimics the json gem. The json gem is built around the use
40
40
  of the `to_json(*)` method defined for a class. Oj attempts to provide the
41
41
  same functionality by being a drop in replacement with a few
42
- exceptions. [{file:JsonGem.md}](JsonGem.md) includes more details on
42
+ exceptions. To universally replace many `JSON` methods with their faster Oj counterparts,
43
+ simply run `Oj.mimic_json`. [{file:JsonGem.md}](JsonGem.md) includes more details on
43
44
  compatibility and use.
44
45
 
45
46
  ## :rails Mode
@@ -108,11 +109,11 @@ information.
108
109
  | :float_precision | Fixnum | x | x | | | | x | |
109
110
  | :hash_class | Class | | | x | x | | x | |
110
111
  | :ignore | Array | | | | | x | x | |
111
- | :indent | Integer | x | x | 3 | 4 | x | x | x |
112
+ | :indent | Integer | x | x | 4 | 4 | x | x | x |
112
113
  | :indent_str | String | | | x | x | | x | |
113
114
  | :integer_range | Range | x | x | x | x | x | x | x |
114
115
  | :match_string | Hash | | | x | x | | x | |
115
- | :max_nesting | Fixnum | 4 | 4 | x | | 5 | 4 | |
116
+ | :max_nesting | Fixnum | 5 | 5 | x | | 5 | 5 | |
116
117
  | :mode | Symbol | - | - | - | - | - | - | |
117
118
  | :nan | Symbol | | | | | | x | |
118
119
  | :nilnil | Boolean | | | | | | x | |
@@ -140,6 +141,8 @@ information.
140
141
  3. By default the bigdecimal_as decimal is not set and the default encoding
141
142
  for Rails is as a string. Setting the value to true will encode a
142
143
  BigDecimal as a number which breaks compatibility.
144
+ Note: after version 3.11.3 both `Oj.generate` and `JSON.generate`
145
+ will not honour this option in Rails Mode, detais on https://github.com/ohler55/oj/pull/716.
143
146
 
144
147
  4. The integer indent value in the default options will be honored by since
145
148
  the json gem expects a String type the indent in calls to 'to_json()',
data/pages/Rails.md CHANGED
@@ -1,3 +1,15 @@
1
+ # Rails Quickstart
2
+
3
+ To universally replace Rails' use of the json gem with Oj, and also
4
+ have Oj "take over" many methods on the JSON constant (`load`, `parse`, etc.) with
5
+ their faster Oj counterparts, add this to an initializer:
6
+
7
+ ```ruby
8
+ Oj.optimize_rails()
9
+ ```
10
+
11
+ For more details and options, read on...
12
+
1
13
  # Oj Rails Compatibility
2
14
 
3
15
  The `:rails` mode mimics the ActiveSupport version 5 encoder. Rails and
data/test/foo.rb CHANGED
@@ -4,17 +4,32 @@ $: << '.'
4
4
  $: << File.join(File.dirname(__FILE__), "../lib")
5
5
  $: << File.join(File.dirname(__FILE__), "../ext")
6
6
 
7
- # require 'json'
7
+ require 'rails'
8
8
  require 'oj'
9
- Oj.mimic_JSON
10
-
11
- source = %( {"a": 1, "b": 2} )
12
- puts "JSON.load, no symbolize => OK"
13
- pp JSON.load( source )
14
- puts "JSON.load, do symbolize => KO: keys are not symbols"
15
- #pp JSON.load( source, nil, symbolize_names: true, create_additions: false )
16
- pp JSON.load( source, nil, symbolize_names: true, create_additions: false )
17
- puts "JSON.parse, no symbolize => OK"
18
- pp JSON.parse( source )
19
- puts "JSON.parse, do symbolize => OK"
20
- pp JSON.parse( source, symbolize_names: true )
9
+
10
+ $data = {:ticker=>"ASAI3", :price=>18.7, :rate=>-0.8.to_d}
11
+
12
+ def encode
13
+ p "JSON.generate: #{JSON.generate($data)}"
14
+ p "Oj.generate: #{Oj.generate($data)}"
15
+ p "Oj.dump: #{Oj.dump($data)}"
16
+ p "to_json: #{$data.to_json}"
17
+ p "ActiveSupport::JSON.encode: #{ActiveSupport::JSON.encode($data)}"
18
+ end
19
+
20
+ puts "With Oj version (#{Oj::VERSION})"
21
+
22
+ puts
23
+ puts "Before optimizing"
24
+ encode
25
+
26
+ Oj.optimize_rails
27
+ Oj.default_options = {
28
+ mode: :rails,
29
+ bigdecimal_as_decimal: true,
30
+ bigdecimal_load: true
31
+ }
32
+
33
+ puts
34
+ puts "After optimizing"
35
+ encode
data/test/test_fast.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # coding: utf-8
2
3
  # frozen_string_literal: true
3
4
 
4
5
  $: << File.dirname(__FILE__)
@@ -395,6 +396,19 @@ class DocTest < Minitest::Test
395
396
  end
396
397
  end
397
398
 
399
+ def test_nested_each_child
400
+ h = {}
401
+ Oj::Doc.open('{"a":1,"c":[2],"d":3}') do |doc|
402
+ doc.each_child('/') do |child|
403
+ h[child.path] = child.fetch
404
+ child.each_child do |grandchild|
405
+ h[grandchild.path] = grandchild.fetch
406
+ end
407
+ end
408
+ end
409
+ assert_equal({"/a"=>1, "/c"=>[2], "/c/1"=>2, "/d"=>3}, h)
410
+ end
411
+
398
412
  def test_size
399
413
  Oj::Doc.open('[1,2,3]') do |doc|
400
414
  assert_equal(4, doc.size)
@@ -491,6 +505,11 @@ class DocTest < Minitest::Test
491
505
  assert_equal({'/a/x' => 2, '/b/y' => 4}, results)
492
506
  end
493
507
 
508
+ def test_doc_empty
509
+ result = Oj::Doc.open("") { |doc| doc.each_child {} }
510
+ assert_nil(result)
511
+ end
512
+
494
513
  def test_comment
495
514
  json = %{{
496
515
  "x"/*one*/:/*two*/true,//three
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.13.9
4
+ version: 3.13.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-06 00:00:00.000000000 Z
11
+ date: 2021-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler