oj 3.11.1 → 3.11.6

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -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 +1042 -1041
  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 +412 -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 +1123 -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/test_fast.rb +32 -2
  62. data/test/test_generate.rb +21 -0
  63. data/test/test_hash.rb +10 -0
  64. data/test/test_scp.rb +1 -1
  65. 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