oj 3.13.23 → 3.16.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +81 -0
  3. data/README.md +2 -2
  4. data/ext/oj/buf.h +7 -6
  5. data/ext/oj/cache.c +29 -26
  6. data/ext/oj/cache.h +3 -2
  7. data/ext/oj/cache8.c +10 -9
  8. data/ext/oj/circarray.c +7 -5
  9. data/ext/oj/circarray.h +2 -2
  10. data/ext/oj/code.c +5 -12
  11. data/ext/oj/code.h +2 -2
  12. data/ext/oj/compat.c +20 -60
  13. data/ext/oj/custom.c +26 -59
  14. data/ext/oj/debug.c +3 -9
  15. data/ext/oj/dump.c +103 -53
  16. data/ext/oj/dump.h +1 -4
  17. data/ext/oj/dump_compat.c +557 -592
  18. data/ext/oj/dump_leaf.c +3 -5
  19. data/ext/oj/dump_object.c +42 -48
  20. data/ext/oj/dump_strict.c +10 -22
  21. data/ext/oj/encoder.c +1 -1
  22. data/ext/oj/err.c +2 -13
  23. data/ext/oj/err.h +9 -12
  24. data/ext/oj/extconf.rb +16 -7
  25. data/ext/oj/fast.c +60 -92
  26. data/ext/oj/intern.c +62 -47
  27. data/ext/oj/intern.h +3 -7
  28. data/ext/oj/mem.c +318 -0
  29. data/ext/oj/mem.h +53 -0
  30. data/ext/oj/mimic_json.c +51 -32
  31. data/ext/oj/object.c +33 -43
  32. data/ext/oj/odd.c +8 -6
  33. data/ext/oj/odd.h +4 -4
  34. data/ext/oj/oj.c +243 -212
  35. data/ext/oj/oj.h +83 -81
  36. data/ext/oj/parse.c +94 -148
  37. data/ext/oj/parse.h +21 -24
  38. data/ext/oj/parser.c +80 -67
  39. data/ext/oj/parser.h +7 -8
  40. data/ext/oj/rails.c +70 -92
  41. data/ext/oj/reader.c +9 -14
  42. data/ext/oj/reader.h +4 -2
  43. data/ext/oj/resolve.c +3 -4
  44. data/ext/oj/rxclass.c +6 -5
  45. data/ext/oj/rxclass.h +1 -1
  46. data/ext/oj/saj.c +10 -9
  47. data/ext/oj/saj2.c +37 -49
  48. data/ext/oj/saj2.h +1 -1
  49. data/ext/oj/scp.c +3 -14
  50. data/ext/oj/sparse.c +22 -70
  51. data/ext/oj/stream_writer.c +45 -41
  52. data/ext/oj/strict.c +20 -52
  53. data/ext/oj/string_writer.c +64 -38
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +125 -114
  56. data/ext/oj/usual.h +7 -6
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +13 -2
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/wab.c +25 -57
  61. data/lib/oj/active_support_helper.rb +1 -3
  62. data/lib/oj/bag.rb +7 -1
  63. data/lib/oj/easy_hash.rb +4 -5
  64. data/lib/oj/error.rb +0 -1
  65. data/lib/oj/json.rb +162 -150
  66. data/lib/oj/mimic.rb +7 -7
  67. data/lib/oj/schandler.rb +5 -4
  68. data/lib/oj/state.rb +8 -5
  69. data/lib/oj/version.rb +1 -2
  70. data/lib/oj.rb +2 -0
  71. data/pages/InstallOptions.md +20 -0
  72. data/pages/Options.md +4 -0
  73. data/test/_test_active.rb +8 -9
  74. data/test/_test_active_mimic.rb +7 -8
  75. data/test/_test_mimic_rails.rb +17 -20
  76. data/test/activerecord/result_test.rb +5 -6
  77. data/test/activesupport6/encoding_test.rb +63 -28
  78. data/test/activesupport7/abstract_unit.rb +4 -1
  79. data/test/activesupport7/encoding_test.rb +72 -22
  80. data/test/files.rb +15 -15
  81. data/test/foo.rb +18 -69
  82. data/test/helper.rb +5 -8
  83. data/test/isolated/shared.rb +3 -2
  84. data/test/json_gem/json_addition_test.rb +2 -2
  85. data/test/json_gem/json_common_interface_test.rb +8 -6
  86. data/test/json_gem/json_encoding_test.rb +0 -0
  87. data/test/json_gem/json_ext_parser_test.rb +1 -0
  88. data/test/json_gem/json_fixtures_test.rb +3 -2
  89. data/test/json_gem/json_generator_test.rb +50 -33
  90. data/test/json_gem/json_generic_object_test.rb +11 -11
  91. data/test/json_gem/json_parser_test.rb +46 -46
  92. data/test/json_gem/json_string_matching_test.rb +9 -9
  93. data/test/mem.rb +13 -12
  94. data/test/perf.rb +21 -26
  95. data/test/perf_compat.rb +31 -33
  96. data/test/perf_dump.rb +28 -28
  97. data/test/perf_fast.rb +80 -82
  98. data/test/perf_file.rb +27 -29
  99. data/test/perf_object.rb +65 -69
  100. data/test/perf_once.rb +12 -11
  101. data/test/perf_parser.rb +42 -48
  102. data/test/perf_saj.rb +46 -54
  103. data/test/perf_scp.rb +57 -69
  104. data/test/perf_simple.rb +41 -39
  105. data/test/perf_strict.rb +68 -70
  106. data/test/perf_wab.rb +67 -69
  107. data/test/prec.rb +5 -5
  108. data/test/sample/change.rb +0 -1
  109. data/test/sample/dir.rb +0 -1
  110. data/test/sample/doc.rb +0 -1
  111. data/test/sample/file.rb +0 -1
  112. data/test/sample/group.rb +0 -1
  113. data/test/sample/hasprops.rb +0 -1
  114. data/test/sample/layer.rb +0 -1
  115. data/test/sample/rect.rb +0 -1
  116. data/test/sample/shape.rb +0 -1
  117. data/test/sample/text.rb +0 -1
  118. data/test/sample.rb +16 -16
  119. data/test/sample_json.rb +8 -8
  120. data/test/test_compat.rb +81 -54
  121. data/test/test_custom.rb +63 -52
  122. data/test/test_debian.rb +7 -10
  123. data/test/test_fast.rb +86 -90
  124. data/test/test_file.rb +24 -29
  125. data/test/test_gc.rb +5 -5
  126. data/test/test_generate.rb +5 -5
  127. data/test/test_hash.rb +4 -4
  128. data/test/test_integer_range.rb +9 -9
  129. data/test/test_null.rb +20 -20
  130. data/test/test_object.rb +92 -87
  131. data/test/test_parser.rb +4 -4
  132. data/test/test_parser_debug.rb +5 -5
  133. data/test/test_parser_saj.rb +27 -25
  134. data/test/test_parser_usual.rb +44 -6
  135. data/test/test_rails.rb +2 -2
  136. data/test/test_saj.rb +10 -8
  137. data/test/test_scp.rb +35 -35
  138. data/test/test_strict.rb +38 -32
  139. data/test/test_various.rb +146 -97
  140. data/test/test_wab.rb +46 -44
  141. data/test/test_writer.rb +63 -47
  142. data/test/tests.rb +7 -7
  143. data/test/tests_mimic.rb +6 -6
  144. data/test/tests_mimic_addition.rb +6 -6
  145. metadata +46 -26
  146. data/test/activesupport4/decoding_test.rb +0 -108
  147. data/test/activesupport4/encoding_test.rb +0 -531
  148. data/test/activesupport4/test_helper.rb +0 -41
  149. data/test/activesupport5/abstract_unit.rb +0 -45
  150. data/test/activesupport5/decoding_test.rb +0 -133
  151. data/test/activesupport5/encoding_test.rb +0 -500
  152. data/test/activesupport5/encoding_test_cases.rb +0 -98
  153. data/test/activesupport5/test_helper.rb +0 -72
  154. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  155. data/test/bar.rb +0 -11
  156. data/test/baz.rb +0 -16
  157. data/test/bug.rb +0 -16
  158. data/test/zoo.rb +0 -13
data/ext/oj/rails.c CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include "code.h"
7
7
  #include "encode.h"
8
+ #include "mem.h"
8
9
  #include "trace.h"
9
10
  #include "util.h"
10
11
 
@@ -15,7 +16,7 @@ typedef struct _encoder {
15
16
  struct _rOptTable ropts;
16
17
  struct _options opts;
17
18
  VALUE arg;
18
- } * Encoder;
19
+ } *Encoder;
19
20
 
20
21
  bool oj_rails_hash_opt = false;
21
22
  bool oj_rails_array_opt = false;
@@ -76,7 +77,7 @@ static ROptTable copy_opts(ROptTable src, ROptTable dest) {
76
77
  if (NULL == src->table) {
77
78
  dest->table = NULL;
78
79
  } else {
79
- dest->table = ALLOC_N(struct _rOpt, dest->alen);
80
+ dest->table = OJ_R_ALLOC_N(struct _rOpt, dest->alen);
80
81
  memcpy(dest->table, src->table, sizeof(struct _rOpt) * dest->alen);
81
82
  }
82
83
  return NULL;
@@ -140,7 +141,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
140
141
  int cnt;
141
142
  int i;
142
143
  int len;
143
- const char * name;
144
+ const char *name;
144
145
 
145
146
  #ifdef RSTRUCT_LEN
146
147
  #if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
@@ -198,8 +199,8 @@ static void dump_enumerable(VALUE obj, int depth, Out out, bool as_ok) {
198
199
  }
199
200
 
200
201
  static void dump_bigdecimal(VALUE obj, int depth, Out out, bool as_ok) {
201
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
202
- const char * str = RSTRING_PTR(rstr);
202
+ volatile VALUE rstr = oj_safe_string_convert(obj);
203
+ const char *str = RSTRING_PTR(rstr);
203
204
 
204
205
  if ('I' == *str || 'N' == *str || ('-' == *str && 'I' == str[1])) {
205
206
  oj_dump_nil(Qnil, depth, out, false);
@@ -262,14 +263,7 @@ static void dump_sec_nano(VALUE obj, int64_t sec, long nsec, Out out) {
262
263
  tzmin);
263
264
  } else if (0 == out->opts->sec_prec) {
264
265
  if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
265
- len = sprintf(buf,
266
- "%04d-%02d-%02dT%02d:%02d:%02dZ",
267
- ti.year,
268
- ti.mon,
269
- ti.day,
270
- ti.hour,
271
- ti.min,
272
- ti.sec);
266
+ len = sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ", ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec);
273
267
  } else {
274
268
  len = sprintf(buf,
275
269
  "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
@@ -300,18 +294,7 @@ static void dump_sec_nano(VALUE obj, int64_t sec, long nsec, Out out) {
300
294
  format[32] = '0' + out->opts->sec_prec;
301
295
  len -= 9 - out->opts->sec_prec;
302
296
  }
303
- len = sprintf(buf,
304
- format,
305
- ti.year,
306
- ti.mon,
307
- ti.day,
308
- ti.hour,
309
- ti.min,
310
- ti.sec,
311
- nsec,
312
- tzsign,
313
- tzhour,
314
- tzmin);
297
+ len = sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, nsec, tzsign, tzhour, tzmin);
315
298
  }
316
299
  oj_dump_cstr(buf, len, 0, 0, out);
317
300
  }
@@ -345,7 +328,7 @@ static void dump_timewithzone(VALUE obj, int depth, Out out, bool as_ok) {
345
328
  }
346
329
 
347
330
  static void dump_to_s(VALUE obj, int depth, Out out, bool as_ok) {
348
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
331
+ volatile VALUE rstr = oj_safe_string_convert(obj);
349
332
 
350
333
  oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
351
334
  }
@@ -355,7 +338,7 @@ static ID parameters_id = 0;
355
338
  typedef struct _strLen {
356
339
  const char *str;
357
340
  int len;
358
- } * StrLen;
341
+ } *StrLen;
359
342
 
360
343
  static void dump_actioncontroller_parameters(VALUE obj, int depth, Out out, bool as_ok) {
361
344
  if (0 == parameters_id) {
@@ -373,11 +356,11 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
373
356
  int cnt = (int)RARRAY_LEN(rcols);
374
357
 
375
358
  *ccnt = cnt;
376
- cols = ALLOC_N(struct _strLen, cnt);
359
+ cols = OJ_R_ALLOC_N(struct _strLen, cnt);
377
360
  for (i = 0, cp = cols; i < cnt; i++, cp++) {
378
361
  v = RARRAY_AREF(rcols, i);
379
362
  if (T_STRING != rb_type(v)) {
380
- v = rb_funcall(v, oj_to_s_id, 0);
363
+ v = oj_safe_string_convert(v);
381
364
  }
382
365
  cp->str = StringValuePtr(v);
383
366
  cp->len = (int)RSTRING_LEN(v);
@@ -481,7 +464,7 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
481
464
  *out->cur++ = ',';
482
465
  }
483
466
  }
484
- xfree(cols);
467
+ OJ_R_FREE(cols);
485
468
  size = depth * out->indent + 1;
486
469
  assure_size(out, size);
487
470
  if (out->opts->dump_opts.use) {
@@ -504,7 +487,7 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
504
487
  typedef struct _namedFunc {
505
488
  const char *name;
506
489
  DumpFunc func;
507
- } * NamedFunc;
490
+ } *NamedFunc;
508
491
 
509
492
  static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
510
493
  if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
@@ -517,9 +500,7 @@ static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
517
500
  static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
518
501
  volatile VALUE ja;
519
502
 
520
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
521
- oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
522
- }
503
+ TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyIn);
523
504
  // Some classes elect to not take an options argument so check the arity
524
505
  // of as_json.
525
506
  if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
@@ -527,9 +508,7 @@ static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
527
508
  } else {
528
509
  ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
529
510
  }
530
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
531
- oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
532
- }
511
+ TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyOut);
533
512
 
534
513
  out->argc = 0;
535
514
  if (ja == obj || !as_ok) {
@@ -587,11 +566,11 @@ static ROpt create_opt(ROptTable rot, VALUE clas) {
587
566
  rot->len++;
588
567
  if (NULL == rot->table) {
589
568
  rot->alen = 256;
590
- rot->table = ALLOC_N(struct _rOpt, rot->alen);
569
+ rot->table = OJ_R_ALLOC_N(struct _rOpt, rot->alen);
591
570
  memset(rot->table, 0, sizeof(struct _rOpt) * rot->alen);
592
571
  } else if (rot->alen <= rot->len) {
593
572
  rot->alen *= 2;
594
- REALLOC_N(rot->table, struct _rOpt, rot->alen);
573
+ OJ_R_REALLOC_N(rot->table, struct _rOpt, rot->alen);
595
574
  memset(rot->table + olen, 0, sizeof(struct _rOpt) * olen);
596
575
  }
597
576
  if (0 == olen) {
@@ -644,9 +623,9 @@ static void encoder_free(void *ptr) {
644
623
  Encoder e = (Encoder)ptr;
645
624
 
646
625
  if (NULL != e->ropts.table) {
647
- xfree(e->ropts.table);
626
+ OJ_R_FREE(e->ropts.table);
648
627
  }
649
- xfree(ptr);
628
+ OJ_R_FREE(ptr);
650
629
  }
651
630
  }
652
631
 
@@ -660,6 +639,17 @@ static void encoder_mark(void *ptr) {
660
639
  }
661
640
  }
662
641
 
642
+ static const rb_data_type_t oj_encoder_type = {
643
+ "Oj/encoder",
644
+ {
645
+ encoder_mark,
646
+ encoder_free,
647
+ NULL,
648
+ },
649
+ 0,
650
+ 0,
651
+ };
652
+
663
653
  /* Document-method: new
664
654
  * call-seq: new(options=nil)
665
655
  *
@@ -667,7 +657,7 @@ static void encoder_mark(void *ptr) {
667
657
  * - *options* [_Hash_] formatting options
668
658
  */
669
659
  static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
670
- Encoder e = ALLOC(struct _encoder);
660
+ Encoder e = OJ_R_ALLOC(struct _encoder);
671
661
 
672
662
  e->opts = oj_default_options;
673
663
  e->arg = Qnil;
@@ -677,14 +667,14 @@ static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
677
667
  oj_parse_options(*argv, &e->opts);
678
668
  e->arg = *argv;
679
669
  }
680
- return Data_Wrap_Struct(encoder_class, encoder_mark, encoder_free, e);
670
+ return TypedData_Wrap_Struct(encoder_class, &oj_encoder_type, e);
681
671
  }
682
672
 
683
673
  static VALUE resolve_classpath(const char *name) {
684
674
  char class_name[1024];
685
675
  VALUE clas;
686
- char * end = class_name + sizeof(class_name) - 1;
687
- char * s;
676
+ char *end = class_name + sizeof(class_name) - 1;
677
+ char *s;
688
678
  const char *n = name;
689
679
  ID cid;
690
680
 
@@ -750,8 +740,7 @@ static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
750
740
  oj_rails_float_opt = on;
751
741
  } else if (oj_string_writer_class == *argv) {
752
742
  string_writer_optimized = on;
753
- } else if (NULL != (ro = oj_rails_get_opt(rot, *argv)) ||
754
- NULL != (ro = create_opt(rot, *argv))) {
743
+ } else if (NULL != (ro = oj_rails_get_opt(rot, *argv)) || NULL != (ro = create_opt(rot, *argv))) {
755
744
  ro->on = on;
756
745
  }
757
746
  }
@@ -770,7 +759,8 @@ static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
770
759
  * - *classes* [_Class_] a list of classes to optimize
771
760
  */
772
761
  static VALUE encoder_optimize(int argc, VALUE *argv, VALUE self) {
773
- Encoder e = (Encoder)DATA_PTR(self);
762
+ Encoder e;
763
+ TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
774
764
 
775
765
  optimize(argc, argv, &e->ropts, true);
776
766
 
@@ -813,7 +803,7 @@ rails_mimic_json(VALUE self) {
813
803
  }
814
804
  oj_mimic_json_methods(json);
815
805
  // Setting the default mode breaks the prmoise in the docs not to.
816
- //oj_default_options.mode = RailsMode;
806
+ // oj_default_options.mode = RailsMode;
817
807
 
818
808
  return Qnil;
819
809
  }
@@ -826,7 +816,8 @@ rails_mimic_json(VALUE self) {
826
816
  * - *classes* [_Class_] a list of classes to deoptimize
827
817
  */
828
818
  static VALUE encoder_deoptimize(int argc, VALUE *argv, VALUE self) {
829
- Encoder e = (Encoder)DATA_PTR(self);
819
+ Encoder e;
820
+ TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
830
821
 
831
822
  optimize(argc, argv, &e->ropts, false);
832
823
 
@@ -855,8 +846,11 @@ static VALUE rails_deoptimize(int argc, VALUE *argv, VALUE self) {
855
846
  * @return true if the class is being optimized for rails and false otherwise
856
847
  */
857
848
  static VALUE encoder_optimized(VALUE self, VALUE clas) {
858
- Encoder e = (Encoder)DATA_PTR(self);
859
- ROpt ro = oj_rails_get_opt(&e->ropts, clas);
849
+ Encoder e;
850
+ ROpt ro;
851
+
852
+ TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
853
+ ro = oj_rails_get_opt(&e->ropts, clas);
860
854
 
861
855
  if (NULL == ro) {
862
856
  return Qfalse;
@@ -881,7 +875,7 @@ static VALUE rails_optimized(VALUE self, VALUE clas) {
881
875
  typedef struct _oo {
882
876
  Out out;
883
877
  VALUE obj;
884
- } * OO;
878
+ } *OO;
885
879
 
886
880
  static VALUE protect_dump(VALUE ov) {
887
881
  OO oo = (OO)ov;
@@ -911,16 +905,15 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
911
905
 
912
906
  oj_out_init(&out);
913
907
 
914
- out.omit_nil = copts.dump_opts.omit_nil;
915
- out.caller = 0;
916
- out.cur = out.buf;
917
- out.circ_cnt = 0;
918
- out.opts = &copts;
919
- out.hash_cnt = 0;
920
- out.indent = copts.indent;
921
- out.argc = argc;
922
- out.argv = argv;
923
- out.ropts = ropts;
908
+ out.omit_nil = copts.dump_opts.omit_nil;
909
+ out.cur = out.buf;
910
+ out.circ_cnt = 0;
911
+ out.opts = &copts;
912
+ out.hash_cnt = 0;
913
+ out.indent = copts.indent;
914
+ out.argc = argc;
915
+ out.argv = argv;
916
+ out.ropts = ropts;
924
917
  if (Yes == copts.circular) {
925
918
  oj_cache8_new(&out.circ_cache);
926
919
  }
@@ -963,7 +956,8 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
963
956
  * Returns encoded object as a JSON string.
964
957
  */
965
958
  static VALUE encoder_encode(VALUE self, VALUE obj) {
966
- Encoder e = (Encoder)DATA_PTR(self);
959
+ Encoder e;
960
+ TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
967
961
 
968
962
  if (Qnil != e->arg) {
969
963
  VALUE argv[1] = {e->arg};
@@ -1065,28 +1059,16 @@ static VALUE rails_set_encoder(VALUE self) {
1065
1059
  verbose = rb_gv_get("$VERBOSE");
1066
1060
  rb_gv_set("$VERBOSE", Qfalse);
1067
1061
  rb_undef_method(encoding, "use_standard_json_time_format=");
1068
- rb_define_module_function(encoding,
1069
- "use_standard_json_time_format=",
1070
- rails_use_standard_json_time_format,
1071
- 1);
1062
+ rb_define_module_function(encoding, "use_standard_json_time_format=", rails_use_standard_json_time_format, 1);
1072
1063
  rb_undef_method(encoding, "use_standard_json_time_format");
1073
- rb_define_module_function(encoding,
1074
- "use_standard_json_time_format",
1075
- rails_use_standard_json_time_format_get,
1076
- 0);
1064
+ rb_define_module_function(encoding, "use_standard_json_time_format", rails_use_standard_json_time_format_get, 0);
1077
1065
 
1078
1066
  pv = rb_iv_get(encoding, "@escape_html_entities_in_json");
1079
1067
  escape_html = Qtrue == pv;
1080
1068
  rb_undef_method(encoding, "escape_html_entities_in_json=");
1081
- rb_define_module_function(encoding,
1082
- "escape_html_entities_in_json=",
1083
- rails_escape_html_entities_in_json,
1084
- 1);
1069
+ rb_define_module_function(encoding, "escape_html_entities_in_json=", rails_escape_html_entities_in_json, 1);
1085
1070
  rb_undef_method(encoding, "escape_html_entities_in_json");
1086
- rb_define_module_function(encoding,
1087
- "escape_html_entities_in_json",
1088
- rails_escape_html_entities_in_json_get,
1089
- 0);
1071
+ rb_define_module_function(encoding, "escape_html_entities_in_json", rails_escape_html_entities_in_json_get, 0);
1090
1072
 
1091
1073
  pv = rb_iv_get(encoding, "@time_precision");
1092
1074
  oj_default_options.sec_prec = NUM2INT(pv);
@@ -1119,6 +1101,8 @@ static VALUE rails_set_decoder(VALUE self) {
1119
1101
  } else {
1120
1102
  json_error = rb_define_class_under(json, "JSONError", rb_eStandardError);
1121
1103
  }
1104
+
1105
+ rb_global_variable(&oj_json_parser_error_class);
1122
1106
  if (rb_const_defined_at(json, rb_intern("ParserError"))) {
1123
1107
  oj_json_parser_error_class = rb_const_get(json, rb_intern("ParserError"));
1124
1108
  } else {
@@ -1188,7 +1172,7 @@ static void dump_to_hash(VALUE obj, int depth, Out out) {
1188
1172
 
1189
1173
  static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1190
1174
  char buf[64];
1191
- char * b;
1175
+ char *b;
1192
1176
  double d = rb_num2dbl(obj);
1193
1177
  int cnt = 0;
1194
1178
 
@@ -1208,7 +1192,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1208
1192
  } else if (oj_rails_float_opt) {
1209
1193
  cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, "%0.16g");
1210
1194
  } else {
1211
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
1195
+ volatile VALUE rstr = oj_safe_string_convert(obj);
1212
1196
 
1213
1197
  strcpy(buf, RSTRING_PTR(rstr));
1214
1198
  cnt = (int)RSTRING_LEN(rstr);
@@ -1301,7 +1285,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
1301
1285
  return ST_CONTINUE;
1302
1286
  }
1303
1287
  if (rtype != T_STRING && rtype != T_SYMBOL) {
1304
- key = rb_funcall(key, oj_to_s_id, 0);
1288
+ key = oj_safe_string_convert(key);
1305
1289
  rtype = rb_type(key);
1306
1290
  }
1307
1291
  if (!out->opts->dump_opts.use) {
@@ -1464,9 +1448,7 @@ static DumpFunc rails_funcs[] = {
1464
1448
  static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
1465
1449
  int type = rb_type(obj);
1466
1450
 
1467
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
1468
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
1469
- }
1451
+ TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
1470
1452
  if (MAX_DEPTH < depth) {
1471
1453
  rb_raise(rb_eNoMemError, "Too deeply nested.\n");
1472
1454
  }
@@ -1475,16 +1457,12 @@ static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
1475
1457
 
1476
1458
  if (NULL != f) {
1477
1459
  f(obj, depth, out, as_ok);
1478
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
1479
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
1480
- }
1460
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
1481
1461
  return;
1482
1462
  }
1483
1463
  }
1484
1464
  oj_dump_nil(Qnil, depth, out, false);
1485
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
1486
- oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
1487
- }
1465
+ TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
1488
1466
  }
1489
1467
 
1490
1468
  void oj_dump_rails_val(VALUE obj, int depth, Out out) {
data/ext/oj/reader.c CHANGED
@@ -14,6 +14,7 @@
14
14
  #include <time.h>
15
15
  #include <unistd.h>
16
16
 
17
+ #include "mem.h"
17
18
  #include "oj.h"
18
19
  #include "reader.h"
19
20
  #include "ruby.h"
@@ -63,8 +64,7 @@ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
63
64
  reader->tail = reader->head;
64
65
  reader->read_end = reader->head + RSTRING_LEN(s);
65
66
  } else if (rb_cFile == io_class && Qnil != (stat = rb_funcall(io, oj_stat_id, 0)) &&
66
- Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) &&
67
- 0 == strcmp("file", StringValuePtr(ftype)) &&
67
+ Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) && 0 == strcmp("file", StringValuePtr(ftype)) &&
68
68
  0 == FIX2INT(rb_funcall(io, oj_pos_id, 0))) {
69
69
  reader->read_func = read_from_fd;
70
70
  reader->fd = FIX2INT(rb_funcall(io, oj_fileno_id, 0));
@@ -75,7 +75,7 @@ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
75
75
  reader->read_func = read_from_io;
76
76
  reader->io = io;
77
77
  } else if (to_s) {
78
- volatile VALUE rstr = rb_funcall(io, oj_to_s_id, 0);
78
+ volatile VALUE rstr = oj_safe_string_convert(io);
79
79
 
80
80
  reader->read_func = 0;
81
81
  reader->in_str = StringValuePtr(rstr);
@@ -83,8 +83,7 @@ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
83
83
  reader->tail = reader->head;
84
84
  reader->read_end = reader->head + RSTRING_LEN(rstr);
85
85
  } else {
86
- rb_raise(rb_eArgError,
87
- "parser io argument must be a String or respond to readpartial() or read().\n");
86
+ rb_raise(rb_eArgError, "parser io argument must be a String or respond to readpartial() or read().\n");
88
87
  }
89
88
  }
90
89
 
@@ -107,10 +106,10 @@ int oj_reader_read(Reader reader) {
107
106
  size_t size = reader->end - reader->head + BUF_PAD;
108
107
 
109
108
  if (reader->head == reader->base) {
110
- reader->head = ALLOC_N(char, size * 2);
109
+ reader->head = OJ_R_ALLOC_N(char, size * 2);
111
110
  memcpy((char *)reader->head, old, size);
112
111
  } else {
113
- REALLOC_N(reader->head, char, size * 2);
112
+ OJ_R_REALLOC_N(reader->head, char, size * 2);
114
113
  }
115
114
  reader->free_head = 1;
116
115
  reader->end = reader->head + size * 2 - BUF_PAD;
@@ -123,9 +122,7 @@ int oj_reader_read(Reader reader) {
123
122
  reader->str = reader->head + (reader->str - old);
124
123
  }
125
124
  } else {
126
- memmove((char *)reader->head,
127
- reader->head + shift,
128
- reader->read_end - (reader->head + shift));
125
+ memmove((char *)reader->head, reader->head + shift, reader->read_end - (reader->head + shift));
129
126
  reader->tail -= shift;
130
127
  reader->read_end -= shift;
131
128
  if (0 != reader->pro) {
@@ -157,7 +154,7 @@ static VALUE partial_io_cb(VALUE rbuf) {
157
154
  Reader reader = (Reader)rbuf;
158
155
  VALUE args[1];
159
156
  VALUE rstr;
160
- char * str;
157
+ char *str;
161
158
  size_t cnt;
162
159
 
163
160
  args[0] = ULONG2NUM(reader->end - reader->tail);
@@ -167,7 +164,6 @@ static VALUE partial_io_cb(VALUE rbuf) {
167
164
  }
168
165
  str = StringValuePtr(rstr);
169
166
  cnt = RSTRING_LEN(rstr);
170
- // printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
171
167
  strcpy(reader->tail, str);
172
168
  reader->read_end = reader->tail + cnt;
173
169
 
@@ -178,7 +174,7 @@ static VALUE io_cb(VALUE rbuf) {
178
174
  Reader reader = (Reader)rbuf;
179
175
  VALUE args[1];
180
176
  VALUE rstr;
181
- char * str;
177
+ char *str;
182
178
  size_t cnt;
183
179
 
184
180
  args[0] = ULONG2NUM(reader->end - reader->tail);
@@ -188,7 +184,6 @@ static VALUE io_cb(VALUE rbuf) {
188
184
  }
189
185
  str = StringValuePtr(rstr);
190
186
  cnt = RSTRING_LEN(rstr);
191
- // printf("*** read %lu bytes, str: '%s'\n", cnt, str);
192
187
  strcpy(reader->tail, str);
193
188
  reader->read_end = reader->tail + cnt;
194
189
 
data/ext/oj/reader.h CHANGED
@@ -4,6 +4,8 @@
4
4
  #ifndef OJ_READER_H
5
5
  #define OJ_READER_H
6
6
 
7
+ #include "mem.h"
8
+
7
9
  typedef struct _reader {
8
10
  char base[0x00001000];
9
11
  char *head;
@@ -22,7 +24,7 @@ typedef struct _reader {
22
24
  VALUE io;
23
25
  const char *in_str;
24
26
  };
25
- } * Reader;
27
+ } *Reader;
26
28
 
27
29
  extern void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s);
28
30
  extern int oj_reader_read(Reader reader);
@@ -114,7 +116,7 @@ static inline int reader_expect(Reader reader, const char *s) {
114
116
 
115
117
  static inline void reader_cleanup(Reader reader) {
116
118
  if (reader->free_head && 0 != reader->head) {
117
- xfree((char *)reader->head);
119
+ OJ_R_FREE((char *)reader->head);
118
120
  reader->head = 0;
119
121
  reader->free_head = 0;
120
122
  }
data/ext/oj/resolve.c CHANGED
@@ -27,12 +27,11 @@ inline static VALUE resolve_classname(VALUE mod, const char *classname, int auto
27
27
  return clas;
28
28
  }
29
29
 
30
- static VALUE
31
- resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
30
+ static VALUE resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
32
31
  char class_name[1024];
33
32
  VALUE clas;
34
- char * end = class_name + sizeof(class_name) - 1;
35
- char * s;
33
+ char *end = class_name + sizeof(class_name) - 1;
34
+ char *s;
36
35
  const char *n = name;
37
36
 
38
37
  clas = rb_cObject;
data/ext/oj/rxclass.c CHANGED
@@ -10,6 +10,7 @@
10
10
  #include <regex.h>
11
11
  #endif
12
12
 
13
+ #include "mem.h"
13
14
  #include "rxclass.h"
14
15
 
15
16
  typedef struct _rxC {
@@ -20,7 +21,7 @@ typedef struct _rxC {
20
21
  #endif
21
22
  VALUE clas;
22
23
  char src[256];
23
- } * RxC;
24
+ } *RxC;
24
25
 
25
26
  void oj_rxclass_init(RxClass rc) {
26
27
  *rc->err = '\0';
@@ -37,13 +38,13 @@ void oj_rxclass_cleanup(RxClass rc) {
37
38
  if (Qnil == rxc->rrx) {
38
39
  regfree(&rxc->rx);
39
40
  }
40
- xfree(rxc);
41
+ OJ_R_FREE(rxc);
41
42
  #endif
42
43
  }
43
44
  }
44
45
 
45
46
  void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas) {
46
- RxC rxc = ALLOC_N(struct _rxC, 1);
47
+ RxC rxc = OJ_R_ALLOC_N(struct _rxC, 1);
47
48
 
48
49
  memset(rxc, 0, sizeof(struct _rxC));
49
50
  rxc->rrx = rx;
@@ -70,7 +71,7 @@ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
70
71
  (unsigned long)sizeof(rxc->src));
71
72
  return EINVAL;
72
73
  }
73
- rxc = ALLOC_N(struct _rxC, 1);
74
+ rxc = OJ_R_ALLOC_N(struct _rxC, 1);
74
75
  rxc->next = 0;
75
76
  rxc->clas = clas;
76
77
 
@@ -80,7 +81,7 @@ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
80
81
  rxc->rrx = Qnil;
81
82
  if (0 != (err = regcomp(&rxc->rx, expr, flags))) {
82
83
  regerror(err, &rxc->rx, rc->err, sizeof(rc->err));
83
- free(rxc);
84
+ OJ_FREE(rxc);
84
85
  return err;
85
86
  }
86
87
  #endif
data/ext/oj/rxclass.h CHANGED
@@ -14,7 +14,7 @@ typedef struct _rxClass {
14
14
  struct _rxC *head;
15
15
  struct _rxC *tail;
16
16
  char err[128];
17
- } * RxClass;
17
+ } *RxClass;
18
18
 
19
19
  extern void oj_rxclass_init(RxClass rc);
20
20
  extern void oj_rxclass_cleanup(RxClass rc);
data/ext/oj/saj.c CHANGED
@@ -15,6 +15,7 @@
15
15
  #define OJ_INFINITY (1.0 / 0.0)
16
16
 
17
17
  #include "encode.h"
18
+ #include "mem.h"
18
19
  #include "oj.h"
19
20
 
20
21
  typedef struct _parseInfo {
@@ -28,7 +29,7 @@ typedef struct _parseInfo {
28
29
  int has_array_end;
29
30
  int has_add_value;
30
31
  int has_error;
31
- } * ParseInfo;
32
+ } *ParseInfo;
32
33
 
33
34
  static void read_next(ParseInfo pi, const char *key);
34
35
  static void read_hash(ParseInfo pi, const char *key);
@@ -577,7 +578,7 @@ static void saj_parse(VALUE handler, char *json) {
577
578
  /* initialize parse info */
578
579
  pi.str = json;
579
580
  pi.s = json;
580
- #if IS_WINDOWS
581
+ #if IS_WINDOWS || !defined(HAVE_GETRLIMIT)
581
582
  pi.stack_min = (void *)((char *)&obj - (512L * 1024L)); /* assume a 1M stack and give half to ruby */
582
583
  #else
583
584
  {
@@ -631,7 +632,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
631
632
  if (rb_type(input) == T_STRING) {
632
633
  // the json string gets modified so make a copy of it
633
634
  len = RSTRING_LEN(input) + 1;
634
- json = ALLOC_N(char, len);
635
+ json = OJ_R_ALLOC_N(char, len);
635
636
  strcpy(json, StringValuePtr(input));
636
637
  } else {
637
638
  VALUE clas = rb_obj_class(input);
@@ -640,8 +641,8 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
640
641
  if (oj_stringio_class == clas) {
641
642
  s = rb_funcall2(input, oj_string_id, 0, 0);
642
643
  len = RSTRING_LEN(s) + 1;
643
- json = ALLOC_N(char, len);
644
- strcpy(json, rb_string_value_cstr((VALUE *)&s));
644
+ json = OJ_R_ALLOC_N(char, len);
645
+ strcpy(json, StringValueCStr(s));
645
646
  #if !IS_WINDOWS
646
647
  } else if (rb_cFile == clas && 0 == FIX2INT(rb_funcall(input, oj_pos_id, 0))) {
647
648
  int fd = FIX2INT(rb_funcall(input, oj_fileno_id, 0));
@@ -649,7 +650,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
649
650
 
650
651
  len = lseek(fd, 0, SEEK_END);
651
652
  lseek(fd, 0, SEEK_SET);
652
- json = ALLOC_N(char, len + 1);
653
+ json = OJ_R_ALLOC_N(char, len + 1);
653
654
  if (0 >= (cnt = read(fd, json, len)) || cnt != (ssize_t)len) {
654
655
  rb_raise(rb_eIOError, "failed to read from IO Object.");
655
656
  }
@@ -658,14 +659,14 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
658
659
  } else if (rb_respond_to(input, oj_read_id)) {
659
660
  s = rb_funcall2(input, oj_read_id, 0, 0);
660
661
  len = RSTRING_LEN(s) + 1;
661
- json = ALLOC_N(char, len);
662
- strcpy(json, rb_string_value_cstr((VALUE *)&s));
662
+ json = OJ_R_ALLOC_N(char, len);
663
+ strcpy(json, StringValueCStr(s));
663
664
  } else {
664
665
  rb_raise(rb_eArgError, "saj_parse() expected a String or IO Object.");
665
666
  }
666
667
  }
667
668
  saj_parse(*argv, json);
668
- xfree(json);
669
+ OJ_R_FREE(json);
669
670
 
670
671
  return Qnil;
671
672
  }