oj 3.13.9 → 3.16.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +101 -0
  3. data/README.md +13 -2
  4. data/ext/oj/buf.h +11 -6
  5. data/ext/oj/cache.c +25 -24
  6. data/ext/oj/cache8.c +10 -9
  7. data/ext/oj/circarray.c +8 -6
  8. data/ext/oj/circarray.h +2 -2
  9. data/ext/oj/code.c +19 -33
  10. data/ext/oj/code.h +2 -2
  11. data/ext/oj/compat.c +20 -60
  12. data/ext/oj/custom.c +76 -155
  13. data/ext/oj/debug.c +3 -9
  14. data/ext/oj/dump.c +203 -213
  15. data/ext/oj/dump.h +26 -12
  16. data/ext/oj/dump_compat.c +565 -642
  17. data/ext/oj/dump_leaf.c +17 -63
  18. data/ext/oj/dump_object.c +59 -181
  19. data/ext/oj/dump_strict.c +24 -48
  20. data/ext/oj/encoder.c +43 -0
  21. data/ext/oj/err.c +2 -13
  22. data/ext/oj/err.h +9 -12
  23. data/ext/oj/extconf.rb +18 -7
  24. data/ext/oj/fast.c +83 -108
  25. data/ext/oj/intern.c +52 -50
  26. data/ext/oj/intern.h +4 -8
  27. data/ext/oj/mem.c +318 -0
  28. data/ext/oj/mem.h +53 -0
  29. data/ext/oj/mimic_json.c +104 -81
  30. data/ext/oj/object.c +50 -67
  31. data/ext/oj/odd.c +89 -67
  32. data/ext/oj/odd.h +15 -15
  33. data/ext/oj/oj.c +171 -106
  34. data/ext/oj/oj.h +96 -74
  35. data/ext/oj/parse.c +169 -189
  36. data/ext/oj/parse.h +23 -24
  37. data/ext/oj/parser.c +89 -34
  38. data/ext/oj/parser.h +20 -9
  39. data/ext/oj/rails.c +86 -151
  40. data/ext/oj/rails.h +1 -1
  41. data/ext/oj/reader.c +12 -15
  42. data/ext/oj/reader.h +4 -2
  43. data/ext/oj/resolve.c +3 -4
  44. data/ext/oj/rxclass.c +6 -5
  45. data/ext/oj/rxclass.h +1 -1
  46. data/ext/oj/saj.c +21 -32
  47. data/ext/oj/saj2.c +329 -93
  48. data/ext/oj/saj2.h +23 -0
  49. data/ext/oj/scp.c +3 -14
  50. data/ext/oj/sparse.c +26 -70
  51. data/ext/oj/stream_writer.c +12 -22
  52. data/ext/oj/strict.c +20 -52
  53. data/ext/oj/string_writer.c +21 -22
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +105 -150
  56. data/ext/oj/usual.h +68 -0
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +1 -1
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/validate.c +21 -26
  61. data/ext/oj/wab.c +32 -69
  62. data/lib/oj/active_support_helper.rb +1 -3
  63. data/lib/oj/bag.rb +7 -1
  64. data/lib/oj/easy_hash.rb +4 -5
  65. data/lib/oj/error.rb +0 -1
  66. data/lib/oj/json.rb +162 -150
  67. data/lib/oj/mimic.rb +6 -2
  68. data/lib/oj/saj.rb +20 -6
  69. data/lib/oj/state.rb +9 -6
  70. data/lib/oj/version.rb +1 -2
  71. data/lib/oj.rb +2 -0
  72. data/pages/Compatibility.md +1 -1
  73. data/pages/InstallOptions.md +20 -0
  74. data/pages/JsonGem.md +15 -0
  75. data/pages/Modes.md +6 -3
  76. data/pages/Options.md +10 -0
  77. data/pages/Rails.md +12 -0
  78. data/test/_test_active.rb +8 -9
  79. data/test/_test_active_mimic.rb +7 -8
  80. data/test/_test_mimic_rails.rb +17 -20
  81. data/test/activerecord/result_test.rb +5 -6
  82. data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
  83. data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
  84. data/test/{activesupport5 → activesupport7}/encoding_test.rb +20 -34
  85. data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
  86. data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
  87. data/test/files.rb +15 -15
  88. data/test/foo.rb +15 -15
  89. data/test/helper.rb +11 -8
  90. data/test/isolated/shared.rb +3 -2
  91. data/test/json_gem/json_addition_test.rb +2 -2
  92. data/test/json_gem/json_common_interface_test.rb +8 -6
  93. data/test/json_gem/json_encoding_test.rb +0 -0
  94. data/test/json_gem/json_ext_parser_test.rb +1 -0
  95. data/test/json_gem/json_fixtures_test.rb +3 -2
  96. data/test/json_gem/json_generator_test.rb +49 -37
  97. data/test/json_gem/json_generic_object_test.rb +11 -11
  98. data/test/json_gem/json_parser_test.rb +54 -47
  99. data/test/json_gem/json_string_matching_test.rb +9 -9
  100. data/test/json_gem/test_helper.rb +7 -3
  101. data/test/mem.rb +13 -12
  102. data/test/perf.rb +21 -26
  103. data/test/perf_compat.rb +31 -33
  104. data/test/perf_dump.rb +50 -0
  105. data/test/perf_fast.rb +80 -82
  106. data/test/perf_file.rb +27 -29
  107. data/test/perf_object.rb +65 -69
  108. data/test/perf_once.rb +12 -11
  109. data/test/perf_parser.rb +42 -48
  110. data/test/perf_saj.rb +46 -54
  111. data/test/perf_scp.rb +57 -69
  112. data/test/perf_simple.rb +41 -39
  113. data/test/perf_strict.rb +68 -70
  114. data/test/perf_wab.rb +67 -69
  115. data/test/prec.rb +3 -3
  116. data/test/sample/change.rb +0 -1
  117. data/test/sample/dir.rb +0 -1
  118. data/test/sample/doc.rb +0 -1
  119. data/test/sample/file.rb +0 -1
  120. data/test/sample/group.rb +0 -1
  121. data/test/sample/hasprops.rb +0 -1
  122. data/test/sample/layer.rb +0 -1
  123. data/test/sample/rect.rb +0 -1
  124. data/test/sample/shape.rb +0 -1
  125. data/test/sample/text.rb +0 -1
  126. data/test/sample.rb +16 -16
  127. data/test/sample_json.rb +8 -8
  128. data/test/test_compat.rb +95 -43
  129. data/test/test_custom.rb +72 -51
  130. data/test/test_debian.rb +7 -10
  131. data/test/test_fast.rb +102 -87
  132. data/test/test_file.rb +41 -30
  133. data/test/test_gc.rb +16 -5
  134. data/test/test_generate.rb +5 -5
  135. data/test/test_hash.rb +4 -4
  136. data/test/test_integer_range.rb +9 -9
  137. data/test/test_null.rb +20 -20
  138. data/test/test_object.rb +85 -96
  139. data/test/test_parser.rb +6 -22
  140. data/test/test_parser_debug.rb +27 -0
  141. data/test/test_parser_saj.rb +115 -23
  142. data/test/test_parser_usual.rb +6 -6
  143. data/test/test_rails.rb +2 -2
  144. data/test/test_saj.rb +10 -8
  145. data/test/test_scp.rb +37 -39
  146. data/test/test_strict.rb +40 -32
  147. data/test/test_various.rb +163 -84
  148. data/test/test_wab.rb +48 -44
  149. data/test/test_writer.rb +47 -47
  150. data/test/tests.rb +13 -5
  151. data/test/tests_mimic.rb +12 -3
  152. data/test/tests_mimic_addition.rb +12 -3
  153. metadata +34 -144
  154. data/test/activesupport4/decoding_test.rb +0 -108
  155. data/test/activesupport4/encoding_test.rb +0 -531
  156. data/test/activesupport4/test_helper.rb +0 -41
  157. data/test/activesupport5/test_helper.rb +0 -72
  158. data/test/bar.rb +0 -16
  159. data/test/baz.rb +0 -16
  160. data/test/bug.rb +0 -16
  161. data/test/zoo.rb +0 -13
data/ext/oj/usual.c CHANGED
@@ -1,6 +1,9 @@
1
1
  // Copyright (c) 2021, Peter Ohler, All rights reserved.
2
2
 
3
+ #include "usual.h"
4
+
3
5
  #include "cache.h"
6
+ #include "mem.h"
4
7
  #include "oj.h"
5
8
  #include "parser.h"
6
9
 
@@ -28,67 +31,12 @@
28
31
 
29
32
  #define DEBUG 0
30
33
 
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
34
  static ID to_f_id = 0;
87
35
  static ID ltlt_id = 0;
88
36
  static ID hset_id = 0;
89
37
 
90
38
  static char *str_dup(const char *s, size_t len) {
91
- char *d = ALLOC_N(char, len + 1);
39
+ char *d = OJ_R_ALLOC_N(char, len + 1);
92
40
 
93
41
  memcpy(d, s, len);
94
42
  d[len] = '\0';
@@ -108,7 +56,7 @@ static VALUE form_attr(const char *str, size_t len) {
108
56
  char buf[256];
109
57
 
110
58
  if (sizeof(buf) - 2 <= len) {
111
- char *b = ALLOC_N(char, len + 2);
59
+ char *b = OJ_R_ALLOC_N(char, len + 2);
112
60
  ID id;
113
61
 
114
62
  *b = '@';
@@ -116,7 +64,7 @@ static VALUE form_attr(const char *str, size_t len) {
116
64
  b[len + 1] = '\0';
117
65
 
118
66
  id = rb_intern3(buf, len + 1, oj_utf8_encoding);
119
- xfree(b);
67
+ OJ_R_FREE(b);
120
68
  return id;
121
69
  }
122
70
  *buf = '@';
@@ -143,8 +91,8 @@ static VALUE resolve_classname(VALUE mod, const char *classname, bool auto_defin
143
91
  static VALUE resolve_classpath(const char *name, size_t len, bool auto_define) {
144
92
  char class_name[1024];
145
93
  VALUE clas;
146
- char * end = class_name + sizeof(class_name) - 1;
147
- char * s;
94
+ char *end = class_name + sizeof(class_name) - 1;
95
+ char *s;
148
96
  const char *n = name;
149
97
 
150
98
  clas = rb_cObject;
@@ -178,27 +126,27 @@ static VALUE form_class_auto(const char *str, size_t len) {
178
126
  return resolve_classpath(str, len, true);
179
127
  }
180
128
 
181
- static void assure_cstack(Delegate d) {
129
+ static void assure_cstack(Usual d) {
182
130
  if (d->cend <= d->ctail + 1) {
183
131
  size_t cap = d->cend - d->chead;
184
132
  long pos = d->ctail - d->chead;
185
133
 
186
134
  cap *= 2;
187
- REALLOC_N(d->chead, struct _col, cap);
135
+ OJ_R_REALLOC_N(d->chead, struct _col, cap);
188
136
  d->ctail = d->chead + pos;
189
137
  d->cend = d->chead + cap;
190
138
  }
191
139
  }
192
140
 
193
141
  static void push(ojParser p, VALUE v) {
194
- Delegate d = (Delegate)p->ctx;
142
+ Usual d = (Usual)p->ctx;
195
143
 
196
144
  if (d->vend <= d->vtail) {
197
145
  size_t cap = d->vend - d->vhead;
198
146
  long pos = d->vtail - d->vhead;
199
147
 
200
148
  cap *= 2;
201
- REALLOC_N(d->vhead, VALUE, cap);
149
+ OJ_R_REALLOC_N(d->vhead, VALUE, cap);
202
150
  d->vtail = d->vhead + pos;
203
151
  d->vend = d->vhead + cap;
204
152
  }
@@ -207,7 +155,7 @@ static void push(ojParser p, VALUE v) {
207
155
  }
208
156
 
209
157
  static VALUE cache_key(ojParser p, Key kp) {
210
- Delegate d = (Delegate)p->ctx;
158
+ Usual d = (Usual)p->ctx;
211
159
 
212
160
  if ((size_t)kp->len < sizeof(kp->buf)) {
213
161
  return cache_intern(d->key_cache, kp->buf, kp->len);
@@ -230,7 +178,7 @@ static VALUE sym_key(ojParser p, Key kp) {
230
178
  }
231
179
 
232
180
  static ID get_attr_id(ojParser p, Key kp) {
233
- Delegate d = (Delegate)p->ctx;
181
+ Usual d = (Usual)p->ctx;
234
182
 
235
183
  if ((size_t)kp->len < sizeof(kp->buf)) {
236
184
  return (ID)cache_intern(d->attr_cache, kp->buf, kp->len);
@@ -239,7 +187,7 @@ static ID get_attr_id(ojParser p, Key kp) {
239
187
  }
240
188
 
241
189
  static void push_key(ojParser p) {
242
- Delegate d = (Delegate)p->ctx;
190
+ Usual d = (Usual)p->ctx;
243
191
  size_t klen = buf_len(&p->key);
244
192
  const char *key = buf_str(&p->key);
245
193
 
@@ -248,7 +196,7 @@ static void push_key(ojParser p) {
248
196
  long pos = d->ktail - d->khead;
249
197
 
250
198
  cap *= 2;
251
- REALLOC_N(d->khead, union _key, cap);
199
+ OJ_R_REALLOC_N(d->khead, union _key, cap);
252
200
  d->ktail = d->khead + pos;
253
201
  d->kend = d->khead + cap;
254
202
  }
@@ -263,14 +211,14 @@ static void push_key(ojParser p) {
263
211
  }
264
212
 
265
213
  static void push2(ojParser p, VALUE v) {
266
- Delegate d = (Delegate)p->ctx;
214
+ Usual d = (Usual)p->ctx;
267
215
 
268
216
  if (d->vend <= d->vtail + 1) {
269
217
  size_t cap = d->vend - d->vhead;
270
218
  long pos = d->vtail - d->vhead;
271
219
 
272
220
  cap *= 2;
273
- REALLOC_N(d->vhead, VALUE, cap);
221
+ OJ_R_REALLOC_N(d->vhead, VALUE, cap);
274
222
  d->vtail = d->vhead + pos;
275
223
  d->vend = d->vhead + cap;
276
224
  }
@@ -281,7 +229,7 @@ static void push2(ojParser p, VALUE v) {
281
229
  }
282
230
 
283
231
  static void open_object(ojParser p) {
284
- Delegate d = (Delegate)p->ctx;
232
+ Usual d = (Usual)p->ctx;
285
233
 
286
234
  assure_cstack(d);
287
235
  d->ctail->vi = d->vtail - d->vhead;
@@ -291,7 +239,7 @@ static void open_object(ojParser p) {
291
239
  }
292
240
 
293
241
  static void open_object_key(ojParser p) {
294
- Delegate d = (Delegate)p->ctx;
242
+ Usual d = (Usual)p->ctx;
295
243
 
296
244
  push_key(p);
297
245
  assure_cstack(d);
@@ -302,7 +250,7 @@ static void open_object_key(ojParser p) {
302
250
  }
303
251
 
304
252
  static void open_array(ojParser p) {
305
- Delegate d = (Delegate)p->ctx;
253
+ Usual d = (Usual)p->ctx;
306
254
 
307
255
  assure_cstack(d);
308
256
  d->ctail->vi = d->vtail - d->vhead;
@@ -312,7 +260,7 @@ static void open_array(ojParser p) {
312
260
  }
313
261
 
314
262
  static void open_array_key(ojParser p) {
315
- Delegate d = (Delegate)p->ctx;
263
+ Usual d = (Usual)p->ctx;
316
264
 
317
265
  push_key(p);
318
266
  assure_cstack(d);
@@ -323,21 +271,21 @@ static void open_array_key(ojParser p) {
323
271
  }
324
272
 
325
273
  static void close_object(ojParser p) {
326
- VALUE * vp;
327
- Delegate d = (Delegate)p->ctx;
274
+ VALUE *vp;
275
+ Usual d = (Usual)p->ctx;
328
276
 
329
277
  d->ctail--;
330
278
 
331
279
  Col c = d->ctail;
332
280
  Key kp = d->khead + c->ki;
333
- VALUE * head = d->vhead + c->vi + 1;
281
+ VALUE *head = d->vhead + c->vi + 1;
334
282
  volatile VALUE obj = rb_hash_new();
335
283
 
336
284
  #if HAVE_RB_HASH_BULK_INSERT
337
285
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
338
286
  *vp = d->get_key(p, kp);
339
287
  if (sizeof(kp->buf) <= (size_t)kp->len) {
340
- xfree(kp->key);
288
+ OJ_R_FREE(kp->key);
341
289
  }
342
290
  }
343
291
  rb_hash_bulk_insert(d->vtail - head, head, obj);
@@ -345,7 +293,7 @@ static void close_object(ojParser p) {
345
293
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
346
294
  rb_hash_aset(obj, d->get_key(p, kp), *(vp + 1));
347
295
  if (sizeof(kp->buf) <= (size_t)kp->len) {
348
- xfree(kp->key);
296
+ OJ_R_FREE(kp->key);
349
297
  }
350
298
  }
351
299
  #endif
@@ -356,20 +304,20 @@ static void close_object(ojParser p) {
356
304
  }
357
305
 
358
306
  static void close_object_class(ojParser p) {
359
- VALUE * vp;
360
- Delegate d = (Delegate)p->ctx;
307
+ VALUE *vp;
308
+ Usual d = (Usual)p->ctx;
361
309
 
362
310
  d->ctail--;
363
311
 
364
312
  Col c = d->ctail;
365
313
  Key kp = d->khead + c->ki;
366
- VALUE * head = d->vhead + c->vi + 1;
314
+ VALUE *head = d->vhead + c->vi + 1;
367
315
  volatile VALUE obj = rb_class_new_instance(0, NULL, d->hash_class);
368
316
 
369
317
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
370
318
  rb_funcall(obj, hset_id, 2, d->get_key(p, kp), *(vp + 1));
371
319
  if (sizeof(kp->buf) <= (size_t)kp->len) {
372
- xfree(kp->key);
320
+ OJ_R_FREE(kp->key);
373
321
  }
374
322
  }
375
323
  d->ktail = d->khead + c->ki;
@@ -379,14 +327,14 @@ static void close_object_class(ojParser p) {
379
327
  }
380
328
 
381
329
  static void close_object_create(ojParser p) {
382
- VALUE * vp;
383
- Delegate d = (Delegate)p->ctx;
330
+ VALUE *vp;
331
+ Usual d = (Usual)p->ctx;
384
332
 
385
333
  d->ctail--;
386
334
 
387
335
  Col c = d->ctail;
388
336
  Key kp = d->khead + c->ki;
389
- VALUE * head = d->vhead + c->vi;
337
+ VALUE *head = d->vhead + c->vi;
390
338
  volatile VALUE obj;
391
339
 
392
340
  if (Qundef == *head) {
@@ -397,7 +345,7 @@ static void close_object_create(ojParser p) {
397
345
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
398
346
  *vp = d->get_key(p, kp);
399
347
  if (sizeof(kp->buf) <= (size_t)kp->len) {
400
- xfree(kp->key);
348
+ OJ_R_FREE(kp->key);
401
349
  }
402
350
  }
403
351
  rb_hash_bulk_insert(d->vtail - head, head, obj);
@@ -405,7 +353,7 @@ static void close_object_create(ojParser p) {
405
353
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
406
354
  rb_hash_aset(obj, d->get_key(p, kp), *(vp + 1));
407
355
  if (sizeof(kp->buf) <= (size_t)kp->len) {
408
- xfree(kp->key);
356
+ OJ_R_FREE(kp->key);
409
357
  }
410
358
  }
411
359
  #endif
@@ -414,7 +362,7 @@ static void close_object_create(ojParser p) {
414
362
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
415
363
  rb_funcall(obj, hset_id, 2, d->get_key(p, kp), *(vp + 1));
416
364
  if (sizeof(kp->buf) <= (size_t)kp->len) {
417
- xfree(kp->key);
365
+ OJ_R_FREE(kp->key);
418
366
  }
419
367
  }
420
368
  }
@@ -429,7 +377,7 @@ static void close_object_create(ojParser p) {
429
377
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
430
378
  *vp = d->get_key(p, kp);
431
379
  if (sizeof(kp->buf) <= (size_t)kp->len) {
432
- xfree(kp->key);
380
+ OJ_R_FREE(kp->key);
433
381
  }
434
382
  }
435
383
  rb_hash_bulk_insert(d->vtail - head, head, arg);
@@ -437,7 +385,7 @@ static void close_object_create(ojParser p) {
437
385
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
438
386
  rb_hash_aset(arg, d->get_key(p, kp), *(vp + 1));
439
387
  if (sizeof(kp->buf) <= (size_t)kp->len) {
440
- xfree(kp->key);
388
+ OJ_R_FREE(kp->key);
441
389
  }
442
390
  }
443
391
  #endif
@@ -447,7 +395,7 @@ static void close_object_create(ojParser p) {
447
395
  for (vp = head; kp < d->ktail; kp++, vp += 2) {
448
396
  rb_ivar_set(obj, get_attr_id(p, kp), *(vp + 1));
449
397
  if (sizeof(kp->buf) <= (size_t)kp->len) {
450
- xfree(kp->key);
398
+ OJ_R_FREE(kp->key);
451
399
  }
452
400
  }
453
401
  }
@@ -459,10 +407,10 @@ static void close_object_create(ojParser p) {
459
407
  }
460
408
 
461
409
  static void close_array(ojParser p) {
462
- Delegate d = (Delegate)p->ctx;
410
+ Usual d = (Usual)p->ctx;
463
411
 
464
412
  d->ctail--;
465
- VALUE * head = d->vhead + d->ctail->vi + 1;
413
+ VALUE *head = d->vhead + d->ctail->vi + 1;
466
414
  volatile VALUE a = rb_ary_new_from_values(d->vtail - head, head);
467
415
 
468
416
  d->vtail = head;
@@ -471,11 +419,11 @@ static void close_array(ojParser p) {
471
419
  }
472
420
 
473
421
  static void close_array_class(ojParser p) {
474
- VALUE * vp;
475
- Delegate d = (Delegate)p->ctx;
422
+ VALUE *vp;
423
+ Usual d = (Usual)p->ctx;
476
424
 
477
425
  d->ctail--;
478
- VALUE * head = d->vhead + d->ctail->vi + 1;
426
+ VALUE *head = d->vhead + d->ctail->vi + 1;
479
427
  volatile VALUE a = rb_class_new_instance(0, NULL, d->array_class);
480
428
 
481
429
  for (vp = head; vp < d->vtail; vp++) {
@@ -585,9 +533,9 @@ static void add_big_as_ruby_key(ojParser p) {
585
533
  }
586
534
 
587
535
  static void add_str(ojParser p) {
588
- Delegate d = (Delegate)p->ctx;
536
+ Usual d = (Usual)p->ctx;
589
537
  volatile VALUE rstr;
590
- const char * str = buf_str(&p->buf);
538
+ const char *str = buf_str(&p->buf);
591
539
  size_t len = buf_len(&p->buf);
592
540
 
593
541
  if (len < d->cache_str) {
@@ -599,9 +547,9 @@ static void add_str(ojParser p) {
599
547
  }
600
548
 
601
549
  static void add_str_key(ojParser p) {
602
- Delegate d = (Delegate)p->ctx;
550
+ Usual d = (Usual)p->ctx;
603
551
  volatile VALUE rstr;
604
- const char * str = buf_str(&p->buf);
552
+ const char *str = buf_str(&p->buf);
605
553
  size_t len = buf_len(&p->buf);
606
554
 
607
555
  if (len < d->cache_str) {
@@ -614,11 +562,11 @@ static void add_str_key(ojParser p) {
614
562
  }
615
563
 
616
564
  static void add_str_key_create(ojParser p) {
617
- Delegate d = (Delegate)p->ctx;
565
+ Usual d = (Usual)p->ctx;
618
566
  volatile VALUE rstr;
619
- const char * str = buf_str(&p->buf);
567
+ const char *str = buf_str(&p->buf);
620
568
  size_t len = buf_len(&p->buf);
621
- const char * key = buf_str(&p->key);
569
+ const char *key = buf_str(&p->key);
622
570
  size_t klen = buf_len(&p->key);
623
571
 
624
572
  if (klen == (size_t)d->create_id_len && 0 == strncmp(d->create_id, key, klen)) {
@@ -648,7 +596,7 @@ static void add_str_key_create(ojParser p) {
648
596
  }
649
597
 
650
598
  static VALUE result(ojParser p) {
651
- Delegate d = (Delegate)p->ctx;
599
+ Usual d = (Usual)p->ctx;
652
600
 
653
601
  if (d->vhead < d->vtail) {
654
602
  return *d->vhead;
@@ -657,7 +605,7 @@ static VALUE result(ojParser p) {
657
605
  }
658
606
 
659
607
  static void start(ojParser p) {
660
- Delegate d = (Delegate)p->ctx;
608
+ Usual d = (Usual)p->ctx;
661
609
 
662
610
  d->vtail = d->vhead;
663
611
  d->ctail = d->chead;
@@ -665,7 +613,7 @@ static void start(ojParser p) {
665
613
  }
666
614
 
667
615
  static void dfree(ojParser p) {
668
- Delegate d = (Delegate)p->ctx;
616
+ Usual d = (Usual)p->ctx;
669
617
 
670
618
  cache_free(d->str_cache);
671
619
  cache_free(d->attr_cache);
@@ -675,20 +623,20 @@ static void dfree(ojParser p) {
675
623
  if (NULL != d->class_cache) {
676
624
  cache_free(d->class_cache);
677
625
  }
678
- xfree(d->vhead);
679
- xfree(d->chead);
680
- xfree(d->khead);
681
- xfree(d->create_id);
682
- xfree(p->ctx);
626
+ OJ_R_FREE(d->vhead);
627
+ OJ_R_FREE(d->chead);
628
+ OJ_R_FREE(d->khead);
629
+ OJ_R_FREE(d->create_id);
630
+ OJ_R_FREE(p->ctx);
683
631
  p->ctx = NULL;
684
632
  }
685
633
 
686
634
  static void mark(ojParser p) {
687
- if (NULL == p->ctx) {
635
+ if (NULL == p || NULL == p->ctx) {
688
636
  return;
689
637
  }
690
- Delegate d = (Delegate)p->ctx;
691
- VALUE * vp;
638
+ Usual d = (Usual)p->ctx;
639
+ VALUE *vp;
692
640
 
693
641
  if (NULL == d) {
694
642
  return;
@@ -720,13 +668,13 @@ struct opt {
720
668
  };
721
669
 
722
670
  static VALUE opt_array_class(ojParser p, VALUE value) {
723
- Delegate d = (Delegate)p->ctx;
671
+ Usual d = (Usual)p->ctx;
724
672
 
725
673
  return d->array_class;
726
674
  }
727
675
 
728
676
  static VALUE opt_array_class_set(ojParser p, VALUE value) {
729
- Delegate d = (Delegate)p->ctx;
677
+ Usual d = (Usual)p->ctx;
730
678
 
731
679
  if (Qnil == value) {
732
680
  p->funcs[TOP_FUN].close_array = close_array;
@@ -747,13 +695,13 @@ static VALUE opt_array_class_set(ojParser p, VALUE value) {
747
695
  }
748
696
 
749
697
  static VALUE opt_cache_keys(ojParser p, VALUE value) {
750
- Delegate d = (Delegate)p->ctx;
698
+ Usual d = (Usual)p->ctx;
751
699
 
752
700
  return d->cache_keys ? Qtrue : Qfalse;
753
701
  }
754
702
 
755
703
  static VALUE opt_cache_keys_set(ojParser p, VALUE value) {
756
- Delegate d = (Delegate)p->ctx;
704
+ Usual d = (Usual)p->ctx;
757
705
 
758
706
  if (Qtrue == value) {
759
707
  d->cache_keys = true;
@@ -775,14 +723,14 @@ static VALUE opt_cache_keys_set(ojParser p, VALUE value) {
775
723
  }
776
724
 
777
725
  static VALUE opt_cache_strings(ojParser p, VALUE value) {
778
- Delegate d = (Delegate)p->ctx;
726
+ Usual d = (Usual)p->ctx;
779
727
 
780
728
  return INT2NUM((int)d->cache_str);
781
729
  }
782
730
 
783
731
  static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
784
- Delegate d = (Delegate)p->ctx;
785
- int limit = NUM2INT(value);
732
+ Usual d = (Usual)p->ctx;
733
+ int limit = NUM2INT(value);
786
734
 
787
735
  if (CACHE_MAX_KEY < limit) {
788
736
  limit = CACHE_MAX_KEY;
@@ -795,14 +743,14 @@ static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
795
743
  }
796
744
 
797
745
  static VALUE opt_cache_expunge(ojParser p, VALUE value) {
798
- Delegate d = (Delegate)p->ctx;
746
+ Usual d = (Usual)p->ctx;
799
747
 
800
748
  return INT2NUM((int)d->cache_xrate);
801
749
  }
802
750
 
803
751
  static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
804
- Delegate d = (Delegate)p->ctx;
805
- int rate = NUM2INT(value);
752
+ Usual d = (Usual)p->ctx;
753
+ int rate = NUM2INT(value);
806
754
 
807
755
  if (rate < 0) {
808
756
  rate = 0;
@@ -819,26 +767,26 @@ static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
819
767
  }
820
768
 
821
769
  static VALUE opt_capacity(ojParser p, VALUE value) {
822
- Delegate d = (Delegate)p->ctx;
770
+ Usual d = (Usual)p->ctx;
823
771
 
824
772
  return ULONG2NUM(d->vend - d->vhead);
825
773
  }
826
774
 
827
775
  static VALUE opt_capacity_set(ojParser p, VALUE value) {
828
- Delegate d = (Delegate)p->ctx;
829
- long cap = NUM2LONG(value);
776
+ Usual d = (Usual)p->ctx;
777
+ long cap = NUM2LONG(value);
830
778
 
831
779
  if (d->vend - d->vhead < cap) {
832
780
  long pos = d->vtail - d->vhead;
833
781
 
834
- REALLOC_N(d->vhead, VALUE, cap);
782
+ OJ_R_REALLOC_N(d->vhead, VALUE, cap);
835
783
  d->vtail = d->vhead + pos;
836
784
  d->vend = d->vhead + cap;
837
785
  }
838
786
  if (d->kend - d->khead < cap) {
839
787
  long pos = d->ktail - d->khead;
840
788
 
841
- REALLOC_N(d->khead, union _key, cap);
789
+ OJ_R_REALLOC_N(d->khead, union _key, cap);
842
790
  d->ktail = d->khead + pos;
843
791
  d->kend = d->khead + cap;
844
792
  }
@@ -846,13 +794,13 @@ static VALUE opt_capacity_set(ojParser p, VALUE value) {
846
794
  }
847
795
 
848
796
  static VALUE opt_class_cache(ojParser p, VALUE value) {
849
- Delegate d = (Delegate)p->ctx;
797
+ Usual d = (Usual)p->ctx;
850
798
 
851
799
  return (NULL != d->class_cache) ? Qtrue : Qfalse;
852
800
  }
853
801
 
854
802
  static VALUE opt_class_cache_set(ojParser p, VALUE value) {
855
- Delegate d = (Delegate)p->ctx;
803
+ Usual d = (Usual)p->ctx;
856
804
 
857
805
  if (Qtrue == value) {
858
806
  if (NULL == d->class_cache) {
@@ -866,7 +814,7 @@ static VALUE opt_class_cache_set(ojParser p, VALUE value) {
866
814
  }
867
815
 
868
816
  static VALUE opt_create_id(ojParser p, VALUE value) {
869
- Delegate d = (Delegate)p->ctx;
817
+ Usual d = (Usual)p->ctx;
870
818
 
871
819
  if (NULL == d->create_id) {
872
820
  return Qnil;
@@ -875,7 +823,7 @@ static VALUE opt_create_id(ojParser p, VALUE value) {
875
823
  }
876
824
 
877
825
  static VALUE opt_create_id_set(ojParser p, VALUE value) {
878
- Delegate d = (Delegate)p->ctx;
826
+ Usual d = (Usual)p->ctx;
879
827
 
880
828
  if (Qnil == value) {
881
829
  d->create_id = NULL;
@@ -924,7 +872,7 @@ static VALUE opt_decimal(ojParser p, VALUE value) {
924
872
  }
925
873
 
926
874
  static VALUE opt_decimal_set(ojParser p, VALUE value) {
927
- const char * mode;
875
+ const char *mode;
928
876
  volatile VALUE s;
929
877
 
930
878
  switch (rb_type(value)) {
@@ -985,13 +933,13 @@ static VALUE opt_decimal_set(ojParser p, VALUE value) {
985
933
  }
986
934
 
987
935
  static VALUE opt_hash_class(ojParser p, VALUE value) {
988
- Delegate d = (Delegate)p->ctx;
936
+ Usual d = (Usual)p->ctx;
989
937
 
990
938
  return d->hash_class;
991
939
  }
992
940
 
993
941
  static VALUE opt_hash_class_set(ojParser p, VALUE value) {
994
- Delegate d = (Delegate)p->ctx;
942
+ Usual d = (Usual)p->ctx;
995
943
 
996
944
  if (Qnil != value) {
997
945
  rb_check_type(value, T_CLASS);
@@ -1015,13 +963,13 @@ static VALUE opt_hash_class_set(ojParser p, VALUE value) {
1015
963
  }
1016
964
 
1017
965
  static VALUE opt_ignore_json_create(ojParser p, VALUE value) {
1018
- Delegate d = (Delegate)p->ctx;
966
+ Usual d = (Usual)p->ctx;
1019
967
 
1020
968
  return d->ignore_json_create ? Qtrue : Qfalse;
1021
969
  }
1022
970
 
1023
971
  static VALUE opt_ignore_json_create_set(ojParser p, VALUE value) {
1024
- Delegate d = (Delegate)p->ctx;
972
+ Usual d = (Usual)p->ctx;
1025
973
 
1026
974
  d->ignore_json_create = (Qtrue == value);
1027
975
 
@@ -1029,7 +977,7 @@ static VALUE opt_ignore_json_create_set(ojParser p, VALUE value) {
1029
977
  }
1030
978
 
1031
979
  static VALUE opt_missing_class(ojParser p, VALUE value) {
1032
- Delegate d = (Delegate)p->ctx;
980
+ Usual d = (Usual)p->ctx;
1033
981
 
1034
982
  switch (d->miss_class) {
1035
983
  case MISS_AUTO: return ID2SYM(rb_intern("auto"));
@@ -1040,8 +988,8 @@ static VALUE opt_missing_class(ojParser p, VALUE value) {
1040
988
  }
1041
989
 
1042
990
  static VALUE opt_missing_class_set(ojParser p, VALUE value) {
1043
- Delegate d = (Delegate)p->ctx;
1044
- const char * mode;
991
+ Usual d = (Usual)p->ctx;
992
+ const char *mode;
1045
993
  volatile VALUE s;
1046
994
 
1047
995
  switch (rb_type(value)) {
@@ -1091,13 +1039,13 @@ static VALUE opt_omit_null_set(ojParser p, VALUE value) {
1091
1039
  }
1092
1040
 
1093
1041
  static VALUE opt_symbol_keys(ojParser p, VALUE value) {
1094
- Delegate d = (Delegate)p->ctx;
1042
+ Usual d = (Usual)p->ctx;
1095
1043
 
1096
1044
  return (NULL != d->sym_cache) ? Qtrue : Qfalse;
1097
1045
  }
1098
1046
 
1099
1047
  static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
1100
- Delegate d = (Delegate)p->ctx;
1048
+ Usual d = (Usual)p->ctx;
1101
1049
 
1102
1050
  if (Qtrue == value) {
1103
1051
  d->sym_cache = cache_create(0, form_sym, true, false);
@@ -1162,20 +1110,19 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
1162
1110
 
1163
1111
  ///// the set up //////////////////////////////////////////////////////////////
1164
1112
 
1165
- void oj_set_parser_usual(ojParser p) {
1166
- Delegate d = ALLOC(struct _delegate);
1167
- int cap = 4096;
1113
+ void oj_init_usual(ojParser p, Usual d) {
1114
+ int cap = 4096;
1168
1115
 
1169
- d->vhead = ALLOC_N(VALUE, cap);
1116
+ d->vhead = OJ_R_ALLOC_N(VALUE, cap);
1170
1117
  d->vend = d->vhead + cap;
1171
1118
  d->vtail = d->vhead;
1172
1119
 
1173
- d->khead = ALLOC_N(union _key, cap);
1120
+ d->khead = OJ_R_ALLOC_N(union _key, cap);
1174
1121
  d->kend = d->khead + cap;
1175
1122
  d->ktail = d->khead;
1176
1123
 
1177
1124
  cap = 256;
1178
- d->chead = ALLOC_N(struct _col, cap);
1125
+ d->chead = OJ_R_ALLOC_N(struct _col, cap);
1179
1126
  d->cend = d->chead + cap;
1180
1127
  d->ctail = d->chead;
1181
1128
 
@@ -1235,6 +1182,8 @@ void oj_set_parser_usual(ojParser p) {
1235
1182
  d->class_cache = NULL;
1236
1183
  d->key_cache = d->str_cache;
1237
1184
 
1185
+ // The parser fields are set but the functions can be replaced by a
1186
+ // delegate that wraps the usual delegate.
1238
1187
  p->ctx = (void *)d;
1239
1188
  p->option = option;
1240
1189
  p->result = result;
@@ -1252,3 +1201,9 @@ void oj_set_parser_usual(ojParser p) {
1252
1201
  hset_id = rb_intern("[]=");
1253
1202
  }
1254
1203
  }
1204
+
1205
+ void oj_set_parser_usual(ojParser p) {
1206
+ Usual d = OJ_R_ALLOC(struct _usual);
1207
+
1208
+ oj_init_usual(p, d);
1209
+ }