oj 3.11.0 → 3.11.5

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