oj 3.11.0 → 3.16.5

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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1421 -0
  3. data/README.md +20 -5
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +48 -38
  6. data/ext/oj/cache.c +329 -0
  7. data/ext/oj/cache.h +22 -0
  8. data/ext/oj/cache8.c +60 -62
  9. data/ext/oj/cache8.h +8 -7
  10. data/ext/oj/circarray.c +35 -35
  11. data/ext/oj/circarray.h +11 -9
  12. data/ext/oj/code.c +156 -174
  13. data/ext/oj/code.h +19 -18
  14. data/ext/oj/compat.c +140 -197
  15. data/ext/oj/custom.c +737 -879
  16. data/ext/oj/debug.c +126 -0
  17. data/ext/oj/dump.c +830 -835
  18. data/ext/oj/dump.h +65 -53
  19. data/ext/oj/dump_compat.c +566 -642
  20. data/ext/oj/dump_leaf.c +95 -182
  21. data/ext/oj/dump_object.c +518 -659
  22. data/ext/oj/dump_strict.c +301 -334
  23. data/ext/oj/encode.h +3 -4
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +27 -24
  26. data/ext/oj/err.h +38 -13
  27. data/ext/oj/extconf.rb +23 -7
  28. data/ext/oj/fast.c +1043 -1073
  29. data/ext/oj/intern.c +313 -0
  30. data/ext/oj/intern.h +22 -0
  31. data/ext/oj/mem.c +318 -0
  32. data/ext/oj/mem.h +53 -0
  33. data/ext/oj/mimic_json.c +449 -423
  34. data/ext/oj/object.c +530 -576
  35. data/ext/oj/odd.c +155 -138
  36. data/ext/oj/odd.h +24 -22
  37. data/ext/oj/oj.c +1331 -993
  38. data/ext/oj/oj.h +306 -292
  39. data/ext/oj/parse.c +934 -938
  40. data/ext/oj/parse.h +73 -70
  41. data/ext/oj/parser.c +1600 -0
  42. data/ext/oj/parser.h +101 -0
  43. data/ext/oj/rails.c +795 -845
  44. data/ext/oj/rails.h +7 -7
  45. data/ext/oj/reader.c +132 -140
  46. data/ext/oj/reader.h +67 -78
  47. data/ext/oj/resolve.c +40 -59
  48. data/ext/oj/resolve.h +3 -2
  49. data/ext/oj/rxclass.c +67 -67
  50. data/ext/oj/rxclass.h +11 -9
  51. data/ext/oj/saj.c +441 -480
  52. data/ext/oj/saj2.c +584 -0
  53. data/ext/oj/saj2.h +23 -0
  54. data/ext/oj/scp.c +78 -111
  55. data/ext/oj/sparse.c +726 -730
  56. data/ext/oj/stream_writer.c +146 -165
  57. data/ext/oj/strict.c +103 -123
  58. data/ext/oj/string_writer.c +241 -253
  59. data/ext/oj/trace.c +29 -33
  60. data/ext/oj/trace.h +41 -11
  61. data/ext/oj/usual.c +1218 -0
  62. data/ext/oj/usual.h +69 -0
  63. data/ext/oj/util.c +103 -103
  64. data/ext/oj/util.h +3 -2
  65. data/ext/oj/val_stack.c +60 -49
  66. data/ext/oj/val_stack.h +79 -85
  67. data/ext/oj/validate.c +46 -0
  68. data/ext/oj/wab.c +307 -350
  69. data/lib/oj/active_support_helper.rb +1 -3
  70. data/lib/oj/bag.rb +8 -1
  71. data/lib/oj/easy_hash.rb +9 -9
  72. data/lib/oj/error.rb +1 -2
  73. data/lib/oj/json.rb +162 -150
  74. data/lib/oj/mimic.rb +9 -19
  75. data/lib/oj/saj.rb +20 -6
  76. data/lib/oj/schandler.rb +5 -4
  77. data/lib/oj/state.rb +12 -8
  78. data/lib/oj/version.rb +1 -2
  79. data/lib/oj.rb +2 -0
  80. data/pages/Compatibility.md +1 -1
  81. data/pages/InstallOptions.md +20 -0
  82. data/pages/JsonGem.md +15 -0
  83. data/pages/Modes.md +8 -3
  84. data/pages/Options.md +43 -5
  85. data/pages/Parser.md +309 -0
  86. data/pages/Rails.md +14 -2
  87. data/test/_test_active.rb +8 -9
  88. data/test/_test_active_mimic.rb +7 -8
  89. data/test/_test_mimic_rails.rb +17 -20
  90. data/test/activerecord/result_test.rb +12 -8
  91. data/test/activesupport6/encoding_test.rb +63 -28
  92. data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
  93. data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
  94. data/test/{activesupport5 → activesupport7}/encoding_test.rb +86 -50
  95. data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
  96. data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
  97. data/test/files.rb +15 -15
  98. data/test/foo.rb +17 -43
  99. data/test/helper.rb +16 -3
  100. data/test/isolated/shared.rb +3 -2
  101. data/test/json_gem/json_addition_test.rb +2 -2
  102. data/test/json_gem/json_common_interface_test.rb +8 -6
  103. data/test/json_gem/json_encoding_test.rb +0 -0
  104. data/test/json_gem/json_ext_parser_test.rb +1 -0
  105. data/test/json_gem/json_fixtures_test.rb +3 -2
  106. data/test/json_gem/json_generator_test.rb +71 -41
  107. data/test/json_gem/json_generic_object_test.rb +11 -11
  108. data/test/json_gem/json_parser_test.rb +54 -47
  109. data/test/json_gem/json_string_matching_test.rb +9 -9
  110. data/test/json_gem/test_helper.rb +12 -0
  111. data/test/mem.rb +34 -0
  112. data/test/perf.rb +22 -27
  113. data/test/perf_compat.rb +31 -33
  114. data/test/perf_dump.rb +50 -0
  115. data/test/perf_fast.rb +80 -82
  116. data/test/perf_file.rb +27 -29
  117. data/test/perf_object.rb +65 -69
  118. data/test/perf_once.rb +59 -0
  119. data/test/perf_parser.rb +183 -0
  120. data/test/perf_saj.rb +46 -54
  121. data/test/perf_scp.rb +58 -69
  122. data/test/perf_simple.rb +41 -39
  123. data/test/perf_strict.rb +74 -82
  124. data/test/perf_wab.rb +67 -69
  125. data/test/prec.rb +5 -5
  126. data/test/sample/change.rb +0 -1
  127. data/test/sample/dir.rb +0 -1
  128. data/test/sample/doc.rb +0 -1
  129. data/test/sample/file.rb +0 -1
  130. data/test/sample/group.rb +0 -1
  131. data/test/sample/hasprops.rb +0 -1
  132. data/test/sample/layer.rb +0 -1
  133. data/test/sample/rect.rb +0 -1
  134. data/test/sample/shape.rb +0 -1
  135. data/test/sample/text.rb +0 -1
  136. data/test/sample.rb +16 -16
  137. data/test/sample_json.rb +8 -8
  138. data/test/test_compat.rb +97 -45
  139. data/test/test_custom.rb +73 -51
  140. data/test/test_debian.rb +7 -10
  141. data/test/test_fast.rb +135 -79
  142. data/test/test_file.rb +41 -30
  143. data/test/test_gc.rb +16 -5
  144. data/test/test_generate.rb +21 -0
  145. data/test/test_hash.rb +15 -5
  146. data/test/test_integer_range.rb +9 -9
  147. data/test/test_null.rb +20 -20
  148. data/test/test_object.rb +99 -96
  149. data/test/test_parser.rb +11 -0
  150. data/test/test_parser_debug.rb +27 -0
  151. data/test/test_parser_saj.rb +337 -0
  152. data/test/test_parser_usual.rb +251 -0
  153. data/test/test_rails.rb +2 -2
  154. data/test/test_saj.rb +10 -8
  155. data/test/test_scp.rb +38 -40
  156. data/test/test_strict.rb +40 -32
  157. data/test/test_various.rb +165 -84
  158. data/test/test_wab.rb +48 -44
  159. data/test/test_writer.rb +47 -47
  160. data/test/tests.rb +13 -5
  161. data/test/tests_mimic.rb +12 -3
  162. data/test/tests_mimic_addition.rb +12 -3
  163. metadata +75 -127
  164. data/ext/oj/hash.c +0 -135
  165. data/ext/oj/hash.h +0 -18
  166. data/ext/oj/hash_test.c +0 -484
  167. data/test/activesupport4/decoding_test.rb +0 -108
  168. data/test/activesupport4/encoding_test.rb +0 -531
  169. data/test/activesupport4/test_helper.rb +0 -41
  170. data/test/activesupport5/test_helper.rb +0 -72
  171. data/test/bar.rb +0 -35
  172. data/test/baz.rb +0 -16
  173. data/test/zoo.rb +0 -13
data/ext/oj/dump_strict.c CHANGED
@@ -1,431 +1,398 @@
1
1
  // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
2
3
 
3
- #include <stdlib.h>
4
- #include <time.h>
4
+ #include <errno.h>
5
+ #include <math.h>
5
6
  #include <stdio.h>
7
+ #include <stdlib.h>
6
8
  #include <string.h>
7
- #include <math.h>
9
+ #include <time.h>
8
10
  #include <unistd.h>
9
- #include <errno.h>
10
11
 
11
12
  #include "dump.h"
12
13
  #include "trace.h"
13
14
 
14
15
  // Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
15
- #define OJ_INFINITY (1.0/0.0)
16
+ #define OJ_INFINITY (1.0 / 0.0)
16
17
 
17
- typedef unsigned long ulong;
18
+ typedef unsigned long ulong;
18
19
 
19
- static const char inf_val[] = INF_VAL;
20
- static const char ninf_val[] = NINF_VAL;
21
- static const char nan_val[] = NAN_VAL;
20
+ static const char inf_val[] = INF_VAL;
21
+ static const char ninf_val[] = NINF_VAL;
22
+ static const char nan_val[] = NAN_VAL;
22
23
 
23
- static void
24
- raise_strict(VALUE obj) {
24
+ static void raise_strict(VALUE obj) {
25
25
  rb_raise(rb_eTypeError, "Failed to dump %s Object to JSON in strict mode.\n", rb_class2name(rb_obj_class(obj)));
26
26
  }
27
27
 
28
28
  // Removed dependencies on math due to problems with CentOS 5.4.
29
- static void
30
- dump_float(VALUE obj, int depth, Out out, bool as_ok) {
31
- char buf[64];
32
- char *b;
33
- double d = rb_num2dbl(obj);
34
- int cnt = 0;
29
+ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
30
+ char buf[64];
31
+ char* b;
32
+ double d = rb_num2dbl(obj);
33
+ int cnt = 0;
35
34
 
36
35
  if (0.0 == d) {
37
- b = buf;
38
- *b++ = '0';
39
- *b++ = '.';
40
- *b++ = '0';
41
- *b++ = '\0';
42
- cnt = 3;
36
+ b = buf;
37
+ *b++ = '0';
38
+ *b++ = '.';
39
+ *b++ = '0';
40
+ *b++ = '\0';
41
+ cnt = 3;
43
42
  } else {
44
- NanDump nd = out->opts->dump_opts.nan_dump;
45
-
46
- if (AutoNan == nd) {
47
- nd = RaiseNan;
48
- }
49
- if (OJ_INFINITY == d) {
50
- switch (nd) {
51
- case RaiseNan:
52
- case WordNan:
53
- raise_strict(obj);
54
- break;
55
- case NullNan:
56
- strcpy(buf, "null");
57
- cnt = 4;
58
- break;
59
- case HugeNan:
60
- default:
61
- strcpy(buf, inf_val);
62
- cnt = sizeof(inf_val) - 1;
63
- break;
64
- }
65
- } else if (-OJ_INFINITY == d) {
66
- switch (nd) {
67
- case RaiseNan:
68
- case WordNan:
69
- raise_strict(obj);
70
- break;
71
- case NullNan:
72
- strcpy(buf, "null");
73
- cnt = 4;
74
- break;
75
- case HugeNan:
76
- default:
77
- strcpy(buf, ninf_val);
78
- cnt = sizeof(ninf_val) - 1;
79
- break;
80
- }
81
- } else if (isnan(d)) {
82
- switch (nd) {
83
- case RaiseNan:
84
- case WordNan:
85
- raise_strict(obj);
86
- break;
87
- case NullNan:
88
- strcpy(buf, "null");
89
- cnt = 4;
90
- break;
91
- case HugeNan:
92
- default:
93
- strcpy(buf, nan_val);
94
- cnt = sizeof(nan_val) - 1;
95
- break;
96
- }
97
- } else if (d == (double)(long long int)d) {
98
- cnt = snprintf(buf, sizeof(buf), "%.1f", d);
99
- } else if (0 == out->opts->float_prec) {
100
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
101
-
102
- cnt = (int)RSTRING_LEN(rstr);
103
- if ((int)sizeof(buf) <= cnt) {
104
- cnt = sizeof(buf) - 1;
105
- }
106
- strncpy(buf, rb_string_value_ptr((VALUE*)&rstr), cnt);
107
- buf[cnt] = '\0';
108
- } else {
109
- cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
110
- }
43
+ NanDump nd = out->opts->dump_opts.nan_dump;
44
+
45
+ if (AutoNan == nd) {
46
+ nd = RaiseNan;
47
+ }
48
+ if (OJ_INFINITY == d) {
49
+ switch (nd) {
50
+ case RaiseNan:
51
+ case WordNan: raise_strict(obj); break;
52
+ case NullNan:
53
+ strcpy(buf, "null");
54
+ cnt = 4;
55
+ break;
56
+ case HugeNan:
57
+ default:
58
+ strcpy(buf, inf_val);
59
+ cnt = sizeof(inf_val) - 1;
60
+ break;
61
+ }
62
+ } else if (-OJ_INFINITY == d) {
63
+ switch (nd) {
64
+ case RaiseNan:
65
+ case WordNan: raise_strict(obj); break;
66
+ case NullNan:
67
+ strcpy(buf, "null");
68
+ cnt = 4;
69
+ break;
70
+ case HugeNan:
71
+ default:
72
+ strcpy(buf, ninf_val);
73
+ cnt = sizeof(ninf_val) - 1;
74
+ break;
75
+ }
76
+ } else if (isnan(d)) {
77
+ switch (nd) {
78
+ case RaiseNan:
79
+ case WordNan: raise_strict(obj); break;
80
+ case NullNan:
81
+ strcpy(buf, "null");
82
+ cnt = 4;
83
+ break;
84
+ case HugeNan:
85
+ default:
86
+ strcpy(buf, nan_val);
87
+ cnt = sizeof(nan_val) - 1;
88
+ break;
89
+ }
90
+ } else if (d == (double)(long long int)d) {
91
+ cnt = snprintf(buf, sizeof(buf), "%.1f", d);
92
+ } else if (0 == out->opts->float_prec) {
93
+ volatile VALUE rstr = oj_safe_string_convert(obj);
94
+
95
+ cnt = (int)RSTRING_LEN(rstr);
96
+ if ((int)sizeof(buf) <= cnt) {
97
+ cnt = sizeof(buf) - 1;
98
+ }
99
+ memcpy(buf, RSTRING_PTR(rstr), cnt);
100
+ buf[cnt] = '\0';
101
+ } else {
102
+ cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
103
+ }
111
104
  }
112
105
  assure_size(out, cnt);
113
- for (b = buf; '\0' != *b; b++) {
114
- *out->cur++ = *b;
115
- }
106
+ APPEND_CHARS(out->cur, buf, cnt);
116
107
  *out->cur = '\0';
117
108
  }
118
109
 
119
- static void
120
- dump_array(VALUE a, int depth, Out out, bool as_ok) {
121
- size_t size;
122
- int i, cnt;
123
- int d2 = depth + 1;
110
+ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
111
+ size_t size;
112
+ int i, cnt;
113
+ int d2 = depth + 1;
124
114
 
125
115
  if (Yes == out->opts->circular) {
126
- if (0 > oj_check_circular(a, out)) {
127
- oj_dump_nil(Qnil, 0, out, false);
128
- return;
129
- }
116
+ if (0 > oj_check_circular(a, out)) {
117
+ oj_dump_nil(Qnil, 0, out, false);
118
+ return;
119
+ }
130
120
  }
131
- cnt = (int)RARRAY_LEN(a);
121
+ cnt = (int)RARRAY_LEN(a);
132
122
  *out->cur++ = '[';
133
- size = 2;
123
+ size = 2;
134
124
  assure_size(out, size);
135
125
  if (0 == cnt) {
136
- *out->cur++ = ']';
126
+ *out->cur++ = ']';
137
127
  } else {
138
- if (out->opts->dump_opts.use) {
139
- size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
140
- } else {
141
- size = d2 * out->indent + 2;
142
- }
143
- cnt--;
144
- for (i = 0; i <= cnt; i++) {
145
- assure_size(out, size);
146
- if (out->opts->dump_opts.use) {
147
- if (0 < out->opts->dump_opts.array_size) {
148
- strcpy(out->cur, out->opts->dump_opts.array_nl);
149
- out->cur += out->opts->dump_opts.array_size;
150
- }
151
- if (0 < out->opts->dump_opts.indent_size) {
152
- int i;
153
- for (i = d2; 0 < i; i--) {
154
- strcpy(out->cur, out->opts->dump_opts.indent_str);
155
- out->cur += out->opts->dump_opts.indent_size;
156
- }
157
- }
158
- } else {
159
- fill_indent(out, d2);
160
- }
161
- if (NullMode == out->opts->mode) {
162
- oj_dump_null_val(rb_ary_entry(a, i), d2, out);
163
- } else {
164
- oj_dump_strict_val(rb_ary_entry(a, i), d2, out);
165
- }
166
- if (i < cnt) {
167
- *out->cur++ = ',';
168
- }
169
- }
170
- size = depth * out->indent + 1;
171
- assure_size(out, size);
172
- if (out->opts->dump_opts.use) {
173
- //printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size, out->opts->dump_opts->indent);
174
- if (0 < out->opts->dump_opts.array_size) {
175
- strcpy(out->cur, out->opts->dump_opts.array_nl);
176
- out->cur += out->opts->dump_opts.array_size;
177
- }
178
- if (0 < out->opts->dump_opts.indent_size) {
179
- int i;
180
-
181
- for (i = depth; 0 < i; i--) {
182
- strcpy(out->cur, out->opts->dump_opts.indent_str);
183
- out->cur += out->opts->dump_opts.indent_size;
184
- }
185
- }
186
- } else {
187
- fill_indent(out, depth);
188
- }
189
- *out->cur++ = ']';
128
+ if (out->opts->dump_opts.use) {
129
+ size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
130
+ } else {
131
+ size = d2 * out->indent + 2;
132
+ }
133
+ assure_size(out, size * cnt);
134
+ cnt--;
135
+ for (i = 0; i <= cnt; i++) {
136
+ if (out->opts->dump_opts.use) {
137
+ if (0 < out->opts->dump_opts.array_size) {
138
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
139
+ }
140
+ if (0 < out->opts->dump_opts.indent_size) {
141
+ int i;
142
+ for (i = d2; 0 < i; i--) {
143
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
144
+ }
145
+ }
146
+ } else {
147
+ fill_indent(out, d2);
148
+ }
149
+ if (NullMode == out->opts->mode) {
150
+ oj_dump_null_val(RARRAY_AREF(a, i), d2, out);
151
+ } else {
152
+ oj_dump_strict_val(RARRAY_AREF(a, i), d2, out);
153
+ }
154
+ if (i < cnt) {
155
+ *out->cur++ = ',';
156
+ }
157
+ }
158
+ size = depth * out->indent + 1;
159
+ assure_size(out, size);
160
+ if (out->opts->dump_opts.use) {
161
+ // printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size,
162
+ // out->opts->dump_opts->indent);
163
+ if (0 < out->opts->dump_opts.array_size) {
164
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
165
+ }
166
+ if (0 < out->opts->dump_opts.indent_size) {
167
+ int i;
168
+
169
+ for (i = depth; 0 < i; i--) {
170
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
171
+ }
172
+ }
173
+ } else {
174
+ fill_indent(out, depth);
175
+ }
176
+ *out->cur++ = ']';
190
177
  }
191
178
  *out->cur = '\0';
192
179
  }
193
180
 
194
- static int
195
- hash_cb(VALUE key, VALUE value, VALUE ov) {
196
- Out out = (Out)ov;
197
- int depth = out->depth;
198
- long size;
199
- int rtype = rb_type(key);
181
+ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
182
+ Out out = (Out)ov;
183
+ int depth = out->depth;
184
+ long size;
185
+ int rtype = rb_type(key);
200
186
 
201
187
  if (rtype != T_STRING && rtype != T_SYMBOL) {
202
- rb_raise(rb_eTypeError, "In :strict and :null mode all Hash keys must be Strings or Symbols, not %s.\n", rb_class2name(rb_obj_class(key)));
188
+ rb_raise(rb_eTypeError,
189
+ "In :strict and :null mode all Hash keys must be Strings or Symbols, not %s.\n",
190
+ rb_class2name(rb_obj_class(key)));
203
191
  }
204
192
  if (out->omit_nil && Qnil == value) {
205
- return ST_CONTINUE;
193
+ return ST_CONTINUE;
206
194
  }
207
195
  if (!out->opts->dump_opts.use) {
208
- size = depth * out->indent + 1;
209
- assure_size(out, size);
210
- fill_indent(out, depth);
211
- if (rtype == T_STRING) {
212
- oj_dump_str(key, 0, out, false);
213
- } else {
214
- oj_dump_sym(key, 0, out, false);
215
- }
216
- *out->cur++ = ':';
196
+ size = depth * out->indent + 1;
197
+ assure_size(out, size);
198
+ fill_indent(out, depth);
199
+ if (rtype == T_STRING) {
200
+ oj_dump_str(key, 0, out, false);
201
+ } else {
202
+ oj_dump_sym(key, 0, out, false);
203
+ }
204
+ *out->cur++ = ':';
217
205
  } else {
218
- size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
219
- assure_size(out, size);
220
- if (0 < out->opts->dump_opts.hash_size) {
221
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
222
- out->cur += out->opts->dump_opts.hash_size;
223
- }
224
- if (0 < out->opts->dump_opts.indent_size) {
225
- int i;
226
- for (i = depth; 0 < i; i--) {
227
- strcpy(out->cur, out->opts->dump_opts.indent_str);
228
- out->cur += out->opts->dump_opts.indent_size;
229
- }
230
- }
231
- if (rtype == T_STRING) {
232
- oj_dump_str(key, 0, out, false);
233
- } else {
234
- oj_dump_sym(key, 0, out, false);
235
- }
236
- size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
237
- assure_size(out, size);
238
- if (0 < out->opts->dump_opts.before_size) {
239
- strcpy(out->cur, out->opts->dump_opts.before_sep);
240
- out->cur += out->opts->dump_opts.before_size;
241
- }
242
- *out->cur++ = ':';
243
- if (0 < out->opts->dump_opts.after_size) {
244
- strcpy(out->cur, out->opts->dump_opts.after_sep);
245
- out->cur += out->opts->dump_opts.after_size;
246
- }
206
+ size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
207
+ assure_size(out, size);
208
+ if (0 < out->opts->dump_opts.hash_size) {
209
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
210
+ }
211
+ if (0 < out->opts->dump_opts.indent_size) {
212
+ int i;
213
+ for (i = depth; 0 < i; i--) {
214
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
215
+ }
216
+ }
217
+ if (rtype == T_STRING) {
218
+ oj_dump_str(key, 0, out, false);
219
+ } else {
220
+ oj_dump_sym(key, 0, out, false);
221
+ }
222
+ size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
223
+ assure_size(out, size);
224
+ if (0 < out->opts->dump_opts.before_size) {
225
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
226
+ }
227
+ *out->cur++ = ':';
228
+ if (0 < out->opts->dump_opts.after_size) {
229
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
230
+ }
247
231
  }
248
232
  if (NullMode == out->opts->mode) {
249
- oj_dump_null_val(value, depth, out);
233
+ oj_dump_null_val(value, depth, out);
250
234
  } else {
251
- oj_dump_strict_val(value, depth, out);
235
+ oj_dump_strict_val(value, depth, out);
252
236
  }
253
- out->depth = depth;
237
+ out->depth = depth;
254
238
  *out->cur++ = ',';
255
239
 
256
240
  return ST_CONTINUE;
257
241
  }
258
242
 
259
- static void
260
- dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
261
- int cnt;
262
- size_t size;
243
+ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
244
+ int cnt;
245
+ size_t size;
263
246
 
264
247
  if (Yes == out->opts->circular) {
265
- if (0 > oj_check_circular(obj, out)) {
266
- oj_dump_nil(Qnil, 0, out, false);
267
- return;
268
- }
248
+ if (0 > oj_check_circular(obj, out)) {
249
+ oj_dump_nil(Qnil, 0, out, false);
250
+ return;
251
+ }
269
252
  }
270
- cnt = (int)RHASH_SIZE(obj);
253
+ cnt = (int)RHASH_SIZE(obj);
271
254
  size = depth * out->indent + 2;
272
255
  assure_size(out, 2);
273
256
  *out->cur++ = '{';
274
257
  if (0 == cnt) {
275
- *out->cur++ = '}';
258
+ *out->cur++ = '}';
276
259
  } else {
277
- out->depth = depth + 1;
278
- rb_hash_foreach(obj, hash_cb, (VALUE)out);
279
- if (',' == *(out->cur - 1)) {
280
- out->cur--; // backup to overwrite last comma
281
- }
282
- if (!out->opts->dump_opts.use) {
283
- assure_size(out, size);
284
- fill_indent(out, depth);
285
- } else {
286
- size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
287
- assure_size(out, size);
288
- if (0 < out->opts->dump_opts.hash_size) {
289
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
290
- out->cur += out->opts->dump_opts.hash_size;
291
- }
292
- if (0 < out->opts->dump_opts.indent_size) {
293
- int i;
294
-
295
- for (i = depth; 0 < i; i--) {
296
- strcpy(out->cur, out->opts->dump_opts.indent_str);
297
- out->cur += out->opts->dump_opts.indent_size;
298
- }
299
- }
300
- }
301
- *out->cur++ = '}';
260
+ out->depth = depth + 1;
261
+ rb_hash_foreach(obj, hash_cb, (VALUE)out);
262
+ if (',' == *(out->cur - 1)) {
263
+ out->cur--; // backup to overwrite last comma
264
+ }
265
+ if (!out->opts->dump_opts.use) {
266
+ assure_size(out, size);
267
+ fill_indent(out, depth);
268
+ } else {
269
+ size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
270
+ assure_size(out, size);
271
+ if (0 < out->opts->dump_opts.hash_size) {
272
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
273
+ }
274
+ if (0 < out->opts->dump_opts.indent_size) {
275
+ int i;
276
+
277
+ for (i = depth; 0 < i; i--) {
278
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
279
+ }
280
+ }
281
+ }
282
+ *out->cur++ = '}';
302
283
  }
303
284
  *out->cur = '\0';
304
285
  }
305
286
 
306
- static void
307
- dump_data_strict(VALUE obj, int depth, Out out, bool as_ok) {
308
- VALUE clas = rb_obj_class(obj);
287
+ static void dump_data_strict(VALUE obj, int depth, Out out, bool as_ok) {
288
+ VALUE clas = rb_obj_class(obj);
309
289
 
310
290
  if (oj_bigdecimal_class == clas) {
311
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
291
+ volatile VALUE rstr = oj_safe_string_convert(obj);
312
292
 
313
- oj_dump_raw(rb_string_value_ptr((VALUE*)&rstr), (int)RSTRING_LEN(rstr), out);
293
+ oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
314
294
  } else {
315
- raise_strict(obj);
295
+ raise_strict(obj);
316
296
  }
317
297
  }
318
298
 
319
- static void
320
- dump_data_null(VALUE obj, int depth, Out out, bool as_ok) {
321
- VALUE clas = rb_obj_class(obj);
299
+ static void dump_data_null(VALUE obj, int depth, Out out, bool as_ok) {
300
+ VALUE clas = rb_obj_class(obj);
322
301
 
323
302
  if (oj_bigdecimal_class == clas) {
324
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
303
+ volatile VALUE rstr = oj_safe_string_convert(obj);
325
304
 
326
- oj_dump_raw(rb_string_value_ptr((VALUE*)&rstr), (int)RSTRING_LEN(rstr), out);
305
+ oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
327
306
  } else {
328
- oj_dump_nil(Qnil, depth, out, false);
307
+ oj_dump_nil(Qnil, depth, out, false);
329
308
  }
330
309
  }
331
310
 
332
- static DumpFunc strict_funcs[] = {
333
- NULL, // RUBY_T_NONE = 0x00,
334
- dump_data_strict, // RUBY_T_OBJECT = 0x01,
335
- NULL, // RUBY_T_CLASS = 0x02,
336
- NULL, // RUBY_T_MODULE = 0x03,
337
- dump_float, // RUBY_T_FLOAT = 0x04,
338
- oj_dump_str, // RUBY_T_STRING = 0x05,
339
- NULL, // RUBY_T_REGEXP = 0x06,
340
- dump_array, // RUBY_T_ARRAY = 0x07,
341
- dump_hash, // RUBY_T_HASH = 0x08,
342
- NULL, // RUBY_T_STRUCT = 0x09,
343
- oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
344
- NULL, // RUBY_T_FILE = 0x0b,
345
- dump_data_strict, // RUBY_T_DATA = 0x0c,
346
- NULL, // RUBY_T_MATCH = 0x0d,
347
- NULL, // RUBY_T_COMPLEX = 0x0e,
348
- NULL, // RUBY_T_RATIONAL = 0x0f,
349
- NULL, // 0x10
350
- oj_dump_nil, // RUBY_T_NIL = 0x11,
351
- oj_dump_true, // RUBY_T_TRUE = 0x12,
352
- oj_dump_false, // RUBY_T_FALSE = 0x13,
353
- oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
354
- oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
311
+ static DumpFunc strict_funcs[] = {
312
+ NULL, // RUBY_T_NONE = 0x00,
313
+ dump_data_strict, // RUBY_T_OBJECT = 0x01,
314
+ NULL, // RUBY_T_CLASS = 0x02,
315
+ NULL, // RUBY_T_MODULE = 0x03,
316
+ dump_float, // RUBY_T_FLOAT = 0x04,
317
+ oj_dump_str, // RUBY_T_STRING = 0x05,
318
+ NULL, // RUBY_T_REGEXP = 0x06,
319
+ dump_array, // RUBY_T_ARRAY = 0x07,
320
+ dump_hash, // RUBY_T_HASH = 0x08,
321
+ NULL, // RUBY_T_STRUCT = 0x09,
322
+ oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
323
+ NULL, // RUBY_T_FILE = 0x0b,
324
+ dump_data_strict, // RUBY_T_DATA = 0x0c,
325
+ NULL, // RUBY_T_MATCH = 0x0d,
326
+ NULL, // RUBY_T_COMPLEX = 0x0e,
327
+ NULL, // RUBY_T_RATIONAL = 0x0f,
328
+ NULL, // 0x10
329
+ oj_dump_nil, // RUBY_T_NIL = 0x11,
330
+ oj_dump_true, // RUBY_T_TRUE = 0x12,
331
+ oj_dump_false, // RUBY_T_FALSE = 0x13,
332
+ oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
333
+ oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
355
334
  };
356
335
 
357
- void
358
- oj_dump_strict_val(VALUE obj, int depth, Out out) {
359
- int type = rb_type(obj);
336
+ void oj_dump_strict_val(VALUE obj, int depth, Out out) {
337
+ int type = rb_type(obj);
360
338
 
361
- if (Yes == out->opts->trace) {
362
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
363
- }
339
+ TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
364
340
  if (MAX_DEPTH < depth) {
365
- rb_raise(rb_eNoMemError, "Too deeply nested.\n");
341
+ rb_raise(rb_eNoMemError, "Too deeply nested.\n");
366
342
  }
367
343
  if (0 < type && type <= RUBY_T_FIXNUM) {
368
- DumpFunc f = strict_funcs[type];
369
-
370
- if (NULL != f) {
371
- f(obj, depth, out, false);
372
- if (Yes == out->opts->trace) {
373
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
374
- }
375
- return;
376
- }
344
+ DumpFunc f = strict_funcs[type];
345
+
346
+ if (NULL != f) {
347
+ f(obj, depth, out, false);
348
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
349
+ return;
350
+ }
377
351
  }
378
352
  raise_strict(obj);
379
353
  }
380
354
 
381
- static DumpFunc null_funcs[] = {
382
- NULL, // RUBY_T_NONE = 0x00,
383
- dump_data_null, // RUBY_T_OBJECT = 0x01,
384
- NULL, // RUBY_T_CLASS = 0x02,
385
- NULL, // RUBY_T_MODULE = 0x03,
386
- dump_float, // RUBY_T_FLOAT = 0x04,
387
- oj_dump_str, // RUBY_T_STRING = 0x05,
388
- NULL, // RUBY_T_REGEXP = 0x06,
389
- dump_array, // RUBY_T_ARRAY = 0x07,
390
- dump_hash, // RUBY_T_HASH = 0x08,
391
- NULL, // RUBY_T_STRUCT = 0x09,
392
- oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
393
- NULL, // RUBY_T_FILE = 0x0b,
394
- dump_data_null, // RUBY_T_DATA = 0x0c,
395
- NULL, // RUBY_T_MATCH = 0x0d,
396
- NULL, // RUBY_T_COMPLEX = 0x0e,
397
- NULL, // RUBY_T_RATIONAL = 0x0f,
398
- NULL, // 0x10
399
- oj_dump_nil, // RUBY_T_NIL = 0x11,
400
- oj_dump_true, // RUBY_T_TRUE = 0x12,
401
- oj_dump_false, // RUBY_T_FALSE = 0x13,
402
- oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
403
- oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
355
+ static DumpFunc null_funcs[] = {
356
+ NULL, // RUBY_T_NONE = 0x00,
357
+ dump_data_null, // RUBY_T_OBJECT = 0x01,
358
+ NULL, // RUBY_T_CLASS = 0x02,
359
+ NULL, // RUBY_T_MODULE = 0x03,
360
+ dump_float, // RUBY_T_FLOAT = 0x04,
361
+ oj_dump_str, // RUBY_T_STRING = 0x05,
362
+ NULL, // RUBY_T_REGEXP = 0x06,
363
+ dump_array, // RUBY_T_ARRAY = 0x07,
364
+ dump_hash, // RUBY_T_HASH = 0x08,
365
+ NULL, // RUBY_T_STRUCT = 0x09,
366
+ oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
367
+ NULL, // RUBY_T_FILE = 0x0b,
368
+ dump_data_null, // RUBY_T_DATA = 0x0c,
369
+ NULL, // RUBY_T_MATCH = 0x0d,
370
+ NULL, // RUBY_T_COMPLEX = 0x0e,
371
+ NULL, // RUBY_T_RATIONAL = 0x0f,
372
+ NULL, // 0x10
373
+ oj_dump_nil, // RUBY_T_NIL = 0x11,
374
+ oj_dump_true, // RUBY_T_TRUE = 0x12,
375
+ oj_dump_false, // RUBY_T_FALSE = 0x13,
376
+ oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
377
+ oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
404
378
  };
405
379
 
406
- void
407
- oj_dump_null_val(VALUE obj, int depth, Out out) {
408
- int type = rb_type(obj);
380
+ void oj_dump_null_val(VALUE obj, int depth, Out out) {
381
+ int type = rb_type(obj);
409
382
 
410
- if (Yes == out->opts->trace) {
411
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
412
- }
383
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
413
384
  if (MAX_DEPTH < depth) {
414
- rb_raise(rb_eNoMemError, "Too deeply nested.\n");
385
+ rb_raise(rb_eNoMemError, "Too deeply nested.\n");
415
386
  }
416
387
  if (0 < type && type <= RUBY_T_FIXNUM) {
417
- DumpFunc f = null_funcs[type];
418
-
419
- if (NULL != f) {
420
- f(obj, depth, out, false);
421
- if (Yes == out->opts->trace) {
422
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
423
- }
424
- return;
425
- }
388
+ DumpFunc f = null_funcs[type];
389
+
390
+ if (NULL != f) {
391
+ f(obj, depth, out, false);
392
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
393
+ return;
394
+ }
426
395
  }
427
396
  oj_dump_nil(Qnil, depth, out, false);
428
- if (Yes == out->opts->trace) {
429
- oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
430
- }
397
+ TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
431
398
  }