oj 3.13.11 → 3.15.0

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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +74 -0
  3. data/README.md +4 -2
  4. data/ext/oj/buf.h +11 -6
  5. data/ext/oj/cache.c +25 -24
  6. data/ext/oj/cache8.c +10 -9
  7. data/ext/oj/circarray.c +8 -6
  8. data/ext/oj/circarray.h +2 -2
  9. data/ext/oj/code.c +17 -24
  10. data/ext/oj/code.h +2 -2
  11. data/ext/oj/compat.c +17 -44
  12. data/ext/oj/custom.c +70 -141
  13. data/ext/oj/debug.c +3 -9
  14. data/ext/oj/dump.c +128 -118
  15. data/ext/oj/dump.h +12 -8
  16. data/ext/oj/dump_compat.c +564 -641
  17. data/ext/oj/dump_leaf.c +17 -63
  18. data/ext/oj/dump_object.c +70 -199
  19. data/ext/oj/dump_strict.c +22 -46
  20. data/ext/oj/encoder.c +1 -1
  21. data/ext/oj/err.c +2 -13
  22. data/ext/oj/err.h +9 -12
  23. data/ext/oj/extconf.rb +14 -5
  24. data/ext/oj/fast.c +75 -103
  25. data/ext/oj/intern.c +52 -50
  26. data/ext/oj/intern.h +4 -8
  27. data/ext/oj/mem.c +318 -0
  28. data/ext/oj/mem.h +53 -0
  29. data/ext/oj/mimic_json.c +75 -47
  30. data/ext/oj/object.c +49 -66
  31. data/ext/oj/odd.c +89 -67
  32. data/ext/oj/odd.h +15 -15
  33. data/ext/oj/oj.c +140 -99
  34. data/ext/oj/oj.h +80 -51
  35. data/ext/oj/parse.c +162 -184
  36. data/ext/oj/parse.h +7 -10
  37. data/ext/oj/parser.c +89 -34
  38. data/ext/oj/parser.h +18 -7
  39. data/ext/oj/rails.c +82 -146
  40. data/ext/oj/rails.h +1 -1
  41. data/ext/oj/reader.c +11 -12
  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 +20 -31
  47. data/ext/oj/saj2.c +329 -93
  48. data/ext/oj/saj2.h +23 -0
  49. data/ext/oj/scp.c +3 -14
  50. data/ext/oj/sparse.c +26 -70
  51. data/ext/oj/stream_writer.c +12 -22
  52. data/ext/oj/strict.c +20 -52
  53. data/ext/oj/string_writer.c +21 -21
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +105 -150
  56. data/ext/oj/usual.h +68 -0
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +1 -1
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/validate.c +21 -26
  61. data/ext/oj/wab.c +31 -68
  62. data/lib/oj/active_support_helper.rb +0 -1
  63. data/lib/oj/bag.rb +7 -1
  64. data/lib/oj/easy_hash.rb +4 -5
  65. data/lib/oj/error.rb +0 -1
  66. data/lib/oj/json.rb +4 -2
  67. data/lib/oj/mimic.rb +4 -2
  68. data/lib/oj/saj.rb +20 -6
  69. data/lib/oj/state.rb +9 -6
  70. data/lib/oj/version.rb +1 -2
  71. data/lib/oj.rb +2 -0
  72. data/pages/Compatibility.md +1 -1
  73. data/pages/InstallOptions.md +20 -0
  74. data/pages/Options.md +10 -0
  75. data/test/_test_active.rb +8 -9
  76. data/test/_test_active_mimic.rb +7 -8
  77. data/test/_test_mimic_rails.rb +17 -20
  78. data/test/activerecord/result_test.rb +5 -6
  79. data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
  80. data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
  81. data/test/{activesupport5 → activesupport7}/encoding_test.rb +20 -34
  82. data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
  83. data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
  84. data/test/files.rb +15 -15
  85. data/test/foo.rb +9 -71
  86. data/test/helper.rb +11 -8
  87. data/test/isolated/shared.rb +3 -2
  88. data/test/json_gem/json_addition_test.rb +2 -2
  89. data/test/json_gem/json_common_interface_test.rb +4 -4
  90. data/test/json_gem/json_encoding_test.rb +0 -0
  91. data/test/json_gem/json_ext_parser_test.rb +1 -0
  92. data/test/json_gem/json_fixtures_test.rb +3 -2
  93. data/test/json_gem/json_generator_test.rb +48 -36
  94. data/test/json_gem/json_generic_object_test.rb +11 -11
  95. data/test/json_gem/json_parser_test.rb +54 -47
  96. data/test/json_gem/json_string_matching_test.rb +9 -9
  97. data/test/json_gem/test_helper.rb +7 -3
  98. data/test/mem.rb +13 -12
  99. data/test/perf.rb +21 -26
  100. data/test/perf_compat.rb +31 -33
  101. data/test/perf_dump.rb +50 -0
  102. data/test/perf_fast.rb +80 -82
  103. data/test/perf_file.rb +27 -29
  104. data/test/perf_object.rb +65 -69
  105. data/test/perf_once.rb +12 -11
  106. data/test/perf_parser.rb +42 -48
  107. data/test/perf_saj.rb +46 -54
  108. data/test/perf_scp.rb +57 -69
  109. data/test/perf_simple.rb +41 -39
  110. data/test/perf_strict.rb +68 -70
  111. data/test/perf_wab.rb +67 -69
  112. data/test/prec.rb +3 -3
  113. data/test/sample/change.rb +0 -1
  114. data/test/sample/dir.rb +0 -1
  115. data/test/sample/doc.rb +0 -1
  116. data/test/sample/file.rb +0 -1
  117. data/test/sample/group.rb +0 -1
  118. data/test/sample/hasprops.rb +0 -1
  119. data/test/sample/layer.rb +0 -1
  120. data/test/sample/rect.rb +0 -1
  121. data/test/sample/shape.rb +0 -1
  122. data/test/sample/text.rb +0 -1
  123. data/test/sample.rb +16 -16
  124. data/test/sample_json.rb +8 -8
  125. data/test/test_compat.rb +76 -42
  126. data/test/test_custom.rb +72 -51
  127. data/test/test_debian.rb +7 -10
  128. data/test/test_fast.rb +86 -90
  129. data/test/test_file.rb +41 -30
  130. data/test/test_gc.rb +16 -5
  131. data/test/test_generate.rb +5 -5
  132. data/test/test_hash.rb +4 -4
  133. data/test/test_integer_range.rb +9 -9
  134. data/test/test_null.rb +20 -20
  135. data/test/test_object.rb +85 -96
  136. data/test/test_parser.rb +6 -22
  137. data/test/test_parser_debug.rb +27 -0
  138. data/test/test_parser_saj.rb +115 -23
  139. data/test/test_parser_usual.rb +6 -6
  140. data/test/test_rails.rb +2 -2
  141. data/test/test_saj.rb +10 -8
  142. data/test/test_scp.rb +37 -39
  143. data/test/test_strict.rb +30 -32
  144. data/test/test_various.rb +147 -99
  145. data/test/test_wab.rb +48 -44
  146. data/test/test_writer.rb +47 -47
  147. data/test/tests.rb +13 -4
  148. data/test/tests_mimic.rb +12 -3
  149. data/test/tests_mimic_addition.rb +12 -3
  150. metadata +33 -144
  151. data/test/activesupport4/decoding_test.rb +0 -108
  152. data/test/activesupport4/encoding_test.rb +0 -531
  153. data/test/activesupport4/test_helper.rb +0 -41
  154. data/test/activesupport5/test_helper.rb +0 -72
  155. data/test/bar.rb +0 -16
  156. data/test/baz.rb +0 -16
  157. data/test/bug.rb +0 -16
  158. data/test/zoo.rb +0 -13
data/ext/oj/dump_compat.c CHANGED
@@ -7,242 +7,219 @@
7
7
  #include "trace.h"
8
8
 
9
9
  // Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
10
- #define OJ_INFINITY (1.0/0.0)
10
+ #define OJ_INFINITY (1.0 / 0.0)
11
11
 
12
- bool oj_use_hash_alt = false;
13
- bool oj_use_array_alt = false;
12
+ bool oj_use_hash_alt = false;
13
+ bool oj_use_array_alt = false;
14
14
 
15
- static bool use_struct_alt = false;
16
- static bool use_exception_alt = false;
17
- static bool use_bignum_alt = false;
15
+ static bool use_struct_alt = false;
16
+ static bool use_exception_alt = false;
17
+ static bool use_bignum_alt = false;
18
18
 
19
- static void
20
- raise_json_err(const char *msg, const char *err_classname) {
19
+ static void raise_json_err(const char *msg, const char *err_classname) {
21
20
  rb_raise(oj_get_json_err_class(err_classname), "%s", msg);
22
21
  }
23
22
 
24
- static void
25
- dump_obj_classname(const char *classname, int depth, Out out) {
26
- int d2 = depth + 1;
27
- size_t len = strlen(classname);
28
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
29
- size_t size = d2 * out->indent + 10 + len + out->opts->create_id_len + sep_len;
23
+ static void dump_obj_classname(const char *classname, int depth, Out out) {
24
+ int d2 = depth + 1;
25
+ size_t len = strlen(classname);
26
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
27
+ size_t size = d2 * out->indent + 10 + len + out->opts->create_id_len + sep_len;
30
28
 
31
29
  assure_size(out, size);
32
30
  *out->cur++ = '{';
33
31
  fill_indent(out, d2);
34
32
  *out->cur++ = '"';
35
- memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
36
- out->cur += out->opts->create_id_len;
33
+ APPEND_CHARS(out->cur, out->opts->create_id, out->opts->create_id_len);
37
34
  *out->cur++ = '"';
38
35
  if (0 < out->opts->dump_opts.before_size) {
39
- strcpy(out->cur, out->opts->dump_opts.before_sep);
40
- out->cur += out->opts->dump_opts.before_size;
36
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
41
37
  }
42
38
  *out->cur++ = ':';
43
39
  if (0 < out->opts->dump_opts.after_size) {
44
- strcpy(out->cur, out->opts->dump_opts.after_sep);
45
- out->cur += out->opts->dump_opts.after_size;
40
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
46
41
  }
47
42
  *out->cur++ = '"';
48
- memcpy(out->cur, classname, len);
49
- out->cur += len;
43
+ APPEND_CHARS(out->cur, classname, len);
50
44
  *out->cur++ = '"';
51
45
  }
52
46
 
53
- static void
54
- dump_values_array(VALUE *values, int depth, Out out) {
55
- size_t size;
56
- int d2 = depth + 1;
47
+ static void dump_values_array(VALUE *values, int depth, Out out) {
48
+ size_t size;
49
+ int d2 = depth + 1;
57
50
 
58
51
  assure_size(out, d2 * out->indent + 3);
59
52
  *out->cur++ = '[';
60
53
  if (Qundef == *values) {
61
- *out->cur++ = ']';
54
+ *out->cur++ = ']';
62
55
  } else {
63
- if (out->opts->dump_opts.use) {
64
- size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 2;
65
- size += out->opts->dump_opts.array_size;
66
- size += out->opts->dump_opts.indent_size;
67
- } else {
68
- size = d2 * out->indent + 3;
69
- }
70
- for (; Qundef != *values; values++) {
71
- assure_size(out, size);
72
- if (out->opts->dump_opts.use) {
73
- if (0 < out->opts->dump_opts.array_size) {
74
- strcpy(out->cur, out->opts->dump_opts.array_nl);
75
- out->cur += out->opts->dump_opts.array_size;
76
- }
77
- if (0 < out->opts->dump_opts.indent_size) {
78
- int i;
79
-
80
- for (i = d2; 0 < i; i--) {
81
- strcpy(out->cur, out->opts->dump_opts.indent_str);
82
- out->cur += out->opts->dump_opts.indent_size;
83
- }
84
- }
85
- } else {
86
- fill_indent(out, d2);
87
- }
88
- oj_dump_compat_val(*values, d2, out, true);
89
- if (Qundef != *(values + 1)) {
90
- *out->cur++ = ',';
91
- }
92
- }
93
- assure_size(out, size);
94
- if (out->opts->dump_opts.use) {
95
- if (0 < out->opts->dump_opts.array_size) {
96
- strcpy(out->cur, out->opts->dump_opts.array_nl);
97
- out->cur += out->opts->dump_opts.array_size;
98
- }
99
- if (0 < out->opts->dump_opts.indent_size) {
100
- int i;
101
-
102
- for (i = depth; 0 < i; i--) {
103
- strcpy(out->cur, out->opts->dump_opts.indent_str);
104
- out->cur += out->opts->dump_opts.indent_size;
105
- }
106
- }
107
- } else {
108
- fill_indent(out, depth);
109
- }
110
- *out->cur++ = ']';
56
+ if (out->opts->dump_opts.use) {
57
+ size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 2;
58
+ size += out->opts->dump_opts.array_size;
59
+ size += out->opts->dump_opts.indent_size;
60
+ } else {
61
+ size = d2 * out->indent + 3;
62
+ }
63
+ for (; Qundef != *values; values++) {
64
+ assure_size(out, size);
65
+ if (out->opts->dump_opts.use) {
66
+ if (0 < out->opts->dump_opts.array_size) {
67
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
68
+ }
69
+ if (0 < out->opts->dump_opts.indent_size) {
70
+ int i;
71
+
72
+ for (i = d2; 0 < i; i--) {
73
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
74
+ }
75
+ }
76
+ } else {
77
+ fill_indent(out, d2);
78
+ }
79
+ oj_dump_compat_val(*values, d2, out, true);
80
+ if (Qundef != *(values + 1)) {
81
+ *out->cur++ = ',';
82
+ }
83
+ }
84
+ assure_size(out, size);
85
+ if (out->opts->dump_opts.use) {
86
+ if (0 < out->opts->dump_opts.array_size) {
87
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
88
+ }
89
+ if (0 < out->opts->dump_opts.indent_size) {
90
+ int i;
91
+
92
+ for (i = depth; 0 < i; i--) {
93
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
94
+ }
95
+ }
96
+ } else {
97
+ fill_indent(out, depth);
98
+ }
99
+ *out->cur++ = ']';
111
100
  }
112
101
  }
113
102
 
114
- static void
115
- dump_to_json(VALUE obj, Out out) {
116
- volatile VALUE rs;
117
- const char *s;
118
- int len;
103
+ static void dump_to_json(VALUE obj, Out out) {
104
+ volatile VALUE rs;
105
+ const char *s;
106
+ int len;
119
107
 
120
- if (Yes == out->opts->trace) {
121
- oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyIn);
122
- }
108
+ TRACE(out->opts->trace, "to_json", obj, 0, TraceRubyIn);
123
109
  if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
124
- rs = rb_funcall(obj, oj_to_json_id, 0);
110
+ rs = rb_funcall(obj, oj_to_json_id, 0);
125
111
  } else {
126
- rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
127
- }
128
- if (Yes == out->opts->trace) {
129
- oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyOut);
112
+ rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
130
113
  }
114
+ TRACE(out->opts->trace, "to_json", obj, 0, TraceRubyOut);
131
115
 
132
- s = RSTRING_PTR(rs);
116
+ StringValue(rs);
117
+ s = RSTRING_PTR(rs);
133
118
  len = (int)RSTRING_LEN(rs);
134
119
 
135
120
  assure_size(out, len + 1);
136
- memcpy(out->cur, s, len);
137
- out->cur += len;
121
+ APPEND_CHARS(out->cur, s, len);
138
122
  *out->cur = '\0';
139
123
  }
140
124
 
141
- static void
142
- dump_array(VALUE a, int depth, Out out, bool as_ok) {
143
- size_t size;
144
- int i, cnt;
145
- int d2 = depth + 1;
146
- long id = oj_check_circular(a, out);
125
+ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
126
+ size_t size;
127
+ int i, cnt;
128
+ int d2 = depth + 1;
129
+ long id = oj_check_circular(a, out);
147
130
 
148
131
  if (0 > id) {
149
- raise_json_err("Too deeply nested", "NestingError");
150
- return;
132
+ raise_json_err("Too deeply nested", "NestingError");
133
+ return;
151
134
  }
152
- if (as_ok && !oj_use_hash_alt && rb_obj_class(a) != rb_cArray && rb_respond_to(a, oj_to_json_id)) {
153
- dump_to_json(a, out);
154
- return;
135
+ if (as_ok && !oj_use_array_alt && rb_obj_class(a) != rb_cArray && rb_respond_to(a, oj_to_json_id)) {
136
+ dump_to_json(a, out);
137
+ return;
155
138
  }
156
- cnt = (int)RARRAY_LEN(a);
139
+ cnt = (int)RARRAY_LEN(a);
157
140
  *out->cur++ = '[';
158
141
  assure_size(out, 2);
159
142
  if (0 == cnt) {
160
- *out->cur++ = ']';
143
+ *out->cur++ = ']';
161
144
  } else {
162
- if (out->opts->dump_opts.use) {
163
- size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
164
- } else {
165
- size = d2 * out->indent + 2;
166
- }
167
- cnt--;
168
- for (i = 0; i <= cnt; i++) {
169
- assure_size(out, size);
170
- if (out->opts->dump_opts.use) {
171
- if (0 < out->opts->dump_opts.array_size) {
172
- strcpy(out->cur, out->opts->dump_opts.array_nl);
173
- out->cur += out->opts->dump_opts.array_size;
174
- }
175
- if (0 < out->opts->dump_opts.indent_size) {
176
- int i;
177
- for (i = d2; 0 < i; i--) {
178
- strcpy(out->cur, out->opts->dump_opts.indent_str);
179
- out->cur += out->opts->dump_opts.indent_size;
180
- }
181
- }
182
- } else {
183
- fill_indent(out, d2);
184
- }
185
- oj_dump_compat_val(RARRAY_AREF(a, i), d2, out, true);
186
- if (i < cnt) {
187
- *out->cur++ = ',';
188
- }
189
- }
190
- if (out->opts->dump_opts.use) {
191
- size = out->opts->dump_opts.array_size + out->opts->dump_opts.indent_size * depth + 1;
192
- assure_size(out, size);
193
- if (0 < out->opts->dump_opts.array_size) {
194
- strcpy(out->cur, out->opts->dump_opts.array_nl);
195
- out->cur += out->opts->dump_opts.array_size;
196
- }
197
- if (0 < out->opts->dump_opts.indent_size) {
198
- int i;
199
-
200
- for (i = depth; 0 < i; i--) {
201
- strcpy(out->cur, out->opts->dump_opts.indent_str);
202
- out->cur += out->opts->dump_opts.indent_size;
203
- }
204
- }
205
- } else {
206
- size = depth * out->indent + 1;
207
- assure_size(out, size);
208
- fill_indent(out, depth);
209
- }
210
- *out->cur++ = ']';
145
+ if (out->opts->dump_opts.use) {
146
+ size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
147
+ } else {
148
+ size = d2 * out->indent + 2;
149
+ }
150
+ assure_size(out, size * cnt);
151
+ cnt--;
152
+ for (i = 0; i <= cnt; i++) {
153
+ if (out->opts->dump_opts.use) {
154
+ if (0 < out->opts->dump_opts.array_size) {
155
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
156
+ }
157
+ if (0 < out->opts->dump_opts.indent_size) {
158
+ int i;
159
+ for (i = d2; 0 < i; i--) {
160
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
161
+ }
162
+ }
163
+ } else {
164
+ fill_indent(out, d2);
165
+ }
166
+ oj_dump_compat_val(RARRAY_AREF(a, i), d2, out, true);
167
+ if (i < cnt) {
168
+ *out->cur++ = ',';
169
+ }
170
+ }
171
+ if (out->opts->dump_opts.use) {
172
+ size = out->opts->dump_opts.array_size + out->opts->dump_opts.indent_size * depth + 1;
173
+ assure_size(out, size);
174
+ if (0 < out->opts->dump_opts.array_size) {
175
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
176
+ }
177
+ if (0 < out->opts->dump_opts.indent_size) {
178
+ int i;
179
+
180
+ for (i = depth; 0 < i; i--) {
181
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
182
+ }
183
+ }
184
+ } else {
185
+ size = depth * out->indent + 1;
186
+ assure_size(out, size);
187
+ fill_indent(out, depth);
188
+ }
189
+ *out->cur++ = ']';
211
190
  }
212
191
  *out->cur = '\0';
213
192
  }
214
193
 
215
- static ID _dump_id = 0;
194
+ static ID _dump_id = 0;
216
195
 
217
- static void
218
- bigdecimal_alt(VALUE obj, int depth, Out out) {
219
- struct _attr attrs[] = {
220
- { "b", 1, Qnil },
221
- { NULL, 0, Qnil },
196
+ static void bigdecimal_alt(VALUE obj, int depth, Out out) {
197
+ struct _attr attrs[] = {
198
+ {"b", 1, Qnil},
199
+ {NULL, 0, Qnil},
222
200
  };
223
201
 
224
202
  if (0 == _dump_id) {
225
- _dump_id = rb_intern("_dump");
203
+ _dump_id = rb_intern("_dump");
226
204
  }
227
205
  attrs[0].value = rb_funcall(obj, _dump_id, 0);
228
206
 
229
207
  oj_code_attrs(obj, attrs, depth, out, true);
230
208
  }
231
209
 
232
- static ID real_id = 0;
233
- static ID imag_id = 0;
210
+ static ID real_id = 0;
211
+ static ID imag_id = 0;
234
212
 
235
- static void
236
- complex_alt(VALUE obj, int depth, Out out) {
237
- struct _attr attrs[] = {
238
- { "r", 1, Qnil },
239
- { "i", 1, Qnil },
240
- { NULL, 0, Qnil },
213
+ static void complex_alt(VALUE obj, int depth, Out out) {
214
+ struct _attr attrs[] = {
215
+ {"r", 1, Qnil},
216
+ {"i", 1, Qnil},
217
+ {NULL, 0, Qnil},
241
218
  };
242
219
 
243
220
  if (0 == real_id) {
244
- real_id = rb_intern("real");
245
- imag_id = rb_intern("imag");
221
+ real_id = rb_intern("real");
222
+ imag_id = rb_intern("imag");
246
223
  }
247
224
  attrs[0].value = rb_funcall(obj, real_id, 0);
248
225
  attrs[1].value = rb_funcall(obj, imag_id, 0);
@@ -250,25 +227,24 @@ complex_alt(VALUE obj, int depth, Out out) {
250
227
  oj_code_attrs(obj, attrs, depth, out, true);
251
228
  }
252
229
 
253
- static ID year_id = 0;
254
- static ID month_id = 0;
255
- static ID day_id = 0;
256
- static ID start_id = 0;
257
-
258
- static void
259
- date_alt(VALUE obj, int depth, Out out) {
260
- struct _attr attrs[] = {
261
- { "y", 1, Qnil },
262
- { "m", 1, Qnil },
263
- { "d", 1, Qnil },
264
- { "sg", 2, Qnil },
265
- { NULL, 0, Qnil },
230
+ static ID year_id = 0;
231
+ static ID month_id = 0;
232
+ static ID day_id = 0;
233
+ static ID start_id = 0;
234
+
235
+ static void date_alt(VALUE obj, int depth, Out out) {
236
+ struct _attr attrs[] = {
237
+ {"y", 1, Qnil},
238
+ {"m", 1, Qnil},
239
+ {"d", 1, Qnil},
240
+ {"sg", 2, Qnil},
241
+ {NULL, 0, Qnil},
266
242
  };
267
243
  if (0 == year_id) {
268
- year_id = rb_intern("year");
269
- month_id = rb_intern("month");
270
- day_id = rb_intern("day");
271
- start_id = rb_intern("start");
244
+ year_id = rb_intern("year");
245
+ month_id = rb_intern("month");
246
+ day_id = rb_intern("day");
247
+ start_id = rb_intern("start");
272
248
  }
273
249
  attrs[0].value = rb_funcall(obj, year_id, 0);
274
250
  attrs[1].value = rb_funcall(obj, month_id, 0);
@@ -278,33 +254,32 @@ date_alt(VALUE obj, int depth, Out out) {
278
254
  oj_code_attrs(obj, attrs, depth, out, true);
279
255
  }
280
256
 
281
- static ID hour_id = 0;
282
- static ID min_id = 0;
283
- static ID sec_id = 0;
284
- static ID offset_id = 0;
285
-
286
- static void
287
- datetime_alt(VALUE obj, int depth, Out out) {
288
- struct _attr attrs[] = {
289
- { "y", 1, Qnil },
290
- { "m", 1, Qnil },
291
- { "d", 1, Qnil },
292
- { "H", 1, Qnil },
293
- { "M", 1, Qnil },
294
- { "S", 1, Qnil },
295
- { "of", 2, Qnil },
296
- { "sg", 2, Qnil },
297
- { NULL, 0, Qnil },
257
+ static ID hour_id = 0;
258
+ static ID min_id = 0;
259
+ static ID sec_id = 0;
260
+ static ID offset_id = 0;
261
+
262
+ static void datetime_alt(VALUE obj, int depth, Out out) {
263
+ struct _attr attrs[] = {
264
+ {"y", 1, Qnil},
265
+ {"m", 1, Qnil},
266
+ {"d", 1, Qnil},
267
+ {"H", 1, Qnil},
268
+ {"M", 1, Qnil},
269
+ {"S", 1, Qnil},
270
+ {"of", 2, Qnil},
271
+ {"sg", 2, Qnil},
272
+ {NULL, 0, Qnil},
298
273
  };
299
274
  if (0 == hour_id) {
300
- year_id = rb_intern("year");
301
- month_id = rb_intern("month");
302
- day_id = rb_intern("day");
303
- hour_id = rb_intern("hour");
304
- min_id = rb_intern("min");
305
- sec_id = rb_intern("sec");
306
- offset_id = rb_intern("offset");
307
- start_id = rb_intern("start");
275
+ year_id = rb_intern("year");
276
+ month_id = rb_intern("month");
277
+ day_id = rb_intern("day");
278
+ hour_id = rb_intern("hour");
279
+ min_id = rb_intern("min");
280
+ sec_id = rb_intern("sec");
281
+ offset_id = rb_intern("offset");
282
+ start_id = rb_intern("start");
308
283
  }
309
284
  attrs[0].value = rb_funcall(obj, year_id, 0);
310
285
  attrs[1].value = rb_funcall(obj, month_id, 0);
@@ -312,103 +287,88 @@ datetime_alt(VALUE obj, int depth, Out out) {
312
287
  attrs[3].value = rb_funcall(obj, hour_id, 0);
313
288
  attrs[4].value = rb_funcall(obj, min_id, 0);
314
289
  attrs[5].value = rb_funcall(obj, sec_id, 0);
315
- attrs[6].value = rb_funcall(rb_funcall(obj, offset_id, 0), oj_to_s_id, 0);
290
+ attrs[6].value = oj_safe_string_convert(rb_funcall(obj, offset_id, 0));
316
291
  attrs[7].value = rb_funcall(obj, start_id, 0);
317
292
 
318
293
  oj_code_attrs(obj, attrs, depth, out, true);
319
294
  }
320
295
 
321
- static ID message_id = 0;
322
- static ID backtrace_id = 0;
296
+ static ID message_id = 0;
297
+ static ID backtrace_id = 0;
323
298
 
324
- static void
325
- exception_alt(VALUE obj, int depth, Out out) {
326
- int d3 = depth + 2;
327
- size_t size = d3 * out->indent + 2;
328
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
299
+ static void exception_alt(VALUE obj, int depth, Out out) {
300
+ int d3 = depth + 2;
301
+ size_t size = d3 * out->indent + 2;
302
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
329
303
 
330
304
  if (0 == message_id) {
331
- message_id = rb_intern("message");
332
- backtrace_id = rb_intern("backtrace");
305
+ message_id = rb_intern("message");
306
+ backtrace_id = rb_intern("backtrace");
333
307
  }
334
308
  dump_obj_classname(rb_class2name(rb_obj_class(obj)), depth, out);
335
309
 
336
310
  assure_size(out, size + sep_len + 6);
337
311
  *out->cur++ = ',';
338
312
  fill_indent(out, d3);
339
- *out->cur++ = '"';
340
- *out->cur++ = 'm';
341
- *out->cur++ = '"';
313
+ APPEND_CHARS(out->cur, "\"m\"", 3);
342
314
  if (0 < out->opts->dump_opts.before_size) {
343
- strcpy(out->cur, out->opts->dump_opts.before_sep);
344
- out->cur += out->opts->dump_opts.before_size;
315
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
345
316
  }
346
317
  *out->cur++ = ':';
347
318
  if (0 < out->opts->dump_opts.after_size) {
348
- strcpy(out->cur, out->opts->dump_opts.after_sep);
349
- out->cur += out->opts->dump_opts.after_size;
319
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
350
320
  }
351
321
  oj_dump_str(rb_funcall(obj, message_id, 0), 0, out, false);
352
322
  assure_size(out, size + sep_len + 6);
353
323
  *out->cur++ = ',';
354
324
  fill_indent(out, d3);
355
- *out->cur++ = '"';
356
- *out->cur++ = 'b';
357
- *out->cur++ = '"';
325
+ APPEND_CHARS(out->cur, "\"b\"", 3);
358
326
  if (0 < out->opts->dump_opts.before_size) {
359
- strcpy(out->cur, out->opts->dump_opts.before_sep);
360
- out->cur += out->opts->dump_opts.before_size;
327
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
361
328
  }
362
329
  *out->cur++ = ':';
363
330
  if (0 < out->opts->dump_opts.after_size) {
364
- strcpy(out->cur, out->opts->dump_opts.after_sep);
365
- out->cur += out->opts->dump_opts.after_size;
331
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
366
332
  }
367
333
  dump_array(rb_funcall(obj, backtrace_id, 0), depth, out, false);
368
334
  fill_indent(out, depth);
369
335
  *out->cur++ = '}';
370
- *out->cur = '\0';
336
+ *out->cur = '\0';
371
337
  }
372
338
 
373
- static ID table_id = 0;
339
+ static ID table_id = 0;
374
340
 
375
- static void
376
- openstruct_alt(VALUE obj, int depth, Out out) {
377
- struct _attr attrs[] = {
378
- { "t", 1, Qnil },
379
- { NULL, 0, Qnil },
341
+ static void openstruct_alt(VALUE obj, int depth, Out out) {
342
+ struct _attr attrs[] = {
343
+ {"t", 1, Qnil},
344
+ {NULL, 0, Qnil},
380
345
  };
381
346
  if (0 == table_id) {
382
- table_id = rb_intern("table");
347
+ table_id = rb_intern("table");
383
348
  }
384
349
  attrs[0].value = rb_funcall(obj, table_id, 0);
385
350
 
386
351
  oj_code_attrs(obj, attrs, depth, out, true);
387
352
  }
388
353
 
389
- static void
390
- range_alt(VALUE obj, int depth, Out out) {
391
- int d3 = depth + 2;
392
- size_t size = d3 * out->indent + 2;
393
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
394
- VALUE args[] = { Qundef, Qundef, Qundef, Qundef };
354
+ static void range_alt(VALUE obj, int depth, Out out) {
355
+ int d3 = depth + 2;
356
+ size_t size = d3 * out->indent + 2;
357
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
358
+ VALUE args[] = {Qundef, Qundef, Qundef, Qundef};
395
359
 
396
360
  dump_obj_classname(rb_class2name(rb_obj_class(obj)), depth, out);
397
361
 
398
362
  assure_size(out, size + sep_len + 6);
399
363
  *out->cur++ = ',';
400
364
  fill_indent(out, d3);
401
- *out->cur++ = '"';
402
- *out->cur++ = 'a';
403
- *out->cur++ = '"';
365
+ APPEND_CHARS(out->cur, "\"a\"", 3);
404
366
  if (0 < out->opts->dump_opts.before_size) {
405
- strcpy(out->cur, out->opts->dump_opts.before_sep);
406
- out->cur += out->opts->dump_opts.before_size;
367
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
407
368
  }
408
369
  *out->cur++ = ':';
409
370
  if (0 < out->opts->dump_opts.after_size) {
410
- strcpy(out->cur, out->opts->dump_opts.after_sep);
411
- out->cur += out->opts->dump_opts.after_size;
371
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
412
372
  }
413
373
  args[0] = rb_funcall(obj, oj_begin_id, 0);
414
374
  args[1] = rb_funcall(obj, oj_end_id, 0);
@@ -416,22 +376,21 @@ range_alt(VALUE obj, int depth, Out out) {
416
376
  dump_values_array(args, depth, out);
417
377
  fill_indent(out, depth);
418
378
  *out->cur++ = '}';
419
- *out->cur = '\0';
379
+ *out->cur = '\0';
420
380
  }
421
381
 
422
- static ID numerator_id = 0;
423
- static ID denominator_id = 0;
382
+ static ID numerator_id = 0;
383
+ static ID denominator_id = 0;
424
384
 
425
- static void
426
- rational_alt(VALUE obj, int depth, Out out) {
427
- struct _attr attrs[] = {
428
- { "n", 1, Qnil },
429
- { "d", 1, Qnil },
430
- { NULL, 0, Qnil },
385
+ static void rational_alt(VALUE obj, int depth, Out out) {
386
+ struct _attr attrs[] = {
387
+ {"n", 1, Qnil},
388
+ {"d", 1, Qnil},
389
+ {NULL, 0, Qnil},
431
390
  };
432
391
  if (0 == numerator_id) {
433
- numerator_id = rb_intern("numerator");
434
- denominator_id = rb_intern("denominator");
392
+ numerator_id = rb_intern("numerator");
393
+ denominator_id = rb_intern("denominator");
435
394
  }
436
395
  attrs[0].value = rb_funcall(obj, numerator_id, 0);
437
396
  attrs[1].value = rb_funcall(obj, denominator_id, 0);
@@ -439,19 +398,18 @@ rational_alt(VALUE obj, int depth, Out out) {
439
398
  oj_code_attrs(obj, attrs, depth, out, true);
440
399
  }
441
400
 
442
- static ID options_id = 0;
443
- static ID source_id = 0;
401
+ static ID options_id = 0;
402
+ static ID source_id = 0;
444
403
 
445
- static void
446
- regexp_alt(VALUE obj, int depth, Out out) {
447
- struct _attr attrs[] = {
448
- { "o", 1, Qnil },
449
- { "s", 1, Qnil },
450
- { NULL, 0, Qnil },
404
+ static void regexp_alt(VALUE obj, int depth, Out out) {
405
+ struct _attr attrs[] = {
406
+ {"o", 1, Qnil},
407
+ {"s", 1, Qnil},
408
+ {NULL, 0, Qnil},
451
409
  };
452
410
  if (0 == options_id) {
453
- options_id = rb_intern("options");
454
- source_id = rb_intern("source");
411
+ options_id = rb_intern("options");
412
+ source_id = rb_intern("source");
455
413
  }
456
414
  attrs[0].value = rb_funcall(obj, options_id, 0);
457
415
  attrs[1].value = rb_funcall(obj, source_id, 0);
@@ -459,30 +417,24 @@ regexp_alt(VALUE obj, int depth, Out out) {
459
417
  oj_code_attrs(obj, attrs, depth, out, true);
460
418
  }
461
419
 
462
- static void
463
- time_alt(VALUE obj, int depth, Out out) {
464
- struct _attr attrs[] = {
465
- { "s", 1, Qundef, 0, Qundef },
466
- { "n", 1, Qundef, 0, Qundef },
467
- { NULL, 0, Qnil },
420
+ static void time_alt(VALUE obj, int depth, Out out) {
421
+ struct _attr attrs[] = {
422
+ {"s", 1, Qundef, 0, Qundef},
423
+ {"n", 1, Qundef, 0, Qundef},
424
+ {NULL, 0, Qnil},
468
425
  };
469
- time_t sec;
470
- long long nsec;
426
+ time_t sec;
427
+ long long nsec;
471
428
 
472
- #ifdef HAVE_RB_TIME_TIMESPEC
473
429
  if (16 <= sizeof(struct timespec)) {
474
- struct timespec ts = rb_time_timespec(obj);
430
+ struct timespec ts = rb_time_timespec(obj);
475
431
 
476
- sec = (long long)ts.tv_sec;
477
- nsec = ts.tv_nsec;
432
+ sec = (long long)ts.tv_sec;
433
+ nsec = ts.tv_nsec;
478
434
  } else {
479
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
480
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
435
+ sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
436
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
481
437
  }
482
- #else
483
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
484
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
485
- #endif
486
438
 
487
439
  attrs[0].num = sec;
488
440
  attrs[1].num = nsec;
@@ -490,68 +442,68 @@ time_alt(VALUE obj, int depth, Out out) {
490
442
  oj_code_attrs(obj, attrs, depth, out, true);
491
443
  }
492
444
 
493
- struct _code oj_compat_codes[] = {
494
- { "BigDecimal", Qnil, bigdecimal_alt, NULL, false },
495
- { "Complex", Qnil, complex_alt, NULL, false },
496
- { "Date", Qnil, date_alt, false },
497
- { "DateTime", Qnil, datetime_alt, NULL, false },
498
- { "OpenStruct", Qnil, openstruct_alt, NULL, false },
499
- { "Range", Qnil, range_alt, NULL, false },
500
- { "Rational", Qnil, rational_alt, NULL, false },
501
- { "Regexp", Qnil, regexp_alt, NULL, false },
502
- { "Time", Qnil, time_alt, NULL, false },
445
+ struct _code oj_compat_codes[] = {
446
+ {"BigDecimal", Qnil, bigdecimal_alt, NULL, false},
447
+ {"Complex", Qnil, complex_alt, NULL, false},
448
+ {"Date", Qnil, date_alt, false},
449
+ {"DateTime", Qnil, datetime_alt, NULL, false},
450
+ {"OpenStruct", Qnil, openstruct_alt, NULL, false},
451
+ {"Range", Qnil, range_alt, NULL, false},
452
+ {"Rational", Qnil, rational_alt, NULL, false},
453
+ {"Regexp", Qnil, regexp_alt, NULL, false},
454
+ {"Time", Qnil, time_alt, NULL, false},
503
455
  // TBD the rest of the library classes
504
- { NULL, Qundef, NULL, NULL, false },
456
+ {NULL, Qundef, NULL, NULL, false},
505
457
  };
506
458
 
507
459
  VALUE
508
460
  oj_add_to_json(int argc, VALUE *argv, VALUE self) {
509
- Code a;
461
+ Code a;
510
462
 
511
463
  if (0 == argc) {
512
- for (a = oj_compat_codes; NULL != a->name; a++) {
513
- if (Qnil == a->clas || Qundef == a->clas) {
514
- a->clas = rb_const_get_at(rb_cObject, rb_intern(a->name));
515
- }
516
- a->active = true;
517
- }
518
- use_struct_alt = true;
519
- use_exception_alt = true;
520
- use_bignum_alt = true;
521
- oj_use_hash_alt = true;
522
- oj_use_array_alt = true;
464
+ for (a = oj_compat_codes; NULL != a->name; a++) {
465
+ if (Qnil == a->clas || Qundef == a->clas) {
466
+ a->clas = rb_const_get_at(rb_cObject, rb_intern(a->name));
467
+ }
468
+ a->active = true;
469
+ }
470
+ use_struct_alt = true;
471
+ use_exception_alt = true;
472
+ use_bignum_alt = true;
473
+ oj_use_hash_alt = true;
474
+ oj_use_array_alt = true;
523
475
  } else {
524
- for (; 0 < argc; argc--, argv++) {
525
- if (rb_cStruct == *argv) {
526
- use_struct_alt = true;
527
- continue;
528
- }
529
- if (rb_eException == *argv) {
530
- use_exception_alt = true;
531
- continue;
532
- }
533
- if (rb_cInteger == *argv) {
534
- use_bignum_alt = true;
535
- continue;
536
- }
537
- if (rb_cHash == *argv) {
538
- oj_use_hash_alt = true;
539
- continue;
540
- }
541
- if (rb_cArray == *argv) {
542
- oj_use_array_alt = true;
543
- continue;
544
- }
545
- for (a = oj_compat_codes; NULL != a->name; a++) {
546
- if (Qnil == a->clas || Qundef == a->clas) {
547
- a->clas = rb_const_get_at(rb_cObject, rb_intern(a->name));
548
- }
549
- if (*argv == a->clas) {
550
- a->active = true;
551
- break;
552
- }
553
- }
554
- }
476
+ for (; 0 < argc; argc--, argv++) {
477
+ if (rb_cStruct == *argv) {
478
+ use_struct_alt = true;
479
+ continue;
480
+ }
481
+ if (rb_eException == *argv) {
482
+ use_exception_alt = true;
483
+ continue;
484
+ }
485
+ if (rb_cInteger == *argv) {
486
+ use_bignum_alt = true;
487
+ continue;
488
+ }
489
+ if (rb_cHash == *argv) {
490
+ oj_use_hash_alt = true;
491
+ continue;
492
+ }
493
+ if (rb_cArray == *argv) {
494
+ oj_use_array_alt = true;
495
+ continue;
496
+ }
497
+ for (a = oj_compat_codes; NULL != a->name; a++) {
498
+ if (Qnil == a->clas || Qundef == a->clas) {
499
+ a->clas = rb_const_get_at(rb_cObject, rb_intern(a->name));
500
+ }
501
+ if (*argv == a->clas) {
502
+ a->active = true;
503
+ break;
504
+ }
505
+ }
506
+ }
555
507
  }
556
508
  return Qnil;
557
509
  }
@@ -559,36 +511,36 @@ oj_add_to_json(int argc, VALUE *argv, VALUE self) {
559
511
  VALUE
560
512
  oj_remove_to_json(int argc, VALUE *argv, VALUE self) {
561
513
  if (0 == argc) {
562
- oj_code_set_active(oj_compat_codes, Qnil, false);
563
- use_struct_alt = false;
564
- use_exception_alt = false;
565
- use_bignum_alt = false;
566
- oj_use_hash_alt = false;
567
- oj_use_array_alt = false;
514
+ oj_code_set_active(oj_compat_codes, Qnil, false);
515
+ use_struct_alt = false;
516
+ use_exception_alt = false;
517
+ use_bignum_alt = false;
518
+ oj_use_hash_alt = false;
519
+ oj_use_array_alt = false;
568
520
  } else {
569
- for (; 0 < argc; argc--, argv++) {
570
- if (rb_cStruct == *argv) {
571
- use_struct_alt = false;
572
- continue;
573
- }
574
- if (rb_eException == *argv) {
575
- use_exception_alt = false;
576
- continue;
577
- }
578
- if (rb_cInteger == *argv) {
579
- use_bignum_alt = false;
580
- continue;
581
- }
582
- if (rb_cHash == *argv) {
583
- oj_use_hash_alt = false;
584
- continue;
585
- }
586
- if (rb_cArray == *argv) {
587
- oj_use_array_alt = false;
588
- continue;
589
- }
590
- oj_code_set_active(oj_compat_codes, *argv, false);
591
- }
521
+ for (; 0 < argc; argc--, argv++) {
522
+ if (rb_cStruct == *argv) {
523
+ use_struct_alt = false;
524
+ continue;
525
+ }
526
+ if (rb_eException == *argv) {
527
+ use_exception_alt = false;
528
+ continue;
529
+ }
530
+ if (rb_cInteger == *argv) {
531
+ use_bignum_alt = false;
532
+ continue;
533
+ }
534
+ if (rb_cHash == *argv) {
535
+ oj_use_hash_alt = false;
536
+ continue;
537
+ }
538
+ if (rb_cArray == *argv) {
539
+ oj_use_array_alt = false;
540
+ continue;
541
+ }
542
+ oj_code_set_active(oj_compat_codes, *argv, false);
543
+ }
592
544
  }
593
545
  return Qnil;
594
546
  }
@@ -596,378 +548,349 @@ oj_remove_to_json(int argc, VALUE *argv, VALUE self) {
596
548
  // The JSON gem is inconsistent with handling of infinity. Using
597
549
  // JSON.dump(0.1/0) returns the string Infinity but (0.1/0).to_json raise and
598
550
  // exception. Worse, for BigDecimals a quoted "Infinity" is returned.
599
- static void
600
- dump_float(VALUE obj, int depth, Out out, bool as_ok) {
601
- char buf[64];
602
- char *b;
603
- double d = rb_num2dbl(obj);
604
- int cnt = 0;
551
+ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
552
+ char buf[64];
553
+ char *b;
554
+ double d = rb_num2dbl(obj);
555
+ int cnt = 0;
605
556
 
606
557
  if (0.0 == d) {
607
- b = buf;
608
- *b++ = '0';
609
- *b++ = '.';
610
- *b++ = '0';
611
- *b++ = '\0';
612
- cnt = 3;
558
+ b = buf;
559
+ *b++ = '0';
560
+ *b++ = '.';
561
+ *b++ = '0';
562
+ *b++ = '\0';
563
+ cnt = 3;
613
564
  } else if (OJ_INFINITY == d) {
614
- if (WordNan == out->opts->dump_opts.nan_dump) {
615
- strcpy(buf, "Infinity");
616
- } else {
617
- raise_json_err("Infinity not allowed in JSON.", "GeneratorError");
618
- }
565
+ if (WordNan == out->opts->dump_opts.nan_dump) {
566
+ strcpy(buf, "Infinity");
567
+ cnt = 8;
568
+ } else {
569
+ raise_json_err("Infinity not allowed in JSON.", "GeneratorError");
570
+ }
619
571
  } else if (-OJ_INFINITY == d) {
620
- if (WordNan == out->opts->dump_opts.nan_dump) {
621
- strcpy(buf, "-Infinity");
622
- } else {
623
- raise_json_err("-Infinity not allowed in JSON.", "GeneratorError");
624
- }
572
+ if (WordNan == out->opts->dump_opts.nan_dump) {
573
+ strcpy(buf, "-Infinity");
574
+ cnt = 9;
575
+ } else {
576
+ raise_json_err("-Infinity not allowed in JSON.", "GeneratorError");
577
+ }
625
578
  } else if (isnan(d)) {
626
- if (WordNan == out->opts->dump_opts.nan_dump) {
627
- strcpy(buf, "NaN");
628
- } else {
629
- raise_json_err("NaN not allowed in JSON.", "GeneratorError");
630
- }
579
+ if (WordNan == out->opts->dump_opts.nan_dump) {
580
+ strcpy(buf, "NaN");
581
+ cnt = 3;
582
+ } else {
583
+ raise_json_err("NaN not allowed in JSON.", "GeneratorError");
584
+ }
631
585
  } else if (d == (double)(long long int)d) {
632
- cnt = snprintf(buf, sizeof(buf), "%.1f", d);
586
+ cnt = snprintf(buf, sizeof(buf), "%.1f", d);
633
587
  } else if (oj_rails_float_opt) {
634
- cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, "%0.16g");
588
+ cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, "%0.16g");
635
589
  } else {
636
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
590
+ volatile VALUE rstr = oj_safe_string_convert(obj);
637
591
 
638
- strcpy(buf, RSTRING_PTR(rstr));
639
- cnt = (int)RSTRING_LEN(rstr);
592
+ strcpy(buf, RSTRING_PTR(rstr));
593
+ cnt = (int)RSTRING_LEN(rstr);
640
594
  }
641
595
  assure_size(out, cnt);
642
- for (b = buf; '\0' != *b; b++) {
643
- *out->cur++ = *b;
644
- }
596
+ APPEND_CHARS(out->cur, buf, cnt);
645
597
  *out->cur = '\0';
646
598
  }
647
599
 
648
- static int
649
- hash_cb(VALUE key, VALUE value, VALUE ov) {
650
- Out out = (Out)ov;
651
- int depth = out->depth;
600
+ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
601
+ Out out = (Out)ov;
602
+ int depth = out->depth;
652
603
 
653
604
  if (out->omit_nil && Qnil == value) {
654
- return ST_CONTINUE;
605
+ return ST_CONTINUE;
655
606
  }
656
607
  if (!out->opts->dump_opts.use) {
657
- assure_size(out, depth * out->indent + 1);
658
- fill_indent(out, depth);
608
+ assure_size(out, depth * out->indent + 1);
609
+ fill_indent(out, depth);
659
610
  } else {
660
- assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
661
- if (0 < out->opts->dump_opts.hash_size) {
662
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
663
- out->cur += out->opts->dump_opts.hash_size;
664
- }
665
- if (0 < out->opts->dump_opts.indent_size) {
666
- int i;
667
- for (i = depth; 0 < i; i--) {
668
- strcpy(out->cur, out->opts->dump_opts.indent_str);
669
- out->cur += out->opts->dump_opts.indent_size;
670
- }
671
- }
611
+ assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
612
+ if (0 < out->opts->dump_opts.hash_size) {
613
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
614
+ }
615
+ if (0 < out->opts->dump_opts.indent_size) {
616
+ int i;
617
+ for (i = depth; 0 < i; i--) {
618
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
619
+ }
620
+ }
672
621
  }
673
622
  switch (rb_type(key)) {
674
- case T_STRING:
675
- oj_dump_str(key, 0, out, false);
676
- break;
677
- case T_SYMBOL:
678
- oj_dump_sym(key, 0, out, false);
679
- break;
623
+ case T_STRING: oj_dump_str(key, 0, out, false); break;
624
+ case T_SYMBOL: oj_dump_sym(key, 0, out, false); break;
680
625
  default:
681
- /*rb_raise(rb_eTypeError, "In :compat mode all Hash keys must be Strings or Symbols, not %s.\n", rb_class2name(rb_obj_class(key)));*/
682
- oj_dump_str(rb_funcall(key, oj_to_s_id, 0), 0, out, false);
683
- break;
626
+ /*rb_raise(rb_eTypeError, "In :compat mode all Hash keys must be Strings or Symbols, not %s.\n",
627
+ * rb_class2name(rb_obj_class(key)));*/
628
+ oj_dump_str(oj_safe_string_convert(key), 0, out, false);
629
+ break;
684
630
  }
685
631
  if (!out->opts->dump_opts.use) {
686
- *out->cur++ = ':';
632
+ *out->cur++ = ':';
687
633
  } else {
688
- assure_size(out, out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2);
689
- if (0 < out->opts->dump_opts.before_size) {
690
- strcpy(out->cur, out->opts->dump_opts.before_sep);
691
- out->cur += out->opts->dump_opts.before_size;
692
- }
693
- *out->cur++ = ':';
694
- if (0 < out->opts->dump_opts.after_size) {
695
- strcpy(out->cur, out->opts->dump_opts.after_sep);
696
- out->cur += out->opts->dump_opts.after_size;
697
- }
634
+ assure_size(out, out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2);
635
+ if (0 < out->opts->dump_opts.before_size) {
636
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
637
+ }
638
+ *out->cur++ = ':';
639
+ if (0 < out->opts->dump_opts.after_size) {
640
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
641
+ }
698
642
  }
699
643
  oj_dump_compat_val(value, depth, out, true);
700
- out->depth = depth;
644
+ out->depth = depth;
701
645
  *out->cur++ = ',';
702
646
 
703
647
  return ST_CONTINUE;
704
648
  }
705
649
 
706
- static void
707
- dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
708
- int cnt;
709
- long id = oj_check_circular(obj, out);
650
+ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
651
+ int cnt;
652
+ long id = oj_check_circular(obj, out);
710
653
 
711
654
  if (0 > id) {
712
- raise_json_err("Too deeply nested", "NestingError");
713
- return;
655
+ raise_json_err("Too deeply nested", "NestingError");
656
+ return;
714
657
  }
715
658
  if (as_ok && !oj_use_hash_alt && rb_obj_class(obj) != rb_cHash && rb_respond_to(obj, oj_to_json_id)) {
716
- dump_to_json(obj, out);
717
- return;
659
+ dump_to_json(obj, out);
660
+ return;
718
661
  }
719
662
  cnt = (int)RHASH_SIZE(obj);
720
663
  assure_size(out, 2);
721
664
  if (0 == cnt) {
722
- *out->cur++ = '{';
723
- *out->cur++ = '}';
665
+ APPEND_CHARS(out->cur, "{}", 2);
724
666
  } else {
725
- *out->cur++ = '{';
726
- out->depth = depth + 1;
727
- rb_hash_foreach(obj, hash_cb, (VALUE)out);
728
- if (',' == *(out->cur - 1)) {
729
- out->cur--; // backup to overwrite last comma
730
- }
731
- if (!out->opts->dump_opts.use) {
732
- assure_size(out, depth * out->indent + 2);
733
- fill_indent(out, depth);
734
- } else {
735
- assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
736
- if (0 < out->opts->dump_opts.hash_size) {
737
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
738
- out->cur += out->opts->dump_opts.hash_size;
739
- }
740
- if (0 < out->opts->dump_opts.indent_size) {
741
- int i;
742
-
743
- for (i = depth; 0 < i; i--) {
744
- strcpy(out->cur, out->opts->dump_opts.indent_str);
745
- out->cur += out->opts->dump_opts.indent_size;
746
- }
747
- }
748
- }
749
- *out->cur++ = '}';
667
+ *out->cur++ = '{';
668
+ out->depth = depth + 1;
669
+ rb_hash_foreach(obj, hash_cb, (VALUE)out);
670
+ if (',' == *(out->cur - 1)) {
671
+ out->cur--; // backup to overwrite last comma
672
+ }
673
+ if (!out->opts->dump_opts.use) {
674
+ assure_size(out, depth * out->indent + 2);
675
+ fill_indent(out, depth);
676
+ } else {
677
+ assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
678
+ if (0 < out->opts->dump_opts.hash_size) {
679
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
680
+ }
681
+ if (0 < out->opts->dump_opts.indent_size) {
682
+ int i;
683
+
684
+ for (i = depth; 0 < i; i--) {
685
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
686
+ }
687
+ }
688
+ }
689
+ *out->cur++ = '}';
750
690
  }
751
691
  *out->cur = '\0';
752
692
  }
753
693
 
754
694
  // In compat mode only the first call check for to_json. After that to_s is
755
695
  // called.
756
- static void
757
- dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
696
+ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
758
697
  if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
759
- return;
698
+ return;
760
699
  }
761
700
  if (use_exception_alt && rb_obj_is_kind_of(obj, rb_eException)) {
762
- exception_alt(obj, depth, out);
763
- return;
701
+ exception_alt(obj, depth, out);
702
+ return;
764
703
  }
765
704
  if (Yes == out->opts->raw_json && rb_respond_to(obj, oj_raw_json_id)) {
766
- oj_dump_raw_json(obj, depth, out);
767
- return;
705
+ oj_dump_raw_json(obj, depth, out);
706
+ return;
768
707
  }
769
708
  if (as_ok && rb_respond_to(obj, oj_to_json_id)) {
770
- dump_to_json(obj, out);
771
- return;
709
+ dump_to_json(obj, out);
710
+ return;
772
711
  }
773
712
  // Nothing else matched so encode as a JSON object with Ruby obj members
774
713
  // as JSON object members.
775
714
  oj_dump_obj_to_s(obj, out);
776
715
  }
777
716
 
778
- static void
779
- dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
780
- VALUE clas = rb_obj_class(obj);
717
+ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
718
+ VALUE clas = rb_obj_class(obj);
781
719
 
782
720
  if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
783
- return;
721
+ return;
784
722
  }
785
723
  if (rb_cRange == clas) {
786
- *out->cur++ = '"';
787
- oj_dump_compat_val(rb_funcall(obj, oj_begin_id, 0), 0, out, false);
788
- assure_size(out, 3);
789
- *out->cur++ = '.';
790
- *out->cur++ = '.';
791
- if (Qtrue == rb_funcall(obj, oj_exclude_end_id, 0)) {
792
- *out->cur++ = '.';
793
- }
794
- oj_dump_compat_val(rb_funcall(obj, oj_end_id, 0), 0, out, false);
795
- *out->cur++ = '"';
796
-
797
- return;
724
+ *out->cur++ = '"';
725
+ oj_dump_compat_val(rb_funcall(obj, oj_begin_id, 0), 0, out, false);
726
+ assure_size(out, 3);
727
+ APPEND_CHARS(out->cur, "..", 2);
728
+ if (Qtrue == rb_funcall(obj, oj_exclude_end_id, 0)) {
729
+ *out->cur++ = '.';
730
+ }
731
+ oj_dump_compat_val(rb_funcall(obj, oj_end_id, 0), 0, out, false);
732
+ *out->cur++ = '"';
733
+
734
+ return;
798
735
  }
799
736
  if (as_ok && rb_respond_to(obj, oj_to_json_id)) {
800
- dump_to_json(obj, out);
737
+ dump_to_json(obj, out);
801
738
 
802
- return;
739
+ return;
803
740
  }
804
741
  if (use_struct_alt) {
805
- int d3 = depth + 2;
806
- size_t size = d3 * out->indent + 2;
807
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
808
- const char *classname = rb_class2name(rb_obj_class(obj));
809
- VALUE args[100];
810
- int cnt;
811
- int i;
812
-
813
- if (NULL == classname || '#' == *classname) {
814
- raise_json_err("Only named structs are supported.", "JSONError");
815
- }
742
+ int d3 = depth + 2;
743
+ size_t size = d3 * out->indent + 2;
744
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
745
+ const char *classname = rb_class2name(rb_obj_class(obj));
746
+ VALUE args[100];
747
+ int cnt;
748
+ int i;
749
+
750
+ if (NULL == classname || '#' == *classname) {
751
+ raise_json_err("Only named structs are supported.", "JSONError");
752
+ }
816
753
  #ifdef RSTRUCT_LEN
817
754
  #if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
818
- cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
819
- #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
820
- cnt = (int)RSTRUCT_LEN(obj);
821
- #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
755
+ cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
756
+ #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
757
+ cnt = (int)RSTRUCT_LEN(obj);
758
+ #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
822
759
  #else
823
- // This is a bit risky as a struct in C ruby is not the same as a Struct
824
- // class in interpreted Ruby so length() may not be defined.
825
- cnt = FIX2INT(rb_funcall2(obj, oj_length_id, 0, 0));
760
+ // This is a bit risky as a struct in C ruby is not the same as a Struct
761
+ // class in interpreted Ruby so length() may not be defined.
762
+ cnt = FIX2INT(rb_funcall2(obj, oj_length_id, 0, 0));
826
763
  #endif
827
- if (sizeof(args) / sizeof(*args) <= (size_t)cnt) {
828
- // TBD allocate and try again
829
- cnt = 99;
830
- }
831
- dump_obj_classname(rb_class2name(rb_obj_class(obj)), depth, out);
832
-
833
- assure_size(out, size + sep_len + 6);
834
- *out->cur++ = ',';
835
- fill_indent(out, d3);
836
- *out->cur++ = '"';
837
- *out->cur++ = 'v';
838
- *out->cur++ = '"';
839
- if (0 < out->opts->dump_opts.before_size) {
840
- strcpy(out->cur, out->opts->dump_opts.before_sep);
841
- out->cur += out->opts->dump_opts.before_size;
842
- }
843
- *out->cur++ = ':';
844
- if (0 < out->opts->dump_opts.after_size) {
845
- strcpy(out->cur, out->opts->dump_opts.after_sep);
846
- out->cur += out->opts->dump_opts.after_size;
847
- }
848
- for (i = 0; i < cnt; i++) {
764
+ if (sizeof(args) / sizeof(*args) <= (size_t)cnt) {
765
+ // TBD allocate and try again
766
+ cnt = 99;
767
+ }
768
+ dump_obj_classname(rb_class2name(rb_obj_class(obj)), depth, out);
769
+
770
+ assure_size(out, size + sep_len + 6);
771
+ *out->cur++ = ',';
772
+ fill_indent(out, d3);
773
+ APPEND_CHARS(out->cur, "\"v\"", 3);
774
+ if (0 < out->opts->dump_opts.before_size) {
775
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
776
+ }
777
+ *out->cur++ = ':';
778
+ if (0 < out->opts->dump_opts.after_size) {
779
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
780
+ }
781
+ for (i = 0; i < cnt; i++) {
849
782
  #ifdef RSTRUCT_LEN
850
- args[i] = RSTRUCT_GET(obj, i);
783
+ args[i] = RSTRUCT_GET(obj, i);
851
784
  #else
852
- args[i] = rb_struct_aref(obj, INT2FIX(i));
785
+ args[i] = rb_struct_aref(obj, INT2FIX(i));
853
786
  #endif
854
- }
855
- args[cnt] = Qundef;
856
- dump_values_array(args, depth, out);
857
- fill_indent(out, depth);
858
- *out->cur++ = '}';
859
- *out->cur = '\0';
787
+ }
788
+ args[cnt] = Qundef;
789
+ dump_values_array(args, depth, out);
790
+ fill_indent(out, depth);
791
+ *out->cur++ = '}';
792
+ *out->cur = '\0';
860
793
  } else {
861
- oj_dump_obj_to_s(obj, out);
794
+ oj_dump_obj_to_s(obj, out);
862
795
  }
863
796
  }
864
797
 
865
- static void
866
- dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
798
+ static void dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
867
799
  // The json gem uses to_s explicitly. to_s can be overridden while
868
800
  // rb_big2str can not so unless overridden by using add_to_json(Integer)
869
801
  // this must use to_s to pass the json gem unit tests.
870
- volatile VALUE rs;
871
- int cnt;
872
- bool dump_as_string = false;
802
+ volatile VALUE rs;
803
+ int cnt;
804
+ bool dump_as_string = false;
873
805
 
874
806
  if (use_bignum_alt) {
875
- rs = rb_big2str(obj, 10);
807
+ rs = rb_big2str(obj, 10);
876
808
  } else {
877
- rs = rb_funcall(obj, oj_to_s_id, 0);
809
+ rs = oj_safe_string_convert(obj);
878
810
  }
879
811
  rb_check_type(rs, T_STRING);
880
812
  cnt = (int)RSTRING_LEN(rs);
881
813
 
882
814
  if (out->opts->int_range_min != 0 || out->opts->int_range_max != 0) {
883
- dump_as_string = true; // Bignum cannot be inside of Fixnum range
884
- assure_size(out, cnt + 2);
885
- *out->cur++ = '"';
815
+ dump_as_string = true; // Bignum cannot be inside of Fixnum range
816
+ assure_size(out, cnt + 2);
817
+ *out->cur++ = '"';
886
818
  } else {
887
- assure_size(out, cnt);
819
+ assure_size(out, cnt);
888
820
  }
889
- memcpy(out->cur, RSTRING_PTR(rs), cnt);
890
- out->cur += cnt;
821
+ APPEND_CHARS(out->cur, RSTRING_PTR(rs), cnt);
891
822
  if (dump_as_string) {
892
- *out->cur++ = '"';
823
+ *out->cur++ = '"';
893
824
  }
894
825
  *out->cur = '\0';
895
826
  }
896
827
 
897
- static DumpFunc compat_funcs[] = {
898
- NULL, // RUBY_T_NONE = 0x00,
899
- dump_obj, // RUBY_T_OBJECT = 0x01,
900
- oj_dump_class, // RUBY_T_CLASS = 0x02,
901
- oj_dump_class, // RUBY_T_MODULE = 0x03,
902
- dump_float, // RUBY_T_FLOAT = 0x04,
903
- oj_dump_str, // RUBY_T_STRING = 0x05,
904
- dump_obj, // RUBY_T_REGEXP = 0x06,
905
- dump_array, // RUBY_T_ARRAY = 0x07,
906
- dump_hash, // RUBY_T_HASH = 0x08,
907
- dump_struct, // RUBY_T_STRUCT = 0x09,
908
- dump_bignum, // RUBY_T_BIGNUM = 0x0a,
909
- NULL, // RUBY_T_FILE = 0x0b,
910
- dump_obj, // RUBY_T_DATA = 0x0c,
911
- NULL, // RUBY_T_MATCH = 0x0d,
912
- dump_obj, // RUBY_T_COMPLEX = 0x0e,
913
- dump_obj, // RUBY_T_RATIONAL = 0x0f,
914
- NULL, // 0x10
915
- oj_dump_nil, // RUBY_T_NIL = 0x11,
916
- oj_dump_true, // RUBY_T_TRUE = 0x12,
917
- oj_dump_false, // RUBY_T_FALSE = 0x13,
918
- oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
919
- oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
828
+ static DumpFunc compat_funcs[] = {
829
+ NULL, // RUBY_T_NONE = 0x00,
830
+ dump_obj, // RUBY_T_OBJECT = 0x01,
831
+ oj_dump_class, // RUBY_T_CLASS = 0x02,
832
+ oj_dump_class, // RUBY_T_MODULE = 0x03,
833
+ dump_float, // RUBY_T_FLOAT = 0x04,
834
+ oj_dump_str, // RUBY_T_STRING = 0x05,
835
+ dump_obj, // RUBY_T_REGEXP = 0x06,
836
+ dump_array, // RUBY_T_ARRAY = 0x07,
837
+ dump_hash, // RUBY_T_HASH = 0x08,
838
+ dump_struct, // RUBY_T_STRUCT = 0x09,
839
+ dump_bignum, // RUBY_T_BIGNUM = 0x0a,
840
+ NULL, // RUBY_T_FILE = 0x0b,
841
+ dump_obj, // RUBY_T_DATA = 0x0c,
842
+ NULL, // RUBY_T_MATCH = 0x0d,
843
+ dump_obj, // RUBY_T_COMPLEX = 0x0e,
844
+ dump_obj, // RUBY_T_RATIONAL = 0x0f,
845
+ NULL, // 0x10
846
+ oj_dump_nil, // RUBY_T_NIL = 0x11,
847
+ oj_dump_true, // RUBY_T_TRUE = 0x12,
848
+ oj_dump_false, // RUBY_T_FALSE = 0x13,
849
+ oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
850
+ oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
920
851
  };
921
852
 
922
- static void
923
- set_state_depth(VALUE state, int depth) {
924
- VALUE json_module = rb_const_get_at(rb_cObject, rb_intern("JSON"));
925
- VALUE ext = rb_const_get(json_module, rb_intern("Ext"));
926
- VALUE generator = rb_const_get(ext, rb_intern("Generator"));
927
- VALUE state_class = rb_const_get(generator, rb_intern("State"));
853
+ static void set_state_depth(VALUE state, int depth) {
854
+ VALUE json_module = rb_const_get_at(rb_cObject, rb_intern("JSON"));
855
+ VALUE ext = rb_const_get(json_module, rb_intern("Ext"));
856
+ VALUE generator = rb_const_get(ext, rb_intern("Generator"));
857
+ VALUE state_class = rb_const_get(generator, rb_intern("State"));
928
858
 
929
859
  if (state_class == rb_obj_class(state)) {
930
- rb_funcall(state, rb_intern("depth="), 1, INT2NUM(depth));
860
+ rb_funcall(state, rb_intern("depth="), 1, INT2NUM(depth));
931
861
  }
932
862
  }
933
863
 
934
- void
935
- oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
936
- int type = rb_type(obj);
864
+ void oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
865
+ int type = rb_type(obj);
937
866
 
938
- if (Yes == out->opts->trace) {
939
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
940
- }
867
+ TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
941
868
  if (out->opts->dump_opts.max_depth <= depth) {
942
- // When JSON.dump is called then an ArgumentError is expected and the
943
- // limit is the depth inclusive. If JSON.generate is called then a
944
- // NestingError is expected and the limit is inclusive. Worse than
945
- // that there are unit tests for both.
946
- if (CALLER_DUMP == out->caller) {
947
- if (0 < out->argc) {
948
- set_state_depth(*out->argv, depth);
949
- }
950
- rb_raise(rb_eArgError, "Too deeply nested.");
951
- } else if (out->opts->dump_opts.max_depth < depth) {
952
- if (0 < out->argc) {
953
- set_state_depth(*out->argv, depth - 1);
954
- }
955
- raise_json_err("Too deeply nested", "NestingError");
956
- }
869
+ // When JSON.dump is called then an ArgumentError is expected and the
870
+ // limit is the depth inclusive. If JSON.generate is called then a
871
+ // NestingError is expected and the limit is inclusive. Worse than
872
+ // that there are unit tests for both.
873
+ if (CALLER_DUMP == out->caller) {
874
+ if (0 < out->argc) {
875
+ set_state_depth(*out->argv, depth);
876
+ }
877
+ rb_raise(rb_eArgError, "Too deeply nested.");
878
+ } else if (out->opts->dump_opts.max_depth < depth) {
879
+ if (0 < out->argc) {
880
+ set_state_depth(*out->argv, depth - 1);
881
+ }
882
+ raise_json_err("Too deeply nested", "NestingError");
883
+ }
957
884
  }
958
885
  if (0 < type && type <= RUBY_T_FIXNUM) {
959
- DumpFunc f = compat_funcs[type];
886
+ DumpFunc f = compat_funcs[type];
960
887
 
961
- if (NULL != f) {
962
- f(obj, depth, out, as_ok);
963
- if (Yes == out->opts->trace) {
964
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
965
- }
966
- return;
967
- }
888
+ if (NULL != f) {
889
+ f(obj, depth, out, as_ok);
890
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
891
+ return;
892
+ }
968
893
  }
969
894
  oj_dump_nil(Qnil, depth, out, false);
970
- if (Yes == out->opts->trace) {
971
- oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
972
- }
895
+ TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
973
896
  }