oj 3.11.5 → 3.16.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1421 -0
  3. data/README.md +19 -5
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +20 -6
  6. data/ext/oj/cache.c +329 -0
  7. data/ext/oj/cache.h +22 -0
  8. data/ext/oj/cache8.c +10 -9
  9. data/ext/oj/circarray.c +8 -6
  10. data/ext/oj/circarray.h +2 -2
  11. data/ext/oj/code.c +19 -33
  12. data/ext/oj/code.h +2 -2
  13. data/ext/oj/compat.c +27 -77
  14. data/ext/oj/custom.c +86 -179
  15. data/ext/oj/debug.c +126 -0
  16. data/ext/oj/dump.c +256 -249
  17. data/ext/oj/dump.h +26 -12
  18. data/ext/oj/dump_compat.c +565 -642
  19. data/ext/oj/dump_leaf.c +17 -63
  20. data/ext/oj/dump_object.c +65 -187
  21. data/ext/oj/dump_strict.c +27 -51
  22. data/ext/oj/encoder.c +43 -0
  23. data/ext/oj/err.c +2 -13
  24. data/ext/oj/err.h +24 -8
  25. data/ext/oj/extconf.rb +21 -6
  26. data/ext/oj/fast.c +149 -149
  27. data/ext/oj/intern.c +313 -0
  28. data/ext/oj/intern.h +22 -0
  29. data/ext/oj/mem.c +318 -0
  30. data/ext/oj/mem.h +53 -0
  31. data/ext/oj/mimic_json.c +121 -106
  32. data/ext/oj/object.c +85 -162
  33. data/ext/oj/odd.c +89 -67
  34. data/ext/oj/odd.h +15 -15
  35. data/ext/oj/oj.c +542 -411
  36. data/ext/oj/oj.h +99 -73
  37. data/ext/oj/parse.c +175 -187
  38. data/ext/oj/parse.h +26 -24
  39. data/ext/oj/parser.c +1600 -0
  40. data/ext/oj/parser.h +101 -0
  41. data/ext/oj/rails.c +112 -159
  42. data/ext/oj/rails.h +1 -1
  43. data/ext/oj/reader.c +11 -14
  44. data/ext/oj/reader.h +4 -2
  45. data/ext/oj/resolve.c +5 -24
  46. data/ext/oj/rxclass.c +7 -6
  47. data/ext/oj/rxclass.h +1 -1
  48. data/ext/oj/saj.c +22 -33
  49. data/ext/oj/saj2.c +584 -0
  50. data/ext/oj/saj2.h +23 -0
  51. data/ext/oj/scp.c +5 -28
  52. data/ext/oj/sparse.c +28 -72
  53. data/ext/oj/stream_writer.c +50 -40
  54. data/ext/oj/strict.c +56 -61
  55. data/ext/oj/string_writer.c +72 -39
  56. data/ext/oj/trace.h +31 -4
  57. data/ext/oj/usual.c +1218 -0
  58. data/ext/oj/usual.h +69 -0
  59. data/ext/oj/util.h +1 -1
  60. data/ext/oj/val_stack.c +14 -3
  61. data/ext/oj/val_stack.h +8 -7
  62. data/ext/oj/validate.c +46 -0
  63. data/ext/oj/wab.c +63 -88
  64. data/lib/oj/active_support_helper.rb +1 -3
  65. data/lib/oj/bag.rb +7 -1
  66. data/lib/oj/easy_hash.rb +4 -5
  67. data/lib/oj/error.rb +1 -2
  68. data/lib/oj/json.rb +162 -150
  69. data/lib/oj/mimic.rb +9 -7
  70. data/lib/oj/saj.rb +20 -6
  71. data/lib/oj/schandler.rb +5 -4
  72. data/lib/oj/state.rb +12 -8
  73. data/lib/oj/version.rb +1 -2
  74. data/lib/oj.rb +2 -0
  75. data/pages/Compatibility.md +1 -1
  76. data/pages/InstallOptions.md +20 -0
  77. data/pages/JsonGem.md +15 -0
  78. data/pages/Modes.md +8 -3
  79. data/pages/Options.md +43 -5
  80. data/pages/Parser.md +309 -0
  81. data/pages/Rails.md +14 -2
  82. data/test/_test_active.rb +8 -9
  83. data/test/_test_active_mimic.rb +7 -8
  84. data/test/_test_mimic_rails.rb +17 -20
  85. data/test/activerecord/result_test.rb +5 -6
  86. data/test/activesupport6/encoding_test.rb +63 -28
  87. data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
  88. data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
  89. data/test/{activesupport5 → activesupport7}/encoding_test.rb +86 -50
  90. data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
  91. data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
  92. data/test/files.rb +15 -15
  93. data/test/foo.rb +16 -45
  94. data/test/helper.rb +11 -8
  95. data/test/isolated/shared.rb +3 -2
  96. data/test/json_gem/json_addition_test.rb +2 -2
  97. data/test/json_gem/json_common_interface_test.rb +8 -6
  98. data/test/json_gem/json_encoding_test.rb +0 -0
  99. data/test/json_gem/json_ext_parser_test.rb +1 -0
  100. data/test/json_gem/json_fixtures_test.rb +3 -2
  101. data/test/json_gem/json_generator_test.rb +56 -38
  102. data/test/json_gem/json_generic_object_test.rb +11 -11
  103. data/test/json_gem/json_parser_test.rb +54 -47
  104. data/test/json_gem/json_string_matching_test.rb +9 -9
  105. data/test/json_gem/test_helper.rb +7 -3
  106. data/test/mem.rb +34 -0
  107. data/test/perf.rb +22 -27
  108. data/test/perf_compat.rb +31 -33
  109. data/test/perf_dump.rb +50 -0
  110. data/test/perf_fast.rb +80 -82
  111. data/test/perf_file.rb +27 -29
  112. data/test/perf_object.rb +65 -69
  113. data/test/perf_once.rb +59 -0
  114. data/test/perf_parser.rb +183 -0
  115. data/test/perf_saj.rb +46 -54
  116. data/test/perf_scp.rb +58 -69
  117. data/test/perf_simple.rb +41 -39
  118. data/test/perf_strict.rb +74 -82
  119. data/test/perf_wab.rb +67 -69
  120. data/test/prec.rb +5 -5
  121. data/test/sample/change.rb +0 -1
  122. data/test/sample/dir.rb +0 -1
  123. data/test/sample/doc.rb +0 -1
  124. data/test/sample/file.rb +0 -1
  125. data/test/sample/group.rb +0 -1
  126. data/test/sample/hasprops.rb +0 -1
  127. data/test/sample/layer.rb +0 -1
  128. data/test/sample/rect.rb +0 -1
  129. data/test/sample/shape.rb +0 -1
  130. data/test/sample/text.rb +0 -1
  131. data/test/sample.rb +16 -16
  132. data/test/sample_json.rb +8 -8
  133. data/test/test_compat.rb +95 -43
  134. data/test/test_custom.rb +73 -51
  135. data/test/test_debian.rb +7 -10
  136. data/test/test_fast.rb +135 -79
  137. data/test/test_file.rb +41 -30
  138. data/test/test_gc.rb +16 -5
  139. data/test/test_generate.rb +5 -5
  140. data/test/test_hash.rb +5 -5
  141. data/test/test_integer_range.rb +9 -9
  142. data/test/test_null.rb +20 -20
  143. data/test/test_object.rb +99 -96
  144. data/test/test_parser.rb +11 -0
  145. data/test/test_parser_debug.rb +27 -0
  146. data/test/test_parser_saj.rb +337 -0
  147. data/test/test_parser_usual.rb +251 -0
  148. data/test/test_rails.rb +2 -2
  149. data/test/test_saj.rb +10 -8
  150. data/test/test_scp.rb +37 -39
  151. data/test/test_strict.rb +40 -32
  152. data/test/test_various.rb +165 -84
  153. data/test/test_wab.rb +48 -44
  154. data/test/test_writer.rb +47 -47
  155. data/test/tests.rb +13 -5
  156. data/test/tests_mimic.rb +12 -3
  157. data/test/tests_mimic_addition.rb +12 -3
  158. metadata +74 -128
  159. data/ext/oj/hash.c +0 -131
  160. data/ext/oj/hash.h +0 -19
  161. data/ext/oj/hash_test.c +0 -491
  162. data/test/activesupport4/decoding_test.rb +0 -108
  163. data/test/activesupport4/encoding_test.rb +0 -531
  164. data/test/activesupport4/test_helper.rb +0 -41
  165. data/test/activesupport5/test_helper.rb +0 -72
  166. data/test/bar.rb +0 -35
  167. data/test/baz.rb +0 -16
  168. data/test/zoo.rb +0 -13
data/ext/oj/dump_object.c CHANGED
@@ -2,6 +2,7 @@
2
2
  // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
3
 
4
4
  #include "dump.h"
5
+ #include "mem.h"
5
6
  #include "odd.h"
6
7
  #include "trace.h"
7
8
 
@@ -24,19 +25,14 @@ static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
24
25
 
25
26
  if (rb_cTime == clas) {
26
27
  assure_size(out, 6);
27
- *out->cur++ = '{';
28
- *out->cur++ = '"';
29
- *out->cur++ = '^';
30
- *out->cur++ = 't';
31
- *out->cur++ = '"';
32
- *out->cur++ = ':';
28
+ APPEND_CHARS(out->cur, "{\"^t\":", 6);
33
29
  dump_time(obj, out);
34
30
  *out->cur++ = '}';
35
31
  *out->cur = '\0';
36
32
  } else {
37
33
  if (oj_bigdecimal_class == clas) {
38
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
39
- const char * str = rb_string_value_ptr((VALUE *)&rstr);
34
+ volatile VALUE rstr = oj_safe_string_convert(obj);
35
+ const char *str = RSTRING_PTR(rstr);
40
36
  int len = (int)RSTRING_LEN(rstr);
41
37
 
42
38
  if (No != out->opts->bigdec_as_num) {
@@ -64,8 +60,8 @@ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
64
60
  VALUE clas = rb_obj_class(obj);
65
61
 
66
62
  if (oj_bigdecimal_class == clas) {
67
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
68
- const char * str = rb_string_value_ptr((VALUE *)&rstr);
63
+ volatile VALUE rstr = oj_safe_string_convert(obj);
64
+ const char *str = RSTRING_PTR(rstr);
69
65
  int len = (int)RSTRING_LEN(rstr);
70
66
 
71
67
  if (0 == strcasecmp("Infinity", str)) {
@@ -91,12 +87,7 @@ static void dump_class(VALUE obj, int depth, Out out, bool as_ok) {
91
87
  size_t len = strlen(s);
92
88
 
93
89
  assure_size(out, 6);
94
- *out->cur++ = '{';
95
- *out->cur++ = '"';
96
- *out->cur++ = '^';
97
- *out->cur++ = 'c';
98
- *out->cur++ = '"';
99
- *out->cur++ = ':';
90
+ APPEND_CHARS(out->cur, "{\"^c\":", 6);
100
91
  oj_dump_cstr(s, len, 0, 0, out);
101
92
  *out->cur++ = '}';
102
93
  *out->cur = '\0';
@@ -120,9 +111,7 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
120
111
  if (0 < id) {
121
112
  assure_size(out, d2 * out->indent + 16);
122
113
  fill_indent(out, d2);
123
- *out->cur++ = '"';
124
- *out->cur++ = '^';
125
- *out->cur++ = 'i';
114
+ APPEND_CHARS(out->cur, "\"^i", 3);
126
115
  dump_ulong(id, out);
127
116
  *out->cur++ = '"';
128
117
  }
@@ -139,25 +128,23 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
139
128
  } else {
140
129
  size = d2 * out->indent + 2;
141
130
  }
131
+ assure_size(out, size * cnt);
142
132
  cnt--;
143
133
  for (i = 0; i <= cnt; i++) {
144
- assure_size(out, size);
145
134
  if (out->opts->dump_opts.use) {
146
135
  if (0 < out->opts->dump_opts.array_size) {
147
- strcpy(out->cur, out->opts->dump_opts.array_nl);
148
- out->cur += out->opts->dump_opts.array_size;
136
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
149
137
  }
150
138
  if (0 < out->opts->dump_opts.indent_size) {
151
139
  int i;
152
140
  for (i = d2; 0 < i; i--) {
153
- strcpy(out->cur, out->opts->dump_opts.indent_str);
154
- out->cur += out->opts->dump_opts.indent_size;
141
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
155
142
  }
156
143
  }
157
144
  } else {
158
145
  fill_indent(out, d2);
159
146
  }
160
- oj_dump_obj_val(rb_ary_entry(a, i), d2, out);
147
+ oj_dump_obj_val(RARRAY_AREF(a, i), d2, out);
161
148
  if (i < cnt) {
162
149
  *out->cur++ = ',';
163
150
  }
@@ -168,15 +155,13 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
168
155
  // printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size,
169
156
  // out->opts->dump_opts->indent);
170
157
  if (0 < out->opts->dump_opts.array_size) {
171
- strcpy(out->cur, out->opts->dump_opts.array_nl);
172
- out->cur += out->opts->dump_opts.array_size;
158
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
173
159
  }
174
160
  if (0 < out->opts->dump_opts.indent_size) {
175
161
  int i;
176
162
 
177
163
  for (i = depth; 0 < i; i--) {
178
- strcpy(out->cur, out->opts->dump_opts.indent_str);
179
- out->cur += out->opts->dump_opts.indent_size;
164
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
180
165
  }
181
166
  }
182
167
  } else {
@@ -195,7 +180,7 @@ static void dump_str_class(VALUE obj, VALUE clas, int depth, Out out) {
195
180
  if (Qundef != clas && rb_cString != clas) {
196
181
  dump_obj_attrs(obj, clas, 0, depth, out);
197
182
  } else {
198
- const char *s = rb_string_value_ptr((VALUE *)&obj);
183
+ const char *s = RSTRING_PTR(obj);
199
184
  size_t len = (int)RSTRING_LEN(obj);
200
185
  char s1 = s[1];
201
186
 
@@ -208,9 +193,9 @@ static void dump_str(VALUE obj, int depth, Out out, bool as_ok) {
208
193
  }
209
194
 
210
195
  static void dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
211
- volatile VALUE s = rb_sym_to_s(obj);
196
+ volatile VALUE s = rb_sym2str(obj);
212
197
 
213
- oj_dump_cstr(rb_string_value_ptr((VALUE *)&s), (int)RSTRING_LEN(s), 1, 0, out);
198
+ oj_dump_cstr(RSTRING_PTR(s), (int)RSTRING_LEN(s), 1, 0, out);
214
199
  }
215
200
 
216
201
  static int hash_cb(VALUE key, VALUE value, VALUE ov) {
@@ -218,7 +203,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
218
203
  int depth = out->depth;
219
204
  long size = depth * out->indent + 1;
220
205
 
221
- if (oj_dump_ignore(out->opts, value)) {
206
+ if (dump_ignore(out->opts, value)) {
222
207
  return ST_CONTINUE;
223
208
  }
224
209
  if (out->omit_nil && Qnil == value) {
@@ -226,15 +211,20 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
226
211
  }
227
212
  assure_size(out, size);
228
213
  fill_indent(out, depth);
229
- if (rb_type(key) == T_STRING) {
214
+ switch (rb_type(key)) {
215
+ case T_STRING:
230
216
  dump_str_class(key, Qundef, depth, out);
231
217
  *out->cur++ = ':';
232
218
  oj_dump_obj_val(value, depth, out);
233
- } else if (rb_type(key) == T_SYMBOL) {
219
+ break;
220
+
221
+ case T_SYMBOL:
234
222
  dump_sym(key, 0, out, false);
235
223
  *out->cur++ = ':';
236
224
  oj_dump_obj_val(value, depth, out);
237
- } else {
225
+ break;
226
+
227
+ default: {
238
228
  int d2 = depth + 1;
239
229
  long s2 = size + out->indent + 1;
240
230
  int i;
@@ -242,9 +232,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
242
232
  uint8_t b;
243
233
 
244
234
  assure_size(out, s2 + 15);
245
- *out->cur++ = '"';
246
- *out->cur++ = '^';
247
- *out->cur++ = '#';
235
+ APPEND_CHARS(out->cur, "\"^#", 3);
248
236
  out->hash_cnt++;
249
237
  for (i = 28; 0 <= i; i -= 4) {
250
238
  b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
@@ -255,9 +243,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
255
243
  *out->cur++ = hex_chars[b];
256
244
  }
257
245
  }
258
- *out->cur++ = '"';
259
- *out->cur++ = ':';
260
- *out->cur++ = '[';
246
+ APPEND_CHARS(out->cur, "\":[", 3);
261
247
  fill_indent(out, d2);
262
248
  oj_dump_obj_val(key, d2, out);
263
249
  assure_size(out, s2);
@@ -268,6 +254,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
268
254
  fill_indent(out, depth);
269
255
  *out->cur++ = ']';
270
256
  }
257
+ }
271
258
  out->depth = depth;
272
259
  *out->cur++ = ',';
273
260
 
@@ -286,8 +273,7 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
286
273
  size = depth * out->indent + 2;
287
274
  assure_size(out, 2);
288
275
  if (0 == cnt) {
289
- *out->cur++ = '{';
290
- *out->cur++ = '}';
276
+ APPEND_CHARS(out->cur, "{}", 2);
291
277
  } else {
292
278
  long id = oj_check_circular(obj, out);
293
279
 
@@ -298,11 +284,7 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
298
284
  if (0 < id) {
299
285
  assure_size(out, size + 16);
300
286
  fill_indent(out, depth + 1);
301
- *out->cur++ = '"';
302
- *out->cur++ = '^';
303
- *out->cur++ = 'i';
304
- *out->cur++ = '"';
305
- *out->cur++ = ':';
287
+ APPEND_CHARS(out->cur, "\"^i\":", 5);
306
288
  dump_ulong(id, out);
307
289
  *out->cur++ = ',';
308
290
  }
@@ -318,15 +300,13 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
318
300
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
319
301
  assure_size(out, size);
320
302
  if (0 < out->opts->dump_opts.hash_size) {
321
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
322
- out->cur += out->opts->dump_opts.hash_size;
303
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
323
304
  }
324
305
  if (0 < out->opts->dump_opts.indent_size) {
325
306
  int i;
326
307
 
327
308
  for (i = depth; 0 < i; i--) {
328
- strcpy(out->cur, out->opts->dump_opts.indent_str);
329
- out->cur += out->opts->dump_opts.indent_size;
309
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
330
310
  }
331
311
  }
332
312
  }
@@ -335,14 +315,13 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
335
315
  *out->cur = '\0';
336
316
  }
337
317
 
338
- #ifdef HAVE_RB_IVAR_FOREACH
339
318
  static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
340
319
  Out out = (Out)ov;
341
320
  int depth = out->depth;
342
321
  size_t size = depth * out->indent + 1;
343
322
  const char *attr = rb_id2name(key);
344
323
 
345
- if (oj_dump_ignore(out->opts, value)) {
324
+ if (dump_ignore(out->opts, value)) {
346
325
  return ST_CONTINUE;
347
326
  }
348
327
  if (out->omit_nil && Qnil == value) {
@@ -378,17 +357,16 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
378
357
 
379
358
  return ST_CONTINUE;
380
359
  }
381
- #endif
382
360
 
383
361
  static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
384
362
  dump_hash_class(obj, rb_obj_class(obj), depth, out);
385
363
  }
386
364
 
387
365
  static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
388
- ID * idp;
389
- AttrGetFunc * fp;
366
+ ID *idp;
367
+ AttrGetFunc *fp;
390
368
  volatile VALUE v;
391
- const char * name;
369
+ const char *name;
392
370
  size_t size;
393
371
  int d2 = depth + 1;
394
372
 
@@ -401,11 +379,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
401
379
  size = d2 * out->indent + clen + 10;
402
380
  assure_size(out, size);
403
381
  fill_indent(out, d2);
404
- *out->cur++ = '"';
405
- *out->cur++ = '^';
406
- *out->cur++ = 'O';
407
- *out->cur++ = '"';
408
- *out->cur++ = ':';
382
+ APPEND_CHARS(out->cur, "\"^O\":", 5);
409
383
  oj_dump_cstr(class_name, clen, 0, 0, out);
410
384
  *out->cur++ = ',';
411
385
  }
@@ -414,7 +388,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
414
388
  if (Qundef == v || T_STRING != rb_type(v)) {
415
389
  rb_raise(rb_eEncodingError, "Invalid type for raw JSON.");
416
390
  } else {
417
- const char *s = rb_string_value_ptr((VALUE *)&v);
391
+ const char *s = RSTRING_PTR(v);
418
392
  int len = (int)RSTRING_LEN(v);
419
393
  const char *name = rb_id2name(*odd->attrs);
420
394
  size_t nlen = strlen(name);
@@ -423,12 +397,9 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
423
397
  assure_size(out, size);
424
398
  fill_indent(out, d2);
425
399
  *out->cur++ = '"';
426
- memcpy(out->cur, name, nlen);
427
- out->cur += nlen;
428
- *out->cur++ = '"';
429
- *out->cur++ = ':';
430
- memcpy(out->cur, s, len);
431
- out->cur += len;
400
+ APPEND_CHARS(out->cur, name, nlen);
401
+ APPEND_CHARS(out->cur, "\":", 2);
402
+ APPEND_CHARS(out->cur, s, len);
432
403
  *out->cur = '\0';
433
404
  }
434
405
  } else {
@@ -439,7 +410,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
439
410
  assure_size(out, size);
440
411
  name = rb_id2name(*idp);
441
412
  nlen = strlen(name);
442
- if (0 != *fp) {
413
+ if (NULL != *fp) {
443
414
  v = (*fp)(obj);
444
415
  } else if (0 == strchr(name, '.')) {
445
416
  v = rb_funcall(obj, *idp, 0);
@@ -451,7 +422,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
451
422
  ID i;
452
423
 
453
424
  if (sizeof(nbuf) <= nlen) {
454
- if (NULL == (n2 = strdup(name))) {
425
+ if (NULL == (n2 = OJ_STRDUP(name))) {
455
426
  rb_raise(rb_eNoMemError, "for attribute name.");
456
427
  }
457
428
  } else {
@@ -468,7 +439,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
468
439
  i = rb_intern(n);
469
440
  v = rb_funcall(v, i, 0);
470
441
  if (nbuf != n2) {
471
- free(n2);
442
+ OJ_FREE(n2);
472
443
  }
473
444
  }
474
445
  fill_indent(out, d2);
@@ -502,22 +473,14 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
502
473
 
503
474
  assure_size(out, d2 * out->indent + clen + 10);
504
475
  fill_indent(out, d2);
505
- *out->cur++ = '"';
506
- *out->cur++ = '^';
507
- *out->cur++ = 'o';
508
- *out->cur++ = '"';
509
- *out->cur++ = ':';
476
+ APPEND_CHARS(out->cur, "\"^o\":", 5);
510
477
  oj_dump_cstr(class_name, clen, 0, 0, out);
511
478
  }
512
479
  if (0 < id) {
513
480
  assure_size(out, d2 * out->indent + 16);
514
481
  *out->cur++ = ',';
515
482
  fill_indent(out, d2);
516
- *out->cur++ = '"';
517
- *out->cur++ = '^';
518
- *out->cur++ = 'i';
519
- *out->cur++ = '"';
520
- *out->cur++ = ':';
483
+ APPEND_CHARS(out->cur, "\"^i\":", 5);
521
484
  dump_ulong(id, out);
522
485
  }
523
486
  switch (type) {
@@ -525,57 +488,28 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
525
488
  assure_size(out, d2 * out->indent + 14);
526
489
  *out->cur++ = ',';
527
490
  fill_indent(out, d2);
528
- *out->cur++ = '"';
529
- *out->cur++ = 's';
530
- *out->cur++ = 'e';
531
- *out->cur++ = 'l';
532
- *out->cur++ = 'f';
533
- *out->cur++ = '"';
534
- *out->cur++ = ':';
535
- oj_dump_cstr(rb_string_value_ptr((VALUE *)&obj), (int)RSTRING_LEN(obj), 0, 0, out);
491
+ APPEND_CHARS(out->cur, "\"self\":", 7);
492
+ oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
536
493
  break;
537
494
  case T_ARRAY:
538
495
  assure_size(out, d2 * out->indent + 14);
539
496
  *out->cur++ = ',';
540
497
  fill_indent(out, d2);
541
- *out->cur++ = '"';
542
- *out->cur++ = 's';
543
- *out->cur++ = 'e';
544
- *out->cur++ = 'l';
545
- *out->cur++ = 'f';
546
- *out->cur++ = '"';
547
- *out->cur++ = ':';
498
+ APPEND_CHARS(out->cur, "\"self\":", 7);
548
499
  dump_array_class(obj, Qundef, depth + 1, out);
549
500
  break;
550
501
  case T_HASH:
551
502
  assure_size(out, d2 * out->indent + 14);
552
503
  *out->cur++ = ',';
553
504
  fill_indent(out, d2);
554
- *out->cur++ = '"';
555
- *out->cur++ = 's';
556
- *out->cur++ = 'e';
557
- *out->cur++ = 'l';
558
- *out->cur++ = 'f';
559
- *out->cur++ = '"';
560
- *out->cur++ = ':';
505
+ APPEND_CHARS(out->cur, "\"self\":", 7);
561
506
  dump_hash_class(obj, Qundef, depth + 1, out);
562
507
  break;
563
508
  default: break;
564
509
  }
565
510
  {
566
- int cnt;
567
- #ifdef HAVE_RB_IVAR_COUNT
568
- cnt = (int)rb_ivar_count(obj);
569
- #else
570
- volatile VALUE vars = rb_funcall2(obj, oj_instance_variables_id, 0, 0);
571
- VALUE * np = RARRAY_PTR(vars);
572
- ID vid;
573
- const char * attr;
574
- int i;
575
- int first = 1;
576
-
577
- cnt = (int)RARRAY_LEN(vars);
578
- #endif
511
+ int cnt = (int)rb_ivar_count(obj);
512
+
579
513
  if (Qundef != clas && 0 < cnt) {
580
514
  *out->cur++ = ',';
581
515
  }
@@ -588,52 +522,10 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
588
522
  }
589
523
  }
590
524
  out->depth = depth + 1;
591
- #ifdef HAVE_RB_IVAR_FOREACH
592
525
  rb_ivar_foreach(obj, dump_attr_cb, (VALUE)out);
593
526
  if (',' == *(out->cur - 1)) {
594
527
  out->cur--; // backup to overwrite last comma
595
528
  }
596
- #else
597
- size = d2 * out->indent + 1;
598
- for (i = cnt; 0 < i; i--, np++) {
599
- VALUE value;
600
-
601
- vid = rb_to_id(*np);
602
- attr = rb_id2name(vid);
603
- if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
604
- continue;
605
- }
606
- value = rb_ivar_get(obj, vid);
607
-
608
- if (oj_dump_ignore(out->opts, value)) {
609
- continue;
610
- }
611
- if (out->omit_nil && Qnil == value) {
612
- continue;
613
- }
614
- if (first) {
615
- first = 0;
616
- } else {
617
- *out->cur++ = ',';
618
- }
619
- assure_size(out, size);
620
- fill_indent(out, d2);
621
- if ('@' == *attr) {
622
- attr++;
623
- oj_dump_cstr(attr, strlen(attr), 0, 0, out);
624
- } else {
625
- char buf[32];
626
-
627
- *buf = '~';
628
- strncpy(buf + 1, attr, sizeof(buf) - 2);
629
- buf[sizeof(buf) - 1] = '\0';
630
- oj_dump_cstr(buf, strlen(attr) + 1, 0, 0, out);
631
- }
632
- *out->cur++ = ':';
633
- oj_dump_obj_val(value, d2, out);
634
- assure_size(out, 2);
635
- }
636
- #endif
637
529
  if (rb_obj_is_kind_of(obj, rb_eException)) {
638
530
  volatile VALUE rv;
639
531
 
@@ -681,12 +573,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
681
573
  assure_size(out, size);
682
574
  *out->cur++ = '{';
683
575
  fill_indent(out, d2);
684
- *out->cur++ = '"';
685
- *out->cur++ = '^';
686
- *out->cur++ = 'u';
687
- *out->cur++ = '"';
688
- *out->cur++ = ':';
689
- *out->cur++ = '[';
576
+ APPEND_CHARS(out->cur, "\"^u\":[", 6);
690
577
  if ('#' == *class_name) {
691
578
  VALUE ma = rb_struct_s_members(clas);
692
579
  const char *name;
@@ -694,9 +581,9 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
694
581
 
695
582
  *out->cur++ = '[';
696
583
  for (i = 0; i < cnt; i++) {
697
- volatile VALUE s = rb_sym_to_s(rb_ary_entry(ma, i));
584
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
698
585
 
699
- name = rb_string_value_ptr((VALUE *)&s);
586
+ name = RSTRING_PTR(s);
700
587
  len = (int)RSTRING_LEN(s);
701
588
  size = len + 3;
702
589
  assure_size(out, size);
@@ -704,16 +591,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
704
591
  *out->cur++ = ',';
705
592
  }
706
593
  *out->cur++ = '"';
707
- memcpy(out->cur, name, len);
708
- out->cur += len;
594
+ APPEND_CHARS(out->cur, name, len);
709
595
  *out->cur++ = '"';
710
596
  }
711
597
  *out->cur++ = ']';
712
598
  } else {
713
599
  fill_indent(out, d3);
714
600
  *out->cur++ = '"';
715
- memcpy(out->cur, class_name, len);
716
- out->cur += len;
601
+ APPEND_CHARS(out->cur, class_name, len);
717
602
  *out->cur++ = '"';
718
603
  }
719
604
  *out->cur++ = ',';
@@ -730,7 +615,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
730
615
 
731
616
  for (i = 0; i < cnt; i++) {
732
617
  v = RSTRUCT_GET(obj, i);
733
- if (oj_dump_ignore(out->opts, v)) {
618
+ if (dump_ignore(out->opts, v)) {
734
619
  v = Qnil;
735
620
  }
736
621
  assure_size(out, size);
@@ -748,7 +633,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
748
633
  for (i = 0; i < slen; i++) {
749
634
  assure_size(out, size);
750
635
  fill_indent(out, d3);
751
- if (oj_dump_ignore(out->opts, v)) {
636
+ if (dump_ignore(out->opts, v)) {
752
637
  v = Qnil;
753
638
  }
754
639
  oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
@@ -757,9 +642,8 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
757
642
  }
758
643
  #endif
759
644
  out->cur--;
760
- *out->cur++ = ']';
761
- *out->cur++ = '}';
762
- *out->cur = '\0';
645
+ APPEND_CHARS(out->cur, "]}", 2);
646
+ *out->cur = '\0';
763
647
  }
764
648
 
765
649
  static void dump_complex(VALUE obj, int depth, Out out, bool as_ok) {
@@ -798,9 +682,7 @@ static DumpFunc obj_funcs[] = {
798
682
  void oj_dump_obj_val(VALUE obj, int depth, Out out) {
799
683
  int type = rb_type(obj);
800
684
 
801
- if (Yes == out->opts->trace) {
802
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
803
- }
685
+ TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
804
686
  if (MAX_DEPTH < depth) {
805
687
  rb_raise(rb_eNoMemError, "Too deeply nested.\n");
806
688
  }
@@ -809,14 +691,10 @@ void oj_dump_obj_val(VALUE obj, int depth, Out out) {
809
691
 
810
692
  if (NULL != f) {
811
693
  f(obj, depth, out, false);
812
- if (Yes == out->opts->trace) {
813
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
814
- }
694
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
815
695
  return;
816
696
  }
817
697
  }
818
698
  oj_dump_nil(Qnil, depth, out, false);
819
- if (Yes == out->opts->trace) {
820
- oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
821
- }
699
+ TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
822
700
  }