oj 3.13.17 → 3.16.3

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 (156) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -0
  3. data/README.md +4 -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 +44 -96
  14. data/ext/oj/debug.c +3 -9
  15. data/ext/oj/dump.c +69 -39
  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 -6
  25. data/ext/oj/fast.c +76 -106
  26. data/ext/oj/intern.c +63 -51
  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 +43 -30
  31. data/ext/oj/object.c +61 -70
  32. data/ext/oj/odd.c +8 -6
  33. data/ext/oj/odd.h +4 -4
  34. data/ext/oj/oj.c +243 -205
  35. data/ext/oj/oj.h +82 -78
  36. data/ext/oj/parse.c +123 -188
  37. data/ext/oj/parse.h +23 -24
  38. data/ext/oj/parser.c +103 -63
  39. data/ext/oj/parser.h +19 -9
  40. data/ext/oj/rails.c +68 -92
  41. data/ext/oj/reader.c +10 -15
  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 +74 -92
  48. data/ext/oj/saj2.h +23 -0
  49. data/ext/oj/scp.c +3 -14
  50. data/ext/oj/sparse.c +22 -70
  51. data/ext/oj/stream_writer.c +43 -35
  52. data/ext/oj/strict.c +20 -52
  53. data/ext/oj/string_writer.c +60 -34
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +125 -150
  56. data/ext/oj/usual.h +69 -0
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +14 -3
  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 +6 -2
  67. data/lib/oj/state.rb +9 -6
  68. data/lib/oj/version.rb +1 -2
  69. data/lib/oj.rb +2 -0
  70. data/pages/Compatibility.md +1 -1
  71. data/pages/InstallOptions.md +20 -0
  72. data/pages/Options.md +10 -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/files.rb +15 -15
  78. data/test/foo.rb +9 -72
  79. data/test/helper.rb +11 -8
  80. data/test/isolated/shared.rb +3 -2
  81. data/test/json_gem/json_addition_test.rb +2 -2
  82. data/test/json_gem/json_common_interface_test.rb +8 -6
  83. data/test/json_gem/json_encoding_test.rb +0 -0
  84. data/test/json_gem/json_ext_parser_test.rb +1 -0
  85. data/test/json_gem/json_fixtures_test.rb +3 -2
  86. data/test/json_gem/json_generator_test.rb +53 -37
  87. data/test/json_gem/json_generic_object_test.rb +11 -11
  88. data/test/json_gem/json_parser_test.rb +47 -47
  89. data/test/json_gem/json_string_matching_test.rb +9 -9
  90. data/test/json_gem/test_helper.rb +7 -3
  91. data/test/mem.rb +13 -12
  92. data/test/perf.rb +21 -26
  93. data/test/perf_compat.rb +31 -33
  94. data/test/perf_dump.rb +28 -28
  95. data/test/perf_fast.rb +80 -82
  96. data/test/perf_file.rb +27 -29
  97. data/test/perf_object.rb +65 -69
  98. data/test/perf_once.rb +12 -11
  99. data/test/perf_parser.rb +42 -48
  100. data/test/perf_saj.rb +46 -54
  101. data/test/perf_scp.rb +57 -69
  102. data/test/perf_simple.rb +41 -39
  103. data/test/perf_strict.rb +68 -70
  104. data/test/perf_wab.rb +67 -69
  105. data/test/prec.rb +5 -5
  106. data/test/sample/change.rb +0 -1
  107. data/test/sample/dir.rb +0 -1
  108. data/test/sample/doc.rb +0 -1
  109. data/test/sample/file.rb +0 -1
  110. data/test/sample/group.rb +0 -1
  111. data/test/sample/hasprops.rb +0 -1
  112. data/test/sample/layer.rb +0 -1
  113. data/test/sample/rect.rb +0 -1
  114. data/test/sample/shape.rb +0 -1
  115. data/test/sample/text.rb +0 -1
  116. data/test/sample.rb +16 -16
  117. data/test/sample_json.rb +8 -8
  118. data/test/test_compat.rb +80 -53
  119. data/test/test_custom.rb +73 -51
  120. data/test/test_debian.rb +7 -10
  121. data/test/test_fast.rb +86 -90
  122. data/test/test_file.rb +28 -35
  123. data/test/test_gc.rb +16 -5
  124. data/test/test_generate.rb +5 -5
  125. data/test/test_hash.rb +4 -4
  126. data/test/test_integer_range.rb +9 -9
  127. data/test/test_null.rb +20 -20
  128. data/test/test_object.rb +94 -96
  129. data/test/test_parser.rb +6 -22
  130. data/test/test_parser_debug.rb +27 -0
  131. data/test/test_parser_saj.rb +61 -22
  132. data/test/test_parser_usual.rb +16 -6
  133. data/test/test_rails.rb +2 -2
  134. data/test/test_saj.rb +10 -8
  135. data/test/test_scp.rb +37 -39
  136. data/test/test_strict.rb +40 -32
  137. data/test/test_various.rb +148 -100
  138. data/test/test_wab.rb +48 -44
  139. data/test/test_writer.rb +47 -47
  140. data/test/tests.rb +13 -4
  141. data/test/tests_mimic.rb +12 -3
  142. data/test/tests_mimic_addition.rb +12 -3
  143. metadata +36 -27
  144. data/test/activesupport4/decoding_test.rb +0 -108
  145. data/test/activesupport4/encoding_test.rb +0 -531
  146. data/test/activesupport4/test_helper.rb +0 -41
  147. data/test/activesupport5/abstract_unit.rb +0 -45
  148. data/test/activesupport5/decoding_test.rb +0 -133
  149. data/test/activesupport5/encoding_test.rb +0 -500
  150. data/test/activesupport5/encoding_test_cases.rb +0 -98
  151. data/test/activesupport5/test_helper.rb +0 -72
  152. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  153. data/test/bar.rb +0 -11
  154. data/test/baz.rb +0 -16
  155. data/test/bug.rb +0 -16
  156. data/test/zoo.rb +0 -13
data/ext/oj/compat.c CHANGED
@@ -6,38 +6,26 @@
6
6
  #include "encode.h"
7
7
  #include "err.h"
8
8
  #include "intern.h"
9
+ #include "mem.h"
9
10
  #include "oj.h"
10
11
  #include "parse.h"
11
12
  #include "resolve.h"
12
13
  #include "trace.h"
13
14
 
14
15
  static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
15
- const char * key = kval->key;
16
- int klen = kval->klen;
17
- Val parent = stack_peek(&pi->stack);
18
- volatile VALUE rkey = kval->key_val;
16
+ const char *key = kval->key;
17
+ int klen = kval->klen;
18
+ Val parent = stack_peek(&pi->stack);
19
19
 
20
- if (Qundef == rkey && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
20
+ if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
21
21
  *pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
22
22
  0 == strncmp(pi->options.create_id, key, klen)) {
23
23
  parent->classname = oj_strndup(str, len);
24
24
  parent->clen = len;
25
25
  } else {
26
26
  volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
27
+ volatile VALUE rkey = oj_calc_hash_key(pi, kval);
27
28
 
28
- if (Qundef == rkey) {
29
- if (Yes != pi->options.cache_keys) {
30
- if (Yes == pi->options.sym_key) {
31
- rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
32
- } else {
33
- rkey = rb_utf8_str_new(key, klen);
34
- }
35
- } else if (Yes == pi->options.sym_key) {
36
- rkey = oj_sym_intern(key, klen);
37
- } else {
38
- rkey = oj_str_intern(key, klen);
39
- }
40
- }
41
29
  if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
42
30
  VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
43
31
 
@@ -54,9 +42,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
54
42
  } else {
55
43
  rb_hash_aset(parent->val, rkey, rstr);
56
44
  }
57
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
58
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
59
- }
45
+ TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rstr);
60
46
  }
61
47
  }
62
48
 
@@ -68,9 +54,7 @@ static VALUE start_hash(ParseInfo pi) {
68
54
  } else {
69
55
  h = rb_hash_new();
70
56
  }
71
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
72
- oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
73
- }
57
+ TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
74
58
  return h;
75
59
  }
76
60
 
@@ -89,13 +73,11 @@ static void end_hash(struct _parseInfo *pi) {
89
73
  }
90
74
  }
91
75
  if (0 != parent->classname) {
92
- xfree((char *)parent->classname);
76
+ OJ_R_FREE((char *)parent->classname);
93
77
  parent->classname = 0;
94
78
  }
95
79
  }
96
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
97
- oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
98
- }
80
+ TRACE_PARSE_HASH_END(pi->options.trace, pi);
99
81
  }
100
82
 
101
83
  static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
@@ -110,37 +92,27 @@ static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig
110
92
  }
111
93
  }
112
94
  pi->stack.head->val = rstr;
113
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
114
- oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, rstr);
115
- }
95
+ TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, rstr);
116
96
  }
117
97
 
118
98
  static void add_num(ParseInfo pi, NumInfo ni) {
119
99
  pi->stack.head->val = oj_num_as_value(ni);
120
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
121
- oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
122
- }
100
+ TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, pi->stack.head->val);
123
101
  }
124
102
 
125
103
  static void hash_set_num(struct _parseInfo *pi, Val parent, NumInfo ni) {
126
104
  volatile VALUE rval = oj_num_as_value(ni);
127
105
 
128
- if (!oj_use_hash_alt && rb_cHash != rb_obj_class(parent->val)) {
106
+ if (rb_cHash != rb_obj_class(parent->val)) {
129
107
  // The rb_hash_set would still work but the unit tests for the
130
108
  // json gem require the less efficient []= method be called to set
131
109
  // values. Even using the store method to set the values will fail
132
110
  // the unit tests.
133
- rb_funcall(stack_peek(&pi->stack)->val,
134
- rb_intern("[]="),
135
- 2,
136
- oj_calc_hash_key(pi, parent),
137
- rval);
111
+ rb_funcall(stack_peek(&pi->stack)->val, rb_intern("[]="), 2, oj_calc_hash_key(pi, parent), rval);
138
112
  } else {
139
113
  rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), rval);
140
114
  }
141
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
142
- oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, rval);
143
- }
115
+ TRACE_PARSE_CALL(pi->options.trace, "set_number", pi, rval);
144
116
  }
145
117
 
146
118
  static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
@@ -149,26 +121,18 @@ static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
149
121
  // json gem require the less efficient []= method be called to set
150
122
  // values. Even using the store method to set the values will fail
151
123
  // the unit tests.
152
- rb_funcall(stack_peek(&pi->stack)->val,
153
- rb_intern("[]="),
154
- 2,
155
- oj_calc_hash_key(pi, parent),
156
- value);
124
+ rb_funcall(stack_peek(&pi->stack)->val, rb_intern("[]="), 2, oj_calc_hash_key(pi, parent), value);
157
125
  } else {
158
126
  rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), value);
159
127
  }
160
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
161
- oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
162
- }
128
+ TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
163
129
  }
164
130
 
165
131
  static VALUE start_array(ParseInfo pi) {
166
132
  if (Qnil != pi->options.array_class) {
167
133
  return rb_class_new_instance(0, NULL, pi->options.array_class);
168
134
  }
169
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
170
- oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
171
- }
135
+ TRACE_PARSE_IN(pi->options.trace, "start_array", pi);
172
136
  return rb_ary_new();
173
137
  }
174
138
 
@@ -184,9 +148,7 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
184
148
  } else {
185
149
  rb_ary_push(parent->val, rval);
186
150
  }
187
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
188
- oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
189
- }
151
+ TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
190
152
  }
191
153
 
192
154
  static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
@@ -201,9 +163,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
201
163
  }
202
164
  }
203
165
  rb_ary_push(stack_peek(&pi->stack)->val, rstr);
204
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
205
- oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
206
- }
166
+ TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rstr);
207
167
  }
208
168
 
209
169
  void oj_set_compat_callbacks(ParseInfo pi) {
data/ext/oj/custom.c CHANGED
@@ -9,6 +9,7 @@
9
9
  #include "encode.h"
10
10
  #include "err.h"
11
11
  #include "intern.h"
12
+ #include "mem.h"
12
13
  #include "odd.h"
13
14
  #include "oj.h"
14
15
  #include "parse.h"
@@ -24,21 +25,21 @@ static void dump_obj_str(VALUE obj, int depth, Out out) {
24
25
  {"s", 1, Qnil},
25
26
  {NULL, 0, Qnil},
26
27
  };
27
- attrs->value = rb_funcall(obj, oj_to_s_id, 0);
28
+ attrs->value = oj_safe_string_convert(obj);
28
29
 
29
30
  oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
30
31
  }
31
32
 
32
33
  static void dump_obj_as_str(VALUE obj, int depth, Out out) {
33
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
34
- const char * str = RSTRING_PTR(rstr);
34
+ volatile VALUE rstr = oj_safe_string_convert(obj);
35
+ const char *str = RSTRING_PTR(rstr);
35
36
 
36
37
  oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
37
38
  }
38
39
 
39
40
  static void bigdecimal_dump(VALUE obj, int depth, Out out) {
40
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
41
- const char * str = RSTRING_PTR(rstr);
41
+ volatile VALUE rstr = oj_safe_string_convert(obj);
42
+ const char *str = RSTRING_PTR(rstr);
42
43
  int len = (int)RSTRING_LEN(rstr);
43
44
 
44
45
  if (0 == strcasecmp("Infinity", str)) {
@@ -82,8 +83,7 @@ static VALUE complex_load(VALUE clas, VALUE args) {
82
83
  real_id = rb_intern("real");
83
84
  imag_id = rb_intern("imag");
84
85
  }
85
- return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)),
86
- rb_hash_aref(args, rb_id2str(imag_id)));
86
+ return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)), rb_hash_aref(args, rb_id2str(imag_id)));
87
87
  }
88
88
 
89
89
  static void time_dump(VALUE obj, int depth, Out out) {
@@ -246,8 +246,7 @@ static VALUE rational_load(VALUE clas, VALUE args) {
246
246
  numerator_id = rb_intern("numerator");
247
247
  denominator_id = rb_intern("denominator");
248
248
  }
249
- return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)),
250
- rb_hash_aref(args, rb_id2str(denominator_id)));
249
+ return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)), rb_hash_aref(args, rb_id2str(denominator_id)));
251
250
  }
252
251
 
253
252
  static VALUE regexp_load(VALUE clas, VALUE args) {
@@ -292,8 +291,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
292
291
  assure_size(out, depth * out->indent + 1);
293
292
  fill_indent(out, depth);
294
293
  } else {
295
- assure_size(out,
296
- depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
294
+ assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
297
295
  if (0 < out->opts->dump_opts.hash_size) {
298
296
  APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
299
297
  }
@@ -308,7 +306,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
308
306
  switch (rb_type(key)) {
309
307
  case T_STRING: oj_dump_str(key, 0, out, false); break;
310
308
  case T_SYMBOL: oj_dump_sym(key, 0, out, false); break;
311
- default: oj_dump_str(rb_funcall(key, oj_to_s_id, 0), 0, out, false); break;
309
+ default: oj_dump_str(oj_safe_string_convert(key), 0, out, false); break;
312
310
  }
313
311
  if (!out->opts->dump_opts.use) {
314
312
  *out->cur++ = ':';
@@ -352,9 +350,7 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
352
350
  assure_size(out, depth * out->indent + 2);
353
351
  fill_indent(out, depth);
354
352
  } else {
355
- assure_size(
356
- out,
357
- depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
353
+ assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
358
354
  if (0 < out->opts->dump_opts.hash_size) {
359
355
  APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
360
356
  }
@@ -372,10 +368,10 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
372
368
  }
373
369
 
374
370
  static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
375
- ID * idp;
376
- AttrGetFunc * fp;
371
+ ID *idp;
372
+ AttrGetFunc *fp;
377
373
  volatile VALUE v;
378
- const char * name;
374
+ const char *name;
379
375
  size_t size;
380
376
  int d2 = depth + 1;
381
377
 
@@ -384,7 +380,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
384
380
  if (NULL != out->opts->create_id && Yes == out->opts->create_ok) {
385
381
  const char *classname = rb_class2name(clas);
386
382
  int clen = (int)strlen(classname);
387
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
383
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
388
384
 
389
385
  size = d2 * out->indent + 10 + clen + out->opts->create_id_len + sep_len;
390
386
  assure_size(out, size);
@@ -442,7 +438,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
442
438
  ID i;
443
439
 
444
440
  if (sizeof(nbuf) <= nlen) {
445
- if (NULL == (n2 = strdup(name))) {
441
+ if (NULL == (n2 = OJ_STRDUP(name))) {
446
442
  rb_raise(rb_eNoMemError, "for attribute name.");
447
443
  }
448
444
  } else {
@@ -459,7 +455,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
459
455
  i = rb_intern(n);
460
456
  v = rb_funcall(v, i, 0);
461
457
  if (nbuf != n2) {
462
- free(n2);
458
+ OJ_FREE(n2);
463
459
  }
464
460
  }
465
461
  fill_indent(out, d2);
@@ -481,20 +477,16 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
481
477
  oj_dump_raw_json(obj, depth, out);
482
478
  } else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
483
479
  volatile VALUE rs;
484
- const char * s;
480
+ const char *s;
485
481
  int len;
486
482
 
487
- if (Yes == out->opts->trace) {
488
- oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
489
- }
483
+ TRACE(out->opts->trace, "to_json", obj, depth + 1, TraceRubyIn);
490
484
  if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
491
485
  rs = rb_funcall(obj, oj_to_json_id, 0);
492
486
  } else {
493
487
  rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
494
488
  }
495
- if (Yes == out->opts->trace) {
496
- oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
497
- }
489
+ TRACE(out->opts->trace, "to_json", obj, depth + 1, TraceRubyOut);
498
490
  s = RSTRING_PTR(rs);
499
491
  len = (int)RSTRING_LEN(rs);
500
492
 
@@ -504,9 +496,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
504
496
  } else if (Yes == out->opts->as_json && rb_respond_to(obj, oj_as_json_id)) {
505
497
  volatile VALUE aj;
506
498
 
507
- if (Yes == out->opts->trace) {
508
- oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
509
- }
499
+ TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyIn);
510
500
  // Some classes elect to not take an options argument so check the arity
511
501
  // of as_json.
512
502
  if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
@@ -514,18 +504,12 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
514
504
  } else {
515
505
  aj = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
516
506
  }
517
- if (Yes == out->opts->trace) {
518
- oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
519
- }
507
+ TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyOut);
520
508
  // Catch the obvious brain damaged recursive dumping.
521
509
  if (aj == obj) {
522
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
510
+ volatile VALUE rstr = oj_safe_string_convert(obj);
523
511
 
524
- oj_dump_cstr(RSTRING_PTR(rstr),
525
- (int)RSTRING_LEN(rstr),
526
- false,
527
- false,
528
- out);
512
+ oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), false, false, out);
529
513
  } else {
530
514
  oj_dump_custom_val(aj, depth, out, true);
531
515
  }
@@ -609,7 +593,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
609
593
  assure_size(out, 2);
610
594
  *out->cur++ = '{';
611
595
  if (Qundef != clas && NULL != out->opts->create_id && Yes == out->opts->create_ok) {
612
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
596
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
613
597
  const char *classname = rb_obj_classname(obj);
614
598
  size_t len = strlen(classname);
615
599
 
@@ -885,9 +869,7 @@ static DumpFunc custom_funcs[] = {
885
869
  void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
886
870
  int type = rb_type(obj);
887
871
 
888
- if (Yes == out->opts->trace) {
889
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
890
- }
872
+ TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
891
873
  if (MAX_DEPTH < depth) {
892
874
  rb_raise(rb_eNoMemError, "Too deeply nested.\n");
893
875
  }
@@ -896,27 +878,22 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
896
878
 
897
879
  if (NULL != f) {
898
880
  f(obj, depth, out, true);
899
- if (Yes == out->opts->trace) {
900
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
901
- }
881
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
902
882
  return;
903
883
  }
904
884
  }
905
885
  oj_dump_nil(Qnil, depth, out, false);
906
- if (Yes == out->opts->trace) {
907
- oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
908
- }
886
+ TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
909
887
  }
910
888
 
911
889
  ///// load functions /////
912
890
 
913
891
  static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
914
- const char * key = kval->key;
915
- int klen = kval->klen;
916
- Val parent = stack_peek(&pi->stack);
917
- volatile VALUE rkey = kval->key_val;
892
+ const char *key = kval->key;
893
+ int klen = kval->klen;
894
+ Val parent = stack_peek(&pi->stack);
918
895
 
919
- if (Qundef == rkey && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
896
+ if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
920
897
  *pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
921
898
  0 == strncmp(pi->options.create_id, key, klen)) {
922
899
  parent->clas = oj_name2class(pi, str, len, false, rb_eArgError);
@@ -928,16 +905,9 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
928
905
  }
929
906
  }
930
907
  } else {
931
- volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
932
- //volatile VALUE rstr = rb_utf8_str_new(str, len);
908
+ volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
909
+ volatile VALUE rkey = oj_calc_hash_key(pi, kval);
933
910
 
934
- if (Qundef == rkey) {
935
- if (Yes == pi->options.sym_key) {
936
- rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
937
- } else {
938
- rkey = rb_utf8_str_new(key, klen);
939
- }
940
- }
941
911
  if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
942
912
  VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
943
913
 
@@ -959,9 +929,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
959
929
  break;
960
930
  default: break;
961
931
  }
962
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
963
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
964
- }
932
+ TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rstr);
965
933
  }
966
934
  }
967
935
 
@@ -978,9 +946,7 @@ static void end_hash(struct _parseInfo *pi) {
978
946
  }
979
947
  parent->clas = Qundef;
980
948
  }
981
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
982
- oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
983
- }
949
+ TRACE_PARSE_HASH_END(pi->options.trace, pi);
984
950
  }
985
951
 
986
952
  static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
@@ -1008,20 +974,10 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1008
974
  // match the expected value.
1009
975
  parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
1010
976
  } else if (ni->has_exp) {
1011
- int64_t t = (int64_t)(ni->i + ni->exp);
1012
- struct _timeInfo ti;
1013
- VALUE args[8];
1014
-
1015
- sec_as_time(t, &ti);
1016
-
1017
- args[0] = LONG2NUM(ti.year);
1018
- args[1] = LONG2NUM(ti.mon);
1019
- args[2] = LONG2NUM(ti.day);
1020
- args[3] = LONG2NUM(ti.hour);
1021
- args[4] = LONG2NUM(ti.min);
1022
- args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
1023
- args[6] = LONG2NUM(ni->exp);
1024
- parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
977
+ struct timespec ts;
978
+ ts.tv_sec = ni->i;
979
+ ts.tv_nsec = nsec;
980
+ parent->val = rb_time_timespec_new(&ts, (int)ni->exp);
1025
981
  } else {
1026
982
  parent->val = rb_time_nano_new(ni->i, (long)nsec);
1027
983
  }
@@ -1032,9 +988,7 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1032
988
  break;
1033
989
  default: break;
1034
990
  }
1035
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
1036
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
1037
- }
991
+ TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
1038
992
  }
1039
993
 
1040
994
  static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
@@ -1045,9 +999,7 @@ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
1045
999
  case T_HASH: rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), value); break;
1046
1000
  default: break;
1047
1001
  }
1048
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
1049
- oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
1050
- }
1002
+ TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
1051
1003
  }
1052
1004
 
1053
1005
  static void array_append_num(ParseInfo pi, NumInfo ni) {
@@ -1055,9 +1007,7 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
1055
1007
  volatile VALUE rval = oj_num_as_value(ni);
1056
1008
 
1057
1009
  rb_ary_push(parent->val, rval);
1058
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
1059
- oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
1060
- }
1010
+ TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
1061
1011
  }
1062
1012
 
1063
1013
  static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
@@ -1072,9 +1022,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
1072
1022
  }
1073
1023
  }
1074
1024
  rb_ary_push(stack_peek(&pi->stack)->val, rstr);
1075
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
1076
- oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
1077
- }
1025
+ TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rstr);
1078
1026
  }
1079
1027
 
1080
1028
  void oj_set_custom_callbacks(ParseInfo pi) {
data/ext/oj/debug.c CHANGED
@@ -30,9 +30,7 @@ static void add_int(struct _ojParser *p) {
30
30
  switch (p->stack[p->depth]) {
31
31
  case TOP_FUN: printf("*** add_int %lld at top\n", (long long)p->num.fixnum); break;
32
32
  case ARRAY_FUN: printf("*** add_int %lld to array\n", (long long)p->num.fixnum); break;
33
- case OBJECT_FUN:
34
- printf("*** add_int %lld with '%s'\n", (long long)p->num.fixnum, buf_str(&p->key));
35
- break;
33
+ case OBJECT_FUN: printf("*** add_int %lld with '%s'\n", (long long)p->num.fixnum, buf_str(&p->key)); break;
36
34
  }
37
35
  }
38
36
 
@@ -48,9 +46,7 @@ static void add_big(struct _ojParser *p) {
48
46
  switch (p->stack[p->depth]) {
49
47
  case TOP_FUN: printf("*** add_big %s at top\n", buf_str(&p->buf)); break;
50
48
  case ARRAY_FUN: printf("*** add_big %s to array\n", buf_str(&p->buf)); break;
51
- case OBJECT_FUN:
52
- printf("*** add_big %s with '%s'\n", buf_str(&p->buf), buf_str(&p->key));
53
- break;
49
+ case OBJECT_FUN: printf("*** add_big %s with '%s'\n", buf_str(&p->buf), buf_str(&p->key)); break;
54
50
  }
55
51
  }
56
52
 
@@ -58,9 +54,7 @@ static void add_str(struct _ojParser *p) {
58
54
  switch (p->stack[p->depth]) {
59
55
  case TOP_FUN: printf("*** add_str '%s' at top\n", buf_str(&p->buf)); break;
60
56
  case ARRAY_FUN: printf("*** add_str '%s' to array\n", buf_str(&p->buf)); break;
61
- case OBJECT_FUN:
62
- printf("*** add_str '%s' with '%s'\n", buf_str(&p->buf), buf_str(&p->key));
63
- break;
57
+ case OBJECT_FUN: printf("*** add_str '%s' with '%s'\n", buf_str(&p->buf), buf_str(&p->key)); break;
64
58
  }
65
59
  }
66
60