oj 3.10.6 → 3.12.1

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 +176 -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 +102 -97
  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 +1186 -906
  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 +321 -325
  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 +47 -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
  }