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/custom.c CHANGED
@@ -1,7 +1,5 @@
1
- /* custom.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 <stdint.h>
7
5
  #include <stdio.h>
@@ -18,212 +16,200 @@
18
16
  #include "trace.h"
19
17
  #include "util.h"
20
18
 
21
- extern void oj_set_obj_ivar(Val parent, Val kval, VALUE value);
22
- extern VALUE oj_parse_xml_time(const char *str, int len); // from object.c
19
+ extern void oj_set_obj_ivar(Val parent, Val kval, VALUE value);
20
+ extern VALUE oj_parse_xml_time(const char *str, int len); // from object.c
23
21
 
24
- static void
25
- dump_obj_str(VALUE obj, int depth, Out out) {
26
- struct _attr attrs[] = {
27
- { "s", 1, Qnil },
28
- { NULL, 0, Qnil },
22
+ static void dump_obj_str(VALUE obj, int depth, Out out) {
23
+ struct _attr attrs[] = {
24
+ {"s", 1, Qnil},
25
+ {NULL, 0, Qnil},
29
26
  };
30
27
  attrs->value = rb_funcall(obj, oj_to_s_id, 0);
31
28
 
32
29
  oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
33
30
  }
34
31
 
35
- static void
36
- dump_obj_as_str(VALUE obj, int depth, Out out) {
37
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
38
- const char *str = rb_string_value_ptr((VALUE*)&rstr);
32
+ static void dump_obj_as_str(VALUE obj, int depth, Out out) {
33
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
34
+ const char * str = rb_string_value_ptr((VALUE *)&rstr);
39
35
 
40
36
  oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
41
37
  }
42
38
 
43
- static void
44
- bigdecimal_dump(VALUE obj, int depth, Out out) {
45
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
46
- const char *str = rb_string_value_ptr((VALUE*)&rstr);
47
- int len = (int)RSTRING_LEN(rstr);
39
+ static void bigdecimal_dump(VALUE obj, int depth, Out out) {
40
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
41
+ const char * str = rb_string_value_ptr((VALUE *)&rstr);
42
+ int len = (int)RSTRING_LEN(rstr);
48
43
 
49
44
  if (0 == strcasecmp("Infinity", str)) {
50
- str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
51
- oj_dump_raw(str, len, out);
45
+ str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
46
+ oj_dump_raw(str, len, out);
52
47
  } else if (0 == strcasecmp("-Infinity", str)) {
53
- str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, false, &len);
54
- oj_dump_raw(str, len, out);
48
+ str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, false, &len);
49
+ oj_dump_raw(str, len, out);
55
50
  } else if (No == out->opts->bigdec_as_num) {
56
- oj_dump_cstr(str, len, 0, 0, out);
51
+ oj_dump_cstr(str, len, 0, 0, out);
57
52
  } else {
58
- oj_dump_raw(str, len, out);
53
+ oj_dump_raw(str, len, out);
59
54
  }
60
55
  }
61
56
 
62
- static ID real_id = 0;
63
- static ID imag_id = 0;
57
+ static ID real_id = 0;
58
+ static ID imag_id = 0;
64
59
 
65
- static void
66
- complex_dump(VALUE obj, int depth, Out out) {
60
+ static void complex_dump(VALUE obj, int depth, Out out) {
67
61
  if (NULL != out->opts->create_id) {
68
- struct _attr attrs[] = {
69
- { "real", 4, Qnil },
70
- { "imag", 4, Qnil },
71
- { NULL, 0, Qnil },
72
- };
73
- if (0 == real_id) {
74
- real_id = rb_intern("real");
75
- imag_id = rb_intern("imag");
76
- }
77
- attrs[0].value = rb_funcall(obj, real_id, 0);
78
- attrs[1].value = rb_funcall(obj, imag_id, 0);
79
-
80
- oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
62
+ struct _attr attrs[] = {
63
+ {"real", 4, Qnil},
64
+ {"imag", 4, Qnil},
65
+ {NULL, 0, Qnil},
66
+ };
67
+ if (0 == real_id) {
68
+ real_id = rb_intern("real");
69
+ imag_id = rb_intern("imag");
70
+ }
71
+ attrs[0].value = rb_funcall(obj, real_id, 0);
72
+ attrs[1].value = rb_funcall(obj, imag_id, 0);
73
+
74
+ oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
81
75
  } else {
82
- dump_obj_as_str(obj, depth, out);
76
+ dump_obj_as_str(obj, depth, out);
83
77
  }
84
78
  }
85
79
 
86
- static VALUE
87
- complex_load(VALUE clas, VALUE args) {
80
+ static VALUE complex_load(VALUE clas, VALUE args) {
88
81
  if (0 == real_id) {
89
- real_id = rb_intern("real");
90
- imag_id = rb_intern("imag");
82
+ real_id = rb_intern("real");
83
+ imag_id = rb_intern("imag");
91
84
  }
92
- return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)), rb_hash_aref(args, rb_id2str(imag_id)));
85
+ return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)),
86
+ rb_hash_aref(args, rb_id2str(imag_id)));
93
87
  }
94
88
 
95
- static void
96
- time_dump(VALUE obj, int depth, Out out) {
89
+ static void time_dump(VALUE obj, int depth, Out out) {
97
90
  if (Yes == out->opts->create_ok) {
98
- struct _attr attrs[] = {
99
- { "time", 4, Qundef, 0, Qundef },
100
- { NULL, 0, Qnil },
101
- };
102
- attrs->time = obj;
91
+ struct _attr attrs[] = {
92
+ {"time", 4, Qundef, 0, Qundef},
93
+ {NULL, 0, Qnil},
94
+ };
95
+ attrs->time = obj;
103
96
 
104
- oj_code_attrs(obj, attrs, depth, out, true);
97
+ oj_code_attrs(obj, attrs, depth, out, true);
105
98
  } else {
106
- switch (out->opts->time_format) {
107
- case RubyTime: oj_dump_ruby_time(obj, out); break;
108
- case XmlTime: oj_dump_xml_time(obj, out); break;
109
- case UnixZTime: oj_dump_time(obj, out, true); break;
110
- case UnixTime:
111
- default: oj_dump_time(obj, out, false); break;
112
- }
99
+ switch (out->opts->time_format) {
100
+ case RubyTime: oj_dump_ruby_time(obj, out); break;
101
+ case XmlTime: oj_dump_xml_time(obj, out); break;
102
+ case UnixZTime: oj_dump_time(obj, out, true); break;
103
+ case UnixTime:
104
+ default: oj_dump_time(obj, out, false); break;
105
+ }
113
106
  }
114
107
  }
115
108
 
116
- static void
117
- date_dump(VALUE obj, int depth, Out out) {
109
+ static void date_dump(VALUE obj, int depth, Out out) {
118
110
  if (Yes == out->opts->create_ok) {
119
- struct _attr attrs[] = {
120
- { "s", 1, Qnil },
121
- { NULL, 0, Qnil },
122
- };
123
- attrs->value = rb_funcall(obj, rb_intern("iso8601"), 0);
111
+ struct _attr attrs[] = {
112
+ {"s", 1, Qnil},
113
+ {NULL, 0, Qnil},
114
+ };
115
+ attrs->value = rb_funcall(obj, rb_intern("iso8601"), 0);
124
116
 
125
- oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
117
+ oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
126
118
  } else {
127
- volatile VALUE v;
128
- volatile VALUE ov;
129
-
130
- switch (out->opts->time_format) {
131
- case RubyTime:
132
- case XmlTime:
133
- v = rb_funcall(obj, rb_intern("iso8601"), 0);
134
- oj_dump_cstr(rb_string_value_ptr((VALUE*)&v), (int)RSTRING_LEN(v), 0, 0, out);
135
- break;
136
- case UnixZTime:
137
- v = rb_funcall(obj, rb_intern("to_time"), 0);
138
- if (oj_date_class == rb_obj_class(obj)) {
139
- ov = rb_funcall(v, rb_intern("utc_offset"), 0);
140
- v = rb_funcall(v, rb_intern("utc"), 0);
141
- v = rb_funcall(v, rb_intern("+"), 1, ov);
142
- oj_dump_time(v, out, false);
143
- } else {
144
- oj_dump_time(v, out, true);
145
- }
146
- break;
147
- case UnixTime:
148
- default:
149
- v = rb_funcall(obj, rb_intern("to_time"), 0);
150
- if (oj_date_class == rb_obj_class(obj)) {
151
- ov = rb_funcall(v, rb_intern("utc_offset"), 0);
152
- v = rb_funcall(v, rb_intern("utc"), 0);
153
- v = rb_funcall(v, rb_intern("+"), 1, ov);
154
- }
155
- oj_dump_time(v, out, false);
156
- break;
157
- }
119
+ volatile VALUE v;
120
+ volatile VALUE ov;
121
+
122
+ switch (out->opts->time_format) {
123
+ case RubyTime:
124
+ case XmlTime:
125
+ v = rb_funcall(obj, rb_intern("iso8601"), 0);
126
+ oj_dump_cstr(rb_string_value_ptr((VALUE *)&v), (int)RSTRING_LEN(v), 0, 0, out);
127
+ break;
128
+ case UnixZTime:
129
+ v = rb_funcall(obj, rb_intern("to_time"), 0);
130
+ if (oj_date_class == rb_obj_class(obj)) {
131
+ ov = rb_funcall(v, rb_intern("utc_offset"), 0);
132
+ v = rb_funcall(v, rb_intern("utc"), 0);
133
+ v = rb_funcall(v, rb_intern("+"), 1, ov);
134
+ oj_dump_time(v, out, false);
135
+ } else {
136
+ oj_dump_time(v, out, true);
137
+ }
138
+ break;
139
+ case UnixTime:
140
+ default:
141
+ v = rb_funcall(obj, rb_intern("to_time"), 0);
142
+ if (oj_date_class == rb_obj_class(obj)) {
143
+ ov = rb_funcall(v, rb_intern("utc_offset"), 0);
144
+ v = rb_funcall(v, rb_intern("utc"), 0);
145
+ v = rb_funcall(v, rb_intern("+"), 1, ov);
146
+ }
147
+ oj_dump_time(v, out, false);
148
+ break;
149
+ }
158
150
  }
159
151
  }
160
152
 
161
- static VALUE
162
- date_load(VALUE clas, VALUE args) {
163
- volatile VALUE v;
153
+ static VALUE date_load(VALUE clas, VALUE args) {
154
+ volatile VALUE v;
164
155
 
165
156
  if (Qnil != (v = rb_hash_aref(args, rb_str_new2("s")))) {
166
- return rb_funcall(oj_date_class, rb_intern("parse"), 1, v);
157
+ return rb_funcall(oj_date_class, rb_intern("parse"), 1, v);
167
158
  }
168
159
  return Qnil;
169
160
  }
170
161
 
171
- static VALUE
172
- datetime_load(VALUE clas, VALUE args) {
173
- volatile VALUE v;
162
+ static VALUE datetime_load(VALUE clas, VALUE args) {
163
+ volatile VALUE v;
174
164
 
175
165
  if (Qnil != (v = rb_hash_aref(args, rb_str_new2("s")))) {
176
- return rb_funcall(oj_datetime_class, rb_intern("parse"), 1, v);
166
+ return rb_funcall(oj_datetime_class, rb_intern("parse"), 1, v);
177
167
  }
178
168
  return Qnil;
179
169
  }
180
170
 
181
- static ID table_id = 0;
171
+ static ID table_id = 0;
182
172
 
183
- static void
184
- openstruct_dump(VALUE obj, int depth, Out out) {
185
- struct _attr attrs[] = {
186
- { "table", 5, Qnil },
187
- { NULL, 0, Qnil },
173
+ static void openstruct_dump(VALUE obj, int depth, Out out) {
174
+ struct _attr attrs[] = {
175
+ {"table", 5, Qnil},
176
+ {NULL, 0, Qnil},
188
177
  };
189
178
  if (0 == table_id) {
190
- table_id = rb_intern("table");
179
+ table_id = rb_intern("table");
191
180
  }
192
181
  attrs->value = rb_funcall(obj, table_id, 0);
193
182
 
194
183
  oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
195
184
  }
196
185
 
197
- static VALUE
198
- openstruct_load(VALUE clas, VALUE args) {
186
+ static VALUE openstruct_load(VALUE clas, VALUE args) {
199
187
  if (0 == table_id) {
200
- table_id = rb_intern("table");
188
+ table_id = rb_intern("table");
201
189
  }
202
190
  return rb_funcall(clas, oj_new_id, 1, rb_hash_aref(args, rb_id2str(table_id)));
203
191
  }
204
192
 
205
- static void
206
- range_dump(VALUE obj, int depth, Out out) {
193
+ static void range_dump(VALUE obj, int depth, Out out) {
207
194
  if (NULL != out->opts->create_id) {
208
- struct _attr attrs[] = {
209
- { "begin", 5, Qnil },
210
- { "end", 3, Qnil },
211
- { "exclude", 7, Qnil },
212
- { NULL, 0, Qnil },
213
- };
214
- attrs[0].value = rb_funcall(obj, oj_begin_id, 0);
215
- attrs[1].value = rb_funcall(obj, oj_end_id, 0);
216
- attrs[2].value = rb_funcall(obj, oj_exclude_end_id, 0);
217
-
218
- oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
195
+ struct _attr attrs[] = {
196
+ {"begin", 5, Qnil},
197
+ {"end", 3, Qnil},
198
+ {"exclude", 7, Qnil},
199
+ {NULL, 0, Qnil},
200
+ };
201
+ attrs[0].value = rb_funcall(obj, oj_begin_id, 0);
202
+ attrs[1].value = rb_funcall(obj, oj_end_id, 0);
203
+ attrs[2].value = rb_funcall(obj, oj_exclude_end_id, 0);
204
+
205
+ oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
219
206
  } else {
220
- dump_obj_as_str(obj, depth, out);
207
+ dump_obj_as_str(obj, depth, out);
221
208
  }
222
209
  }
223
210
 
224
- static VALUE
225
- range_load(VALUE clas, VALUE args) {
226
- VALUE nargs[3];
211
+ static VALUE range_load(VALUE clas, VALUE args) {
212
+ VALUE nargs[3];
227
213
 
228
214
  nargs[0] = rb_hash_aref(args, rb_id2str(oj_begin_id));
229
215
  nargs[1] = rb_hash_aref(args, rb_id2str(oj_end_id));
@@ -232,985 +218,935 @@ range_load(VALUE clas, VALUE args) {
232
218
  return rb_class_new_instance(3, nargs, rb_cRange);
233
219
  }
234
220
 
235
- static ID numerator_id = 0;
236
- static ID denominator_id = 0;
221
+ static ID numerator_id = 0;
222
+ static ID denominator_id = 0;
237
223
 
238
- static void
239
- rational_dump(VALUE obj, int depth, Out out) {
224
+ static void rational_dump(VALUE obj, int depth, Out out) {
240
225
  if (NULL != out->opts->create_id) {
241
- struct _attr attrs[] = {
242
- { "numerator", 9, Qnil },
243
- { "denominator", 11, Qnil },
244
- { NULL, 0, Qnil },
245
- };
246
- if (0 == numerator_id) {
247
- numerator_id = rb_intern("numerator");
248
- denominator_id = rb_intern("denominator");
249
- }
250
- attrs[0].value = rb_funcall(obj, numerator_id, 0);
251
- attrs[1].value = rb_funcall(obj, denominator_id, 0);
252
-
253
- oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
226
+ struct _attr attrs[] = {
227
+ {"numerator", 9, Qnil},
228
+ {"denominator", 11, Qnil},
229
+ {NULL, 0, Qnil},
230
+ };
231
+ if (0 == numerator_id) {
232
+ numerator_id = rb_intern("numerator");
233
+ denominator_id = rb_intern("denominator");
234
+ }
235
+ attrs[0].value = rb_funcall(obj, numerator_id, 0);
236
+ attrs[1].value = rb_funcall(obj, denominator_id, 0);
237
+
238
+ oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
254
239
  } else {
255
- dump_obj_as_str(obj, depth, out);
240
+ dump_obj_as_str(obj, depth, out);
256
241
  }
257
242
  }
258
243
 
259
- static VALUE
260
- rational_load(VALUE clas, VALUE args) {
244
+ static VALUE rational_load(VALUE clas, VALUE args) {
261
245
  if (0 == numerator_id) {
262
- numerator_id = rb_intern("numerator");
263
- denominator_id = rb_intern("denominator");
246
+ numerator_id = rb_intern("numerator");
247
+ denominator_id = rb_intern("denominator");
264
248
  }
265
249
  return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)),
266
- rb_hash_aref(args, rb_id2str(denominator_id)));
250
+ rb_hash_aref(args, rb_id2str(denominator_id)));
267
251
  }
268
252
 
269
- static VALUE
270
- regexp_load(VALUE clas, VALUE args) {
271
- volatile VALUE v;
253
+ static VALUE regexp_load(VALUE clas, VALUE args) {
254
+ volatile VALUE v;
272
255
 
273
256
  if (Qnil != (v = rb_hash_aref(args, rb_str_new2("s")))) {
274
- return rb_funcall(rb_cRegexp, oj_new_id, 1, v);
257
+ return rb_funcall(rb_cRegexp, oj_new_id, 1, v);
275
258
  }
276
259
  return Qnil;
277
260
  }
278
261
 
279
- static VALUE
280
- time_load(VALUE clas, VALUE args) {
262
+ static VALUE time_load(VALUE clas, VALUE args) {
281
263
  // Value should have already been replaced in one of the hash_set_xxx
282
264
  // functions.
283
265
  return args;
284
266
  }
285
267
 
286
- static struct _code codes[] = {
287
- { "BigDecimal", Qnil, bigdecimal_dump, NULL, true },
288
- { "Complex", Qnil, complex_dump, complex_load, true },
289
- { "Date", Qnil, date_dump, date_load, true },
290
- { "DateTime", Qnil, date_dump, datetime_load, true },
291
- { "OpenStruct", Qnil, openstruct_dump, openstruct_load, true },
292
- { "Range", Qnil, range_dump, range_load, true },
293
- { "Rational", Qnil, rational_dump, rational_load, true },
294
- { "Regexp", Qnil, dump_obj_str, regexp_load, true },
295
- { "Time", Qnil, time_dump, time_load, true },
296
- { NULL, Qundef, NULL, NULL, false },
268
+ static struct _code codes[] = {
269
+ {"BigDecimal", Qnil, bigdecimal_dump, NULL, true},
270
+ {"Complex", Qnil, complex_dump, complex_load, true},
271
+ {"Date", Qnil, date_dump, date_load, true},
272
+ {"DateTime", Qnil, date_dump, datetime_load, true},
273
+ {"OpenStruct", Qnil, openstruct_dump, openstruct_load, true},
274
+ {"Range", Qnil, range_dump, range_load, true},
275
+ {"Rational", Qnil, rational_dump, rational_load, true},
276
+ {"Regexp", Qnil, dump_obj_str, regexp_load, true},
277
+ {"Time", Qnil, time_dump, time_load, true},
278
+ {NULL, Qundef, NULL, NULL, false},
297
279
  };
298
280
 
299
- static int
300
- hash_cb(VALUE key, VALUE value, VALUE ov) {
301
- Out out = (Out)ov;
302
- int depth = out->depth;
281
+ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
282
+ Out out = (Out)ov;
283
+ int depth = out->depth;
303
284
 
304
285
  if (oj_dump_ignore(out->opts, value)) {
305
- return ST_CONTINUE;
286
+ return ST_CONTINUE;
306
287
  }
307
288
  if (out->omit_nil && Qnil == value) {
308
- return ST_CONTINUE;
289
+ return ST_CONTINUE;
309
290
  }
310
291
  if (!out->opts->dump_opts.use) {
311
- assure_size(out, depth * out->indent + 1);
312
- fill_indent(out, depth);
292
+ assure_size(out, depth * out->indent + 1);
293
+ fill_indent(out, depth);
313
294
  } else {
314
- assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
315
- if (0 < out->opts->dump_opts.hash_size) {
316
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
317
- out->cur += out->opts->dump_opts.hash_size;
318
- }
319
- if (0 < out->opts->dump_opts.indent_size) {
320
- int i;
321
-
322
- for (i = depth; 0 < i; i--) {
323
- strcpy(out->cur, out->opts->dump_opts.indent_str);
324
- out->cur += out->opts->dump_opts.indent_size;
325
- }
326
- }
295
+ assure_size(out,
296
+ depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
297
+ if (0 < out->opts->dump_opts.hash_size) {
298
+ strcpy(out->cur, out->opts->dump_opts.hash_nl);
299
+ out->cur += out->opts->dump_opts.hash_size;
300
+ }
301
+ if (0 < out->opts->dump_opts.indent_size) {
302
+ int i;
303
+
304
+ for (i = depth; 0 < i; i--) {
305
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
306
+ out->cur += out->opts->dump_opts.indent_size;
307
+ }
308
+ }
327
309
  }
328
310
  switch (rb_type(key)) {
329
- case T_STRING:
330
- oj_dump_str(key, 0, out, false);
331
- break;
332
- case T_SYMBOL:
333
- oj_dump_sym(key, 0, out, false);
334
- break;
335
- default:
336
- oj_dump_str(rb_funcall(key, oj_to_s_id, 0), 0, out, false);
337
- break;
311
+ case T_STRING: oj_dump_str(key, 0, out, false); break;
312
+ case T_SYMBOL: oj_dump_sym(key, 0, out, false); break;
313
+ default: oj_dump_str(rb_funcall(key, oj_to_s_id, 0), 0, out, false); break;
338
314
  }
339
315
  if (!out->opts->dump_opts.use) {
340
- *out->cur++ = ':';
316
+ *out->cur++ = ':';
341
317
  } else {
342
- assure_size(out, out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2);
343
- if (0 < out->opts->dump_opts.before_size) {
344
- strcpy(out->cur, out->opts->dump_opts.before_sep);
345
- out->cur += out->opts->dump_opts.before_size;
346
- }
347
- *out->cur++ = ':';
348
- if (0 < out->opts->dump_opts.after_size) {
349
- strcpy(out->cur, out->opts->dump_opts.after_sep);
350
- out->cur += out->opts->dump_opts.after_size;
351
- }
318
+ assure_size(out, out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2);
319
+ if (0 < out->opts->dump_opts.before_size) {
320
+ strcpy(out->cur, out->opts->dump_opts.before_sep);
321
+ out->cur += out->opts->dump_opts.before_size;
322
+ }
323
+ *out->cur++ = ':';
324
+ if (0 < out->opts->dump_opts.after_size) {
325
+ strcpy(out->cur, out->opts->dump_opts.after_sep);
326
+ out->cur += out->opts->dump_opts.after_size;
327
+ }
352
328
  }
353
329
  oj_dump_custom_val(value, depth, out, true);
354
- out->depth = depth;
330
+ out->depth = depth;
355
331
  *out->cur++ = ',';
356
332
 
357
333
  return ST_CONTINUE;
358
334
  }
359
335
 
360
- static void
361
- dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
362
- int cnt;
363
- long id = oj_check_circular(obj, out);
336
+ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
337
+ int cnt;
338
+ long id = oj_check_circular(obj, out);
364
339
 
365
340
  if (0 > id) {
366
- oj_dump_nil(Qnil, depth, out, false);
367
- return;
341
+ oj_dump_nil(Qnil, depth, out, false);
342
+ return;
368
343
  }
369
344
  cnt = (int)RHASH_SIZE(obj);
370
345
  assure_size(out, 2);
371
346
  if (0 == cnt) {
372
- *out->cur++ = '{';
373
- *out->cur++ = '}';
347
+ *out->cur++ = '{';
348
+ *out->cur++ = '}';
374
349
  } else {
375
- *out->cur++ = '{';
376
- out->depth = depth + 1;
377
- rb_hash_foreach(obj, hash_cb, (VALUE)out);
378
- if (',' == *(out->cur - 1)) {
379
- out->cur--; // backup to overwrite last comma
380
- }
381
- if (!out->opts->dump_opts.use) {
382
- assure_size(out, depth * out->indent + 2);
383
- fill_indent(out, depth);
384
- } else {
385
- assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
386
- if (0 < out->opts->dump_opts.hash_size) {
387
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
388
- out->cur += out->opts->dump_opts.hash_size;
389
- }
390
- if (0 < out->opts->dump_opts.indent_size) {
391
- int i;
392
-
393
- for (i = depth; 0 < i; i--) {
394
- strcpy(out->cur, out->opts->dump_opts.indent_str);
395
- out->cur += out->opts->dump_opts.indent_size;
396
- }
397
- }
398
- }
399
- *out->cur++ = '}';
350
+ *out->cur++ = '{';
351
+ out->depth = depth + 1;
352
+ rb_hash_foreach(obj, hash_cb, (VALUE)out);
353
+ if (',' == *(out->cur - 1)) {
354
+ out->cur--; // backup to overwrite last comma
355
+ }
356
+ if (!out->opts->dump_opts.use) {
357
+ assure_size(out, depth * out->indent + 2);
358
+ fill_indent(out, depth);
359
+ } else {
360
+ assure_size(
361
+ out,
362
+ depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
363
+ if (0 < out->opts->dump_opts.hash_size) {
364
+ strcpy(out->cur, out->opts->dump_opts.hash_nl);
365
+ out->cur += out->opts->dump_opts.hash_size;
366
+ }
367
+ if (0 < out->opts->dump_opts.indent_size) {
368
+ int i;
369
+
370
+ for (i = depth; 0 < i; i--) {
371
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
372
+ out->cur += out->opts->dump_opts.indent_size;
373
+ }
374
+ }
375
+ }
376
+ *out->cur++ = '}';
400
377
  }
401
378
  *out->cur = '\0';
402
379
  }
403
380
 
404
- static void
405
- dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
406
- ID *idp;
407
- AttrGetFunc *fp;
408
- volatile VALUE v;
409
- const char *name;
410
- size_t size;
411
- int d2 = depth + 1;
381
+ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
382
+ ID * idp;
383
+ AttrGetFunc * fp;
384
+ volatile VALUE v;
385
+ const char * name;
386
+ size_t size;
387
+ int d2 = depth + 1;
412
388
 
413
389
  assure_size(out, 2);
414
390
  *out->cur++ = '{';
415
391
  if (NULL != out->opts->create_id && Yes == out->opts->create_ok) {
416
- const char *classname = rb_class2name(clas);
417
- int clen = (int)strlen(classname);
418
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
419
-
420
- size = d2 * out->indent + 10 + clen + out->opts->create_id_len + sep_len;
421
- assure_size(out, size);
422
- fill_indent(out, d2);
423
- *out->cur++ = '"';
424
- memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
425
- out->cur += out->opts->create_id_len;
426
- *out->cur++ = '"';
427
- if (0 < out->opts->dump_opts.before_size) {
428
- strcpy(out->cur, out->opts->dump_opts.before_sep);
429
- out->cur += out->opts->dump_opts.before_size;
430
- }
431
- *out->cur++ = ':';
432
- if (0 < out->opts->dump_opts.after_size) {
433
- strcpy(out->cur, out->opts->dump_opts.after_sep);
434
- out->cur += out->opts->dump_opts.after_size;
435
- }
436
- *out->cur++ = '"';
437
- memcpy(out->cur, classname, clen);
438
- out->cur += clen;
439
- *out->cur++ = '"';
440
- *out->cur++ = ',';
392
+ const char *classname = rb_class2name(clas);
393
+ int clen = (int)strlen(classname);
394
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
395
+
396
+ size = d2 * out->indent + 10 + clen + out->opts->create_id_len + sep_len;
397
+ assure_size(out, size);
398
+ fill_indent(out, d2);
399
+ *out->cur++ = '"';
400
+ memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
401
+ out->cur += out->opts->create_id_len;
402
+ *out->cur++ = '"';
403
+ if (0 < out->opts->dump_opts.before_size) {
404
+ strcpy(out->cur, out->opts->dump_opts.before_sep);
405
+ out->cur += out->opts->dump_opts.before_size;
406
+ }
407
+ *out->cur++ = ':';
408
+ if (0 < out->opts->dump_opts.after_size) {
409
+ strcpy(out->cur, out->opts->dump_opts.after_sep);
410
+ out->cur += out->opts->dump_opts.after_size;
411
+ }
412
+ *out->cur++ = '"';
413
+ memcpy(out->cur, classname, clen);
414
+ out->cur += clen;
415
+ *out->cur++ = '"';
416
+ *out->cur++ = ',';
441
417
  }
442
418
  if (odd->raw) {
443
- v = rb_funcall(obj, *odd->attrs, 0);
444
- if (Qundef == v || T_STRING != rb_type(v)) {
445
- rb_raise(rb_eEncodingError, "Invalid type for raw JSON.\n");
446
- } else {
447
- const char *s = rb_string_value_ptr((VALUE*)&v);
448
- int len = (int)RSTRING_LEN(v);
449
- const char *name = rb_id2name(*odd->attrs);
450
- size_t nlen = strlen(name);
451
-
452
- size = len + d2 * out->indent + nlen + 10;
453
- assure_size(out, size);
454
- fill_indent(out, d2);
455
- *out->cur++ = '"';
456
- memcpy(out->cur, name, nlen);
457
- out->cur += nlen;
458
- *out->cur++ = '"';
459
- *out->cur++ = ':';
460
- memcpy(out->cur, s, len);
461
- out->cur += len;
462
- *out->cur = '\0';
463
- }
419
+ v = rb_funcall(obj, *odd->attrs, 0);
420
+ if (Qundef == v || T_STRING != rb_type(v)) {
421
+ rb_raise(rb_eEncodingError, "Invalid type for raw JSON.\n");
422
+ } else {
423
+ const char *s = rb_string_value_ptr((VALUE *)&v);
424
+ int len = (int)RSTRING_LEN(v);
425
+ const char *name = rb_id2name(*odd->attrs);
426
+ size_t nlen = strlen(name);
427
+
428
+ size = len + d2 * out->indent + nlen + 10;
429
+ assure_size(out, size);
430
+ fill_indent(out, d2);
431
+ *out->cur++ = '"';
432
+ memcpy(out->cur, name, nlen);
433
+ out->cur += nlen;
434
+ *out->cur++ = '"';
435
+ *out->cur++ = ':';
436
+ memcpy(out->cur, s, len);
437
+ out->cur += len;
438
+ *out->cur = '\0';
439
+ }
464
440
  } else {
465
- size = d2 * out->indent + 1;
466
- for (idp = odd->attrs, fp = odd->attrFuncs; 0 != *idp; idp++, fp++) {
467
- size_t nlen;
468
-
469
- assure_size(out, size);
470
- name = rb_id2name(*idp);
471
- nlen = strlen(name);
472
- if (0 != *fp) {
473
- v = (*fp)(obj);
474
- } else if (0 == strchr(name, '.')) {
475
- v = rb_funcall(obj, *idp, 0);
476
- } else {
477
- char nbuf[256];
478
- char *n2 = nbuf;
479
- char *n;
480
- char *end;
481
- ID i;
482
-
483
- if (sizeof(nbuf) <= nlen) {
484
- if (NULL == (n2 = strdup(name))) {
485
- rb_raise(rb_eNoMemError, "for attribute name.");
486
- }
487
- } else {
488
- strcpy(n2, name);
489
- }
490
- n = n2;
491
- v = obj;
492
- while (0 != (end = strchr(n, '.'))) {
493
- *end = '\0';
494
- i = rb_intern(n);
495
- v = rb_funcall(v, i, 0);
496
- n = end + 1;
497
- }
498
- i = rb_intern(n);
499
- v = rb_funcall(v, i, 0);
500
- if (nbuf != n2) {
501
- free(n2);
502
- }
503
- }
504
- fill_indent(out, d2);
505
- oj_dump_cstr(name, nlen, 0, 0, out);
506
- *out->cur++ = ':';
507
- oj_dump_custom_val(v, d2, out, true);
508
- assure_size(out, 2);
509
- *out->cur++ = ',';
510
- }
511
- out->cur--;
441
+ size = d2 * out->indent + 1;
442
+ for (idp = odd->attrs, fp = odd->attrFuncs; 0 != *idp; idp++, fp++) {
443
+ size_t nlen;
444
+
445
+ assure_size(out, size);
446
+ name = rb_id2name(*idp);
447
+ nlen = strlen(name);
448
+ if (0 != *fp) {
449
+ v = (*fp)(obj);
450
+ } else if (0 == strchr(name, '.')) {
451
+ v = rb_funcall(obj, *idp, 0);
452
+ } else {
453
+ char nbuf[256];
454
+ char *n2 = nbuf;
455
+ char *n;
456
+ char *end;
457
+ ID i;
458
+
459
+ if (sizeof(nbuf) <= nlen) {
460
+ if (NULL == (n2 = strdup(name))) {
461
+ rb_raise(rb_eNoMemError, "for attribute name.");
462
+ }
463
+ } else {
464
+ strcpy(n2, name);
465
+ }
466
+ n = n2;
467
+ v = obj;
468
+ while (0 != (end = strchr(n, '.'))) {
469
+ *end = '\0';
470
+ i = rb_intern(n);
471
+ v = rb_funcall(v, i, 0);
472
+ n = end + 1;
473
+ }
474
+ i = rb_intern(n);
475
+ v = rb_funcall(v, i, 0);
476
+ if (nbuf != n2) {
477
+ free(n2);
478
+ }
479
+ }
480
+ fill_indent(out, d2);
481
+ oj_dump_cstr(name, nlen, 0, 0, out);
482
+ *out->cur++ = ':';
483
+ oj_dump_custom_val(v, d2, out, true);
484
+ assure_size(out, 2);
485
+ *out->cur++ = ',';
486
+ }
487
+ out->cur--;
512
488
  }
513
489
  *out->cur++ = '}';
514
- *out->cur = '\0';
490
+ *out->cur = '\0';
515
491
  }
516
492
 
517
493
  // Return class if still needs dumping.
518
- static VALUE
519
- dump_common(VALUE obj, int depth, Out out) {
520
-
494
+ static VALUE dump_common(VALUE obj, int depth, Out out) {
521
495
  if (Yes == out->opts->raw_json && rb_respond_to(obj, oj_raw_json_id)) {
522
- oj_dump_raw_json(obj, depth, out);
496
+ oj_dump_raw_json(obj, depth, out);
523
497
  } else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
524
- volatile VALUE rs;
525
- const char *s;
526
- int len;
527
-
528
- if (Yes == out->opts->trace) {
529
- oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
530
- }
531
- if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
532
- rs = rb_funcall(obj, oj_to_json_id, 0);
533
- } else {
534
- rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
535
- }
536
- if (Yes == out->opts->trace) {
537
- oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
538
- }
539
- s = rb_string_value_ptr((VALUE*)&rs);
540
- len = (int)RSTRING_LEN(rs);
541
-
542
- assure_size(out, len + 1);
543
- memcpy(out->cur, s, len);
544
- out->cur += len;
545
- *out->cur = '\0';
498
+ volatile VALUE rs;
499
+ const char * s;
500
+ int len;
501
+
502
+ if (Yes == out->opts->trace) {
503
+ oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
504
+ }
505
+ if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
506
+ rs = rb_funcall(obj, oj_to_json_id, 0);
507
+ } else {
508
+ rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
509
+ }
510
+ if (Yes == out->opts->trace) {
511
+ oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
512
+ }
513
+ s = rb_string_value_ptr((VALUE *)&rs);
514
+ len = (int)RSTRING_LEN(rs);
515
+
516
+ assure_size(out, len + 1);
517
+ memcpy(out->cur, s, len);
518
+ out->cur += len;
519
+ *out->cur = '\0';
546
520
  } else if (Yes == out->opts->as_json && rb_respond_to(obj, oj_as_json_id)) {
547
- volatile VALUE aj;
548
-
549
- if (Yes == out->opts->trace) {
550
- oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
551
- }
552
- // Some classes elect to not take an options argument so check the arity
553
- // of as_json.
554
- if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
555
- aj = rb_funcall(obj, oj_as_json_id, 0);
556
- } else {
557
- aj = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
558
- }
559
- if (Yes == out->opts->trace) {
560
- oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
561
- }
562
- // Catch the obvious brain damaged recursive dumping.
563
- if (aj == obj) {
564
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
565
-
566
- oj_dump_cstr(rb_string_value_ptr((VALUE*)&rstr), (int)RSTRING_LEN(rstr), false, false, out);
567
- } else {
568
- oj_dump_custom_val(aj, depth, out, true);
569
- }
521
+ volatile VALUE aj;
522
+
523
+ if (Yes == out->opts->trace) {
524
+ oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
525
+ }
526
+ // Some classes elect to not take an options argument so check the arity
527
+ // of as_json.
528
+ if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
529
+ aj = rb_funcall(obj, oj_as_json_id, 0);
530
+ } else {
531
+ aj = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
532
+ }
533
+ if (Yes == out->opts->trace) {
534
+ oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
535
+ }
536
+ // Catch the obvious brain damaged recursive dumping.
537
+ if (aj == obj) {
538
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
539
+
540
+ oj_dump_cstr(rb_string_value_ptr((VALUE *)&rstr),
541
+ (int)RSTRING_LEN(rstr),
542
+ false,
543
+ false,
544
+ out);
545
+ } else {
546
+ oj_dump_custom_val(aj, depth, out, true);
547
+ }
570
548
  } else if (Yes == out->opts->to_hash && rb_respond_to(obj, oj_to_hash_id)) {
571
- volatile VALUE h = rb_funcall(obj, oj_to_hash_id, 0);
572
-
573
- if (T_HASH != rb_type(h)) {
574
- // It seems that ActiveRecord implemented to_hash so that it returns
575
- // an Array and not a Hash. To get around that any value returned
576
- // will be dumped.
577
-
578
- //rb_raise(rb_eTypeError, "%s.to_hash() did not return a Hash.\n", rb_class2name(rb_obj_class(obj)));
579
- oj_dump_custom_val(h, depth, out, false);
580
- } else {
581
- dump_hash(h, depth, out, true);
582
- }
549
+ volatile VALUE h = rb_funcall(obj, oj_to_hash_id, 0);
550
+
551
+ if (T_HASH != rb_type(h)) {
552
+ // It seems that ActiveRecord implemented to_hash so that it returns
553
+ // an Array and not a Hash. To get around that any value returned
554
+ // will be dumped.
555
+
556
+ // rb_raise(rb_eTypeError, "%s.to_hash() did not return a Hash.\n",
557
+ // rb_class2name(rb_obj_class(obj)));
558
+ oj_dump_custom_val(h, depth, out, false);
559
+ } else {
560
+ dump_hash(h, depth, out, true);
561
+ }
583
562
  } else if (!oj_code_dump(codes, obj, depth, out)) {
584
- VALUE clas = rb_obj_class(obj);
585
- Odd odd = oj_get_odd(clas);
563
+ VALUE clas = rb_obj_class(obj);
564
+ Odd odd = oj_get_odd(clas);
586
565
 
587
- if (NULL == odd) {
588
- return clas;
589
- }
590
- dump_odd(obj, odd, clas, depth + 1, out);
566
+ if (NULL == odd) {
567
+ return clas;
568
+ }
569
+ dump_odd(obj, odd, clas, depth + 1, out);
591
570
  }
592
571
  return Qnil;
593
572
  }
594
573
 
595
- static int
596
- dump_attr_cb(ID key, VALUE value, VALUE ov) {
597
- Out out = (Out)ov;
598
- int depth = out->depth;
599
- size_t size;
600
- const char *attr;
574
+ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
575
+ Out out = (Out)ov;
576
+ int depth = out->depth;
577
+ size_t size;
578
+ const char *attr;
601
579
 
602
580
  if (oj_dump_ignore(out->opts, value)) {
603
- return ST_CONTINUE;
581
+ return ST_CONTINUE;
604
582
  }
605
583
  if (out->omit_nil && Qnil == value) {
606
- return ST_CONTINUE;
584
+ return ST_CONTINUE;
607
585
  }
608
586
  size = depth * out->indent + 1;
609
587
  attr = rb_id2name(key);
610
588
  // Some exceptions such as NoMethodError have an invisible attribute where
611
589
  // the key name is NULL. Not an empty string but NULL.
612
590
  if (NULL == attr) {
613
- attr = "";
591
+ attr = "";
614
592
  } else if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
615
- return ST_CONTINUE;
593
+ return ST_CONTINUE;
616
594
  }
617
595
  if (0 == strcmp("bt", attr) || 0 == strcmp("mesg", attr)) {
618
- return ST_CONTINUE;
596
+ return ST_CONTINUE;
619
597
  }
620
598
  assure_size(out, size);
621
599
  fill_indent(out, depth);
622
600
  if ('@' == *attr) {
623
- attr++;
624
- oj_dump_cstr(attr, strlen(attr), 0, 0, out);
601
+ attr++;
602
+ oj_dump_cstr(attr, strlen(attr), 0, 0, out);
625
603
  } else {
626
- char buf[32];
604
+ char buf[32];
627
605
 
628
- *buf = '~';
629
- strncpy(buf + 1, attr, sizeof(buf) - 2);
630
- buf[sizeof(buf) - 1] = '\0';
631
- oj_dump_cstr(buf, strlen(buf), 0, 0, out);
606
+ *buf = '~';
607
+ strncpy(buf + 1, attr, sizeof(buf) - 2);
608
+ buf[sizeof(buf) - 1] = '\0';
609
+ oj_dump_cstr(buf, strlen(buf), 0, 0, out);
632
610
  }
633
611
  *out->cur++ = ':';
634
612
  oj_dump_custom_val(value, depth, out, true);
635
- out->depth = depth;
613
+ out->depth = depth;
636
614
  *out->cur++ = ',';
637
615
 
638
616
  return ST_CONTINUE;
639
617
  }
640
618
 
641
- static void
642
- dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
643
- size_t size = 0;
644
- int d2 = depth + 1;
645
- int cnt;
646
- bool class_written = false;
619
+ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
620
+ size_t size = 0;
621
+ int d2 = depth + 1;
622
+ int cnt;
623
+ bool class_written = false;
647
624
 
648
625
  assure_size(out, 2);
649
626
  *out->cur++ = '{';
650
627
  if (Qundef != clas && NULL != out->opts->create_id && Yes == out->opts->create_ok) {
651
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
652
- const char *classname = rb_obj_classname(obj);
653
- size_t len = strlen(classname);
654
-
655
- size = d2 * out->indent + 10 + len + out->opts->create_id_len + sep_len;
656
- assure_size(out, size);
657
- fill_indent(out, d2);
658
- *out->cur++ = '"';
659
- memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
660
- out->cur += out->opts->create_id_len;
661
- *out->cur++ = '"';
662
- if (0 < out->opts->dump_opts.before_size) {
663
- strcpy(out->cur, out->opts->dump_opts.before_sep);
664
- out->cur += out->opts->dump_opts.before_size;
665
- }
666
- *out->cur++ = ':';
667
- if (0 < out->opts->dump_opts.after_size) {
668
- strcpy(out->cur, out->opts->dump_opts.after_sep);
669
- out->cur += out->opts->dump_opts.after_size;
670
- }
671
- *out->cur++ = '"';
672
- memcpy(out->cur, classname, len);
673
- out->cur += len;
674
- *out->cur++ = '"';
675
- class_written = true;
628
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
629
+ const char *classname = rb_obj_classname(obj);
630
+ size_t len = strlen(classname);
631
+
632
+ size = d2 * out->indent + 10 + len + out->opts->create_id_len + sep_len;
633
+ assure_size(out, size);
634
+ fill_indent(out, d2);
635
+ *out->cur++ = '"';
636
+ memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
637
+ out->cur += out->opts->create_id_len;
638
+ *out->cur++ = '"';
639
+ if (0 < out->opts->dump_opts.before_size) {
640
+ strcpy(out->cur, out->opts->dump_opts.before_sep);
641
+ out->cur += out->opts->dump_opts.before_size;
642
+ }
643
+ *out->cur++ = ':';
644
+ if (0 < out->opts->dump_opts.after_size) {
645
+ strcpy(out->cur, out->opts->dump_opts.after_sep);
646
+ out->cur += out->opts->dump_opts.after_size;
647
+ }
648
+ *out->cur++ = '"';
649
+ memcpy(out->cur, classname, len);
650
+ out->cur += len;
651
+ *out->cur++ = '"';
652
+ class_written = true;
676
653
  }
677
654
  cnt = (int)rb_ivar_count(obj);
678
655
  if (class_written) {
679
- *out->cur++ = ',';
656
+ *out->cur++ = ',';
680
657
  }
681
658
  if (0 == cnt && Qundef == clas) {
682
- // Might be something special like an Enumerable.
683
- if (Qtrue == rb_obj_is_kind_of(obj, oj_enumerable_class)) {
684
- out->cur--;
685
- oj_dump_custom_val(rb_funcall(obj, rb_intern("entries"), 0), depth, out, false);
686
- return;
687
- }
659
+ // Might be something special like an Enumerable.
660
+ if (Qtrue == rb_obj_is_kind_of(obj, oj_enumerable_class)) {
661
+ out->cur--;
662
+ oj_dump_custom_val(rb_funcall(obj, rb_intern("entries"), 0), depth, out, false);
663
+ return;
664
+ }
688
665
  }
689
666
  out->depth = depth + 1;
690
667
  rb_ivar_foreach(obj, dump_attr_cb, (VALUE)out);
691
668
  if (',' == *(out->cur - 1)) {
692
- out->cur--; // backup to overwrite last comma
669
+ out->cur--; // backup to overwrite last comma
693
670
  }
694
671
  if (rb_obj_is_kind_of(obj, rb_eException)) {
695
- volatile VALUE rv;
696
-
697
- if (',' != *(out->cur - 1)) {
698
- *out->cur++ = ',';
699
- }
700
- // message
701
- assure_size(out, 2);
702
- fill_indent(out, d2);
703
- oj_dump_cstr("~mesg", 5, 0, 0, out);
704
- *out->cur++ = ':';
705
- rv = rb_funcall2(obj, rb_intern("message"), 0, 0);
706
- oj_dump_custom_val(rv, d2, out, true);
707
- assure_size(out, size + 2);
708
- *out->cur++ = ',';
709
- // backtrace
710
- fill_indent(out, d2);
711
- oj_dump_cstr("~bt", 3, 0, 0, out);
712
- *out->cur++ = ':';
713
- rv = rb_funcall2(obj, rb_intern("backtrace"), 0, 0);
714
- oj_dump_custom_val(rv, d2, out, true);
715
- assure_size(out, 2);
672
+ volatile VALUE rv;
673
+
674
+ if (',' != *(out->cur - 1)) {
675
+ *out->cur++ = ',';
676
+ }
677
+ // message
678
+ assure_size(out, 2);
679
+ fill_indent(out, d2);
680
+ oj_dump_cstr("~mesg", 5, 0, 0, out);
681
+ *out->cur++ = ':';
682
+ rv = rb_funcall2(obj, rb_intern("message"), 0, 0);
683
+ oj_dump_custom_val(rv, d2, out, true);
684
+ assure_size(out, size + 2);
685
+ *out->cur++ = ',';
686
+ // backtrace
687
+ fill_indent(out, d2);
688
+ oj_dump_cstr("~bt", 3, 0, 0, out);
689
+ *out->cur++ = ':';
690
+ rv = rb_funcall2(obj, rb_intern("backtrace"), 0, 0);
691
+ oj_dump_custom_val(rv, d2, out, true);
692
+ assure_size(out, 2);
716
693
  }
717
694
  out->depth = depth;
718
695
 
719
696
  fill_indent(out, depth);
720
697
  *out->cur++ = '}';
721
- *out->cur = '\0';
698
+ *out->cur = '\0';
722
699
  }
723
700
 
724
- static void
725
- dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
726
- long id = oj_check_circular(obj, out);
727
- VALUE clas;
701
+ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
702
+ long id = oj_check_circular(obj, out);
703
+ VALUE clas;
728
704
 
729
705
  if (0 > id) {
730
- oj_dump_nil(Qnil, depth, out, false);
706
+ oj_dump_nil(Qnil, depth, out, false);
731
707
  } else if (Qnil != (clas = dump_common(obj, depth, out))) {
732
- dump_obj_attrs(obj, clas, 0, depth, out);
708
+ dump_obj_attrs(obj, clas, 0, depth, out);
733
709
  }
734
710
  *out->cur = '\0';
735
711
  }
736
712
 
737
- static void
738
- dump_array(VALUE a, int depth, Out out, bool as_ok) {
739
- size_t size;
740
- int i, cnt;
741
- int d2 = depth + 1;
742
- long id = oj_check_circular(a, out);
713
+ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
714
+ size_t size;
715
+ int i, cnt;
716
+ int d2 = depth + 1;
717
+ long id = oj_check_circular(a, out);
743
718
 
744
719
  if (0 > id) {
745
- oj_dump_nil(Qnil, depth, out, false);
746
- return;
720
+ oj_dump_nil(Qnil, depth, out, false);
721
+ return;
747
722
  }
748
- cnt = (int)RARRAY_LEN(a);
723
+ cnt = (int)RARRAY_LEN(a);
749
724
  *out->cur++ = '[';
750
725
  assure_size(out, 2);
751
726
  if (0 == cnt) {
752
- *out->cur++ = ']';
727
+ *out->cur++ = ']';
753
728
  } else {
754
- if (out->opts->dump_opts.use) {
755
- size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
756
- } else {
757
- size = d2 * out->indent + 2;
758
- }
759
- cnt--;
760
- for (i = 0; i <= cnt; i++) {
761
- assure_size(out, size);
762
- if (out->opts->dump_opts.use) {
763
- if (0 < out->opts->dump_opts.array_size) {
764
- strcpy(out->cur, out->opts->dump_opts.array_nl);
765
- out->cur += out->opts->dump_opts.array_size;
766
- }
767
- if (0 < out->opts->dump_opts.indent_size) {
768
- int i;
769
- for (i = d2; 0 < i; i--) {
770
- strcpy(out->cur, out->opts->dump_opts.indent_str);
771
- out->cur += out->opts->dump_opts.indent_size;
772
- }
773
- }
774
- } else {
775
- fill_indent(out, d2);
776
- }
777
- oj_dump_custom_val(rb_ary_entry(a, i), d2, out, true);
778
- if (i < cnt) {
779
- *out->cur++ = ',';
780
- }
781
- }
782
- size = depth * out->indent + 1;
783
- assure_size(out, size);
784
- if (out->opts->dump_opts.use) {
785
- if (0 < out->opts->dump_opts.array_size) {
786
- strcpy(out->cur, out->opts->dump_opts.array_nl);
787
- out->cur += out->opts->dump_opts.array_size;
788
- }
789
- if (0 < out->opts->dump_opts.indent_size) {
790
- int i;
791
-
792
- for (i = depth; 0 < i; i--) {
793
- strcpy(out->cur, out->opts->dump_opts.indent_str);
794
- out->cur += out->opts->dump_opts.indent_size;
795
- }
796
- }
797
- } else {
798
- fill_indent(out, depth);
799
- }
800
- *out->cur++ = ']';
729
+ if (out->opts->dump_opts.use) {
730
+ size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
731
+ } else {
732
+ size = d2 * out->indent + 2;
733
+ }
734
+ cnt--;
735
+ for (i = 0; i <= cnt; i++) {
736
+ assure_size(out, size);
737
+ if (out->opts->dump_opts.use) {
738
+ if (0 < out->opts->dump_opts.array_size) {
739
+ strcpy(out->cur, out->opts->dump_opts.array_nl);
740
+ out->cur += out->opts->dump_opts.array_size;
741
+ }
742
+ if (0 < out->opts->dump_opts.indent_size) {
743
+ int i;
744
+ for (i = d2; 0 < i; i--) {
745
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
746
+ out->cur += out->opts->dump_opts.indent_size;
747
+ }
748
+ }
749
+ } else {
750
+ fill_indent(out, d2);
751
+ }
752
+ oj_dump_custom_val(rb_ary_entry(a, i), d2, out, true);
753
+ if (i < cnt) {
754
+ *out->cur++ = ',';
755
+ }
756
+ }
757
+ size = depth * out->indent + 1;
758
+ assure_size(out, size);
759
+ if (out->opts->dump_opts.use) {
760
+ if (0 < out->opts->dump_opts.array_size) {
761
+ strcpy(out->cur, out->opts->dump_opts.array_nl);
762
+ out->cur += out->opts->dump_opts.array_size;
763
+ }
764
+ if (0 < out->opts->dump_opts.indent_size) {
765
+ int i;
766
+
767
+ for (i = depth; 0 < i; i--) {
768
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
769
+ out->cur += out->opts->dump_opts.indent_size;
770
+ }
771
+ }
772
+ } else {
773
+ fill_indent(out, depth);
774
+ }
775
+ *out->cur++ = ']';
801
776
  }
802
777
  *out->cur = '\0';
803
778
  }
804
779
 
805
- static void
806
- dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
807
- long id = oj_check_circular(obj, out);
808
- VALUE clas;
780
+ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
781
+ long id = oj_check_circular(obj, out);
782
+ VALUE clas;
809
783
 
810
784
  if (0 > id) {
811
- oj_dump_nil(Qnil, depth, out, false);
785
+ oj_dump_nil(Qnil, depth, out, false);
812
786
  } else if (Qnil != (clas = dump_common(obj, depth, out))) {
813
- VALUE ma = Qnil;
814
- VALUE v;
815
- char num_id[32];
816
- int i;
817
- int d2 = depth + 1;
818
- int d3 = d2 + 1;
819
- size_t size = d2 * out->indent + d3 * out->indent + 3;
820
- const char *name;
821
- int cnt;
822
- size_t len;
823
-
824
- assure_size(out, size);
825
- if (clas == rb_cRange) {
826
- *out->cur++ = '"';
827
- oj_dump_custom_val(rb_funcall(obj, oj_begin_id, 0), d3, out, false);
828
- assure_size(out, 3);
829
- *out->cur++ = '.';
830
- *out->cur++ = '.';
831
- if (Qtrue == rb_funcall(obj, oj_exclude_end_id, 0)) {
832
- *out->cur++ = '.';
833
- }
834
- oj_dump_custom_val(rb_funcall(obj, oj_end_id, 0), d3, out, false);
835
- *out->cur++ = '"';
836
-
837
- return;
838
- }
839
- *out->cur++ = '{';
840
- fill_indent(out, d2);
841
- size = d3 * out->indent + 2;
842
- ma = rb_struct_s_members(clas);
787
+ VALUE ma = Qnil;
788
+ VALUE v;
789
+ char num_id[32];
790
+ int i;
791
+ int d2 = depth + 1;
792
+ int d3 = d2 + 1;
793
+ size_t size = d2 * out->indent + d3 * out->indent + 3;
794
+ const char *name;
795
+ int cnt;
796
+ size_t len;
797
+
798
+ assure_size(out, size);
799
+ if (clas == rb_cRange) {
800
+ *out->cur++ = '"';
801
+ oj_dump_custom_val(rb_funcall(obj, oj_begin_id, 0), d3, out, false);
802
+ assure_size(out, 3);
803
+ *out->cur++ = '.';
804
+ *out->cur++ = '.';
805
+ if (Qtrue == rb_funcall(obj, oj_exclude_end_id, 0)) {
806
+ *out->cur++ = '.';
807
+ }
808
+ oj_dump_custom_val(rb_funcall(obj, oj_end_id, 0), d3, out, false);
809
+ *out->cur++ = '"';
810
+
811
+ return;
812
+ }
813
+ *out->cur++ = '{';
814
+ fill_indent(out, d2);
815
+ size = d3 * out->indent + 2;
816
+ ma = rb_struct_s_members(clas);
843
817
 
844
818
  #ifdef RSTRUCT_LEN
845
819
  #if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
846
- cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
847
- #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
848
- cnt = (int)RSTRUCT_LEN(obj);
849
- #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
820
+ cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
821
+ #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
822
+ cnt = (int)RSTRUCT_LEN(obj);
823
+ #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
850
824
  #else
851
- // This is a bit risky as a struct in C ruby is not the same as a Struct
852
- // class in interpreted Ruby so length() may not be defined.
853
- cnt = FIX2INT(rb_funcall2(obj, oj_length_id, 0, 0));
825
+ // This is a bit risky as a struct in C ruby is not the same as a Struct
826
+ // class in interpreted Ruby so length() may not be defined.
827
+ cnt = FIX2INT(rb_funcall2(obj, oj_length_id, 0, 0));
854
828
  #endif
855
- for (i = 0; i < cnt; i++) {
829
+ for (i = 0; i < cnt; i++) {
856
830
  #ifdef RSTRUCT_LEN
857
- v = RSTRUCT_GET(obj, i);
831
+ v = RSTRUCT_GET(obj, i);
858
832
  #else
859
- v = rb_struct_aref(obj, INT2FIX(i));
833
+ v = rb_struct_aref(obj, INT2FIX(i));
860
834
  #endif
861
- if (ma != Qnil) {
862
- volatile VALUE s = rb_sym_to_s(rb_ary_entry(ma, i));
863
-
864
- name = rb_string_value_ptr((VALUE*)&s);
865
- len = (int)RSTRING_LEN(s);
866
- } else {
867
- len = snprintf(num_id, sizeof(num_id), "%d", i);
868
- name = num_id;
869
- }
870
- assure_size(out, size + len + 3);
871
- fill_indent(out, d3);
872
- *out->cur++ = '"';
873
- memcpy(out->cur, name, len);
874
- out->cur += len;
875
- *out->cur++ = '"';
876
- *out->cur++ = ':';
877
- oj_dump_custom_val(v, d3, out, true);
878
- *out->cur++ = ',';
879
- }
880
- out->cur--;
881
- *out->cur++ = '}';
882
- *out->cur = '\0';
835
+ if (ma != Qnil) {
836
+ volatile VALUE s = rb_sym_to_s(rb_ary_entry(ma, i));
837
+
838
+ name = rb_string_value_ptr((VALUE *)&s);
839
+ len = (int)RSTRING_LEN(s);
840
+ } else {
841
+ len = snprintf(num_id, sizeof(num_id), "%d", i);
842
+ name = num_id;
843
+ }
844
+ assure_size(out, size + len + 3);
845
+ fill_indent(out, d3);
846
+ *out->cur++ = '"';
847
+ memcpy(out->cur, name, len);
848
+ out->cur += len;
849
+ *out->cur++ = '"';
850
+ *out->cur++ = ':';
851
+ oj_dump_custom_val(v, d3, out, true);
852
+ *out->cur++ = ',';
853
+ }
854
+ out->cur--;
855
+ *out->cur++ = '}';
856
+ *out->cur = '\0';
883
857
  }
884
858
  }
885
859
 
886
- static void
887
- dump_data(VALUE obj, int depth, Out out, bool as_ok) {
888
- long id = oj_check_circular(obj, out);
889
- VALUE clas;
860
+ static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
861
+ long id = oj_check_circular(obj, out);
862
+ VALUE clas;
890
863
 
891
864
  if (0 > id) {
892
- oj_dump_nil(Qnil, depth, out, false);
865
+ oj_dump_nil(Qnil, depth, out, false);
893
866
  } else if (Qnil != (clas = dump_common(obj, depth, out))) {
894
- dump_obj_attrs(obj, clas, id, depth, out);
867
+ dump_obj_attrs(obj, clas, id, depth, out);
895
868
  }
896
869
  }
897
870
 
898
- static void
899
- dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
871
+ static void dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
900
872
  if (NULL != out->opts->create_id) {
901
- dump_obj_str(obj, depth, out);
873
+ dump_obj_str(obj, depth, out);
902
874
  } else {
903
- dump_obj_as_str(obj, depth, out);
875
+ dump_obj_as_str(obj, depth, out);
904
876
  }
905
877
  }
906
878
 
907
- static void
908
- dump_complex(VALUE obj, int depth, Out out, bool as_ok) {
879
+ static void dump_complex(VALUE obj, int depth, Out out, bool as_ok) {
909
880
  complex_dump(obj, depth, out);
910
881
  }
911
882
 
912
- static void
913
- dump_rational(VALUE obj, int depth, Out out, bool as_ok) {
883
+ static void dump_rational(VALUE obj, int depth, Out out, bool as_ok) {
914
884
  rational_dump(obj, depth, out);
915
885
  }
916
886
 
917
- static DumpFunc custom_funcs[] = {
918
- NULL, // RUBY_T_NONE = 0x00,
919
- dump_obj, // RUBY_T_OBJECT = 0x01,
920
- oj_dump_class, // RUBY_T_CLASS = 0x02,
921
- oj_dump_class, // RUBY_T_MODULE = 0x03,
922
- oj_dump_float, // RUBY_T_FLOAT = 0x04,
923
- oj_dump_str, // RUBY_T_STRING = 0x05,
924
- dump_regexp, // RUBY_T_REGEXP = 0x06,
925
- dump_array, // RUBY_T_ARRAY = 0x07,
926
- dump_hash, // RUBY_T_HASH = 0x08,
927
- dump_struct, // RUBY_T_STRUCT = 0x09,
928
- oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
929
- NULL, // RUBY_T_FILE = 0x0b,
930
- dump_data, // RUBY_T_DATA = 0x0c,
931
- NULL, // RUBY_T_MATCH = 0x0d,
932
- dump_complex, // RUBY_T_COMPLEX = 0x0e,
933
- dump_rational, // RUBY_T_RATIONAL = 0x0f,
934
- NULL, // 0x10
935
- oj_dump_nil, // RUBY_T_NIL = 0x11,
936
- oj_dump_true, // RUBY_T_TRUE = 0x12,
937
- oj_dump_false, // RUBY_T_FALSE = 0x13,
938
- oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
939
- oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
887
+ static DumpFunc custom_funcs[] = {
888
+ NULL, // RUBY_T_NONE = 0x00,
889
+ dump_obj, // RUBY_T_OBJECT = 0x01,
890
+ oj_dump_class, // RUBY_T_CLASS = 0x02,
891
+ oj_dump_class, // RUBY_T_MODULE = 0x03,
892
+ oj_dump_float, // RUBY_T_FLOAT = 0x04,
893
+ oj_dump_str, // RUBY_T_STRING = 0x05,
894
+ dump_regexp, // RUBY_T_REGEXP = 0x06,
895
+ dump_array, // RUBY_T_ARRAY = 0x07,
896
+ dump_hash, // RUBY_T_HASH = 0x08,
897
+ dump_struct, // RUBY_T_STRUCT = 0x09,
898
+ oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
899
+ NULL, // RUBY_T_FILE = 0x0b,
900
+ dump_data, // RUBY_T_DATA = 0x0c,
901
+ NULL, // RUBY_T_MATCH = 0x0d,
902
+ dump_complex, // RUBY_T_COMPLEX = 0x0e,
903
+ dump_rational, // RUBY_T_RATIONAL = 0x0f,
904
+ NULL, // 0x10
905
+ oj_dump_nil, // RUBY_T_NIL = 0x11,
906
+ oj_dump_true, // RUBY_T_TRUE = 0x12,
907
+ oj_dump_false, // RUBY_T_FALSE = 0x13,
908
+ oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
909
+ oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
940
910
  };
941
911
 
942
- void
943
- oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
944
- int type = rb_type(obj);
912
+ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
913
+ int type = rb_type(obj);
945
914
 
946
915
  if (Yes == out->opts->trace) {
947
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
916
+ oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
948
917
  }
949
918
  if (MAX_DEPTH < depth) {
950
- rb_raise(rb_eNoMemError, "Too deeply nested.\n");
919
+ rb_raise(rb_eNoMemError, "Too deeply nested.\n");
951
920
  }
952
921
  if (0 < type && type <= RUBY_T_FIXNUM) {
953
- DumpFunc f = custom_funcs[type];
954
-
955
- if (NULL != f) {
956
- f(obj, depth, out, true);
957
- if (Yes == out->opts->trace) {
958
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
959
- }
960
- return;
961
- }
922
+ DumpFunc f = custom_funcs[type];
923
+
924
+ if (NULL != f) {
925
+ f(obj, depth, out, true);
926
+ if (Yes == out->opts->trace) {
927
+ oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
928
+ }
929
+ return;
930
+ }
962
931
  }
963
932
  oj_dump_nil(Qnil, depth, out, false);
964
933
  if (Yes == out->opts->trace) {
965
- oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
934
+ oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
966
935
  }
967
936
  }
968
937
 
969
938
  ///// load functions /////
970
939
 
971
- static void
972
- hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
973
- const char *key = kval->key;
974
- int klen = kval->klen;
975
- Val parent = stack_peek(&pi->stack);
976
- volatile VALUE rkey = kval->key_val;
977
-
978
- if (Qundef == rkey &&
979
- Yes == pi->options.create_ok &&
980
- NULL != pi->options.create_id &&
981
- *pi->options.create_id == *key &&
982
- (int)pi->options.create_id_len == klen &&
983
- 0 == strncmp(pi->options.create_id, key, klen)) {
984
-
985
- parent->clas = oj_name2class(pi, str, len, false, rb_eArgError);
986
- if (2 == klen && '^' == *key && 'o' == key[1]) {
987
- if (Qundef != parent->clas) {
988
- if (!oj_code_has(codes, parent->clas, false)) {
989
- parent->val = rb_obj_alloc(parent->clas);
990
- }
991
- }
992
- }
940
+ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
941
+ const char * key = kval->key;
942
+ int klen = kval->klen;
943
+ Val parent = stack_peek(&pi->stack);
944
+ volatile VALUE rkey = kval->key_val;
945
+
946
+ if (Qundef == rkey && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
947
+ *pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
948
+ 0 == strncmp(pi->options.create_id, key, klen)) {
949
+ parent->clas = oj_name2class(pi, str, len, false, rb_eArgError);
950
+ if (2 == klen && '^' == *key && 'o' == key[1]) {
951
+ if (Qundef != parent->clas) {
952
+ if (!oj_code_has(codes, parent->clas, false)) {
953
+ parent->val = rb_obj_alloc(parent->clas);
954
+ }
955
+ }
956
+ }
993
957
  } else {
994
- volatile VALUE rstr = rb_str_new(str, len);
995
-
996
- if (Qundef == rkey) {
997
- rkey = rb_str_new(key, klen);
998
- rstr = oj_encode(rstr);
999
- rkey = oj_encode(rkey);
1000
- if (Yes == pi->options.sym_key) {
1001
- rkey = rb_str_intern(rkey);
1002
- }
1003
- }
1004
- if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
1005
- VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
1006
-
1007
- if (Qnil != clas) {
1008
- rstr = rb_funcall(clas, oj_json_create_id, 1, rstr);
1009
- }
1010
- }
1011
- switch (rb_type(parent->val)) {
1012
- case T_OBJECT:
1013
- oj_set_obj_ivar(parent, kval, rstr);
1014
- break;
1015
- case T_HASH:
1016
- if (4 == parent->klen && NULL != parent->key && rb_cTime == parent->clas && 0 == strncmp("time", parent->key, 4)) {
1017
- if (Qnil == (parent->val = oj_parse_xml_time(str, (int)len))) {
1018
- parent->val = rb_funcall(rb_cTime, rb_intern("parse"), 1, rb_str_new(str, len));
1019
- }
1020
- } else {
1021
- rb_hash_aset(parent->val, rkey, rstr);
1022
- }
1023
- break;
1024
- default:
1025
- break;
1026
- }
1027
- if (Yes == pi->options.trace) {
1028
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
1029
- }
958
+ //volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
959
+ volatile VALUE rstr = rb_str_new(str, len);
960
+
961
+ if (Qundef == rkey) {
962
+ rkey = rb_str_new(key, klen);
963
+ rstr = oj_encode(rstr);
964
+ rkey = oj_encode(rkey);
965
+ if (Yes == pi->options.sym_key) {
966
+ rkey = rb_str_intern(rkey);
967
+ }
968
+ }
969
+ if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
970
+ VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
971
+
972
+ if (Qnil != clas) {
973
+ rstr = rb_funcall(clas, oj_json_create_id, 1, rstr);
974
+ }
975
+ }
976
+ switch (rb_type(parent->val)) {
977
+ case T_OBJECT: oj_set_obj_ivar(parent, kval, rstr); break;
978
+ case T_HASH:
979
+ if (4 == parent->klen && NULL != parent->key && rb_cTime == parent->clas &&
980
+ 0 == strncmp("time", parent->key, 4)) {
981
+ if (Qnil == (parent->val = oj_parse_xml_time(str, (int)len))) {
982
+ parent->val = rb_funcall(rb_cTime, rb_intern("parse"), 1, rb_str_new(str, len));
983
+ }
984
+ } else {
985
+ rb_hash_aset(parent->val, rkey, rstr);
986
+ }
987
+ break;
988
+ default: break;
989
+ }
990
+ if (Yes == pi->options.trace) {
991
+ oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
992
+ }
1030
993
  }
1031
994
  }
1032
995
 
1033
- static void
1034
- end_hash(struct _parseInfo *pi) {
1035
- Val parent = stack_peek(&pi->stack);
996
+ static void end_hash(struct _parseInfo *pi) {
997
+ Val parent = stack_peek(&pi->stack);
1036
998
 
1037
999
  if (Qundef != parent->clas && parent->clas != rb_obj_class(parent->val)) {
1038
- volatile VALUE obj = oj_code_load(codes, parent->clas, parent->val);
1039
-
1040
- if (Qnil != obj) {
1041
- parent->val = obj;
1042
- } else {
1043
- parent->val = rb_funcall(parent->clas, oj_json_create_id, 1, parent->val);
1044
- }
1045
- parent->clas = Qundef;
1000
+ volatile VALUE obj = oj_code_load(codes, parent->clas, parent->val);
1001
+
1002
+ if (Qnil != obj) {
1003
+ parent->val = obj;
1004
+ } else {
1005
+ parent->val = rb_funcall(parent->clas, oj_json_create_id, 1, parent->val);
1006
+ }
1007
+ parent->clas = Qundef;
1046
1008
  }
1047
1009
  if (Yes == pi->options.trace) {
1048
- oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
1010
+ oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
1049
1011
  }
1050
1012
  }
1051
1013
 
1052
- static VALUE
1053
- calc_hash_key(ParseInfo pi, Val parent) {
1054
- volatile VALUE rkey = parent->key_val;
1055
-
1056
- if (Qundef == rkey) {
1057
- rkey = rb_str_new(parent->key, parent->klen);
1058
- }
1059
- rkey = oj_encode(rkey);
1060
- if (Yes == pi->options.sym_key) {
1061
- rkey = rb_str_intern(rkey);
1062
- }
1063
- return rkey;
1064
- }
1065
-
1066
- static void
1067
- hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1068
- Val parent = stack_peek(&pi->stack);
1069
- volatile VALUE rval = oj_num_as_value(ni);
1014
+ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1015
+ Val parent = stack_peek(&pi->stack);
1016
+ volatile VALUE rval = oj_num_as_value(ni);
1070
1017
 
1071
1018
  switch (rb_type(parent->val)) {
1072
- case T_OBJECT:
1073
- oj_set_obj_ivar(parent, kval, rval);
1074
- break;
1019
+ case T_OBJECT: oj_set_obj_ivar(parent, kval, rval); break;
1075
1020
  case T_HASH:
1076
- if (4 == parent->klen && NULL != parent->key && rb_cTime == parent->clas && 0 != ni->div && 0 == strncmp("time", parent->key, 4)) {
1077
- int64_t nsec = ni->num * 1000000000LL / ni->div;
1078
-
1079
- if (ni->neg) {
1080
- ni->i = -ni->i;
1081
- if (0 < nsec) {
1082
- ni->i--;
1083
- nsec = 1000000000LL - nsec;
1084
- }
1085
- }
1086
- if (86400 == ni->exp) { // UTC time
1087
- parent->val = rb_time_nano_new(ni->i, (long)nsec);
1088
- // Since the ruby C routines alway create local time, the
1089
- // offset and then a conversion to UTC keeps makes the time
1090
- // match the expected value.
1091
- parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
1092
- } else if (ni->hasExp) {
1093
- int64_t t = (int64_t)(ni->i + ni->exp);
1094
- struct _timeInfo ti;
1095
- VALUE args[8];
1096
-
1097
- sec_as_time(t, &ti);
1098
-
1099
- args[0] = LONG2NUM(ti.year);
1100
- args[1] = LONG2NUM(ti.mon);
1101
- args[2] = LONG2NUM(ti.day);
1102
- args[3] = LONG2NUM(ti.hour);
1103
- args[4] = LONG2NUM(ti.min);
1104
- args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
1105
- args[6] = LONG2NUM(ni->exp);
1106
- parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
1107
- } else {
1108
- parent->val = rb_time_nano_new(ni->i, (long)nsec);
1109
- }
1110
- rval = parent->val;
1111
- } else {
1112
- rb_hash_aset(parent->val, calc_hash_key(pi, kval), rval);
1113
- }
1114
- break;
1115
- default:
1116
- break;
1021
+ if (4 == parent->klen && NULL != parent->key && rb_cTime == parent->clas && 0 != ni->div &&
1022
+ 0 == strncmp("time", parent->key, 4)) {
1023
+ int64_t nsec = ni->num * 1000000000LL / ni->div;
1024
+
1025
+ if (ni->neg) {
1026
+ ni->i = -ni->i;
1027
+ if (0 < nsec) {
1028
+ ni->i--;
1029
+ nsec = 1000000000LL - nsec;
1030
+ }
1031
+ }
1032
+ if (86400 == ni->exp) { // UTC time
1033
+ parent->val = rb_time_nano_new(ni->i, (long)nsec);
1034
+ // Since the ruby C routines alway create local time, the
1035
+ // offset and then a conversion to UTC keeps makes the time
1036
+ // match the expected value.
1037
+ parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
1038
+ } else if (ni->has_exp) {
1039
+ int64_t t = (int64_t)(ni->i + ni->exp);
1040
+ struct _timeInfo ti;
1041
+ VALUE args[8];
1042
+
1043
+ sec_as_time(t, &ti);
1044
+
1045
+ args[0] = LONG2NUM(ti.year);
1046
+ args[1] = LONG2NUM(ti.mon);
1047
+ args[2] = LONG2NUM(ti.day);
1048
+ args[3] = LONG2NUM(ti.hour);
1049
+ args[4] = LONG2NUM(ti.min);
1050
+ args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
1051
+ args[6] = LONG2NUM(ni->exp);
1052
+ parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
1053
+ } else {
1054
+ parent->val = rb_time_nano_new(ni->i, (long)nsec);
1055
+ }
1056
+ rval = parent->val;
1057
+ } else {
1058
+ rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), rval);
1059
+ }
1060
+ break;
1061
+ default: break;
1117
1062
  }
1118
1063
  if (Yes == pi->options.trace) {
1119
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
1064
+ oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
1120
1065
  }
1121
1066
  }
1122
1067
 
1123
- static void
1124
- hash_set_value(ParseInfo pi, Val kval, VALUE value) {
1125
- Val parent = stack_peek(&pi->stack);
1068
+ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
1069
+ Val parent = stack_peek(&pi->stack);
1126
1070
 
1127
1071
  switch (rb_type(parent->val)) {
1128
- case T_OBJECT:
1129
- oj_set_obj_ivar(parent, kval, value);
1130
- break;
1131
- case T_HASH:
1132
- rb_hash_aset(parent->val, calc_hash_key(pi, kval), value);
1133
- break;
1134
- default:
1135
- break;
1072
+ case T_OBJECT: oj_set_obj_ivar(parent, kval, value); break;
1073
+ case T_HASH: rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), value); break;
1074
+ default: break;
1136
1075
  }
1137
1076
  if (Yes == pi->options.trace) {
1138
- oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
1077
+ oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
1139
1078
  }
1140
1079
  }
1141
1080
 
1142
- static void
1143
- array_append_num(ParseInfo pi, NumInfo ni) {
1144
- Val parent = stack_peek(&pi->stack);
1145
- volatile VALUE rval = oj_num_as_value(ni);
1081
+ static void array_append_num(ParseInfo pi, NumInfo ni) {
1082
+ Val parent = stack_peek(&pi->stack);
1083
+ volatile VALUE rval = oj_num_as_value(ni);
1146
1084
 
1147
1085
  rb_ary_push(parent->val, rval);
1148
1086
  if (Yes == pi->options.trace) {
1149
- oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
1087
+ oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
1150
1088
  }
1151
1089
  }
1152
1090
 
1153
- static void
1154
- array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
1155
- volatile VALUE rstr = rb_str_new(str, len);
1091
+ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
1092
+ volatile VALUE rstr = rb_str_new(str, len);
1156
1093
 
1157
1094
  rstr = oj_encode(rstr);
1158
1095
  if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
1159
- VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
1096
+ VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
1160
1097
 
1161
- if (Qnil != clas) {
1162
- rb_ary_push(stack_peek(&pi->stack)->val, rb_funcall(clas, oj_json_create_id, 1, rstr));
1163
- return;
1164
- }
1098
+ if (Qnil != clas) {
1099
+ rb_ary_push(stack_peek(&pi->stack)->val, rb_funcall(clas, oj_json_create_id, 1, rstr));
1100
+ return;
1101
+ }
1165
1102
  }
1166
1103
  rb_ary_push(stack_peek(&pi->stack)->val, rstr);
1167
1104
  if (Yes == pi->options.trace) {
1168
- oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
1105
+ oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
1169
1106
  }
1170
1107
  }
1171
1108
 
1172
- void
1173
- oj_set_custom_callbacks(ParseInfo pi) {
1109
+ void oj_set_custom_callbacks(ParseInfo pi) {
1174
1110
  oj_set_compat_callbacks(pi);
1175
- pi->hash_set_cstr = hash_set_cstr;
1176
- pi->end_hash = end_hash;
1177
- pi->hash_set_num = hash_set_num;
1178
- pi->hash_set_value = hash_set_value;
1111
+ pi->hash_set_cstr = hash_set_cstr;
1112
+ pi->end_hash = end_hash;
1113
+ pi->hash_set_num = hash_set_num;
1114
+ pi->hash_set_value = hash_set_value;
1179
1115
  pi->array_append_cstr = array_append_cstr;
1180
- pi->array_append_num = array_append_num;
1116
+ pi->array_append_num = array_append_num;
1181
1117
  }
1182
1118
 
1183
1119
  VALUE
1184
1120
  oj_custom_parse(int argc, VALUE *argv, VALUE self) {
1185
- struct _parseInfo pi;
1121
+ struct _parseInfo pi;
1186
1122
 
1187
1123
  parse_info_init(&pi);
1188
- pi.options = oj_default_options;
1189
- pi.handler = Qnil;
1190
- pi.err_class = Qnil;
1191
- pi.max_depth = 0;
1124
+ pi.options = oj_default_options;
1125
+ pi.handler = Qnil;
1126
+ pi.err_class = Qnil;
1127
+ pi.max_depth = 0;
1192
1128
  pi.options.allow_nan = Yes;
1193
- pi.options.nilnil = Yes;
1129
+ pi.options.nilnil = Yes;
1194
1130
  oj_set_custom_callbacks(&pi);
1195
1131
 
1196
1132
  if (T_STRING == rb_type(*argv)) {
1197
- return oj_pi_parse(argc, argv, &pi, 0, 0, false);
1133
+ return oj_pi_parse(argc, argv, &pi, 0, 0, false);
1198
1134
  } else {
1199
- return oj_pi_sparse(argc, argv, &pi, 0);
1135
+ return oj_pi_sparse(argc, argv, &pi, 0);
1200
1136
  }
1201
1137
  }
1202
1138
 
1203
1139
  VALUE
1204
1140
  oj_custom_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
1205
- struct _parseInfo pi;
1141
+ struct _parseInfo pi;
1206
1142
 
1207
1143
  parse_info_init(&pi);
1208
- pi.options = oj_default_options;
1209
- pi.handler = Qnil;
1210
- pi.err_class = Qnil;
1211
- pi.max_depth = 0;
1144
+ pi.options = oj_default_options;
1145
+ pi.handler = Qnil;
1146
+ pi.err_class = Qnil;
1147
+ pi.max_depth = 0;
1212
1148
  pi.options.allow_nan = Yes;
1213
- pi.options.nilnil = Yes;
1149
+ pi.options.nilnil = Yes;
1214
1150
  oj_set_custom_callbacks(&pi);
1215
1151
  pi.end_hash = end_hash;
1216
1152