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