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/object.c CHANGED
@@ -1,411 +1,397 @@
1
1
  // Copyright (c) 2012 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>
5
6
  #include <time.h>
6
7
 
7
- #include "oj.h"
8
+ #include "encode.h"
8
9
  #include "err.h"
9
- #include "parse.h"
10
- #include "resolve.h"
11
10
  #include "hash.h"
12
11
  #include "odd.h"
13
- #include "encode.h"
12
+ #include "oj.h"
13
+ #include "parse.h"
14
+ #include "resolve.h"
14
15
  #include "trace.h"
15
16
  #include "util.h"
16
17
 
17
- inline static long
18
- read_long(const char *str, size_t len) {
19
- long n = 0;
18
+ inline static long read_long(const char *str, size_t len) {
19
+ long n = 0;
20
20
 
21
21
  for (; 0 < len; str++, len--) {
22
- if ('0' <= *str && *str <= '9') {
23
- n = n * 10 + (*str - '0');
24
- } else {
25
- return -1;
26
- }
22
+ if ('0' <= *str && *str <= '9') {
23
+ n = n * 10 + (*str - '0');
24
+ } else {
25
+ return -1;
26
+ }
27
27
  }
28
28
  return n;
29
29
  }
30
30
 
31
- static VALUE
32
- calc_hash_key(ParseInfo pi, Val kval, char k1) {
33
- volatile VALUE rkey;
31
+ static VALUE calc_hash_key(ParseInfo pi, Val kval, char k1) {
32
+ volatile VALUE rkey;
34
33
 
35
34
  if (':' == k1) {
36
- rkey = rb_str_new(kval->key + 1, kval->klen - 1);
37
- rkey = oj_encode(rkey);
38
- rkey = rb_funcall(rkey, oj_to_sym_id, 0);
35
+ rkey = rb_str_new(kval->key + 1, kval->klen - 1);
36
+ rkey = oj_encode(rkey);
37
+ rkey = rb_funcall(rkey, oj_to_sym_id, 0);
39
38
  } else {
40
- rkey = rb_str_new(kval->key, kval->klen);
41
- rkey = oj_encode(rkey);
42
- if (Yes == pi->options.sym_key) {
43
- rkey = rb_str_intern(rkey);
44
- }
39
+ rkey = rb_str_new(kval->key, kval->klen);
40
+ rkey = oj_encode(rkey);
41
+ if (Yes == pi->options.sym_key) {
42
+ rkey = rb_str_intern(rkey);
43
+ }
45
44
  }
46
45
  return rkey;
47
46
  }
48
47
 
49
- static VALUE
50
- str_to_value(ParseInfo pi, const char *str, size_t len, const char *orig) {
51
- volatile VALUE rstr = Qnil;
48
+ static VALUE str_to_value(ParseInfo pi, const char *str, size_t len, const char *orig) {
49
+ volatile VALUE rstr = Qnil;
52
50
 
53
51
  if (':' == *orig && 0 < len) {
54
- rstr = rb_str_new(str + 1, len - 1);
55
- rstr = oj_encode(rstr);
56
- rstr = rb_funcall(rstr, oj_to_sym_id, 0);
52
+ rstr = rb_str_new(str + 1, len - 1);
53
+ rstr = oj_encode(rstr);
54
+ rstr = rb_funcall(rstr, oj_to_sym_id, 0);
57
55
  } else if (pi->circ_array && 3 <= len && '^' == *orig && 'r' == orig[1]) {
58
- long i = read_long(str + 2, len - 2);
56
+ long i = read_long(str + 2, len - 2);
59
57
 
60
- if (0 > i) {
61
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a valid ID number");
62
- return Qnil;
63
- }
64
- rstr = oj_circ_array_get(pi->circ_array, i);
58
+ if (0 > i) {
59
+ oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a valid ID number");
60
+ return Qnil;
61
+ }
62
+ rstr = oj_circ_array_get(pi->circ_array, i);
65
63
  } else {
66
- rstr = rb_str_new(str, len);
67
- rstr = oj_encode(rstr);
64
+ rstr = rb_str_new(str, len);
65
+ rstr = oj_encode(rstr);
68
66
  }
69
67
  return rstr;
70
68
  }
71
69
 
72
70
  #if (RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8)
73
- static VALUE
74
- oj_parse_xml_time(const char *str, int len) {
71
+ static VALUE oj_parse_xml_time(const char *str, int len) {
75
72
  return rb_funcall(rb_cTime, oj_parse_id, 1, rb_str_new(str, len));
76
73
  }
77
74
  #else
78
75
  // The much faster approach (4x faster)
79
- static int
80
- parse_num(const char *str, const char *end, int cnt) {
81
- int n = 0;
82
- char c;
83
- int i;
76
+ static int parse_num(const char *str, const char *end, int cnt) {
77
+ int n = 0;
78
+ char c;
79
+ int i;
84
80
 
85
81
  for (i = cnt; 0 < i; i--, str++) {
86
- c = *str;
87
- if (end <= str || c < '0' || '9' < c) {
88
- return -1;
89
- }
90
- n = n * 10 + (c - '0');
82
+ c = *str;
83
+ if (end <= str || c < '0' || '9' < c) {
84
+ return -1;
85
+ }
86
+ n = n * 10 + (c - '0');
91
87
  }
92
88
  return n;
93
89
  }
94
90
 
95
91
  VALUE
96
92
  oj_parse_xml_time(const char *str, int len) {
97
- VALUE args[8];
98
- const char *end = str + len;
99
- int n;
93
+ VALUE args[8];
94
+ const char *end = str + len;
95
+ int n;
100
96
 
101
97
  // year
102
98
  if (0 > (n = parse_num(str, end, 4))) {
103
- return Qnil;
99
+ return Qnil;
104
100
  }
105
101
  str += 4;
106
102
  args[0] = LONG2NUM(n);
107
103
  if ('-' != *str++) {
108
- return Qnil;
104
+ return Qnil;
109
105
  }
110
106
  // month
111
107
  if (0 > (n = parse_num(str, end, 2))) {
112
- return Qnil;
108
+ return Qnil;
113
109
  }
114
110
  str += 2;
115
111
  args[1] = LONG2NUM(n);
116
112
  if ('-' != *str++) {
117
- return Qnil;
113
+ return Qnil;
118
114
  }
119
115
  // day
120
116
  if (0 > (n = parse_num(str, end, 2))) {
121
- return Qnil;
117
+ return Qnil;
122
118
  }
123
119
  str += 2;
124
120
  args[2] = LONG2NUM(n);
125
121
  if ('T' != *str++) {
126
- return Qnil;
122
+ return Qnil;
127
123
  }
128
124
  // hour
129
125
  if (0 > (n = parse_num(str, end, 2))) {
130
- return Qnil;
126
+ return Qnil;
131
127
  }
132
128
  str += 2;
133
129
  args[3] = LONG2NUM(n);
134
130
  if (':' != *str++) {
135
- return Qnil;
131
+ return Qnil;
136
132
  }
137
133
  // minute
138
134
  if (0 > (n = parse_num(str, end, 2))) {
139
- return Qnil;
135
+ return Qnil;
140
136
  }
141
137
  str += 2;
142
138
  args[4] = LONG2NUM(n);
143
139
  if (':' != *str++) {
144
- return Qnil;
140
+ return Qnil;
145
141
  }
146
142
  // second
147
143
  if (0 > (n = parse_num(str, end, 2))) {
148
- return Qnil;
144
+ return Qnil;
149
145
  }
150
146
  str += 2;
151
147
  if (str == end) {
152
- args[5] = LONG2NUM(n);
153
- args[6] = LONG2NUM(0);
148
+ args[5] = LONG2NUM(n);
149
+ args[6] = LONG2NUM(0);
154
150
  } else {
155
- char c = *str++;
156
-
157
- if ('.' == c) {
158
- long long nsec = 0;
159
-
160
- for (; str < end; str++) {
161
- c = *str;
162
- if (c < '0' || '9' < c) {
163
- str++;
164
- break;
165
- }
166
- nsec = nsec * 10 + (c - '0');
167
- }
168
- args[5] = rb_float_new((double)n + ((double)nsec + 0.5) / 1000000000.0);
169
- } else {
170
- args[5] = rb_ll2inum(n);
171
- }
172
- if (end < str) {
173
- args[6] = LONG2NUM(0);
174
- } else {
175
- if ('Z' == c) {
176
- return rb_funcall2(rb_cTime, oj_utc_id, 6, args);
177
- } else if ('+' == c) {
178
- int hr = parse_num(str, end, 2);
179
- int min;
180
-
181
- str += 2;
182
- if (0 > hr || ':' != *str++) {
183
- return Qnil;
184
- }
185
- min = parse_num(str, end, 2);
186
- if (0 > min) {
187
- return Qnil;
188
- }
189
- args[6] = LONG2NUM(hr * 3600 + min * 60);
190
- } else if ('-' == c) {
191
- int hr = parse_num(str, end, 2);
192
- int min;
193
-
194
- str += 2;
195
- if (0 > hr || ':' != *str++) {
196
- return Qnil;
197
- }
198
- min = parse_num(str, end, 2);
199
- if (0 > min) {
200
- return Qnil;
201
- }
202
- args[6] = LONG2NUM(-(hr * 3600 + min * 60));
203
- } else {
204
- args[6] = LONG2NUM(0);
205
- }
206
- }
151
+ char c = *str++;
152
+
153
+ if ('.' == c) {
154
+ long long nsec = 0;
155
+
156
+ for (; str < end; str++) {
157
+ c = *str;
158
+ if (c < '0' || '9' < c) {
159
+ str++;
160
+ break;
161
+ }
162
+ nsec = nsec * 10 + (c - '0');
163
+ }
164
+ args[5] = rb_float_new((double)n + ((double)nsec + 0.5) / 1000000000.0);
165
+ } else {
166
+ args[5] = rb_ll2inum(n);
167
+ }
168
+ if (end < str) {
169
+ args[6] = LONG2NUM(0);
170
+ } else {
171
+ if ('Z' == c) {
172
+ return rb_funcall2(rb_cTime, oj_utc_id, 6, args);
173
+ } else if ('+' == c) {
174
+ int hr = parse_num(str, end, 2);
175
+ int min;
176
+
177
+ str += 2;
178
+ if (0 > hr || ':' != *str++) {
179
+ return Qnil;
180
+ }
181
+ min = parse_num(str, end, 2);
182
+ if (0 > min) {
183
+ return Qnil;
184
+ }
185
+ args[6] = LONG2NUM(hr * 3600 + min * 60);
186
+ } else if ('-' == c) {
187
+ int hr = parse_num(str, end, 2);
188
+ int min;
189
+
190
+ str += 2;
191
+ if (0 > hr || ':' != *str++) {
192
+ return Qnil;
193
+ }
194
+ min = parse_num(str, end, 2);
195
+ if (0 > min) {
196
+ return Qnil;
197
+ }
198
+ args[6] = LONG2NUM(-(hr * 3600 + min * 60));
199
+ } else {
200
+ args[6] = LONG2NUM(0);
201
+ }
202
+ }
207
203
  }
208
204
  return rb_funcall2(rb_cTime, oj_new_id, 7, args);
209
205
  }
210
206
  #endif
211
207
 
212
- static int
213
- hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t len) {
214
- const char *key = kval->key;
215
- int klen = kval->klen;
208
+ static int hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t len) {
209
+ const char *key = kval->key;
210
+ int klen = kval->klen;
216
211
 
217
212
  if (2 == klen) {
218
- switch (key[1]) {
219
- case 'o': // object
220
- { // name2class sets an error if the class is not found or created
221
- VALUE clas = oj_name2class(pi, str, len, Yes == pi->options.auto_define, rb_eArgError);
222
-
223
- if (Qundef != clas) {
224
- parent->val = rb_obj_alloc(clas);
225
- }
226
- }
227
- break;
228
- case 'O': // odd object
229
- {
230
- Odd odd = oj_get_oddc(str, len);
231
-
232
- if (0 == odd) {
233
- return 0;
234
- }
235
- parent->val = odd->clas;
236
- parent->odd_args = oj_odd_alloc_args(odd);
237
- }
238
- break;
239
- case 'm':
240
- parent->val = rb_str_new(str + 1, len - 1);
241
- parent->val = oj_encode(parent->val);
242
- parent->val = rb_funcall(parent->val, oj_to_sym_id, 0);
243
- break;
244
- case 's':
245
- parent->val = rb_str_new(str, len);
246
- parent->val = oj_encode(parent->val);
247
- break;
248
- case 'c': // class
249
- {
250
- VALUE clas = oj_name2class(pi, str, len, Yes == pi->options.auto_define, rb_eArgError);
251
-
252
- if (Qundef == clas) {
253
- return 0;
254
- } else {
255
- parent->val = clas;
256
- }
257
- }
258
- break;
259
- case 't': // time
260
- parent->val = oj_parse_xml_time(str, (int)len);
261
- break;
262
- default:
263
- return 0;
264
- break;
265
- }
266
- return 1; // handled
213
+ switch (key[1]) {
214
+ case 'o': // object
215
+ { // name2class sets an error if the class is not found or created
216
+ VALUE clas = oj_name2class(pi, str, len, Yes == pi->options.auto_define, rb_eArgError);
217
+
218
+ if (Qundef != clas) {
219
+ parent->val = rb_obj_alloc(clas);
220
+ }
221
+ } break;
222
+ case 'O': // odd object
223
+ {
224
+ Odd odd = oj_get_oddc(str, len);
225
+
226
+ if (0 == odd) {
227
+ return 0;
228
+ }
229
+ parent->val = odd->clas;
230
+ parent->odd_args = oj_odd_alloc_args(odd);
231
+ } break;
232
+ case 'm':
233
+ parent->val = rb_str_new(str + 1, len - 1);
234
+ parent->val = oj_encode(parent->val);
235
+ parent->val = rb_funcall(parent->val, oj_to_sym_id, 0);
236
+ break;
237
+ case 's':
238
+ parent->val = rb_str_new(str, len);
239
+ parent->val = oj_encode(parent->val);
240
+ break;
241
+ case 'c': // class
242
+ {
243
+ VALUE clas = oj_name2class(pi, str, len, Yes == pi->options.auto_define, rb_eArgError);
244
+
245
+ if (Qundef == clas) {
246
+ return 0;
247
+ } else {
248
+ parent->val = clas;
249
+ }
250
+ } break;
251
+ case 't': // time
252
+ parent->val = oj_parse_xml_time(str, (int)len);
253
+ break;
254
+ default: return 0; break;
255
+ }
256
+ return 1; // handled
267
257
  }
268
258
  return 0;
269
259
  }
270
260
 
271
- static int
272
- hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
261
+ static int hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
273
262
  if (2 == kval->klen) {
274
- switch (kval->key[1]) {
275
- case 't': // time as a float
276
- if (0 == ni->div || 9 < ni->di) {
277
- rb_raise(rb_eArgError, "Invalid time decimal representation.");
278
- //parent->val = rb_time_nano_new(0, 0);
279
- } else {
280
- int64_t nsec = ni->num * 1000000000LL / ni->div;
281
-
282
- if (ni->neg) {
283
- ni->i = -ni->i;
284
- if (0 < nsec) {
285
- ni->i--;
286
- nsec = 1000000000LL - nsec;
287
- }
288
- }
289
- if (86400 == ni->exp) { // UTC time
290
- parent->val = rb_time_nano_new(ni->i, (long)nsec);
291
- // Since the ruby C routines alway create local time, the
292
- // offset and then a conversion to UTC keeps makes the time
293
- // match the expected value.
294
- parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
295
- } else if (ni->has_exp) {
296
- int64_t t = (int64_t)(ni->i + ni->exp);
297
- struct _timeInfo ti;
298
- VALUE args[8];
299
-
300
- sec_as_time(t, &ti);
301
- args[0] = LONG2NUM((long)(ti.year));
302
- args[1] = LONG2NUM(ti.mon);
303
- args[2] = LONG2NUM(ti.day);
304
- args[3] = LONG2NUM(ti.hour);
305
- args[4] = LONG2NUM(ti.min);
306
- args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
307
- args[6] = LONG2NUM(ni->exp);
308
- parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
309
- } else {
310
- parent->val = rb_time_nano_new(ni->i, (long)nsec);
311
- }
312
- }
313
- break;
314
- case 'i': // circular index
315
- if (!ni->infinity && !ni->neg && 1 == ni->div && 0 == ni->exp && 0 != pi->circ_array) { // fixnum
316
- if (Qnil == parent->val) {
317
- parent->val = rb_hash_new();
318
- }
319
- oj_circ_array_set(pi->circ_array, parent->val, ni->i);
320
- } else {
321
- return 0;
322
- }
323
- break;
324
- default:
325
- return 0;
326
- break;
327
- }
328
- return 1; // handled
263
+ switch (kval->key[1]) {
264
+ case 't': // time as a float
265
+ if (0 == ni->div || 9 < ni->di) {
266
+ rb_raise(rb_eArgError, "Invalid time decimal representation.");
267
+ // parent->val = rb_time_nano_new(0, 0);
268
+ } else {
269
+ int64_t nsec = ni->num * 1000000000LL / ni->div;
270
+
271
+ if (ni->neg) {
272
+ ni->i = -ni->i;
273
+ if (0 < nsec) {
274
+ ni->i--;
275
+ nsec = 1000000000LL - nsec;
276
+ }
277
+ }
278
+ if (86400 == ni->exp) { // UTC time
279
+ parent->val = rb_time_nano_new(ni->i, (long)nsec);
280
+ // Since the ruby C routines alway create local time, the
281
+ // offset and then a conversion to UTC keeps makes the time
282
+ // match the expected value.
283
+ parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
284
+ } else if (ni->has_exp) {
285
+ int64_t t = (int64_t)(ni->i + ni->exp);
286
+ struct _timeInfo ti;
287
+ VALUE args[8];
288
+
289
+ sec_as_time(t, &ti);
290
+ args[0] = LONG2NUM((long)(ti.year));
291
+ args[1] = LONG2NUM(ti.mon);
292
+ args[2] = LONG2NUM(ti.day);
293
+ args[3] = LONG2NUM(ti.hour);
294
+ args[4] = LONG2NUM(ti.min);
295
+ args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
296
+ args[6] = LONG2NUM(ni->exp);
297
+ parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
298
+ } else {
299
+ parent->val = rb_time_nano_new(ni->i, (long)nsec);
300
+ }
301
+ }
302
+ break;
303
+ case 'i': // circular index
304
+ if (!ni->infinity && !ni->neg && 1 == ni->div && 0 == ni->exp &&
305
+ 0 != pi->circ_array) { // fixnum
306
+ if (Qnil == parent->val) {
307
+ parent->val = rb_hash_new();
308
+ }
309
+ oj_circ_array_set(pi->circ_array, parent->val, ni->i);
310
+ } else {
311
+ return 0;
312
+ }
313
+ break;
314
+ default: return 0; break;
315
+ }
316
+ return 1; // handled
329
317
  }
330
318
  return 0;
331
319
  }
332
320
 
333
- static int
334
- hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, volatile VALUE value) {
321
+ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, volatile VALUE value) {
335
322
  if (T_ARRAY == rb_type(value)) {
336
- int len = (int)RARRAY_LEN(value);
337
-
338
- if (2 == klen && 'u' == key[1]) {
339
- volatile VALUE sc;
340
- volatile VALUE e1;
341
- int slen;
342
-
343
- if (0 == len) {
344
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
345
- return 1;
346
- }
347
- e1 = *RARRAY_PTR(value);
348
- // check for anonymous Struct
349
- if (T_ARRAY == rb_type(e1)) {
350
- VALUE args[1024];
351
- volatile VALUE rstr;
352
- int i, cnt = (int)RARRAY_LEN(e1);
353
-
354
- for (i = 0; i < cnt; i++) {
355
- rstr = rb_ary_entry(e1, i);
356
- args[i] = rb_funcall(rstr, oj_to_sym_id, 0);
357
- }
358
- sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
359
- } else {
360
- // If struct is not defined then we let this fail and raise an exception.
361
- sc = oj_name2struct(pi, *RARRAY_PTR(value), rb_eArgError);
362
- }
323
+ int len = (int)RARRAY_LEN(value);
324
+
325
+ if (2 == klen && 'u' == key[1]) {
326
+ volatile VALUE sc;
327
+ volatile VALUE e1;
328
+ int slen;
329
+
330
+ if (0 == len) {
331
+ oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
332
+ return 1;
333
+ }
334
+ e1 = *RARRAY_PTR(value);
335
+ // check for anonymous Struct
336
+ if (T_ARRAY == rb_type(e1)) {
337
+ VALUE args[1024];
338
+ volatile VALUE rstr;
339
+ int i, cnt = (int)RARRAY_LEN(e1);
340
+
341
+ for (i = 0; i < cnt; i++) {
342
+ rstr = rb_ary_entry(e1, i);
343
+ args[i] = rb_funcall(rstr, oj_to_sym_id, 0);
344
+ }
345
+ sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
346
+ } else {
347
+ // If struct is not defined then we let this fail and raise an exception.
348
+ sc = oj_name2struct(pi, *RARRAY_PTR(value), rb_eArgError);
349
+ }
363
350
  // Create a properly initialized struct instance without calling the initialize method.
364
351
  parent->val = rb_obj_alloc(sc);
365
352
  // If the JSON array has more entries than the struct class allows, we record an error.
366
353
  #ifdef RSTRUCT_LEN
367
354
  #if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
368
- slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
369
- #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
370
- slen = (int)RSTRUCT_LEN(parent->val);
371
- #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
355
+ slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
356
+ #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
357
+ slen = (int)RSTRUCT_LEN(parent->val);
358
+ #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
372
359
  #else
373
- slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0));
360
+ slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0));
374
361
  #endif
375
362
  // MRI >= 1.9
376
363
  if (len - 1 > slen) {
377
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
364
+ oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
378
365
  } else {
379
- int i;
366
+ int i;
380
367
 
381
- for (i = 0; i < len - 1; i++) {
382
- rb_struct_aset(parent->val, INT2FIX(i), RARRAY_PTR(value)[i + 1]);
383
- }
368
+ for (i = 0; i < len - 1; i++) {
369
+ rb_struct_aset(parent->val, INT2FIX(i), RARRAY_PTR(value)[i + 1]);
370
+ }
384
371
  }
385
- return 1;
386
- } else if (3 <= klen && '#' == key[1]) {
387
- volatile VALUE *a;
372
+ return 1;
373
+ } else if (3 <= klen && '#' == key[1]) {
374
+ volatile VALUE *a;
388
375
 
389
- if (2 != len) {
390
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
391
- return 1;
392
- }
393
- parent->val = rb_hash_new();
394
- a = RARRAY_PTR(value);
395
- rb_hash_aset(parent->val, *a, a[1]);
376
+ if (2 != len) {
377
+ oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
378
+ return 1;
379
+ }
380
+ parent->val = rb_hash_new();
381
+ a = RARRAY_PTR(value);
382
+ rb_hash_aset(parent->val, *a, a[1]);
396
383
 
397
- return 1;
398
- }
384
+ return 1;
385
+ }
399
386
  }
400
387
  return 0;
401
388
  }
402
389
 
403
- void
404
- oj_set_obj_ivar(Val parent, Val kval, VALUE value) {
405
- const char *key = kval->key;
406
- int klen = kval->klen;
407
- ID var_id;
408
- ID *slot;
390
+ void oj_set_obj_ivar(Val parent, Val kval, VALUE value) {
391
+ const char *key = kval->key;
392
+ int klen = kval->klen;
393
+ ID var_id;
394
+ ID * slot;
409
395
 
410
396
  #ifdef HAVE_PTHREAD_MUTEX_INIT
411
397
  pthread_mutex_lock(&oj_cache_mutex);
@@ -413,33 +399,33 @@ oj_set_obj_ivar(Val parent, Val kval, VALUE value) {
413
399
  rb_mutex_lock(oj_cache_mutex);
414
400
  #endif
415
401
  if (0 == (var_id = oj_attr_hash_get(key, klen, &slot))) {
416
- char attr[256];
417
-
418
- if ((int)sizeof(attr) <= klen + 2) {
419
- char *buf = ALLOC_N(char, klen + 2);
420
-
421
- if ('~' == *key) {
422
- strncpy(buf, key + 1, klen - 1);
423
- buf[klen - 1] = '\0';
424
- } else {
425
- *buf = '@';
426
- strncpy(buf + 1, key, klen);
427
- buf[klen + 1] = '\0';
428
- }
429
- var_id = rb_intern(buf);
430
- xfree(buf);
431
- } else {
432
- if ('~' == *key) {
433
- strncpy(attr, key + 1, klen - 1);
434
- attr[klen - 1] = '\0';
435
- } else {
436
- *attr = '@';
437
- strncpy(attr + 1, key, klen);
438
- attr[klen + 1] = '\0';
439
- }
440
- var_id = rb_intern(attr);
441
- }
442
- *slot = var_id;
402
+ char attr[256];
403
+
404
+ if ((int)sizeof(attr) <= klen + 2) {
405
+ char *buf = ALLOC_N(char, klen + 2);
406
+
407
+ if ('~' == *key) {
408
+ strncpy(buf, key + 1, klen - 1);
409
+ buf[klen - 1] = '\0';
410
+ } else {
411
+ *buf = '@';
412
+ strncpy(buf + 1, key, klen);
413
+ buf[klen + 1] = '\0';
414
+ }
415
+ var_id = rb_intern(buf);
416
+ xfree(buf);
417
+ } else {
418
+ if ('~' == *key) {
419
+ strncpy(attr, key + 1, klen - 1);
420
+ attr[klen - 1] = '\0';
421
+ } else {
422
+ *attr = '@';
423
+ strncpy(attr + 1, key, klen);
424
+ attr[klen + 1] = '\0';
425
+ }
426
+ var_id = rb_intern(attr);
427
+ }
428
+ *slot = var_id;
443
429
  }
444
430
  #ifdef HAVE_PTHREAD_MUTEX_INIT
445
431
  pthread_mutex_unlock(&oj_cache_mutex);
@@ -449,324 +435,369 @@ oj_set_obj_ivar(Val parent, Val kval, VALUE value) {
449
435
  rb_ivar_set(parent->val, var_id, value);
450
436
  }
451
437
 
452
- static void
453
- hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
454
- const char *key = kval->key;
455
- int klen = kval->klen;
456
- Val parent = stack_peek(&pi->stack);
457
- volatile VALUE rval = Qnil;
438
+ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
439
+ const char * key = kval->key;
440
+ int klen = kval->klen;
441
+ Val parent = stack_peek(&pi->stack);
442
+ volatile VALUE rval = Qnil;
458
443
 
459
- WHICH_TYPE:
444
+ WHICH_TYPE:
460
445
  switch (rb_type(parent->val)) {
461
446
  case T_NIL:
462
- parent->odd_args = NULL; // make sure it is NULL in case not odd
463
- if ('^' != *key || !hat_cstr(pi, parent, kval, str, len)) {
464
- parent->val = rb_hash_new();
465
- goto WHICH_TYPE;
466
- }
467
- break;
447
+ parent->odd_args = NULL; // make sure it is NULL in case not odd
448
+ if ('^' != *key || !hat_cstr(pi, parent, kval, str, len)) {
449
+ parent->val = rb_hash_new();
450
+ goto WHICH_TYPE;
451
+ }
452
+ break;
468
453
  case T_HASH:
469
- rb_hash_aset(parent->val, calc_hash_key(pi, kval, parent->k1), str_to_value(pi, str, len, orig));
470
- break;
454
+ rb_hash_aset(parent->val,
455
+ calc_hash_key(pi, kval, parent->k1),
456
+ str_to_value(pi, str, len, orig));
457
+ break;
471
458
  case T_STRING:
472
- rval = str_to_value(pi, str, len, orig);
473
- if (4 == klen && 's' == *key && 'e' == key[1] && 'l' == key[2] && 'f' == key[3]) {
474
- rb_funcall(parent->val, oj_replace_id, 1, rval);
475
- } else {
476
- oj_set_obj_ivar(parent, kval, rval);
477
- }
478
- break;
459
+ rval = str_to_value(pi, str, len, orig);
460
+ if (4 == klen && 's' == *key && 'e' == key[1] && 'l' == key[2] && 'f' == key[3]) {
461
+ rb_funcall(parent->val, oj_replace_id, 1, rval);
462
+ } else {
463
+ oj_set_obj_ivar(parent, kval, rval);
464
+ }
465
+ break;
479
466
  case T_OBJECT:
480
- rval = str_to_value(pi, str, len, orig);
481
- oj_set_obj_ivar(parent, kval, rval);
482
- break;
467
+ rval = str_to_value(pi, str, len, orig);
468
+ oj_set_obj_ivar(parent, kval, rval);
469
+ break;
483
470
  case T_CLASS:
484
- if (NULL == parent->odd_args) {
485
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "%s is not an odd class", rb_class2name(rb_obj_class(parent->val)));
486
- return;
487
- } else {
488
- rval = str_to_value(pi, str, len, orig);
489
- if (0 != oj_odd_set_arg(parent->odd_args, kval->key, kval->klen, rval)) {
490
- char buf[256];
491
-
492
- if ((int)sizeof(buf) - 1 <= klen) {
493
- klen = sizeof(buf) - 2;
494
- }
495
- memcpy(buf, key, klen);
496
- buf[klen] = '\0';
497
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "%s is not an attribute of %s", buf, rb_class2name(rb_obj_class(parent->val)));
498
- }
499
- }
500
- break;
471
+ if (NULL == parent->odd_args) {
472
+ oj_set_error_at(pi,
473
+ oj_parse_error_class,
474
+ __FILE__,
475
+ __LINE__,
476
+ "%s is not an odd class",
477
+ rb_class2name(rb_obj_class(parent->val)));
478
+ return;
479
+ } else {
480
+ rval = str_to_value(pi, str, len, orig);
481
+ if (0 != oj_odd_set_arg(parent->odd_args, kval->key, kval->klen, rval)) {
482
+ char buf[256];
483
+
484
+ if ((int)sizeof(buf) - 1 <= klen) {
485
+ klen = sizeof(buf) - 2;
486
+ }
487
+ memcpy(buf, key, klen);
488
+ buf[klen] = '\0';
489
+ oj_set_error_at(pi,
490
+ oj_parse_error_class,
491
+ __FILE__,
492
+ __LINE__,
493
+ "%s is not an attribute of %s",
494
+ buf,
495
+ rb_class2name(rb_obj_class(parent->val)));
496
+ }
497
+ }
498
+ break;
501
499
  default:
502
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "can not add attributes to a %s", rb_class2name(rb_obj_class(parent->val)));
503
- return;
500
+ oj_set_error_at(pi,
501
+ oj_parse_error_class,
502
+ __FILE__,
503
+ __LINE__,
504
+ "can not add attributes to a %s",
505
+ rb_class2name(rb_obj_class(parent->val)));
506
+ return;
504
507
  }
505
508
  if (Yes == pi->options.trace) {
506
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
509
+ oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
507
510
  }
508
511
  }
509
512
 
510
- static void
511
- hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
512
- const char *key = kval->key;
513
- int klen = kval->klen;
514
- Val parent = stack_peek(&pi->stack);
515
- volatile VALUE rval = Qnil;
513
+ static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
514
+ const char * key = kval->key;
515
+ int klen = kval->klen;
516
+ Val parent = stack_peek(&pi->stack);
517
+ volatile VALUE rval = Qnil;
516
518
 
517
- WHICH_TYPE:
519
+ WHICH_TYPE:
518
520
  switch (rb_type(parent->val)) {
519
521
  case T_NIL:
520
- parent->odd_args = NULL; // make sure it is NULL in case not odd
521
- if ('^' != *key || !hat_num(pi, parent, kval, ni)) {
522
- parent->val = rb_hash_new();
523
- goto WHICH_TYPE;
524
- }
525
- break;
522
+ parent->odd_args = NULL; // make sure it is NULL in case not odd
523
+ if ('^' != *key || !hat_num(pi, parent, kval, ni)) {
524
+ parent->val = rb_hash_new();
525
+ goto WHICH_TYPE;
526
+ }
527
+ break;
526
528
  case T_HASH:
527
- rval = oj_num_as_value(ni);
528
- rb_hash_aset(parent->val, calc_hash_key(pi, kval, parent->k1), rval);
529
- break;
529
+ rval = oj_num_as_value(ni);
530
+ rb_hash_aset(parent->val, calc_hash_key(pi, kval, parent->k1), rval);
531
+ break;
530
532
  case T_OBJECT:
531
- if (2 == klen && '^' == *key && 'i' == key[1] &&
532
- !ni->infinity && !ni->neg && 1 == ni->div && 0 == ni->exp && 0 != pi->circ_array) { // fixnum
533
- oj_circ_array_set(pi->circ_array, parent->val, ni->i);
534
- } else {
535
- rval = oj_num_as_value(ni);
536
- oj_set_obj_ivar(parent, kval, rval);
537
- }
538
- break;
533
+ if (2 == klen && '^' == *key && 'i' == key[1] && !ni->infinity && !ni->neg &&
534
+ 1 == ni->div && 0 == ni->exp && 0 != pi->circ_array) { // fixnum
535
+ oj_circ_array_set(pi->circ_array, parent->val, ni->i);
536
+ } else {
537
+ rval = oj_num_as_value(ni);
538
+ oj_set_obj_ivar(parent, kval, rval);
539
+ }
540
+ break;
539
541
  case T_CLASS:
540
- if (NULL == parent->odd_args) {
541
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "%s is not an odd class", rb_class2name(rb_obj_class(parent->val)));
542
- return;
543
- } else {
544
- rval = oj_num_as_value(ni);
545
- if (0 != oj_odd_set_arg(parent->odd_args, key, klen, rval)) {
546
- char buf[256];
547
-
548
- if ((int)sizeof(buf) - 1 <= klen) {
549
- klen = sizeof(buf) - 2;
550
- }
551
- memcpy(buf, key, klen);
552
- buf[klen] = '\0';
553
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "%s is not an attribute of %s", buf, rb_class2name(rb_obj_class(parent->val)));
554
- }
555
- }
556
- break;
542
+ if (NULL == parent->odd_args) {
543
+ oj_set_error_at(pi,
544
+ oj_parse_error_class,
545
+ __FILE__,
546
+ __LINE__,
547
+ "%s is not an odd class",
548
+ rb_class2name(rb_obj_class(parent->val)));
549
+ return;
550
+ } else {
551
+ rval = oj_num_as_value(ni);
552
+ if (0 != oj_odd_set_arg(parent->odd_args, key, klen, rval)) {
553
+ char buf[256];
554
+
555
+ if ((int)sizeof(buf) - 1 <= klen) {
556
+ klen = sizeof(buf) - 2;
557
+ }
558
+ memcpy(buf, key, klen);
559
+ buf[klen] = '\0';
560
+ oj_set_error_at(pi,
561
+ oj_parse_error_class,
562
+ __FILE__,
563
+ __LINE__,
564
+ "%s is not an attribute of %s",
565
+ buf,
566
+ rb_class2name(rb_obj_class(parent->val)));
567
+ }
568
+ }
569
+ break;
557
570
  default:
558
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "can not add attributes to a %s", rb_class2name(rb_obj_class(parent->val)));
559
- return;
571
+ oj_set_error_at(pi,
572
+ oj_parse_error_class,
573
+ __FILE__,
574
+ __LINE__,
575
+ "can not add attributes to a %s",
576
+ rb_class2name(rb_obj_class(parent->val)));
577
+ return;
560
578
  }
561
579
  if (Yes == pi->options.trace) {
562
- oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, rval);
580
+ oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, rval);
563
581
  }
564
582
  }
565
583
 
566
- static void
567
- hash_set_value(ParseInfo pi, Val kval, VALUE value) {
568
- const char *key = kval->key;
569
- int klen = kval->klen;
570
- Val parent = stack_peek(&pi->stack);
584
+ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
585
+ const char *key = kval->key;
586
+ int klen = kval->klen;
587
+ Val parent = stack_peek(&pi->stack);
571
588
 
572
- WHICH_TYPE:
589
+ WHICH_TYPE:
573
590
  switch (rb_type(parent->val)) {
574
591
  case T_NIL:
575
- parent->odd_args = NULL; // make sure it is NULL in case not odd
576
- if ('^' != *key || !hat_value(pi, parent, key, klen, value)) {
577
- parent->val = rb_hash_new();
578
- goto WHICH_TYPE;
579
- }
580
- break;
592
+ parent->odd_args = NULL; // make sure it is NULL in case not odd
593
+ if ('^' != *key || !hat_value(pi, parent, key, klen, value)) {
594
+ parent->val = rb_hash_new();
595
+ goto WHICH_TYPE;
596
+ }
597
+ break;
581
598
  case T_HASH:
582
- if (rb_cHash != rb_obj_class(parent->val)) {
583
- if (4 == klen && 's' == *key && 'e' == key[1] && 'l' == key[2] && 'f' == key[3]) {
584
- rb_funcall(parent->val, oj_replace_id, 1, value);
585
- } else {
586
- oj_set_obj_ivar(parent, kval, value);
587
- }
588
- } else {
589
- if (3 <= klen && '^' == *key && '#' == key[1] && T_ARRAY == rb_type(value)) {
590
- long len = RARRAY_LEN(value);
591
- volatile VALUE *a = RARRAY_PTR(value);
592
-
593
- if (2 != len) {
594
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
595
- return;
596
- }
597
- rb_hash_aset(parent->val, *a, a[1]);
598
- } else {
599
- rb_hash_aset(parent->val, calc_hash_key(pi, kval, parent->k1), value);
600
- }
601
- }
602
- break;
599
+ if (rb_cHash != rb_obj_class(parent->val)) {
600
+ if (4 == klen && 's' == *key && 'e' == key[1] && 'l' == key[2] && 'f' == key[3]) {
601
+ rb_funcall(parent->val, oj_replace_id, 1, value);
602
+ } else {
603
+ oj_set_obj_ivar(parent, kval, value);
604
+ }
605
+ } else {
606
+ if (3 <= klen && '^' == *key && '#' == key[1] && T_ARRAY == rb_type(value)) {
607
+ long len = RARRAY_LEN(value);
608
+ volatile VALUE *a = RARRAY_PTR(value);
609
+
610
+ if (2 != len) {
611
+ oj_set_error_at(pi,
612
+ oj_parse_error_class,
613
+ __FILE__,
614
+ __LINE__,
615
+ "invalid hash pair");
616
+ return;
617
+ }
618
+ rb_hash_aset(parent->val, *a, a[1]);
619
+ } else {
620
+ rb_hash_aset(parent->val, calc_hash_key(pi, kval, parent->k1), value);
621
+ }
622
+ }
623
+ break;
603
624
  case T_ARRAY:
604
- if (4 == klen && 's' == *key && 'e' == key[1] && 'l' == key[2] && 'f' == key[3]) {
605
- rb_funcall(parent->val, oj_replace_id, 1, value);
606
- } else {
607
- oj_set_obj_ivar(parent, kval, value);
608
- }
609
- break;
610
- case T_STRING: // for subclassed strings
611
- case T_OBJECT:
612
- oj_set_obj_ivar(parent, kval, value);
613
- break;
625
+ if (4 == klen && 's' == *key && 'e' == key[1] && 'l' == key[2] && 'f' == key[3]) {
626
+ rb_funcall(parent->val, oj_replace_id, 1, value);
627
+ } else {
628
+ oj_set_obj_ivar(parent, kval, value);
629
+ }
630
+ break;
631
+ case T_STRING: // for subclassed strings
632
+ case T_OBJECT: oj_set_obj_ivar(parent, kval, value); break;
614
633
  case T_MODULE:
615
634
  case T_CLASS:
616
- if (NULL == parent->odd_args) {
617
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "%s is not an odd class", rb_class2name(rb_obj_class(parent->val)));
618
- return;
619
- } else if (0 != oj_odd_set_arg(parent->odd_args, key, klen, value)) {
620
- char buf[256];
621
-
622
- if ((int)sizeof(buf) - 1 <= klen) {
623
- klen = sizeof(buf) - 2;
624
- }
625
- memcpy(buf, key, klen);
626
- buf[klen] = '\0';
627
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "%s is not an attribute of %s", buf, rb_class2name(rb_obj_class(parent->val)));
628
- }
629
- break;
635
+ if (NULL == parent->odd_args) {
636
+ oj_set_error_at(pi,
637
+ oj_parse_error_class,
638
+ __FILE__,
639
+ __LINE__,
640
+ "%s is not an odd class",
641
+ rb_class2name(rb_obj_class(parent->val)));
642
+ return;
643
+ } else if (0 != oj_odd_set_arg(parent->odd_args, key, klen, value)) {
644
+ char buf[256];
645
+
646
+ if ((int)sizeof(buf) - 1 <= klen) {
647
+ klen = sizeof(buf) - 2;
648
+ }
649
+ memcpy(buf, key, klen);
650
+ buf[klen] = '\0';
651
+ oj_set_error_at(pi,
652
+ oj_parse_error_class,
653
+ __FILE__,
654
+ __LINE__,
655
+ "%s is not an attribute of %s",
656
+ buf,
657
+ rb_class2name(rb_obj_class(parent->val)));
658
+ }
659
+ break;
630
660
  default:
631
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "can not add attributes to a %s", rb_class2name(rb_obj_class(parent->val)));
632
- return;
661
+ oj_set_error_at(pi,
662
+ oj_parse_error_class,
663
+ __FILE__,
664
+ __LINE__,
665
+ "can not add attributes to a %s",
666
+ rb_class2name(rb_obj_class(parent->val)));
667
+ return;
633
668
  }
634
669
  if (Yes == pi->options.trace) {
635
- oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, value);
670
+ oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, value);
636
671
  }
637
672
  }
638
673
 
639
- static VALUE
640
- start_hash(ParseInfo pi) {
674
+ static VALUE start_hash(ParseInfo pi) {
641
675
  if (Yes == pi->options.trace) {
642
- oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
676
+ oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
643
677
  }
644
678
  return Qnil;
645
679
  }
646
680
 
647
- static void
648
- end_hash(ParseInfo pi) {
649
- Val parent = stack_peek(&pi->stack);
681
+ static void end_hash(ParseInfo pi) {
682
+ Val parent = stack_peek(&pi->stack);
650
683
 
651
684
  if (Qnil == parent->val) {
652
- parent->val = rb_hash_new();
685
+ parent->val = rb_hash_new();
653
686
  } else if (NULL != parent->odd_args) {
654
- OddArgs oa = parent->odd_args;
687
+ OddArgs oa = parent->odd_args;
655
688
 
656
- parent->val = rb_funcall2(oa->odd->create_obj, oa->odd->create_op, oa->odd->attr_cnt, oa->args);
657
- oj_odd_free(oa);
658
- parent->odd_args = NULL;
689
+ parent->val = rb_funcall2(oa->odd->create_obj,
690
+ oa->odd->create_op,
691
+ oa->odd->attr_cnt,
692
+ oa->args);
693
+ oj_odd_free(oa);
694
+ parent->odd_args = NULL;
659
695
  }
660
696
  if (Yes == pi->options.trace) {
661
- oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
697
+ oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
662
698
  }
663
699
  }
664
700
 
665
- static void
666
- array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
667
- volatile VALUE rval = Qnil;
701
+ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
702
+ volatile VALUE rval = Qnil;
668
703
 
669
704
  // orig lets us know whether the string was ^r1 or \u005er1
670
- if (3 <= len && 0 != pi->circ_array && '^' == orig[0] && 0 == rb_array_len(stack_peek(&pi->stack)->val)) {
671
- if ('i' == str[1]) {
672
- long i = read_long(str + 2, len - 2);
673
-
674
- if (0 < i) {
675
- oj_circ_array_set(pi->circ_array, stack_peek(&pi->stack)->val, i);
676
- return;
677
- }
678
- } else if ('r' == str[1]) {
679
- long i = read_long(str + 2, len - 2);
680
-
681
- if (0 < i) {
682
- rb_ary_push(stack_peek(&pi->stack)->val, oj_circ_array_get(pi->circ_array, i));
683
- return;
684
- }
705
+ if (3 <= len && 0 != pi->circ_array && '^' == orig[0] &&
706
+ 0 == rb_array_len(stack_peek(&pi->stack)->val)) {
707
+ if ('i' == str[1]) {
708
+ long i = read_long(str + 2, len - 2);
709
+
710
+ if (0 < i) {
711
+ oj_circ_array_set(pi->circ_array, stack_peek(&pi->stack)->val, i);
712
+ return;
713
+ }
714
+ } else if ('r' == str[1]) {
715
+ long i = read_long(str + 2, len - 2);
685
716
 
686
- }
717
+ if (0 < i) {
718
+ rb_ary_push(stack_peek(&pi->stack)->val, oj_circ_array_get(pi->circ_array, i));
719
+ return;
720
+ }
721
+ }
687
722
  }
688
723
  rval = str_to_value(pi, str, len, orig);
689
724
  rb_ary_push(stack_peek(&pi->stack)->val, rval);
690
725
  if (Yes == pi->options.trace) {
691
- oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rval);
726
+ oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rval);
692
727
  }
693
728
  }
694
729
 
695
- static void
696
- array_append_num(ParseInfo pi, NumInfo ni) {
697
- volatile VALUE rval = oj_num_as_value(ni);
730
+ static void array_append_num(ParseInfo pi, NumInfo ni) {
731
+ volatile VALUE rval = oj_num_as_value(ni);
698
732
 
699
733
  rb_ary_push(stack_peek(&pi->stack)->val, rval);
700
734
  if (Yes == pi->options.trace) {
701
- oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
735
+ oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
702
736
  }
703
737
  }
704
738
 
705
- static void
706
- add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
739
+ static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
707
740
  pi->stack.head->val = str_to_value(pi, str, len, orig);
708
741
  if (Yes == pi->options.trace) {
709
- oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
742
+ oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
710
743
  }
711
744
  }
712
745
 
713
- static void
714
- add_num(ParseInfo pi, NumInfo ni) {
746
+ static void add_num(ParseInfo pi, NumInfo ni) {
715
747
  pi->stack.head->val = oj_num_as_value(ni);
716
748
  if (Yes == pi->options.trace) {
717
- oj_trace_parse_call("add_num", pi, __FILE__, __LINE__, pi->stack.head->val);
749
+ oj_trace_parse_call("add_num", pi, __FILE__, __LINE__, pi->stack.head->val);
718
750
  }
719
751
  }
720
752
 
721
- void
722
- oj_set_object_callbacks(ParseInfo pi) {
753
+ void oj_set_object_callbacks(ParseInfo pi) {
723
754
  oj_set_strict_callbacks(pi);
724
- pi->end_hash = end_hash;
725
- pi->start_hash = start_hash;
726
- pi->hash_set_cstr = hash_set_cstr;
727
- pi->hash_set_num = hash_set_num;
728
- pi->hash_set_value = hash_set_value;
729
- pi->add_cstr = add_cstr;
730
- pi->add_num = add_num;
755
+ pi->end_hash = end_hash;
756
+ pi->start_hash = start_hash;
757
+ pi->hash_set_cstr = hash_set_cstr;
758
+ pi->hash_set_num = hash_set_num;
759
+ pi->hash_set_value = hash_set_value;
760
+ pi->add_cstr = add_cstr;
761
+ pi->add_num = add_num;
731
762
  pi->array_append_cstr = array_append_cstr;
732
- pi->array_append_num = array_append_num;
763
+ pi->array_append_num = array_append_num;
733
764
  }
734
765
 
735
766
  VALUE
736
767
  oj_object_parse(int argc, VALUE *argv, VALUE self) {
737
- struct _parseInfo pi;
768
+ struct _parseInfo pi;
738
769
 
739
770
  parse_info_init(&pi);
740
- pi.options = oj_default_options;
741
- pi.handler = Qnil;
771
+ pi.options = oj_default_options;
772
+ pi.handler = Qnil;
742
773
  pi.err_class = Qnil;
743
774
  oj_set_object_callbacks(&pi);
744
775
 
745
776
  if (T_STRING == rb_type(*argv)) {
746
- return oj_pi_parse(argc, argv, &pi, 0, 0, 1);
777
+ return oj_pi_parse(argc, argv, &pi, 0, 0, 1);
747
778
  } else {
748
- return oj_pi_sparse(argc, argv, &pi, 0);
779
+ return oj_pi_sparse(argc, argv, &pi, 0);
749
780
  }
750
781
  }
751
782
 
752
783
  VALUE
753
784
  oj_object_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
754
- struct _parseInfo pi;
785
+ struct _parseInfo pi;
755
786
 
756
787
  parse_info_init(&pi);
757
- pi.options = oj_default_options;
758
- pi.handler = Qnil;
788
+ pi.options = oj_default_options;
789
+ pi.handler = Qnil;
759
790
  pi.err_class = Qnil;
760
791
  oj_set_strict_callbacks(&pi);
761
- pi.end_hash = end_hash;
762
- pi.start_hash = start_hash;
763
- pi.hash_set_cstr = hash_set_cstr;
764
- pi.hash_set_num = hash_set_num;
765
- pi.hash_set_value = hash_set_value;
766
- pi.add_cstr = add_cstr;
767
- pi.add_num = add_num;
792
+ pi.end_hash = end_hash;
793
+ pi.start_hash = start_hash;
794
+ pi.hash_set_cstr = hash_set_cstr;
795
+ pi.hash_set_num = hash_set_num;
796
+ pi.hash_set_value = hash_set_value;
797
+ pi.add_cstr = add_cstr;
798
+ pi.add_num = add_num;
768
799
  pi.array_append_cstr = array_append_cstr;
769
- pi.array_append_num = array_append_num;
800
+ pi.array_append_num = array_append_num;
770
801
 
771
802
  return oj_pi_parse(argc, argv, &pi, json, len, 1);
772
803
  }