oj 3.13.7 → 3.13.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +75 -0
  3. data/README.md +11 -0
  4. data/ext/oj/buf.h +4 -0
  5. data/ext/oj/circarray.c +1 -1
  6. data/ext/oj/code.c +15 -22
  7. data/ext/oj/compat.c +10 -10
  8. data/ext/oj/custom.c +66 -112
  9. data/ext/oj/dump.c +147 -184
  10. data/ext/oj/dump.h +25 -8
  11. data/ext/oj/dump_compat.c +47 -89
  12. data/ext/oj/dump_leaf.c +14 -58
  13. data/ext/oj/dump_object.c +72 -188
  14. data/ext/oj/dump_strict.c +19 -31
  15. data/ext/oj/encoder.c +43 -0
  16. data/ext/oj/extconf.rb +5 -4
  17. data/ext/oj/fast.c +36 -24
  18. data/ext/oj/intern.c +22 -12
  19. data/ext/oj/intern.h +1 -1
  20. data/ext/oj/mimic_json.c +74 -73
  21. data/ext/oj/object.c +54 -72
  22. data/ext/oj/odd.c +83 -63
  23. data/ext/oj/odd.h +13 -13
  24. data/ext/oj/oj.c +166 -175
  25. data/ext/oj/oj.h +25 -3
  26. data/ext/oj/parse.c +123 -79
  27. data/ext/oj/parse.h +2 -0
  28. data/ext/oj/parser.c +77 -21
  29. data/ext/oj/parser.h +12 -0
  30. data/ext/oj/rails.c +46 -70
  31. data/ext/oj/rails.h +1 -1
  32. data/ext/oj/reader.c +2 -0
  33. data/ext/oj/saj.c +11 -23
  34. data/ext/oj/saj2.c +333 -85
  35. data/ext/oj/saj2.h +23 -0
  36. data/ext/oj/sparse.c +4 -0
  37. data/ext/oj/stream_writer.c +3 -1
  38. data/ext/oj/strict.c +13 -13
  39. data/ext/oj/string_writer.c +12 -5
  40. data/ext/oj/usual.c +86 -131
  41. data/ext/oj/usual.h +68 -0
  42. data/ext/oj/val_stack.c +1 -1
  43. data/ext/oj/validate.c +21 -26
  44. data/ext/oj/wab.c +22 -27
  45. data/lib/oj/saj.rb +20 -6
  46. data/lib/oj/state.rb +1 -1
  47. data/lib/oj/version.rb +1 -1
  48. data/pages/Compatibility.md +1 -1
  49. data/pages/JsonGem.md +15 -0
  50. data/pages/Modes.md +6 -3
  51. data/pages/Options.md +6 -0
  52. data/pages/Rails.md +12 -0
  53. data/test/activesupport7/abstract_unit.rb +49 -0
  54. data/test/activesupport7/decoding_test.rb +125 -0
  55. data/test/activesupport7/encoding_test.rb +486 -0
  56. data/test/activesupport7/encoding_test_cases.rb +104 -0
  57. data/test/activesupport7/time_zone_test_helpers.rb +47 -0
  58. data/test/bar.rb +3 -8
  59. data/test/bug.rb +16 -0
  60. data/test/foo.rb +71 -7
  61. data/test/helper.rb +8 -2
  62. data/test/json_gem/json_generator_test.rb +5 -4
  63. data/test/json_gem/json_parser_test.rb +8 -1
  64. data/test/json_gem/test_helper.rb +7 -3
  65. data/test/perf_dump.rb +50 -0
  66. data/test/test_compat.rb +25 -0
  67. data/test/test_custom.rb +13 -2
  68. data/test/test_fast.rb +37 -7
  69. data/test/test_file.rb +23 -7
  70. data/test/test_gc.rb +11 -0
  71. data/test/test_object.rb +8 -10
  72. data/test/test_parser.rb +3 -19
  73. data/test/test_parser_debug.rb +27 -0
  74. data/test/test_parser_saj.rb +92 -2
  75. data/test/test_saj.rb +1 -1
  76. data/test/test_scp.rb +2 -4
  77. data/test/test_strict.rb +2 -0
  78. data/test/test_various.rb +32 -2
  79. data/test/test_wab.rb +2 -0
  80. data/test/tests.rb +9 -1
  81. data/test/tests_mimic.rb +9 -0
  82. data/test/tests_mimic_addition.rb +9 -0
  83. metadata +15 -115
data/ext/oj/custom.c CHANGED
@@ -31,14 +31,14 @@ static void dump_obj_str(VALUE obj, int depth, Out out) {
31
31
 
32
32
  static void dump_obj_as_str(VALUE obj, int depth, Out out) {
33
33
  volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
34
- const char * str = RSTRING_PTR(rstr);
34
+ const char *str = RSTRING_PTR(rstr);
35
35
 
36
36
  oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
37
37
  }
38
38
 
39
39
  static void bigdecimal_dump(VALUE obj, int depth, Out out) {
40
40
  volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
41
- const char * str = RSTRING_PTR(rstr);
41
+ const char *str = RSTRING_PTR(rstr);
42
42
  int len = (int)RSTRING_LEN(rstr);
43
43
 
44
44
  if (0 == strcasecmp("Infinity", str)) {
@@ -82,8 +82,7 @@ static VALUE complex_load(VALUE clas, VALUE args) {
82
82
  real_id = rb_intern("real");
83
83
  imag_id = rb_intern("imag");
84
84
  }
85
- return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)),
86
- rb_hash_aref(args, rb_id2str(imag_id)));
85
+ return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)), rb_hash_aref(args, rb_id2str(imag_id)));
87
86
  }
88
87
 
89
88
  static void time_dump(VALUE obj, int depth, Out out) {
@@ -246,8 +245,7 @@ static VALUE rational_load(VALUE clas, VALUE args) {
246
245
  numerator_id = rb_intern("numerator");
247
246
  denominator_id = rb_intern("denominator");
248
247
  }
249
- return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)),
250
- rb_hash_aref(args, rb_id2str(denominator_id)));
248
+ return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)), rb_hash_aref(args, rb_id2str(denominator_id)));
251
249
  }
252
250
 
253
251
  static VALUE regexp_load(VALUE clas, VALUE args) {
@@ -282,7 +280,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
282
280
  Out out = (Out)ov;
283
281
  int depth = out->depth;
284
282
 
285
- if (oj_dump_ignore(out->opts, value)) {
283
+ if (dump_ignore(out->opts, value)) {
286
284
  return ST_CONTINUE;
287
285
  }
288
286
  if (out->omit_nil && Qnil == value) {
@@ -292,18 +290,15 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
292
290
  assure_size(out, depth * out->indent + 1);
293
291
  fill_indent(out, depth);
294
292
  } else {
295
- assure_size(out,
296
- depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
293
+ assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
297
294
  if (0 < out->opts->dump_opts.hash_size) {
298
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
299
- out->cur += out->opts->dump_opts.hash_size;
295
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
300
296
  }
301
297
  if (0 < out->opts->dump_opts.indent_size) {
302
298
  int i;
303
299
 
304
300
  for (i = depth; 0 < i; i--) {
305
- strcpy(out->cur, out->opts->dump_opts.indent_str);
306
- out->cur += out->opts->dump_opts.indent_size;
301
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
307
302
  }
308
303
  }
309
304
  }
@@ -317,13 +312,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
317
312
  } else {
318
313
  assure_size(out, out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2);
319
314
  if (0 < out->opts->dump_opts.before_size) {
320
- strcpy(out->cur, out->opts->dump_opts.before_sep);
321
- out->cur += out->opts->dump_opts.before_size;
315
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
322
316
  }
323
317
  *out->cur++ = ':';
324
318
  if (0 < out->opts->dump_opts.after_size) {
325
- strcpy(out->cur, out->opts->dump_opts.after_sep);
326
- out->cur += out->opts->dump_opts.after_size;
319
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
327
320
  }
328
321
  }
329
322
  oj_dump_custom_val(value, depth, out, true);
@@ -344,8 +337,7 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
344
337
  cnt = (int)RHASH_SIZE(obj);
345
338
  assure_size(out, 2);
346
339
  if (0 == cnt) {
347
- *out->cur++ = '{';
348
- *out->cur++ = '}';
340
+ APPEND_CHARS(out->cur, "{}", 2);
349
341
  } else {
350
342
  *out->cur++ = '{';
351
343
  out->depth = depth + 1;
@@ -357,19 +349,15 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
357
349
  assure_size(out, depth * out->indent + 2);
358
350
  fill_indent(out, depth);
359
351
  } else {
360
- assure_size(
361
- out,
362
- depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
352
+ assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
363
353
  if (0 < out->opts->dump_opts.hash_size) {
364
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
365
- out->cur += out->opts->dump_opts.hash_size;
354
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
366
355
  }
367
356
  if (0 < out->opts->dump_opts.indent_size) {
368
357
  int i;
369
358
 
370
359
  for (i = depth; 0 < i; i--) {
371
- strcpy(out->cur, out->opts->dump_opts.indent_str);
372
- out->cur += out->opts->dump_opts.indent_size;
360
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
373
361
  }
374
362
  }
375
363
  }
@@ -379,10 +367,10 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
379
367
  }
380
368
 
381
369
  static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
382
- ID * idp;
383
- AttrGetFunc * fp;
370
+ ID *idp;
371
+ AttrGetFunc *fp;
384
372
  volatile VALUE v;
385
- const char * name;
373
+ const char *name;
386
374
  size_t size;
387
375
  int d2 = depth + 1;
388
376
 
@@ -391,29 +379,24 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
391
379
  if (NULL != out->opts->create_id && Yes == out->opts->create_ok) {
392
380
  const char *classname = rb_class2name(clas);
393
381
  int clen = (int)strlen(classname);
394
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
382
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
395
383
 
396
384
  size = d2 * out->indent + 10 + clen + out->opts->create_id_len + sep_len;
397
385
  assure_size(out, size);
398
386
  fill_indent(out, d2);
399
387
  *out->cur++ = '"';
400
- memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
401
- out->cur += out->opts->create_id_len;
388
+ APPEND_CHARS(out->cur, out->opts->create_id, out->opts->create_id_len);
402
389
  *out->cur++ = '"';
403
390
  if (0 < out->opts->dump_opts.before_size) {
404
- strcpy(out->cur, out->opts->dump_opts.before_sep);
405
- out->cur += out->opts->dump_opts.before_size;
391
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
406
392
  }
407
393
  *out->cur++ = ':';
408
394
  if (0 < out->opts->dump_opts.after_size) {
409
- strcpy(out->cur, out->opts->dump_opts.after_sep);
410
- out->cur += out->opts->dump_opts.after_size;
395
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
411
396
  }
412
397
  *out->cur++ = '"';
413
- memcpy(out->cur, classname, clen);
414
- out->cur += clen;
415
- *out->cur++ = '"';
416
- *out->cur++ = ',';
398
+ APPEND_CHARS(out->cur, classname, clen);
399
+ APPEND_CHARS(out->cur, "\",", 2);
417
400
  }
418
401
  if (odd->raw) {
419
402
  v = rb_funcall(obj, *odd->attrs, 0);
@@ -429,12 +412,9 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
429
412
  assure_size(out, size);
430
413
  fill_indent(out, d2);
431
414
  *out->cur++ = '"';
432
- memcpy(out->cur, name, nlen);
433
- out->cur += nlen;
434
- *out->cur++ = '"';
435
- *out->cur++ = ':';
436
- memcpy(out->cur, s, len);
437
- out->cur += len;
415
+ APPEND_CHARS(out->cur, name, nlen);
416
+ APPEND_CHARS(out->cur, "\":", 2);
417
+ APPEND_CHARS(out->cur, s, len);
438
418
  *out->cur = '\0';
439
419
  }
440
420
  } else {
@@ -496,10 +476,10 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
496
476
  oj_dump_raw_json(obj, depth, out);
497
477
  } else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
498
478
  volatile VALUE rs;
499
- const char * s;
479
+ const char *s;
500
480
  int len;
501
481
 
502
- if (Yes == out->opts->trace) {
482
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
503
483
  oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
504
484
  }
505
485
  if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
@@ -507,20 +487,19 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
507
487
  } else {
508
488
  rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
509
489
  }
510
- if (Yes == out->opts->trace) {
490
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
511
491
  oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
512
492
  }
513
493
  s = RSTRING_PTR(rs);
514
494
  len = (int)RSTRING_LEN(rs);
515
495
 
516
496
  assure_size(out, len + 1);
517
- memcpy(out->cur, s, len);
518
- out->cur += len;
497
+ APPEND_CHARS(out->cur, s, len);
519
498
  *out->cur = '\0';
520
499
  } else if (Yes == out->opts->as_json && rb_respond_to(obj, oj_as_json_id)) {
521
500
  volatile VALUE aj;
522
501
 
523
- if (Yes == out->opts->trace) {
502
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
524
503
  oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
525
504
  }
526
505
  // Some classes elect to not take an options argument so check the arity
@@ -530,18 +509,14 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
530
509
  } else {
531
510
  aj = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
532
511
  }
533
- if (Yes == out->opts->trace) {
512
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
534
513
  oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
535
514
  }
536
515
  // Catch the obvious brain damaged recursive dumping.
537
516
  if (aj == obj) {
538
517
  volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
539
518
 
540
- oj_dump_cstr(RSTRING_PTR(rstr),
541
- (int)RSTRING_LEN(rstr),
542
- false,
543
- false,
544
- out);
519
+ oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), false, false, out);
545
520
  } else {
546
521
  oj_dump_custom_val(aj, depth, out, true);
547
522
  }
@@ -577,7 +552,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
577
552
  size_t size;
578
553
  const char *attr;
579
554
 
580
- if (oj_dump_ignore(out->opts, value)) {
555
+ if (dump_ignore(out->opts, value)) {
581
556
  return ST_CONTINUE;
582
557
  }
583
558
  if (out->omit_nil && Qnil == value) {
@@ -625,7 +600,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
625
600
  assure_size(out, 2);
626
601
  *out->cur++ = '{';
627
602
  if (Qundef != clas && NULL != out->opts->create_id && Yes == out->opts->create_ok) {
628
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
603
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
629
604
  const char *classname = rb_obj_classname(obj);
630
605
  size_t len = strlen(classname);
631
606
 
@@ -633,21 +608,17 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
633
608
  assure_size(out, size);
634
609
  fill_indent(out, d2);
635
610
  *out->cur++ = '"';
636
- memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
637
- out->cur += out->opts->create_id_len;
611
+ APPEND_CHARS(out->cur, out->opts->create_id, out->opts->create_id_len);
638
612
  *out->cur++ = '"';
639
613
  if (0 < out->opts->dump_opts.before_size) {
640
- strcpy(out->cur, out->opts->dump_opts.before_sep);
641
- out->cur += out->opts->dump_opts.before_size;
614
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
642
615
  }
643
616
  *out->cur++ = ':';
644
617
  if (0 < out->opts->dump_opts.after_size) {
645
- strcpy(out->cur, out->opts->dump_opts.after_sep);
646
- out->cur += out->opts->dump_opts.after_size;
618
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
647
619
  }
648
620
  *out->cur++ = '"';
649
- memcpy(out->cur, classname, len);
650
- out->cur += len;
621
+ APPEND_CHARS(out->cur, classname, len);
651
622
  *out->cur++ = '"';
652
623
  class_written = true;
653
624
  }
@@ -731,25 +702,23 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
731
702
  } else {
732
703
  size = d2 * out->indent + 2;
733
704
  }
705
+ assure_size(out, size * cnt);
734
706
  cnt--;
735
707
  for (i = 0; i <= cnt; i++) {
736
- assure_size(out, size);
737
708
  if (out->opts->dump_opts.use) {
738
709
  if (0 < out->opts->dump_opts.array_size) {
739
- strcpy(out->cur, out->opts->dump_opts.array_nl);
740
- out->cur += out->opts->dump_opts.array_size;
710
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
741
711
  }
742
712
  if (0 < out->opts->dump_opts.indent_size) {
743
713
  int i;
744
714
  for (i = d2; 0 < i; i--) {
745
- strcpy(out->cur, out->opts->dump_opts.indent_str);
746
- out->cur += out->opts->dump_opts.indent_size;
715
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
747
716
  }
748
717
  }
749
718
  } else {
750
719
  fill_indent(out, d2);
751
720
  }
752
- oj_dump_custom_val(rb_ary_entry(a, i), d2, out, true);
721
+ oj_dump_custom_val(RARRAY_AREF(a, i), d2, out, true);
753
722
  if (i < cnt) {
754
723
  *out->cur++ = ',';
755
724
  }
@@ -758,15 +727,13 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
758
727
  assure_size(out, size);
759
728
  if (out->opts->dump_opts.use) {
760
729
  if (0 < out->opts->dump_opts.array_size) {
761
- strcpy(out->cur, out->opts->dump_opts.array_nl);
762
- out->cur += out->opts->dump_opts.array_size;
730
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
763
731
  }
764
732
  if (0 < out->opts->dump_opts.indent_size) {
765
733
  int i;
766
734
 
767
735
  for (i = depth; 0 < i; i--) {
768
- strcpy(out->cur, out->opts->dump_opts.indent_str);
769
- out->cur += out->opts->dump_opts.indent_size;
736
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
770
737
  }
771
738
  }
772
739
  } else {
@@ -800,8 +767,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
800
767
  *out->cur++ = '"';
801
768
  oj_dump_custom_val(rb_funcall(obj, oj_begin_id, 0), d3, out, false);
802
769
  assure_size(out, 3);
803
- *out->cur++ = '.';
804
- *out->cur++ = '.';
770
+ APPEND_CHARS(out->cur, "..", 2);
805
771
  if (Qtrue == rb_funcall(obj, oj_exclude_end_id, 0)) {
806
772
  *out->cur++ = '.';
807
773
  }
@@ -833,7 +799,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
833
799
  v = rb_struct_aref(obj, INT2FIX(i));
834
800
  #endif
835
801
  if (ma != Qnil) {
836
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
802
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
837
803
 
838
804
  name = RSTRING_PTR(s);
839
805
  len = (int)RSTRING_LEN(s);
@@ -844,10 +810,8 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
844
810
  assure_size(out, size + len + 3);
845
811
  fill_indent(out, d3);
846
812
  *out->cur++ = '"';
847
- memcpy(out->cur, name, len);
848
- out->cur += len;
849
- *out->cur++ = '"';
850
- *out->cur++ = ':';
813
+ APPEND_CHARS(out->cur, name, len);
814
+ APPEND_CHARS(out->cur, "\":", 2);
851
815
  oj_dump_custom_val(v, d3, out, true);
852
816
  *out->cur++ = ',';
853
817
  }
@@ -912,7 +876,7 @@ static DumpFunc custom_funcs[] = {
912
876
  void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
913
877
  int type = rb_type(obj);
914
878
 
915
- if (Yes == out->opts->trace) {
879
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
916
880
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
917
881
  }
918
882
  if (MAX_DEPTH < depth) {
@@ -923,14 +887,14 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
923
887
 
924
888
  if (NULL != f) {
925
889
  f(obj, depth, out, true);
926
- if (Yes == out->opts->trace) {
890
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
927
891
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
928
892
  }
929
893
  return;
930
894
  }
931
895
  }
932
896
  oj_dump_nil(Qnil, depth, out, false);
933
- if (Yes == out->opts->trace) {
897
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
934
898
  oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
935
899
  }
936
900
  }
@@ -938,7 +902,7 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
938
902
  ///// load functions /////
939
903
 
940
904
  static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
941
- const char * key = kval->key;
905
+ const char *key = kval->key;
942
906
  int klen = kval->klen;
943
907
  Val parent = stack_peek(&pi->stack);
944
908
  volatile VALUE rkey = kval->key_val;
@@ -955,14 +919,14 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
955
919
  }
956
920
  }
957
921
  } else {
958
- volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
959
- //volatile VALUE rstr = rb_utf8_str_new(str, len);
922
+ volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
923
+ // volatile VALUE rstr = rb_utf8_str_new(str, len);
960
924
 
961
925
  if (Qundef == rkey) {
962
926
  if (Yes == pi->options.sym_key) {
963
927
  rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
964
928
  } else {
965
- rkey = rb_utf8_str_new(key, klen);
929
+ rkey = rb_utf8_str_new(key, klen);
966
930
  }
967
931
  }
968
932
  if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
@@ -986,7 +950,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
986
950
  break;
987
951
  default: break;
988
952
  }
989
- if (Yes == pi->options.trace) {
953
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
990
954
  oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
991
955
  }
992
956
  }
@@ -1005,7 +969,7 @@ static void end_hash(struct _parseInfo *pi) {
1005
969
  }
1006
970
  parent->clas = Qundef;
1007
971
  }
1008
- if (Yes == pi->options.trace) {
972
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
1009
973
  oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
1010
974
  }
1011
975
  }
@@ -1035,20 +999,10 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1035
999
  // match the expected value.
1036
1000
  parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
1037
1001
  } else if (ni->has_exp) {
1038
- int64_t t = (int64_t)(ni->i + ni->exp);
1039
- struct _timeInfo ti;
1040
- VALUE args[8];
1041
-
1042
- sec_as_time(t, &ti);
1043
-
1044
- args[0] = LONG2NUM(ti.year);
1045
- args[1] = LONG2NUM(ti.mon);
1046
- args[2] = LONG2NUM(ti.day);
1047
- args[3] = LONG2NUM(ti.hour);
1048
- args[4] = LONG2NUM(ti.min);
1049
- args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
1050
- args[6] = LONG2NUM(ni->exp);
1051
- parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
1002
+ struct timespec ts;
1003
+ ts.tv_sec = ni->i;
1004
+ ts.tv_nsec = nsec;
1005
+ parent->val = rb_time_timespec_new(&ts, (int)ni->exp);
1052
1006
  } else {
1053
1007
  parent->val = rb_time_nano_new(ni->i, (long)nsec);
1054
1008
  }
@@ -1059,7 +1013,7 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1059
1013
  break;
1060
1014
  default: break;
1061
1015
  }
1062
- if (Yes == pi->options.trace) {
1016
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
1063
1017
  oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
1064
1018
  }
1065
1019
  }
@@ -1072,7 +1026,7 @@ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
1072
1026
  case T_HASH: rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), value); break;
1073
1027
  default: break;
1074
1028
  }
1075
- if (Yes == pi->options.trace) {
1029
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
1076
1030
  oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
1077
1031
  }
1078
1032
  }
@@ -1082,7 +1036,7 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
1082
1036
  volatile VALUE rval = oj_num_as_value(ni);
1083
1037
 
1084
1038
  rb_ary_push(parent->val, rval);
1085
- if (Yes == pi->options.trace) {
1039
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
1086
1040
  oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
1087
1041
  }
1088
1042
  }
@@ -1099,7 +1053,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
1099
1053
  }
1100
1054
  }
1101
1055
  rb_ary_push(stack_peek(&pi->stack)->val, rstr);
1102
- if (Yes == pi->options.trace) {
1056
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
1103
1057
  oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
1104
1058
  }
1105
1059
  }