oj 3.13.14 → 3.13.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/README.md +2 -0
  4. data/ext/oj/buf.h +4 -0
  5. data/ext/oj/compat.c +10 -10
  6. data/ext/oj/custom.c +34 -53
  7. data/ext/oj/dump.c +24 -13
  8. data/ext/oj/dump_compat.c +5 -10
  9. data/ext/oj/dump_object.c +5 -60
  10. data/ext/oj/dump_strict.c +5 -5
  11. data/ext/oj/extconf.rb +5 -4
  12. data/ext/oj/fast.c +15 -13
  13. data/ext/oj/intern.c +6 -9
  14. data/ext/oj/introspect.c +96 -0
  15. data/ext/oj/mimic_json.c +18 -8
  16. data/ext/oj/object.c +42 -41
  17. data/ext/oj/oj.c +27 -4
  18. data/ext/oj/oj.h +4 -1
  19. data/ext/oj/parse.c +111 -76
  20. data/ext/oj/parse.h +2 -0
  21. data/ext/oj/parser.c +61 -4
  22. data/ext/oj/parser.h +12 -0
  23. data/ext/oj/rails.c +5 -10
  24. data/ext/oj/saj2.c +333 -85
  25. data/ext/oj/saj2.h +23 -0
  26. data/ext/oj/sparse.c +4 -0
  27. data/ext/oj/strict.c +13 -13
  28. data/ext/oj/usual.c +82 -129
  29. data/ext/oj/usual.h +68 -0
  30. data/ext/oj/val_stack.c +1 -1
  31. data/ext/oj/validate.c +21 -26
  32. data/ext/oj/wab.c +15 -20
  33. data/lib/oj/saj.rb +20 -6
  34. data/lib/oj/state.rb +1 -1
  35. data/lib/oj/version.rb +1 -1
  36. data/pages/Compatibility.md +1 -1
  37. data/test/bar.rb +3 -1
  38. data/test/helper.rb +8 -2
  39. data/test/json_gem/json_generator_test.rb +3 -4
  40. data/test/json_gem/json_parser_test.rb +8 -1
  41. data/test/json_gem/test_helper.rb +7 -3
  42. data/test/test_compat.rb +25 -0
  43. data/test/test_custom.rb +13 -2
  44. data/test/test_file.rb +23 -7
  45. data/test/test_gc.rb +11 -0
  46. data/test/test_object.rb +3 -10
  47. data/test/test_parser.rb +3 -19
  48. data/test/test_parser_debug.rb +27 -0
  49. data/test/test_parser_saj.rb +92 -2
  50. data/test/test_scp.rb +2 -4
  51. data/test/test_strict.rb +2 -0
  52. data/test/test_various.rb +8 -3
  53. data/test/test_wab.rb +2 -0
  54. data/test/tests.rb +9 -0
  55. data/test/tests_mimic.rb +9 -0
  56. data/test/tests_mimic_addition.rb +9 -0
  57. metadata +7 -107
data/ext/oj/saj2.h ADDED
@@ -0,0 +1,23 @@
1
+ // Copyright (c) 2021, Peter Ohler, All rights reserved.
2
+
3
+ #include <ruby.h>
4
+ #include <stdbool.h>
5
+
6
+ struct _cache;
7
+ struct _ojParser;
8
+
9
+ typedef struct _saj {
10
+ VALUE handler;
11
+ VALUE *keys;
12
+ VALUE *tail;
13
+ size_t klen;
14
+ struct _cache *str_cache;
15
+ uint8_t cache_str;
16
+ bool cache_keys;
17
+ bool thread_safe;
18
+ } * Saj;
19
+
20
+ // Initialize the parser with the SAJ delegate. If the SAJ delegate is wrapped
21
+ // then this function is called first and then the parser functions can be
22
+ // replaced.
23
+ extern void oj_init_saj(struct _ojParser *p, Saj d);
data/ext/oj/sparse.c CHANGED
@@ -953,7 +953,11 @@ CLEANUP:
953
953
  }
954
954
  stack_cleanup(&pi->stack);
955
955
  if (0 != fd) {
956
+ #ifdef _WIN32
957
+ rb_w32_close(fd);
958
+ #else
956
959
  close(fd);
960
+ #endif
957
961
  }
958
962
  if (err_has(&pi->err)) {
959
963
  rb_set_errinfo(Qnil);
data/ext/oj/strict.c CHANGED
@@ -50,13 +50,13 @@ VALUE oj_calc_hash_key(ParseInfo pi, Val parent) {
50
50
  }
51
51
 
52
52
  static void hash_end(ParseInfo pi) {
53
- if (Yes == pi->options.trace) {
53
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
54
54
  oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
55
55
  }
56
56
  }
57
57
 
58
58
  static void array_end(ParseInfo pi) {
59
- if (Yes == pi->options.trace) {
59
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
60
60
  oj_trace_parse_array_end(pi, __FILE__, __LINE__);
61
61
  }
62
62
  }
@@ -66,7 +66,7 @@ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
66
66
  }
67
67
 
68
68
  static void add_value(ParseInfo pi, VALUE val) {
69
- if (Yes == pi->options.trace) {
69
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
70
70
  oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
71
71
  }
72
72
  pi->stack.head->val = val;
@@ -76,7 +76,7 @@ static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig
76
76
  volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
77
77
 
78
78
  pi->stack.head->val = rstr;
79
- if (Yes == pi->options.trace) {
79
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
80
80
  oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, rstr);
81
81
  }
82
82
  }
@@ -86,7 +86,7 @@ static void add_num(ParseInfo pi, NumInfo ni) {
86
86
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
87
87
  }
88
88
  pi->stack.head->val = oj_num_as_value(ni);
89
- if (Yes == pi->options.trace) {
89
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
90
90
  oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
91
91
  }
92
92
  }
@@ -95,7 +95,7 @@ static VALUE start_hash(ParseInfo pi) {
95
95
  if (Qnil != pi->options.hash_class) {
96
96
  return rb_class_new_instance(0, NULL, pi->options.hash_class);
97
97
  }
98
- if (Yes == pi->options.trace) {
98
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
99
99
  oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
100
100
  }
101
101
  return rb_hash_new();
@@ -107,7 +107,7 @@ static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len,
107
107
  rb_hash_aset(stack_peek(&pi->stack)->val,
108
108
  oj_calc_hash_key(pi, parent),
109
109
  rstr);
110
- if (Yes == pi->options.trace) {
110
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
111
111
  oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
112
112
  }
113
113
  }
@@ -122,7 +122,7 @@ static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
122
122
  rb_hash_aset(stack_peek(&pi->stack)->val,
123
123
  oj_calc_hash_key(pi, parent),
124
124
  v);
125
- if (Yes == pi->options.trace) {
125
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
126
126
  oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, v);
127
127
  }
128
128
  }
@@ -131,13 +131,13 @@ static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
131
131
  rb_hash_aset(stack_peek(&pi->stack)->val,
132
132
  oj_calc_hash_key(pi, parent),
133
133
  value);
134
- if (Yes == pi->options.trace) {
134
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
135
135
  oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
136
136
  }
137
137
  }
138
138
 
139
139
  static VALUE start_array(ParseInfo pi) {
140
- if (Yes == pi->options.trace) {
140
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
141
141
  oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
142
142
  }
143
143
  return rb_ary_new();
@@ -147,7 +147,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
147
147
  volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
148
148
 
149
149
  rb_ary_push(stack_peek(&pi->stack)->val, rstr);
150
- if (Yes == pi->options.trace) {
150
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
151
151
  oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
152
152
  }
153
153
  }
@@ -160,14 +160,14 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
160
160
  }
161
161
  v = oj_num_as_value(ni);
162
162
  rb_ary_push(stack_peek(&pi->stack)->val, v);
163
- if (Yes == pi->options.trace) {
163
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
164
164
  oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, v);
165
165
  }
166
166
  }
167
167
 
168
168
  static void array_append_value(ParseInfo pi, VALUE value) {
169
169
  rb_ary_push(stack_peek(&pi->stack)->val, value);
170
- if (Yes == pi->options.trace) {
170
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
171
171
  oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
172
172
  }
173
173
  }
data/ext/oj/usual.c CHANGED
@@ -3,6 +3,7 @@
3
3
  #include "cache.h"
4
4
  #include "oj.h"
5
5
  #include "parser.h"
6
+ #include "usual.h"
6
7
 
7
8
  // The Usual delegate builds Ruby objects during parsing. It makes use of
8
9
  // three stacks. The first is the value stack. This is where parsed values are
@@ -28,61 +29,6 @@
28
29
 
29
30
  #define DEBUG 0
30
31
 
31
- // Used to mark the start of each Hash, Array, or Object. The members point at
32
- // positions of the start in the value stack and if not an Array into the key
33
- // stack.
34
- typedef struct _col {
35
- long vi; // value stack index
36
- long ki; // key stack index if an hash else -1 for an array
37
- } * Col;
38
-
39
- typedef union _key {
40
- struct {
41
- int16_t len;
42
- char buf[30];
43
- };
44
- struct {
45
- int16_t xlen; // should be the same as len
46
- char * key;
47
- };
48
- } * Key;
49
-
50
- #define MISS_AUTO 'A'
51
- #define MISS_RAISE 'R'
52
- #define MISS_IGNORE 'I'
53
-
54
- typedef struct _delegate {
55
- VALUE *vhead;
56
- VALUE *vtail;
57
- VALUE *vend;
58
-
59
- Col chead;
60
- Col ctail;
61
- Col cend;
62
-
63
- Key khead;
64
- Key ktail;
65
- Key kend;
66
-
67
- VALUE (*get_key)(ojParser p, Key kp);
68
- struct _cache *key_cache; // same as str_cache or sym_cache
69
- struct _cache *str_cache;
70
- struct _cache *sym_cache;
71
- struct _cache *class_cache;
72
- struct _cache *attr_cache;
73
-
74
- VALUE array_class;
75
- VALUE hash_class;
76
-
77
- char * create_id;
78
- uint8_t create_id_len;
79
- uint8_t cache_str;
80
- uint8_t cache_xrate;
81
- uint8_t miss_class;
82
- bool cache_keys;
83
- bool ignore_json_create;
84
- } * Delegate;
85
-
86
32
  static ID to_f_id = 0;
87
33
  static ID ltlt_id = 0;
88
34
  static ID hset_id = 0;
@@ -178,7 +124,7 @@ static VALUE form_class_auto(const char *str, size_t len) {
178
124
  return resolve_classpath(str, len, true);
179
125
  }
180
126
 
181
- static void assure_cstack(Delegate d) {
127
+ static void assure_cstack(Usual d) {
182
128
  if (d->cend <= d->ctail + 1) {
183
129
  size_t cap = d->cend - d->chead;
184
130
  long pos = d->ctail - d->chead;
@@ -191,7 +137,7 @@ static void assure_cstack(Delegate d) {
191
137
  }
192
138
 
193
139
  static void push(ojParser p, VALUE v) {
194
- Delegate d = (Delegate)p->ctx;
140
+ Usual d = (Usual)p->ctx;
195
141
 
196
142
  if (d->vend <= d->vtail) {
197
143
  size_t cap = d->vend - d->vhead;
@@ -207,7 +153,7 @@ static void push(ojParser p, VALUE v) {
207
153
  }
208
154
 
209
155
  static VALUE cache_key(ojParser p, Key kp) {
210
- Delegate d = (Delegate)p->ctx;
156
+ Usual d = (Usual)p->ctx;
211
157
 
212
158
  if ((size_t)kp->len < sizeof(kp->buf)) {
213
159
  return cache_intern(d->key_cache, kp->buf, kp->len);
@@ -230,7 +176,7 @@ static VALUE sym_key(ojParser p, Key kp) {
230
176
  }
231
177
 
232
178
  static ID get_attr_id(ojParser p, Key kp) {
233
- Delegate d = (Delegate)p->ctx;
179
+ Usual d = (Usual)p->ctx;
234
180
 
235
181
  if ((size_t)kp->len < sizeof(kp->buf)) {
236
182
  return (ID)cache_intern(d->attr_cache, kp->buf, kp->len);
@@ -239,7 +185,7 @@ static ID get_attr_id(ojParser p, Key kp) {
239
185
  }
240
186
 
241
187
  static void push_key(ojParser p) {
242
- Delegate d = (Delegate)p->ctx;
188
+ Usual d = (Usual)p->ctx;
243
189
  size_t klen = buf_len(&p->key);
244
190
  const char *key = buf_str(&p->key);
245
191
 
@@ -263,7 +209,7 @@ static void push_key(ojParser p) {
263
209
  }
264
210
 
265
211
  static void push2(ojParser p, VALUE v) {
266
- Delegate d = (Delegate)p->ctx;
212
+ Usual d = (Usual)p->ctx;
267
213
 
268
214
  if (d->vend <= d->vtail + 1) {
269
215
  size_t cap = d->vend - d->vhead;
@@ -281,7 +227,7 @@ static void push2(ojParser p, VALUE v) {
281
227
  }
282
228
 
283
229
  static void open_object(ojParser p) {
284
- Delegate d = (Delegate)p->ctx;
230
+ Usual d = (Usual)p->ctx;
285
231
 
286
232
  assure_cstack(d);
287
233
  d->ctail->vi = d->vtail - d->vhead;
@@ -291,7 +237,7 @@ static void open_object(ojParser p) {
291
237
  }
292
238
 
293
239
  static void open_object_key(ojParser p) {
294
- Delegate d = (Delegate)p->ctx;
240
+ Usual d = (Usual)p->ctx;
295
241
 
296
242
  push_key(p);
297
243
  assure_cstack(d);
@@ -302,7 +248,7 @@ static void open_object_key(ojParser p) {
302
248
  }
303
249
 
304
250
  static void open_array(ojParser p) {
305
- Delegate d = (Delegate)p->ctx;
251
+ Usual d = (Usual)p->ctx;
306
252
 
307
253
  assure_cstack(d);
308
254
  d->ctail->vi = d->vtail - d->vhead;
@@ -312,7 +258,7 @@ static void open_array(ojParser p) {
312
258
  }
313
259
 
314
260
  static void open_array_key(ojParser p) {
315
- Delegate d = (Delegate)p->ctx;
261
+ Usual d = (Usual)p->ctx;
316
262
 
317
263
  push_key(p);
318
264
  assure_cstack(d);
@@ -324,7 +270,7 @@ static void open_array_key(ojParser p) {
324
270
 
325
271
  static void close_object(ojParser p) {
326
272
  VALUE * vp;
327
- Delegate d = (Delegate)p->ctx;
273
+ Usual d = (Usual)p->ctx;
328
274
 
329
275
  d->ctail--;
330
276
 
@@ -357,7 +303,7 @@ static void close_object(ojParser p) {
357
303
 
358
304
  static void close_object_class(ojParser p) {
359
305
  VALUE * vp;
360
- Delegate d = (Delegate)p->ctx;
306
+ Usual d = (Usual)p->ctx;
361
307
 
362
308
  d->ctail--;
363
309
 
@@ -380,7 +326,7 @@ static void close_object_class(ojParser p) {
380
326
 
381
327
  static void close_object_create(ojParser p) {
382
328
  VALUE * vp;
383
- Delegate d = (Delegate)p->ctx;
329
+ Usual d = (Usual)p->ctx;
384
330
 
385
331
  d->ctail--;
386
332
 
@@ -459,7 +405,7 @@ static void close_object_create(ojParser p) {
459
405
  }
460
406
 
461
407
  static void close_array(ojParser p) {
462
- Delegate d = (Delegate)p->ctx;
408
+ Usual d = (Usual)p->ctx;
463
409
 
464
410
  d->ctail--;
465
411
  VALUE * head = d->vhead + d->ctail->vi + 1;
@@ -472,7 +418,7 @@ static void close_array(ojParser p) {
472
418
 
473
419
  static void close_array_class(ojParser p) {
474
420
  VALUE * vp;
475
- Delegate d = (Delegate)p->ctx;
421
+ Usual d = (Usual)p->ctx;
476
422
 
477
423
  d->ctail--;
478
424
  VALUE * head = d->vhead + d->ctail->vi + 1;
@@ -585,7 +531,7 @@ static void add_big_as_ruby_key(ojParser p) {
585
531
  }
586
532
 
587
533
  static void add_str(ojParser p) {
588
- Delegate d = (Delegate)p->ctx;
534
+ Usual d = (Usual)p->ctx;
589
535
  volatile VALUE rstr;
590
536
  const char * str = buf_str(&p->buf);
591
537
  size_t len = buf_len(&p->buf);
@@ -599,7 +545,7 @@ static void add_str(ojParser p) {
599
545
  }
600
546
 
601
547
  static void add_str_key(ojParser p) {
602
- Delegate d = (Delegate)p->ctx;
548
+ Usual d = (Usual)p->ctx;
603
549
  volatile VALUE rstr;
604
550
  const char * str = buf_str(&p->buf);
605
551
  size_t len = buf_len(&p->buf);
@@ -614,7 +560,7 @@ static void add_str_key(ojParser p) {
614
560
  }
615
561
 
616
562
  static void add_str_key_create(ojParser p) {
617
- Delegate d = (Delegate)p->ctx;
563
+ Usual d = (Usual)p->ctx;
618
564
  volatile VALUE rstr;
619
565
  const char * str = buf_str(&p->buf);
620
566
  size_t len = buf_len(&p->buf);
@@ -648,7 +594,7 @@ static void add_str_key_create(ojParser p) {
648
594
  }
649
595
 
650
596
  static VALUE result(ojParser p) {
651
- Delegate d = (Delegate)p->ctx;
597
+ Usual d = (Usual)p->ctx;
652
598
 
653
599
  if (d->vhead < d->vtail) {
654
600
  return *d->vhead;
@@ -657,7 +603,7 @@ static VALUE result(ojParser p) {
657
603
  }
658
604
 
659
605
  static void start(ojParser p) {
660
- Delegate d = (Delegate)p->ctx;
606
+ Usual d = (Usual)p->ctx;
661
607
 
662
608
  d->vtail = d->vhead;
663
609
  d->ctail = d->chead;
@@ -665,7 +611,7 @@ static void start(ojParser p) {
665
611
  }
666
612
 
667
613
  static void dfree(ojParser p) {
668
- Delegate d = (Delegate)p->ctx;
614
+ Usual d = (Usual)p->ctx;
669
615
 
670
616
  cache_free(d->str_cache);
671
617
  cache_free(d->attr_cache);
@@ -684,10 +630,10 @@ static void dfree(ojParser p) {
684
630
  }
685
631
 
686
632
  static void mark(ojParser p) {
687
- if (NULL == p->ctx) {
633
+ if (NULL == p || NULL == p->ctx) {
688
634
  return;
689
635
  }
690
- Delegate d = (Delegate)p->ctx;
636
+ Usual d = (Usual)p->ctx;
691
637
  VALUE * vp;
692
638
 
693
639
  if (NULL == d) {
@@ -720,13 +666,13 @@ struct opt {
720
666
  };
721
667
 
722
668
  static VALUE opt_array_class(ojParser p, VALUE value) {
723
- Delegate d = (Delegate)p->ctx;
669
+ Usual d = (Usual)p->ctx;
724
670
 
725
671
  return d->array_class;
726
672
  }
727
673
 
728
674
  static VALUE opt_array_class_set(ojParser p, VALUE value) {
729
- Delegate d = (Delegate)p->ctx;
675
+ Usual d = (Usual)p->ctx;
730
676
 
731
677
  if (Qnil == value) {
732
678
  p->funcs[TOP_FUN].close_array = close_array;
@@ -747,13 +693,13 @@ static VALUE opt_array_class_set(ojParser p, VALUE value) {
747
693
  }
748
694
 
749
695
  static VALUE opt_cache_keys(ojParser p, VALUE value) {
750
- Delegate d = (Delegate)p->ctx;
696
+ Usual d = (Usual)p->ctx;
751
697
 
752
698
  return d->cache_keys ? Qtrue : Qfalse;
753
699
  }
754
700
 
755
701
  static VALUE opt_cache_keys_set(ojParser p, VALUE value) {
756
- Delegate d = (Delegate)p->ctx;
702
+ Usual d = (Usual)p->ctx;
757
703
 
758
704
  if (Qtrue == value) {
759
705
  d->cache_keys = true;
@@ -775,13 +721,13 @@ static VALUE opt_cache_keys_set(ojParser p, VALUE value) {
775
721
  }
776
722
 
777
723
  static VALUE opt_cache_strings(ojParser p, VALUE value) {
778
- Delegate d = (Delegate)p->ctx;
724
+ Usual d = (Usual)p->ctx;
779
725
 
780
726
  return INT2NUM((int)d->cache_str);
781
727
  }
782
728
 
783
729
  static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
784
- Delegate d = (Delegate)p->ctx;
730
+ Usual d = (Usual)p->ctx;
785
731
  int limit = NUM2INT(value);
786
732
 
787
733
  if (CACHE_MAX_KEY < limit) {
@@ -795,13 +741,13 @@ static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
795
741
  }
796
742
 
797
743
  static VALUE opt_cache_expunge(ojParser p, VALUE value) {
798
- Delegate d = (Delegate)p->ctx;
744
+ Usual d = (Usual)p->ctx;
799
745
 
800
746
  return INT2NUM((int)d->cache_xrate);
801
747
  }
802
748
 
803
749
  static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
804
- Delegate d = (Delegate)p->ctx;
750
+ Usual d = (Usual)p->ctx;
805
751
  int rate = NUM2INT(value);
806
752
 
807
753
  if (rate < 0) {
@@ -819,13 +765,13 @@ static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
819
765
  }
820
766
 
821
767
  static VALUE opt_capacity(ojParser p, VALUE value) {
822
- Delegate d = (Delegate)p->ctx;
768
+ Usual d = (Usual)p->ctx;
823
769
 
824
770
  return ULONG2NUM(d->vend - d->vhead);
825
771
  }
826
772
 
827
773
  static VALUE opt_capacity_set(ojParser p, VALUE value) {
828
- Delegate d = (Delegate)p->ctx;
774
+ Usual d = (Usual)p->ctx;
829
775
  long cap = NUM2LONG(value);
830
776
 
831
777
  if (d->vend - d->vhead < cap) {
@@ -846,13 +792,13 @@ static VALUE opt_capacity_set(ojParser p, VALUE value) {
846
792
  }
847
793
 
848
794
  static VALUE opt_class_cache(ojParser p, VALUE value) {
849
- Delegate d = (Delegate)p->ctx;
795
+ Usual d = (Usual)p->ctx;
850
796
 
851
797
  return (NULL != d->class_cache) ? Qtrue : Qfalse;
852
798
  }
853
799
 
854
800
  static VALUE opt_class_cache_set(ojParser p, VALUE value) {
855
- Delegate d = (Delegate)p->ctx;
801
+ Usual d = (Usual)p->ctx;
856
802
 
857
803
  if (Qtrue == value) {
858
804
  if (NULL == d->class_cache) {
@@ -866,7 +812,7 @@ static VALUE opt_class_cache_set(ojParser p, VALUE value) {
866
812
  }
867
813
 
868
814
  static VALUE opt_create_id(ojParser p, VALUE value) {
869
- Delegate d = (Delegate)p->ctx;
815
+ Usual d = (Usual)p->ctx;
870
816
 
871
817
  if (NULL == d->create_id) {
872
818
  return Qnil;
@@ -875,7 +821,7 @@ static VALUE opt_create_id(ojParser p, VALUE value) {
875
821
  }
876
822
 
877
823
  static VALUE opt_create_id_set(ojParser p, VALUE value) {
878
- Delegate d = (Delegate)p->ctx;
824
+ Usual d = (Usual)p->ctx;
879
825
 
880
826
  if (Qnil == value) {
881
827
  d->create_id = NULL;
@@ -985,13 +931,13 @@ static VALUE opt_decimal_set(ojParser p, VALUE value) {
985
931
  }
986
932
 
987
933
  static VALUE opt_hash_class(ojParser p, VALUE value) {
988
- Delegate d = (Delegate)p->ctx;
934
+ Usual d = (Usual)p->ctx;
989
935
 
990
936
  return d->hash_class;
991
937
  }
992
938
 
993
939
  static VALUE opt_hash_class_set(ojParser p, VALUE value) {
994
- Delegate d = (Delegate)p->ctx;
940
+ Usual d = (Usual)p->ctx;
995
941
 
996
942
  if (Qnil != value) {
997
943
  rb_check_type(value, T_CLASS);
@@ -1015,13 +961,13 @@ static VALUE opt_hash_class_set(ojParser p, VALUE value) {
1015
961
  }
1016
962
 
1017
963
  static VALUE opt_ignore_json_create(ojParser p, VALUE value) {
1018
- Delegate d = (Delegate)p->ctx;
964
+ Usual d = (Usual)p->ctx;
1019
965
 
1020
966
  return d->ignore_json_create ? Qtrue : Qfalse;
1021
967
  }
1022
968
 
1023
969
  static VALUE opt_ignore_json_create_set(ojParser p, VALUE value) {
1024
- Delegate d = (Delegate)p->ctx;
970
+ Usual d = (Usual)p->ctx;
1025
971
 
1026
972
  d->ignore_json_create = (Qtrue == value);
1027
973
 
@@ -1029,7 +975,7 @@ static VALUE opt_ignore_json_create_set(ojParser p, VALUE value) {
1029
975
  }
1030
976
 
1031
977
  static VALUE opt_missing_class(ojParser p, VALUE value) {
1032
- Delegate d = (Delegate)p->ctx;
978
+ Usual d = (Usual)p->ctx;
1033
979
 
1034
980
  switch (d->miss_class) {
1035
981
  case MISS_AUTO: return ID2SYM(rb_intern("auto"));
@@ -1040,7 +986,7 @@ static VALUE opt_missing_class(ojParser p, VALUE value) {
1040
986
  }
1041
987
 
1042
988
  static VALUE opt_missing_class_set(ojParser p, VALUE value) {
1043
- Delegate d = (Delegate)p->ctx;
989
+ Usual d = (Usual)p->ctx;
1044
990
  const char * mode;
1045
991
  volatile VALUE s;
1046
992
 
@@ -1091,13 +1037,13 @@ static VALUE opt_omit_null_set(ojParser p, VALUE value) {
1091
1037
  }
1092
1038
 
1093
1039
  static VALUE opt_symbol_keys(ojParser p, VALUE value) {
1094
- Delegate d = (Delegate)p->ctx;
1040
+ Usual d = (Usual)p->ctx;
1095
1041
 
1096
1042
  return (NULL != d->sym_cache) ? Qtrue : Qfalse;
1097
1043
  }
1098
1044
 
1099
1045
  static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
1100
- Delegate d = (Delegate)p->ctx;
1046
+ Usual d = (Usual)p->ctx;
1101
1047
 
1102
1048
  if (Qtrue == value) {
1103
1049
  d->sym_cache = cache_create(0, form_sym, true, false);
@@ -1121,33 +1067,33 @@ static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
1121
1067
  static VALUE option(ojParser p, const char *key, VALUE value) {
1122
1068
  struct opt *op;
1123
1069
  struct opt opts[] = {
1124
- {.name = "array_class", .func = opt_array_class},
1125
- {.name = "array_class=", .func = opt_array_class_set},
1126
- {.name = "cache_keys", .func = opt_cache_keys},
1127
- {.name = "cache_keys=", .func = opt_cache_keys_set},
1128
- {.name = "cache_strings", .func = opt_cache_strings},
1129
- {.name = "cache_strings=", .func = opt_cache_strings_set},
1130
- {.name = "cache_expunge", .func = opt_cache_expunge},
1131
- {.name = "cache_expunge=", .func = opt_cache_expunge_set},
1132
- {.name = "capacity", .func = opt_capacity},
1133
- {.name = "capacity=", .func = opt_capacity_set},
1134
- {.name = "class_cache", .func = opt_class_cache},
1135
- {.name = "class_cache=", .func = opt_class_cache_set},
1136
- {.name = "create_id", .func = opt_create_id},
1137
- {.name = "create_id=", .func = opt_create_id_set},
1138
- {.name = "decimal", .func = opt_decimal},
1139
- {.name = "decimal=", .func = opt_decimal_set},
1140
- {.name = "hash_class", .func = opt_hash_class},
1141
- {.name = "hash_class=", .func = opt_hash_class_set},
1142
- {.name = "ignore_json_create", .func = opt_ignore_json_create},
1143
- {.name = "ignore_json_create=", .func = opt_ignore_json_create_set},
1144
- {.name = "missing_class", .func = opt_missing_class},
1145
- {.name = "missing_class=", .func = opt_missing_class_set},
1146
- {.name = "omit_null", .func = opt_omit_null},
1147
- {.name = "omit_null=", .func = opt_omit_null_set},
1148
- {.name = "symbol_keys", .func = opt_symbol_keys},
1149
- {.name = "symbol_keys=", .func = opt_symbol_keys_set},
1150
- {.name = NULL},
1070
+ {.name = "array_class", .func = opt_array_class},
1071
+ {.name = "array_class=", .func = opt_array_class_set},
1072
+ {.name = "cache_keys", .func = opt_cache_keys},
1073
+ {.name = "cache_keys=", .func = opt_cache_keys_set},
1074
+ {.name = "cache_strings", .func = opt_cache_strings},
1075
+ {.name = "cache_strings=", .func = opt_cache_strings_set},
1076
+ {.name = "cache_expunge", .func = opt_cache_expunge},
1077
+ {.name = "cache_expunge=", .func = opt_cache_expunge_set},
1078
+ {.name = "capacity", .func = opt_capacity},
1079
+ {.name = "capacity=", .func = opt_capacity_set},
1080
+ {.name = "class_cache", .func = opt_class_cache},
1081
+ {.name = "class_cache=", .func = opt_class_cache_set},
1082
+ {.name = "create_id", .func = opt_create_id},
1083
+ {.name = "create_id=", .func = opt_create_id_set},
1084
+ {.name = "decimal", .func = opt_decimal},
1085
+ {.name = "decimal=", .func = opt_decimal_set},
1086
+ {.name = "hash_class", .func = opt_hash_class},
1087
+ {.name = "hash_class=", .func = opt_hash_class_set},
1088
+ {.name = "ignore_json_create", .func = opt_ignore_json_create},
1089
+ {.name = "ignore_json_create=", .func = opt_ignore_json_create_set},
1090
+ {.name = "missing_class", .func = opt_missing_class},
1091
+ {.name = "missing_class=", .func = opt_missing_class_set},
1092
+ {.name = "omit_null", .func = opt_omit_null},
1093
+ {.name = "omit_null=", .func = opt_omit_null_set},
1094
+ {.name = "symbol_keys", .func = opt_symbol_keys},
1095
+ {.name = "symbol_keys=", .func = opt_symbol_keys_set},
1096
+ {.name = NULL},
1151
1097
  };
1152
1098
 
1153
1099
  for (op = opts; NULL != op->name; op++) {
@@ -1162,8 +1108,7 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
1162
1108
 
1163
1109
  ///// the set up //////////////////////////////////////////////////////////////
1164
1110
 
1165
- void oj_set_parser_usual(ojParser p) {
1166
- Delegate d = ALLOC(struct _delegate);
1111
+ void oj_init_usual(ojParser p, Usual d) {
1167
1112
  int cap = 4096;
1168
1113
 
1169
1114
  d->vhead = ALLOC_N(VALUE, cap);
@@ -1235,6 +1180,8 @@ void oj_set_parser_usual(ojParser p) {
1235
1180
  d->class_cache = NULL;
1236
1181
  d->key_cache = d->str_cache;
1237
1182
 
1183
+ // The parser fields are set but the functions can be replaced by a
1184
+ // delegate that wraps the usual delegate.
1238
1185
  p->ctx = (void *)d;
1239
1186
  p->option = option;
1240
1187
  p->result = result;
@@ -1252,3 +1199,9 @@ void oj_set_parser_usual(ojParser p) {
1252
1199
  hset_id = rb_intern("[]=");
1253
1200
  }
1254
1201
  }
1202
+
1203
+ void oj_set_parser_usual(ojParser p) {
1204
+ Usual d = ALLOC(struct _usual);
1205
+
1206
+ oj_init_usual(p, d);
1207
+ }