oj 3.10.6 → 3.12.0

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