oj 3.11.0 → 3.11.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -1
  3. data/ext/oj/buf.h +34 -38
  4. data/ext/oj/cache8.c +59 -62
  5. data/ext/oj/cache8.h +8 -7
  6. data/ext/oj/circarray.c +33 -35
  7. data/ext/oj/circarray.h +11 -9
  8. data/ext/oj/code.c +170 -174
  9. data/ext/oj/code.h +21 -20
  10. data/ext/oj/compat.c +159 -166
  11. data/ext/oj/custom.c +802 -851
  12. data/ext/oj/dump.c +766 -778
  13. data/ext/oj/dump.h +49 -51
  14. data/ext/oj/dump_compat.c +1 -0
  15. data/ext/oj/dump_leaf.c +116 -157
  16. data/ext/oj/dump_object.c +609 -628
  17. data/ext/oj/dump_strict.c +318 -327
  18. data/ext/oj/encode.h +3 -4
  19. data/ext/oj/err.c +39 -25
  20. data/ext/oj/err.h +24 -15
  21. data/ext/oj/extconf.rb +2 -1
  22. data/ext/oj/fast.c +1008 -1038
  23. data/ext/oj/hash.c +62 -66
  24. data/ext/oj/hash.h +7 -6
  25. data/ext/oj/hash_test.c +450 -443
  26. data/ext/oj/mimic_json.c +413 -402
  27. data/ext/oj/object.c +559 -528
  28. data/ext/oj/odd.c +123 -128
  29. data/ext/oj/odd.h +27 -25
  30. data/ext/oj/oj.c +1131 -924
  31. data/ext/oj/oj.h +286 -298
  32. data/ext/oj/parse.c +938 -930
  33. data/ext/oj/parse.h +70 -69
  34. data/ext/oj/rails.c +836 -839
  35. data/ext/oj/rails.h +7 -7
  36. data/ext/oj/reader.c +135 -140
  37. data/ext/oj/reader.h +66 -79
  38. data/ext/oj/resolve.c +43 -43
  39. data/ext/oj/resolve.h +3 -2
  40. data/ext/oj/rxclass.c +67 -68
  41. data/ext/oj/rxclass.h +12 -10
  42. data/ext/oj/saj.c +451 -479
  43. data/ext/oj/scp.c +93 -103
  44. data/ext/oj/sparse.c +770 -730
  45. data/ext/oj/stream_writer.c +120 -149
  46. data/ext/oj/strict.c +71 -86
  47. data/ext/oj/string_writer.c +198 -243
  48. data/ext/oj/trace.c +29 -33
  49. data/ext/oj/trace.h +14 -11
  50. data/ext/oj/util.c +103 -103
  51. data/ext/oj/util.h +3 -2
  52. data/ext/oj/val_stack.c +47 -47
  53. data/ext/oj/val_stack.h +79 -86
  54. data/ext/oj/wab.c +291 -309
  55. data/lib/oj/bag.rb +1 -0
  56. data/lib/oj/easy_hash.rb +5 -4
  57. data/lib/oj/mimic.rb +0 -12
  58. data/lib/oj/version.rb +1 -1
  59. data/test/activerecord/result_test.rb +7 -2
  60. data/test/foo.rb +35 -32
  61. data/test/helper.rb +10 -0
  62. data/test/json_gem/json_generator_test.rb +15 -3
  63. data/test/json_gem/test_helper.rb +8 -0
  64. data/test/test_compat.rb +2 -2
  65. data/test/test_generate.rb +21 -0
  66. data/test/test_hash.rb +10 -0
  67. data/test/test_scp.rb +1 -1
  68. metadata +4 -2
data/ext/oj/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
  }