oj 3.10.6 → 3.12.0

Sign up to get free protection for your applications and to get access to all the features.
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_object.c CHANGED
@@ -1,100 +1,94 @@
1
- /* dump_object.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
4
  #include "dump.h"
7
5
  #include "odd.h"
8
6
  #include "trace.h"
9
7
 
10
- static const char hex_chars[17] = "0123456789abcdef";
8
+ static const char hex_chars[17] = "0123456789abcdef";
11
9
 
12
- static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out);
10
+ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out);
13
11
 
14
- static void
15
- dump_time(VALUE obj, Out out) {
12
+ static void dump_time(VALUE obj, Out out) {
16
13
  switch (out->opts->time_format) {
17
14
  case RubyTime:
18
- case XmlTime: oj_dump_xml_time(obj, out); break;
19
- case UnixZTime: oj_dump_time(obj, out, 1); break;
15
+ case XmlTime: oj_dump_xml_time(obj, out); break;
16
+ case UnixZTime: oj_dump_time(obj, out, 1); break;
20
17
  case UnixTime:
21
- default: oj_dump_time(obj, out, 0); break;
18
+ default: oj_dump_time(obj, out, 0); break;
22
19
  }
23
20
  }
24
21
 
25
- static void
26
- dump_data(VALUE obj, int depth, Out out, bool as_ok) {
27
- VALUE clas = rb_obj_class(obj);
22
+ static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
23
+ VALUE clas = rb_obj_class(obj);
28
24
 
29
25
  if (rb_cTime == clas) {
30
- assure_size(out, 6);
31
- *out->cur++ = '{';
32
- *out->cur++ = '"';
33
- *out->cur++ = '^';
34
- *out->cur++ = 't';
35
- *out->cur++ = '"';
36
- *out->cur++ = ':';
37
- dump_time(obj, out);
38
- *out->cur++ = '}';
39
- *out->cur = '\0';
26
+ assure_size(out, 6);
27
+ *out->cur++ = '{';
28
+ *out->cur++ = '"';
29
+ *out->cur++ = '^';
30
+ *out->cur++ = 't';
31
+ *out->cur++ = '"';
32
+ *out->cur++ = ':';
33
+ dump_time(obj, out);
34
+ *out->cur++ = '}';
35
+ *out->cur = '\0';
40
36
  } else {
41
- if (oj_bigdecimal_class == clas) {
42
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
43
- const char *str = rb_string_value_ptr((VALUE*)&rstr);
44
- int len = (int)RSTRING_LEN(rstr);
45
-
46
- if (No != out->opts->bigdec_as_num) {
47
- oj_dump_raw(str, len, out);
48
- } else if (0 == strcasecmp("Infinity", str)) {
49
- str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
50
- oj_dump_raw(str, len, out);
51
- } else if (0 == strcasecmp("-Infinity", str)) {
52
- str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, false, &len);
53
- oj_dump_raw(str, len, out);
54
- } else {
55
- oj_dump_cstr(str, len, 0, 0, out);
56
- }
57
- } else {
58
- long id = oj_check_circular(obj, out);
59
-
60
- if (0 <= id) {
61
- dump_obj_attrs(obj, clas, id, depth, out);
62
- }
63
- }
37
+ if (oj_bigdecimal_class == clas) {
38
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
39
+ const char * str = rb_string_value_ptr((VALUE *)&rstr);
40
+ int len = (int)RSTRING_LEN(rstr);
41
+
42
+ if (No != out->opts->bigdec_as_num) {
43
+ oj_dump_raw(str, len, out);
44
+ } else if (0 == strcasecmp("Infinity", str)) {
45
+ str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
46
+ oj_dump_raw(str, len, out);
47
+ } else if (0 == strcasecmp("-Infinity", str)) {
48
+ str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, false, &len);
49
+ oj_dump_raw(str, len, out);
50
+ } else {
51
+ oj_dump_cstr(str, len, 0, 0, out);
52
+ }
53
+ } else {
54
+ long id = oj_check_circular(obj, out);
55
+
56
+ if (0 <= id) {
57
+ dump_obj_attrs(obj, clas, id, depth, out);
58
+ }
59
+ }
64
60
  }
65
61
  }
66
62
 
67
- static void
68
- dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
69
- VALUE clas = rb_obj_class(obj);
63
+ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
64
+ VALUE clas = rb_obj_class(obj);
70
65
 
71
66
  if (oj_bigdecimal_class == clas) {
72
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
73
- const char *str = rb_string_value_ptr((VALUE*)&rstr);
74
- int len = (int)RSTRING_LEN(rstr);
75
-
76
- if (0 == strcasecmp("Infinity", str)) {
77
- str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
78
- oj_dump_raw(str, len, out);
79
- } else if (0 == strcasecmp("-Infinity", str)) {
80
- str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, false, &len);
81
- oj_dump_raw(str, len, out);
82
- } else {
83
- oj_dump_raw(str, len, out);
84
- }
67
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
68
+ const char * str = rb_string_value_ptr((VALUE *)&rstr);
69
+ int len = (int)RSTRING_LEN(rstr);
70
+
71
+ if (0 == strcasecmp("Infinity", str)) {
72
+ str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
73
+ oj_dump_raw(str, len, out);
74
+ } else if (0 == strcasecmp("-Infinity", str)) {
75
+ str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, false, &len);
76
+ oj_dump_raw(str, len, out);
77
+ } else {
78
+ oj_dump_raw(str, len, out);
79
+ }
85
80
  } else {
86
- long id = oj_check_circular(obj, out);
81
+ long id = oj_check_circular(obj, out);
87
82
 
88
- if (0 <= id) {
89
- dump_obj_attrs(obj, clas, id, depth, out);
90
- }
83
+ if (0 <= id) {
84
+ dump_obj_attrs(obj, clas, id, depth, out);
85
+ }
91
86
  }
92
87
  }
93
88
 
94
- static void
95
- dump_class(VALUE obj, int depth, Out out, bool as_ok) {
96
- const char *s = rb_class2name(obj);
97
- size_t len = strlen(s);
89
+ static void dump_class(VALUE obj, int depth, Out out, bool as_ok) {
90
+ const char *s = rb_class2name(obj);
91
+ size_t len = strlen(s);
98
92
 
99
93
  assure_size(out, 6);
100
94
  *out->cur++ = '{';
@@ -105,597 +99,584 @@ dump_class(VALUE obj, int depth, Out out, bool as_ok) {
105
99
  *out->cur++ = ':';
106
100
  oj_dump_cstr(s, len, 0, 0, out);
107
101
  *out->cur++ = '}';
108
- *out->cur = '\0';
102
+ *out->cur = '\0';
109
103
  }
110
104
 
111
- static void
112
- dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
113
- size_t size;
114
- int i, cnt;
115
- int d2 = depth + 1;
116
- long id = oj_check_circular(a, out);
105
+ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
106
+ size_t size;
107
+ int i, cnt;
108
+ int d2 = depth + 1;
109
+ long id = oj_check_circular(a, out);
117
110
 
118
111
  if (id < 0) {
119
- return;
112
+ return;
120
113
  }
121
114
  if (Qundef != clas && rb_cArray != clas && ObjectMode == out->opts->mode) {
122
- dump_obj_attrs(a, clas, 0, depth, out);
123
- return;
115
+ dump_obj_attrs(a, clas, 0, depth, out);
116
+ return;
124
117
  }
125
- cnt = (int)RARRAY_LEN(a);
118
+ cnt = (int)RARRAY_LEN(a);
126
119
  *out->cur++ = '[';
127
120
  if (0 < id) {
128
- assure_size(out, d2 * out->indent + 16);
129
- fill_indent(out, d2);
130
- *out->cur++ = '"';
131
- *out->cur++ = '^';
132
- *out->cur++ = 'i';
133
- dump_ulong(id, out);
134
- *out->cur++ = '"';
121
+ assure_size(out, d2 * out->indent + 16);
122
+ fill_indent(out, d2);
123
+ *out->cur++ = '"';
124
+ *out->cur++ = '^';
125
+ *out->cur++ = 'i';
126
+ dump_ulong(id, out);
127
+ *out->cur++ = '"';
135
128
  }
136
129
  size = 2;
137
130
  assure_size(out, 2);
138
131
  if (0 == cnt) {
139
- *out->cur++ = ']';
132
+ *out->cur++ = ']';
140
133
  } else {
141
- if (0 < id) {
142
- *out->cur++ = ',';
143
- }
144
- if (out->opts->dump_opts.use) {
145
- size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
146
- } else {
147
- size = d2 * out->indent + 2;
148
- }
149
- cnt--;
150
- for (i = 0; i <= cnt; i++) {
151
- assure_size(out, size);
152
- if (out->opts->dump_opts.use) {
153
- if (0 < out->opts->dump_opts.array_size) {
154
- strcpy(out->cur, out->opts->dump_opts.array_nl);
155
- out->cur += 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
- strcpy(out->cur, out->opts->dump_opts.indent_str);
161
- out->cur += out->opts->dump_opts.indent_size;
162
- }
163
- }
164
- } else {
165
- fill_indent(out, d2);
166
- }
167
- oj_dump_obj_val(rb_ary_entry(a, i), d2, out);
168
- if (i < cnt) {
169
- *out->cur++ = ',';
170
- }
171
- }
172
- size = depth * out->indent + 1;
173
- assure_size(out, size);
174
- if (out->opts->dump_opts.use) {
175
- //printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size, out->opts->dump_opts->indent);
176
- if (0 < out->opts->dump_opts.array_size) {
177
- strcpy(out->cur, out->opts->dump_opts.array_nl);
178
- out->cur += out->opts->dump_opts.array_size;
179
- }
180
- if (0 < out->opts->dump_opts.indent_size) {
181
- int i;
182
-
183
- for (i = depth; 0 < i; i--) {
184
- strcpy(out->cur, out->opts->dump_opts.indent_str);
185
- out->cur += out->opts->dump_opts.indent_size;
186
- }
187
- }
188
- } else {
189
- fill_indent(out, depth);
190
- }
191
- *out->cur++ = ']';
134
+ if (0 < id) {
135
+ *out->cur++ = ',';
136
+ }
137
+ if (out->opts->dump_opts.use) {
138
+ size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
139
+ } else {
140
+ size = d2 * out->indent + 2;
141
+ }
142
+ cnt--;
143
+ for (i = 0; i <= cnt; i++) {
144
+ assure_size(out, size);
145
+ if (out->opts->dump_opts.use) {
146
+ if (0 < out->opts->dump_opts.array_size) {
147
+ strcpy(out->cur, out->opts->dump_opts.array_nl);
148
+ out->cur += out->opts->dump_opts.array_size;
149
+ }
150
+ if (0 < out->opts->dump_opts.indent_size) {
151
+ int i;
152
+ for (i = d2; 0 < i; i--) {
153
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
154
+ out->cur += out->opts->dump_opts.indent_size;
155
+ }
156
+ }
157
+ } else {
158
+ fill_indent(out, d2);
159
+ }
160
+ oj_dump_obj_val(rb_ary_entry(a, i), d2, out);
161
+ if (i < cnt) {
162
+ *out->cur++ = ',';
163
+ }
164
+ }
165
+ size = depth * out->indent + 1;
166
+ assure_size(out, size);
167
+ if (out->opts->dump_opts.use) {
168
+ // printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size,
169
+ // out->opts->dump_opts->indent);
170
+ if (0 < out->opts->dump_opts.array_size) {
171
+ strcpy(out->cur, out->opts->dump_opts.array_nl);
172
+ out->cur += out->opts->dump_opts.array_size;
173
+ }
174
+ if (0 < out->opts->dump_opts.indent_size) {
175
+ int i;
176
+
177
+ for (i = depth; 0 < i; i--) {
178
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
179
+ out->cur += out->opts->dump_opts.indent_size;
180
+ }
181
+ }
182
+ } else {
183
+ fill_indent(out, depth);
184
+ }
185
+ *out->cur++ = ']';
192
186
  }
193
187
  *out->cur = '\0';
194
188
  }
195
189
 
196
- static void
197
- dump_array(VALUE obj, int depth, Out out, bool as_ok) {
190
+ static void dump_array(VALUE obj, int depth, Out out, bool as_ok) {
198
191
  dump_array_class(obj, rb_obj_class(obj), depth, out);
199
192
  }
200
193
 
201
- static void
202
- dump_str_class(VALUE obj, VALUE clas, int depth, Out out) {
194
+ static void dump_str_class(VALUE obj, VALUE clas, int depth, Out out) {
203
195
  if (Qundef != clas && rb_cString != clas) {
204
- dump_obj_attrs(obj, clas, 0, depth, out);
196
+ dump_obj_attrs(obj, clas, 0, depth, out);
205
197
  } else {
206
- const char *s = rb_string_value_ptr((VALUE*)&obj);
207
- size_t len = (int)RSTRING_LEN(obj);
208
- char s1 = s[1];
198
+ const char *s = rb_string_value_ptr((VALUE *)&obj);
199
+ size_t len = (int)RSTRING_LEN(obj);
200
+ char s1 = s[1];
209
201
 
210
- oj_dump_cstr(s, len, 0, (':' == *s || ('^' == *s && ('r' == s1 || 'i' == s1))), out);
202
+ oj_dump_cstr(s, len, 0, (':' == *s || ('^' == *s && ('r' == s1 || 'i' == s1))), out);
211
203
  }
212
204
  }
213
205
 
214
- static void
215
- dump_str(VALUE obj, int depth, Out out, bool as_ok) {
206
+ static void dump_str(VALUE obj, int depth, Out out, bool as_ok) {
216
207
  dump_str_class(obj, rb_obj_class(obj), depth, out);
217
208
  }
218
209
 
219
- static void
220
- dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
221
- volatile VALUE s = rb_sym_to_s(obj);
210
+ static void dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
211
+ volatile VALUE s = rb_sym_to_s(obj);
222
212
 
223
- oj_dump_cstr(rb_string_value_ptr((VALUE*)&s), (int)RSTRING_LEN(s), 1, 0, out);
213
+ oj_dump_cstr(rb_string_value_ptr((VALUE *)&s), (int)RSTRING_LEN(s), 1, 0, out);
224
214
  }
225
215
 
226
- static int
227
- hash_cb(VALUE key, VALUE value, VALUE ov) {
228
- Out out = (Out)ov;
229
- int depth = out->depth;
230
- long size = depth * out->indent + 1;
216
+ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
217
+ Out out = (Out)ov;
218
+ int depth = out->depth;
219
+ long size = depth * out->indent + 1;
231
220
 
232
221
  if (oj_dump_ignore(out->opts, value)) {
233
- return ST_CONTINUE;
222
+ return ST_CONTINUE;
234
223
  }
235
224
  if (out->omit_nil && Qnil == value) {
236
- return ST_CONTINUE;
225
+ return ST_CONTINUE;
237
226
  }
238
227
  assure_size(out, size);
239
228
  fill_indent(out, depth);
240
229
  if (rb_type(key) == T_STRING) {
241
- dump_str_class(key, Qundef, depth, out);
242
- *out->cur++ = ':';
243
- oj_dump_obj_val(value, depth, out);
230
+ dump_str_class(key, Qundef, depth, out);
231
+ *out->cur++ = ':';
232
+ oj_dump_obj_val(value, depth, out);
244
233
  } else if (rb_type(key) == T_SYMBOL) {
245
- dump_sym(key, 0, out, false);
246
- *out->cur++ = ':';
247
- oj_dump_obj_val(value, depth, out);
234
+ dump_sym(key, 0, out, false);
235
+ *out->cur++ = ':';
236
+ oj_dump_obj_val(value, depth, out);
248
237
  } else {
249
- int d2 = depth + 1;
250
- long s2 = size + out->indent + 1;
251
- int i;
252
- int started = 0;
253
- uint8_t b;
254
-
255
- assure_size(out, s2 + 15);
256
- *out->cur++ = '"';
257
- *out->cur++ = '^';
258
- *out->cur++ = '#';
259
- out->hash_cnt++;
260
- for (i = 28; 0 <= i; i -= 4) {
261
- b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
262
- if ('\0' != b) {
263
- started = 1;
264
- }
265
- if (started) {
266
- *out->cur++ = hex_chars[b];
267
- }
268
- }
269
- *out->cur++ = '"';
270
- *out->cur++ = ':';
271
- *out->cur++ = '[';
272
- fill_indent(out, d2);
273
- oj_dump_obj_val(key, d2, out);
274
- assure_size(out, s2);
275
- *out->cur++ = ',';
276
- fill_indent(out, d2);
277
- oj_dump_obj_val(value, d2, out);
278
- assure_size(out, size);
279
- fill_indent(out, depth);
280
- *out->cur++ = ']';
281
- }
282
- out->depth = depth;
238
+ int d2 = depth + 1;
239
+ long s2 = size + out->indent + 1;
240
+ int i;
241
+ int started = 0;
242
+ uint8_t b;
243
+
244
+ assure_size(out, s2 + 15);
245
+ *out->cur++ = '"';
246
+ *out->cur++ = '^';
247
+ *out->cur++ = '#';
248
+ out->hash_cnt++;
249
+ for (i = 28; 0 <= i; i -= 4) {
250
+ b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
251
+ if ('\0' != b) {
252
+ started = 1;
253
+ }
254
+ if (started) {
255
+ *out->cur++ = hex_chars[b];
256
+ }
257
+ }
258
+ *out->cur++ = '"';
259
+ *out->cur++ = ':';
260
+ *out->cur++ = '[';
261
+ fill_indent(out, d2);
262
+ oj_dump_obj_val(key, d2, out);
263
+ assure_size(out, s2);
264
+ *out->cur++ = ',';
265
+ fill_indent(out, d2);
266
+ oj_dump_obj_val(value, d2, out);
267
+ assure_size(out, size);
268
+ fill_indent(out, depth);
269
+ *out->cur++ = ']';
270
+ }
271
+ out->depth = depth;
283
272
  *out->cur++ = ',';
284
273
 
285
274
  return ST_CONTINUE;
286
275
  }
287
276
 
288
- static void
289
- dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
290
- int cnt;
291
- size_t size;
277
+ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
278
+ int cnt;
279
+ size_t size;
292
280
 
293
281
  if (Qundef != clas && rb_cHash != clas) {
294
- dump_obj_attrs(obj, clas, 0, depth, out);
295
- return;
282
+ dump_obj_attrs(obj, clas, 0, depth, out);
283
+ return;
296
284
  }
297
- cnt = (int)RHASH_SIZE(obj);
285
+ cnt = (int)RHASH_SIZE(obj);
298
286
  size = depth * out->indent + 2;
299
287
  assure_size(out, 2);
300
288
  if (0 == cnt) {
301
- *out->cur++ = '{';
302
- *out->cur++ = '}';
289
+ *out->cur++ = '{';
290
+ *out->cur++ = '}';
303
291
  } else {
304
- long id = oj_check_circular(obj, out);
305
-
306
- if (0 > id) {
307
- return;
308
- }
309
- *out->cur++ = '{';
310
- if (0 < id) {
311
- assure_size(out, size + 16);
312
- fill_indent(out, depth + 1);
313
- *out->cur++ = '"';
314
- *out->cur++ = '^';
315
- *out->cur++ = 'i';
316
- *out->cur++ = '"';
317
- *out->cur++ = ':';
318
- dump_ulong(id, out);
319
- *out->cur++ = ',';
320
- }
321
- out->depth = depth + 1;
322
- rb_hash_foreach(obj, hash_cb, (VALUE)out);
323
- if (',' == *(out->cur - 1)) {
324
- out->cur--; // backup to overwrite last comma
325
- }
326
- if (!out->opts->dump_opts.use) {
327
- assure_size(out, size);
328
- fill_indent(out, depth);
329
- } else {
330
- size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
331
- assure_size(out, size);
332
- if (0 < out->opts->dump_opts.hash_size) {
333
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
334
- out->cur += out->opts->dump_opts.hash_size;
335
- }
336
- if (0 < out->opts->dump_opts.indent_size) {
337
- int i;
338
-
339
- for (i = depth; 0 < i; i--) {
340
- strcpy(out->cur, out->opts->dump_opts.indent_str);
341
- out->cur += out->opts->dump_opts.indent_size;
342
- }
343
- }
344
- }
345
- *out->cur++ = '}';
292
+ long id = oj_check_circular(obj, out);
293
+
294
+ if (0 > id) {
295
+ return;
296
+ }
297
+ *out->cur++ = '{';
298
+ if (0 < id) {
299
+ assure_size(out, size + 16);
300
+ fill_indent(out, depth + 1);
301
+ *out->cur++ = '"';
302
+ *out->cur++ = '^';
303
+ *out->cur++ = 'i';
304
+ *out->cur++ = '"';
305
+ *out->cur++ = ':';
306
+ dump_ulong(id, out);
307
+ *out->cur++ = ',';
308
+ }
309
+ out->depth = depth + 1;
310
+ rb_hash_foreach(obj, hash_cb, (VALUE)out);
311
+ if (',' == *(out->cur - 1)) {
312
+ out->cur--; // backup to overwrite last comma
313
+ }
314
+ if (!out->opts->dump_opts.use) {
315
+ assure_size(out, size);
316
+ fill_indent(out, depth);
317
+ } else {
318
+ size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
319
+ assure_size(out, size);
320
+ if (0 < out->opts->dump_opts.hash_size) {
321
+ strcpy(out->cur, out->opts->dump_opts.hash_nl);
322
+ out->cur += out->opts->dump_opts.hash_size;
323
+ }
324
+ if (0 < out->opts->dump_opts.indent_size) {
325
+ int i;
326
+
327
+ for (i = depth; 0 < i; i--) {
328
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
329
+ out->cur += out->opts->dump_opts.indent_size;
330
+ }
331
+ }
332
+ }
333
+ *out->cur++ = '}';
346
334
  }
347
335
  *out->cur = '\0';
348
336
  }
349
337
 
350
338
  #ifdef HAVE_RB_IVAR_FOREACH
351
- static int
352
- dump_attr_cb(ID key, VALUE value, VALUE ov) {
353
- Out out = (Out)ov;
354
- int depth = out->depth;
355
- size_t size = depth * out->indent + 1;
356
- const char *attr = rb_id2name(key);
339
+ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
340
+ Out out = (Out)ov;
341
+ int depth = out->depth;
342
+ size_t size = depth * out->indent + 1;
343
+ const char *attr = rb_id2name(key);
357
344
 
358
345
  if (oj_dump_ignore(out->opts, value)) {
359
- return ST_CONTINUE;
346
+ return ST_CONTINUE;
360
347
  }
361
348
  if (out->omit_nil && Qnil == value) {
362
- return ST_CONTINUE;
349
+ return ST_CONTINUE;
363
350
  }
364
351
  // Some exceptions such as NoMethodError have an invisible attribute where
365
352
  // the key name is NULL. Not an empty string but NULL.
366
353
  if (NULL == attr) {
367
- attr = "";
354
+ attr = "";
368
355
  } else if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
369
- return ST_CONTINUE;
356
+ return ST_CONTINUE;
370
357
  }
371
358
  if (0 == strcmp("bt", attr) || 0 == strcmp("mesg", attr)) {
372
- return ST_CONTINUE;
359
+ return ST_CONTINUE;
373
360
  }
374
361
  assure_size(out, size);
375
362
  fill_indent(out, depth);
376
363
  if ('@' == *attr) {
377
- attr++;
378
- oj_dump_cstr(attr, strlen(attr), 0, 0, out);
364
+ attr++;
365
+ oj_dump_cstr(attr, strlen(attr), 0, 0, out);
379
366
  } else {
380
- char buf[32];
367
+ char buf[32];
381
368
 
382
- *buf = '~';
383
- strncpy(buf + 1, attr, sizeof(buf) - 2);
384
- buf[sizeof(buf) - 1] = '\0';
385
- oj_dump_cstr(buf, strlen(buf), 0, 0, out);
369
+ *buf = '~';
370
+ strncpy(buf + 1, attr, sizeof(buf) - 2);
371
+ buf[sizeof(buf) - 1] = '\0';
372
+ oj_dump_cstr(buf, strlen(buf), 0, 0, out);
386
373
  }
387
374
  *out->cur++ = ':';
388
375
  oj_dump_obj_val(value, depth, out);
389
- out->depth = depth;
376
+ out->depth = depth;
390
377
  *out->cur++ = ',';
391
378
 
392
379
  return ST_CONTINUE;
393
380
  }
394
381
  #endif
395
382
 
396
- static void
397
- dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
383
+ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
398
384
  dump_hash_class(obj, rb_obj_class(obj), depth, out);
399
385
  }
400
386
 
401
- static void
402
- dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
403
- ID *idp;
404
- AttrGetFunc *fp;
405
- volatile VALUE v;
406
- const char *name;
407
- size_t size;
408
- int d2 = depth + 1;
387
+ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
388
+ ID * idp;
389
+ AttrGetFunc * fp;
390
+ volatile VALUE v;
391
+ const char * name;
392
+ size_t size;
393
+ int d2 = depth + 1;
409
394
 
410
395
  assure_size(out, 2);
411
396
  *out->cur++ = '{';
412
397
  if (Qundef != clas) {
413
- const char *class_name = rb_class2name(clas);
414
- int clen = (int)strlen(class_name);
415
-
416
- size = d2 * out->indent + clen + 10;
417
- assure_size(out, size);
418
- fill_indent(out, d2);
419
- *out->cur++ = '"';
420
- *out->cur++ = '^';
421
- *out->cur++ = 'O';
422
- *out->cur++ = '"';
423
- *out->cur++ = ':';
424
- oj_dump_cstr(class_name, clen, 0, 0, out);
425
- *out->cur++ = ',';
398
+ const char *class_name = rb_class2name(clas);
399
+ int clen = (int)strlen(class_name);
400
+
401
+ size = d2 * out->indent + clen + 10;
402
+ assure_size(out, size);
403
+ fill_indent(out, d2);
404
+ *out->cur++ = '"';
405
+ *out->cur++ = '^';
406
+ *out->cur++ = 'O';
407
+ *out->cur++ = '"';
408
+ *out->cur++ = ':';
409
+ oj_dump_cstr(class_name, clen, 0, 0, out);
410
+ *out->cur++ = ',';
426
411
  }
427
412
  if (odd->raw) {
428
- v = rb_funcall(obj, *odd->attrs, 0);
429
- if (Qundef == v || T_STRING != rb_type(v)) {
430
- rb_raise(rb_eEncodingError, "Invalid type for raw JSON.");
431
- } else {
432
- const char *s = rb_string_value_ptr((VALUE*)&v);
433
- int len = (int)RSTRING_LEN(v);
434
- const char *name = rb_id2name(*odd->attrs);
435
- size_t nlen = strlen(name);
436
-
437
- size = len + d2 * out->indent + nlen + 10;
438
- assure_size(out, size);
439
- fill_indent(out, d2);
440
- *out->cur++ = '"';
441
- memcpy(out->cur, name, nlen);
442
- out->cur += nlen;
443
- *out->cur++ = '"';
444
- *out->cur++ = ':';
445
- memcpy(out->cur, s, len);
446
- out->cur += len;
447
- *out->cur = '\0';
448
- }
413
+ v = rb_funcall(obj, *odd->attrs, 0);
414
+ if (Qundef == v || T_STRING != rb_type(v)) {
415
+ rb_raise(rb_eEncodingError, "Invalid type for raw JSON.");
416
+ } else {
417
+ const char *s = rb_string_value_ptr((VALUE *)&v);
418
+ int len = (int)RSTRING_LEN(v);
419
+ const char *name = rb_id2name(*odd->attrs);
420
+ size_t nlen = strlen(name);
421
+
422
+ size = len + d2 * out->indent + nlen + 10;
423
+ assure_size(out, size);
424
+ fill_indent(out, d2);
425
+ *out->cur++ = '"';
426
+ memcpy(out->cur, name, nlen);
427
+ out->cur += nlen;
428
+ *out->cur++ = '"';
429
+ *out->cur++ = ':';
430
+ memcpy(out->cur, s, len);
431
+ out->cur += len;
432
+ *out->cur = '\0';
433
+ }
449
434
  } else {
450
- size = d2 * out->indent + 1;
451
- for (idp = odd->attrs, fp = odd->attrFuncs; 0 != *idp; idp++, fp++) {
452
- size_t nlen;
453
-
454
- assure_size(out, size);
455
- name = rb_id2name(*idp);
456
- nlen = strlen(name);
457
- if (0 != *fp) {
458
- v = (*fp)(obj);
459
- } else if (0 == strchr(name, '.')) {
460
- v = rb_funcall(obj, *idp, 0);
461
- } else {
462
- char nbuf[256];
463
- char *n2 = nbuf;
464
- char *n;
465
- char *end;
466
- ID i;
467
-
468
- if (sizeof(nbuf) <= nlen) {
469
- if (NULL == (n2 = strdup(name))) {
470
- rb_raise(rb_eNoMemError, "for attribute name.");
471
- }
472
- } else {
473
- strcpy(n2, name);
474
- }
475
- n = n2;
476
- v = obj;
477
- while (0 != (end = strchr(n, '.'))) {
478
- *end = '\0';
479
- i = rb_intern(n);
480
- v = rb_funcall(v, i, 0);
481
- n = end + 1;
482
- }
483
- i = rb_intern(n);
484
- v = rb_funcall(v, i, 0);
485
- if (nbuf != n2) {
486
- free(n2);
487
- }
488
- }
489
- fill_indent(out, d2);
490
- oj_dump_cstr(name, nlen, 0, 0, out);
491
- *out->cur++ = ':';
492
- oj_dump_obj_val(v, d2, out);
493
- assure_size(out, 2);
494
- *out->cur++ = ',';
495
- }
496
- out->cur--;
435
+ size = d2 * out->indent + 1;
436
+ for (idp = odd->attrs, fp = odd->attrFuncs; 0 != *idp; idp++, fp++) {
437
+ size_t nlen;
438
+
439
+ assure_size(out, size);
440
+ name = rb_id2name(*idp);
441
+ nlen = strlen(name);
442
+ if (0 != *fp) {
443
+ v = (*fp)(obj);
444
+ } else if (0 == strchr(name, '.')) {
445
+ v = rb_funcall(obj, *idp, 0);
446
+ } else {
447
+ char nbuf[256];
448
+ char *n2 = nbuf;
449
+ char *n;
450
+ char *end;
451
+ ID i;
452
+
453
+ if (sizeof(nbuf) <= nlen) {
454
+ if (NULL == (n2 = strdup(name))) {
455
+ rb_raise(rb_eNoMemError, "for attribute name.");
456
+ }
457
+ } else {
458
+ strcpy(n2, name);
459
+ }
460
+ n = n2;
461
+ v = obj;
462
+ while (0 != (end = strchr(n, '.'))) {
463
+ *end = '\0';
464
+ i = rb_intern(n);
465
+ v = rb_funcall(v, i, 0);
466
+ n = end + 1;
467
+ }
468
+ i = rb_intern(n);
469
+ v = rb_funcall(v, i, 0);
470
+ if (nbuf != n2) {
471
+ free(n2);
472
+ }
473
+ }
474
+ fill_indent(out, d2);
475
+ oj_dump_cstr(name, nlen, 0, 0, out);
476
+ *out->cur++ = ':';
477
+ oj_dump_obj_val(v, d2, out);
478
+ assure_size(out, 2);
479
+ *out->cur++ = ',';
480
+ }
481
+ out->cur--;
497
482
  }
498
483
  *out->cur++ = '}';
499
- *out->cur = '\0';
484
+ *out->cur = '\0';
500
485
  }
501
486
 
502
- static void
503
- dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
504
- size_t size = 0;
505
- int d2 = depth + 1;
506
- int type = rb_type(obj);
507
- Odd odd;
487
+ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
488
+ size_t size = 0;
489
+ int d2 = depth + 1;
490
+ int type = rb_type(obj);
491
+ Odd odd;
508
492
 
509
493
  if (0 != (odd = oj_get_odd(clas))) {
510
- dump_odd(obj, odd, clas, depth + 1, out);
511
- return;
494
+ dump_odd(obj, odd, clas, depth + 1, out);
495
+ return;
512
496
  }
513
497
  assure_size(out, 2);
514
498
  *out->cur++ = '{';
515
499
  if (Qundef != clas) {
516
- const char *class_name = rb_class2name(clas);
517
- int clen = (int)strlen(class_name);
518
-
519
- assure_size(out, d2 * out->indent + clen + 10);
520
- fill_indent(out, d2);
521
- *out->cur++ = '"';
522
- *out->cur++ = '^';
523
- *out->cur++ = 'o';
524
- *out->cur++ = '"';
525
- *out->cur++ = ':';
526
- oj_dump_cstr(class_name, clen, 0, 0, out);
500
+ const char *class_name = rb_class2name(clas);
501
+ int clen = (int)strlen(class_name);
502
+
503
+ assure_size(out, d2 * out->indent + clen + 10);
504
+ fill_indent(out, d2);
505
+ *out->cur++ = '"';
506
+ *out->cur++ = '^';
507
+ *out->cur++ = 'o';
508
+ *out->cur++ = '"';
509
+ *out->cur++ = ':';
510
+ oj_dump_cstr(class_name, clen, 0, 0, out);
527
511
  }
528
512
  if (0 < id) {
529
- assure_size(out, d2 * out->indent + 16);
530
- *out->cur++ = ',';
531
- fill_indent(out, d2);
532
- *out->cur++ = '"';
533
- *out->cur++ = '^';
534
- *out->cur++ = 'i';
535
- *out->cur++ = '"';
536
- *out->cur++ = ':';
537
- dump_ulong(id, out);
513
+ assure_size(out, d2 * out->indent + 16);
514
+ *out->cur++ = ',';
515
+ fill_indent(out, d2);
516
+ *out->cur++ = '"';
517
+ *out->cur++ = '^';
518
+ *out->cur++ = 'i';
519
+ *out->cur++ = '"';
520
+ *out->cur++ = ':';
521
+ dump_ulong(id, out);
538
522
  }
539
523
  switch (type) {
540
524
  case T_STRING:
541
- assure_size(out, d2 * out->indent + 14);
542
- *out->cur++ = ',';
543
- fill_indent(out, d2);
544
- *out->cur++ = '"';
545
- *out->cur++ = 's';
546
- *out->cur++ = 'e';
547
- *out->cur++ = 'l';
548
- *out->cur++ = 'f';
549
- *out->cur++ = '"';
550
- *out->cur++ = ':';
551
- oj_dump_cstr(rb_string_value_ptr((VALUE*)&obj), (int)RSTRING_LEN(obj), 0, 0, out);
552
- break;
525
+ assure_size(out, d2 * out->indent + 14);
526
+ *out->cur++ = ',';
527
+ fill_indent(out, d2);
528
+ *out->cur++ = '"';
529
+ *out->cur++ = 's';
530
+ *out->cur++ = 'e';
531
+ *out->cur++ = 'l';
532
+ *out->cur++ = 'f';
533
+ *out->cur++ = '"';
534
+ *out->cur++ = ':';
535
+ oj_dump_cstr(rb_string_value_ptr((VALUE *)&obj), (int)RSTRING_LEN(obj), 0, 0, out);
536
+ break;
553
537
  case T_ARRAY:
554
- assure_size(out, d2 * out->indent + 14);
555
- *out->cur++ = ',';
556
- fill_indent(out, d2);
557
- *out->cur++ = '"';
558
- *out->cur++ = 's';
559
- *out->cur++ = 'e';
560
- *out->cur++ = 'l';
561
- *out->cur++ = 'f';
562
- *out->cur++ = '"';
563
- *out->cur++ = ':';
564
- dump_array_class(obj, Qundef, depth + 1, out);
565
- break;
538
+ assure_size(out, d2 * out->indent + 14);
539
+ *out->cur++ = ',';
540
+ fill_indent(out, d2);
541
+ *out->cur++ = '"';
542
+ *out->cur++ = 's';
543
+ *out->cur++ = 'e';
544
+ *out->cur++ = 'l';
545
+ *out->cur++ = 'f';
546
+ *out->cur++ = '"';
547
+ *out->cur++ = ':';
548
+ dump_array_class(obj, Qundef, depth + 1, out);
549
+ break;
566
550
  case T_HASH:
567
- assure_size(out, d2 * out->indent + 14);
568
- *out->cur++ = ',';
569
- fill_indent(out, d2);
570
- *out->cur++ = '"';
571
- *out->cur++ = 's';
572
- *out->cur++ = 'e';
573
- *out->cur++ = 'l';
574
- *out->cur++ = 'f';
575
- *out->cur++ = '"';
576
- *out->cur++ = ':';
577
- dump_hash_class(obj, Qundef, depth + 1, out);
578
- break;
579
- default:
580
- break;
551
+ assure_size(out, d2 * out->indent + 14);
552
+ *out->cur++ = ',';
553
+ fill_indent(out, d2);
554
+ *out->cur++ = '"';
555
+ *out->cur++ = 's';
556
+ *out->cur++ = 'e';
557
+ *out->cur++ = 'l';
558
+ *out->cur++ = 'f';
559
+ *out->cur++ = '"';
560
+ *out->cur++ = ':';
561
+ dump_hash_class(obj, Qundef, depth + 1, out);
562
+ break;
563
+ default: break;
581
564
  }
582
565
  {
583
- int cnt;
566
+ int cnt;
584
567
  #ifdef HAVE_RB_IVAR_COUNT
585
- cnt = (int)rb_ivar_count(obj);
568
+ cnt = (int)rb_ivar_count(obj);
586
569
  #else
587
- volatile VALUE vars = rb_funcall2(obj, oj_instance_variables_id, 0, 0);
588
- VALUE *np = RARRAY_PTR(vars);
589
- ID vid;
590
- const char *attr;
591
- int i;
592
- int first = 1;
593
-
594
- cnt = (int)RARRAY_LEN(vars);
570
+ volatile VALUE vars = rb_funcall2(obj, oj_instance_variables_id, 0, 0);
571
+ VALUE * np = RARRAY_PTR(vars);
572
+ ID vid;
573
+ const char * attr;
574
+ int i;
575
+ int first = 1;
576
+
577
+ cnt = (int)RARRAY_LEN(vars);
595
578
  #endif
596
- if (Qundef != clas && 0 < cnt) {
597
- *out->cur++ = ',';
598
- }
599
- if (0 == cnt && Qundef == clas) {
600
- // Might be something special like an Enumerable.
601
- if (Qtrue == rb_obj_is_kind_of(obj, oj_enumerable_class)) {
602
- out->cur--;
603
- oj_dump_obj_val(rb_funcall(obj, rb_intern("entries"), 0), depth, out);
604
- return;
605
- }
606
- }
607
- out->depth = depth + 1;
579
+ if (Qundef != clas && 0 < cnt) {
580
+ *out->cur++ = ',';
581
+ }
582
+ if (0 == cnt && Qundef == clas) {
583
+ // Might be something special like an Enumerable.
584
+ if (Qtrue == rb_obj_is_kind_of(obj, oj_enumerable_class)) {
585
+ out->cur--;
586
+ oj_dump_obj_val(rb_funcall(obj, rb_intern("entries"), 0), depth, out);
587
+ return;
588
+ }
589
+ }
590
+ out->depth = depth + 1;
608
591
  #ifdef HAVE_RB_IVAR_FOREACH
609
- rb_ivar_foreach(obj, dump_attr_cb, (VALUE)out);
610
- if (',' == *(out->cur - 1)) {
611
- out->cur--; // backup to overwrite last comma
612
- }
592
+ rb_ivar_foreach(obj, dump_attr_cb, (VALUE)out);
593
+ if (',' == *(out->cur - 1)) {
594
+ out->cur--; // backup to overwrite last comma
595
+ }
613
596
  #else
614
- size = d2 * out->indent + 1;
615
- for (i = cnt; 0 < i; i--, np++) {
616
- VALUE value;
617
-
618
- vid = rb_to_id(*np);
619
- attr = rb_id2name(vid);
620
- if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
621
- continue;
622
- }
623
- value = rb_ivar_get(obj, vid);
624
-
625
- if (oj_dump_ignore(out->opts, value)) {
626
- continue;
627
- }
628
- if (out->omit_nil && Qnil == value) {
629
- continue;
630
- }
631
- if (first) {
632
- first = 0;
633
- } else {
634
- *out->cur++ = ',';
635
- }
636
- assure_size(out, size);
637
- fill_indent(out, d2);
638
- if ('@' == *attr) {
639
- attr++;
640
- oj_dump_cstr(attr, strlen(attr), 0, 0, out);
641
- } else {
642
- char buf[32];
643
-
644
- *buf = '~';
645
- strncpy(buf + 1, attr, sizeof(buf) - 2);
646
- buf[sizeof(buf) - 1] = '\0';
647
- oj_dump_cstr(buf, strlen(attr) + 1, 0, 0, out);
648
- }
649
- *out->cur++ = ':';
650
- oj_dump_obj_val(value, d2, out);
651
- assure_size(out, 2);
652
- }
597
+ size = d2 * out->indent + 1;
598
+ for (i = cnt; 0 < i; i--, np++) {
599
+ VALUE value;
600
+
601
+ vid = rb_to_id(*np);
602
+ attr = rb_id2name(vid);
603
+ if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
604
+ continue;
605
+ }
606
+ value = rb_ivar_get(obj, vid);
607
+
608
+ if (oj_dump_ignore(out->opts, value)) {
609
+ continue;
610
+ }
611
+ if (out->omit_nil && Qnil == value) {
612
+ continue;
613
+ }
614
+ if (first) {
615
+ first = 0;
616
+ } else {
617
+ *out->cur++ = ',';
618
+ }
619
+ assure_size(out, size);
620
+ fill_indent(out, d2);
621
+ if ('@' == *attr) {
622
+ attr++;
623
+ oj_dump_cstr(attr, strlen(attr), 0, 0, out);
624
+ } else {
625
+ char buf[32];
626
+
627
+ *buf = '~';
628
+ strncpy(buf + 1, attr, sizeof(buf) - 2);
629
+ buf[sizeof(buf) - 1] = '\0';
630
+ oj_dump_cstr(buf, strlen(attr) + 1, 0, 0, out);
631
+ }
632
+ *out->cur++ = ':';
633
+ oj_dump_obj_val(value, d2, out);
634
+ assure_size(out, 2);
635
+ }
653
636
  #endif
654
- if (rb_obj_is_kind_of(obj, rb_eException)) {
655
- volatile VALUE rv;
656
-
657
- if (',' != *(out->cur - 1)) {
658
- *out->cur++ = ',';
659
- }
660
- // message
661
- assure_size(out, size);
662
- fill_indent(out, d2);
663
- oj_dump_cstr("~mesg", 5, 0, 0, out);
664
- *out->cur++ = ':';
665
- rv = rb_funcall2(obj, rb_intern("message"), 0, 0);
666
- oj_dump_obj_val(rv, d2, out);
667
- assure_size(out, 2);
668
- *out->cur++ = ',';
669
- // backtrace
670
- assure_size(out, size);
671
- fill_indent(out, d2);
672
- oj_dump_cstr("~bt", 3, 0, 0, out);
673
- *out->cur++ = ':';
674
- rv = rb_funcall2(obj, rb_intern("backtrace"), 0, 0);
675
- oj_dump_obj_val(rv, d2, out);
676
- assure_size(out, 2);
677
- }
678
- out->depth = depth;
637
+ if (rb_obj_is_kind_of(obj, rb_eException)) {
638
+ volatile VALUE rv;
639
+
640
+ if (',' != *(out->cur - 1)) {
641
+ *out->cur++ = ',';
642
+ }
643
+ // message
644
+ assure_size(out, size);
645
+ fill_indent(out, d2);
646
+ oj_dump_cstr("~mesg", 5, 0, 0, out);
647
+ *out->cur++ = ':';
648
+ rv = rb_funcall2(obj, rb_intern("message"), 0, 0);
649
+ oj_dump_obj_val(rv, d2, out);
650
+ assure_size(out, 2);
651
+ *out->cur++ = ',';
652
+ // backtrace
653
+ assure_size(out, size);
654
+ fill_indent(out, d2);
655
+ oj_dump_cstr("~bt", 3, 0, 0, out);
656
+ *out->cur++ = ':';
657
+ rv = rb_funcall2(obj, rb_intern("backtrace"), 0, 0);
658
+ oj_dump_obj_val(rv, d2, out);
659
+ assure_size(out, 2);
660
+ }
661
+ out->depth = depth;
679
662
  }
680
663
  fill_indent(out, depth);
681
664
  *out->cur++ = '}';
682
- *out->cur = '\0';
665
+ *out->cur = '\0';
683
666
  }
684
667
 
685
- static void
686
- dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
668
+ static void dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
687
669
  dump_obj_attrs(obj, rb_obj_class(obj), 0, depth, out);
688
670
  }
689
671
 
690
- static void
691
- dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
692
- VALUE clas = rb_obj_class(obj);
693
- const char *class_name = rb_class2name(clas);
694
- int i;
695
- int d2 = depth + 1;
696
- int d3 = d2 + 1;
697
- size_t len = strlen(class_name);
698
- size_t size = d2 * out->indent + d3 * out->indent + 10 + len;
672
+ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
673
+ VALUE clas = rb_obj_class(obj);
674
+ const char *class_name = rb_class2name(clas);
675
+ int i;
676
+ int d2 = depth + 1;
677
+ int d3 = d2 + 1;
678
+ size_t len = strlen(class_name);
679
+ size_t size = d2 * out->indent + d3 * out->indent + 10 + len;
699
680
 
700
681
  assure_size(out, size);
701
682
  *out->cur++ = '{';
@@ -707,138 +688,135 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
707
688
  *out->cur++ = ':';
708
689
  *out->cur++ = '[';
709
690
  if ('#' == *class_name) {
710
- VALUE ma = rb_struct_s_members(clas);
711
- const char *name;
712
- int cnt = (int)RARRAY_LEN(ma);
713
-
714
- *out->cur++ = '[';
715
- for (i = 0; i < cnt; i++) {
716
- volatile VALUE s = rb_sym_to_s(rb_ary_entry(ma, i));
717
-
718
- name = rb_string_value_ptr((VALUE*)&s);
719
- len = (int)RSTRING_LEN(s);
720
- size = len + 3;
721
- assure_size(out, size);
722
- if (0 < i) {
723
- *out->cur++ = ',';
724
- }
725
- *out->cur++ = '"';
726
- memcpy(out->cur, name, len);
727
- out->cur += len;
728
- *out->cur++ = '"';
729
- }
730
- *out->cur++ = ']';
691
+ VALUE ma = rb_struct_s_members(clas);
692
+ const char *name;
693
+ int cnt = (int)RARRAY_LEN(ma);
694
+
695
+ *out->cur++ = '[';
696
+ for (i = 0; i < cnt; i++) {
697
+ volatile VALUE s = rb_sym_to_s(rb_ary_entry(ma, i));
698
+
699
+ name = rb_string_value_ptr((VALUE *)&s);
700
+ len = (int)RSTRING_LEN(s);
701
+ size = len + 3;
702
+ assure_size(out, size);
703
+ if (0 < i) {
704
+ *out->cur++ = ',';
705
+ }
706
+ *out->cur++ = '"';
707
+ memcpy(out->cur, name, len);
708
+ out->cur += len;
709
+ *out->cur++ = '"';
710
+ }
711
+ *out->cur++ = ']';
731
712
  } else {
732
- fill_indent(out, d3);
733
- *out->cur++ = '"';
734
- memcpy(out->cur, class_name, len);
735
- out->cur += len;
736
- *out->cur++ = '"';
713
+ fill_indent(out, d3);
714
+ *out->cur++ = '"';
715
+ memcpy(out->cur, class_name, len);
716
+ out->cur += len;
717
+ *out->cur++ = '"';
737
718
  }
738
719
  *out->cur++ = ',';
739
- size = d3 * out->indent + 2;
720
+ size = d3 * out->indent + 2;
740
721
  #ifdef RSTRUCT_LEN
741
722
  {
742
- VALUE v;
743
- int cnt;
723
+ VALUE v;
724
+ int cnt;
744
725
  #if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
745
- cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
746
- #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
747
- cnt = (int)RSTRUCT_LEN(obj);
748
- #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
749
-
750
- for (i = 0; i < cnt; i++) {
751
- v = RSTRUCT_GET(obj, i);
752
- if (oj_dump_ignore(out->opts, v)) {
753
- v = Qnil;
754
- }
755
- assure_size(out, size);
756
- fill_indent(out, d3);
757
- oj_dump_obj_val(v, d3, out);
758
- *out->cur++ = ',';
759
- }
726
+ cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
727
+ #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
728
+ cnt = (int)RSTRUCT_LEN(obj);
729
+ #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
730
+
731
+ for (i = 0; i < cnt; i++) {
732
+ v = RSTRUCT_GET(obj, i);
733
+ if (oj_dump_ignore(out->opts, v)) {
734
+ v = Qnil;
735
+ }
736
+ assure_size(out, size);
737
+ fill_indent(out, d3);
738
+ oj_dump_obj_val(v, d3, out);
739
+ *out->cur++ = ',';
740
+ }
760
741
  }
761
742
  #else
762
743
  {
763
- // This is a bit risky as a struct in C ruby is not the same as a Struct
764
- // class in interpreted Ruby so length() may not be defined.
765
- int slen = FIX2INT(rb_funcall2(obj, oj_length_id, 0, 0));
766
-
767
- for (i = 0; i < slen; i++) {
768
- assure_size(out, size);
769
- fill_indent(out, d3);
770
- if (oj_dump_ignore(out->opts, v)) {
771
- v = Qnil;
772
- }
773
- oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
774
- *out->cur++ = ',';
775
- }
744
+ // This is a bit risky as a struct in C ruby is not the same as a Struct
745
+ // class in interpreted Ruby so length() may not be defined.
746
+ int slen = FIX2INT(rb_funcall2(obj, oj_length_id, 0, 0));
747
+
748
+ for (i = 0; i < slen; i++) {
749
+ assure_size(out, size);
750
+ fill_indent(out, d3);
751
+ if (oj_dump_ignore(out->opts, v)) {
752
+ v = Qnil;
753
+ }
754
+ oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
755
+ *out->cur++ = ',';
756
+ }
776
757
  }
777
758
  #endif
778
759
  out->cur--;
779
760
  *out->cur++ = ']';
780
761
  *out->cur++ = '}';
781
- *out->cur = '\0';
762
+ *out->cur = '\0';
782
763
  }
783
764
 
784
- static void
785
- dump_complex(VALUE obj, int depth, Out out, bool as_ok) {
765
+ static void dump_complex(VALUE obj, int depth, Out out, bool as_ok) {
786
766
  dump_obj_attrs(obj, rb_obj_class(obj), 0, depth, out);
787
767
  }
788
768
 
789
- static void
790
- dump_rational(VALUE obj, int depth, Out out, bool as_ok) {
769
+ static void dump_rational(VALUE obj, int depth, Out out, bool as_ok) {
791
770
  dump_obj_attrs(obj, rb_obj_class(obj), 0, depth, out);
792
771
  }
793
772
 
794
- static DumpFunc obj_funcs[] = {
795
- NULL, // RUBY_T_NONE = 0x00,
796
- dump_obj, // RUBY_T_OBJECT = 0x01,
797
- dump_class, // RUBY_T_CLASS = 0x02,
798
- dump_class, // RUBY_T_MODULE = 0x03,
799
- oj_dump_float, // RUBY_T_FLOAT = 0x04,
800
- dump_str, // RUBY_T_STRING = 0x05,
801
- dump_regexp, // RUBY_T_REGEXP = 0x06,
802
- dump_array, // RUBY_T_ARRAY = 0x07,
803
- dump_hash, // RUBY_T_HASH = 0x08,
804
- dump_struct, // RUBY_T_STRUCT = 0x09,
805
- oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
806
- NULL, // RUBY_T_FILE = 0x0b,
807
- dump_data, // RUBY_T_DATA = 0x0c,
808
- NULL, // RUBY_T_MATCH = 0x0d,
809
- dump_complex, // RUBY_T_COMPLEX = 0x0e,
810
- dump_rational, // RUBY_T_RATIONAL = 0x0f,
811
- NULL, // 0x10
812
- oj_dump_nil, // RUBY_T_NIL = 0x11,
813
- oj_dump_true, // RUBY_T_TRUE = 0x12,
814
- oj_dump_false, // RUBY_T_FALSE = 0x13,
815
- dump_sym, // RUBY_T_SYMBOL = 0x14,
816
- oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
773
+ static DumpFunc obj_funcs[] = {
774
+ NULL, // RUBY_T_NONE = 0x00,
775
+ dump_obj, // RUBY_T_OBJECT = 0x01,
776
+ dump_class, // RUBY_T_CLASS = 0x02,
777
+ dump_class, // RUBY_T_MODULE = 0x03,
778
+ oj_dump_float, // RUBY_T_FLOAT = 0x04,
779
+ dump_str, // RUBY_T_STRING = 0x05,
780
+ dump_regexp, // RUBY_T_REGEXP = 0x06,
781
+ dump_array, // RUBY_T_ARRAY = 0x07,
782
+ dump_hash, // RUBY_T_HASH = 0x08,
783
+ dump_struct, // RUBY_T_STRUCT = 0x09,
784
+ oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
785
+ NULL, // RUBY_T_FILE = 0x0b,
786
+ dump_data, // RUBY_T_DATA = 0x0c,
787
+ NULL, // RUBY_T_MATCH = 0x0d,
788
+ dump_complex, // RUBY_T_COMPLEX = 0x0e,
789
+ dump_rational, // RUBY_T_RATIONAL = 0x0f,
790
+ NULL, // 0x10
791
+ oj_dump_nil, // RUBY_T_NIL = 0x11,
792
+ oj_dump_true, // RUBY_T_TRUE = 0x12,
793
+ oj_dump_false, // RUBY_T_FALSE = 0x13,
794
+ dump_sym, // RUBY_T_SYMBOL = 0x14,
795
+ oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
817
796
  };
818
797
 
819
- void
820
- oj_dump_obj_val(VALUE obj, int depth, Out out) {
821
- int type = rb_type(obj);
798
+ void oj_dump_obj_val(VALUE obj, int depth, Out out) {
799
+ int type = rb_type(obj);
822
800
 
823
801
  if (Yes == out->opts->trace) {
824
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
802
+ oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
825
803
  }
826
804
  if (MAX_DEPTH < depth) {
827
- rb_raise(rb_eNoMemError, "Too deeply nested.\n");
805
+ rb_raise(rb_eNoMemError, "Too deeply nested.\n");
828
806
  }
829
807
  if (0 < type && type <= RUBY_T_FIXNUM) {
830
- DumpFunc f = obj_funcs[type];
808
+ DumpFunc f = obj_funcs[type];
831
809
 
832
- if (NULL != f) {
833
- f(obj, depth, out, false);
834
- if (Yes == out->opts->trace) {
835
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
836
- }
837
- return;
838
- }
810
+ if (NULL != f) {
811
+ f(obj, depth, out, false);
812
+ if (Yes == out->opts->trace) {
813
+ oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
814
+ }
815
+ return;
816
+ }
839
817
  }
840
818
  oj_dump_nil(Qnil, depth, out, false);
841
819
  if (Yes == out->opts->trace) {
842
- oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
820
+ oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
843
821
  }
844
822
  }