oj 2.18.3 → 3.13.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1324 -0
  3. data/README.md +51 -204
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +49 -72
  6. data/ext/oj/cache.c +326 -0
  7. data/ext/oj/cache.h +21 -0
  8. data/ext/oj/cache8.c +61 -64
  9. data/ext/oj/cache8.h +12 -39
  10. data/ext/oj/circarray.c +37 -68
  11. data/ext/oj/circarray.h +16 -42
  12. data/ext/oj/code.c +221 -0
  13. data/ext/oj/code.h +40 -0
  14. data/ext/oj/compat.c +231 -107
  15. data/ext/oj/custom.c +1125 -0
  16. data/ext/oj/debug.c +132 -0
  17. data/ext/oj/dump.c +935 -2513
  18. data/ext/oj/dump.h +108 -0
  19. data/ext/oj/dump_compat.c +936 -0
  20. data/ext/oj/dump_leaf.c +164 -0
  21. data/ext/oj/dump_object.c +761 -0
  22. data/ext/oj/dump_strict.c +410 -0
  23. data/ext/oj/encode.h +7 -42
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +40 -54
  26. data/ext/oj/err.h +52 -46
  27. data/ext/oj/extconf.rb +21 -30
  28. data/ext/oj/fast.c +1097 -1080
  29. data/ext/oj/intern.c +301 -0
  30. data/ext/oj/intern.h +26 -0
  31. data/ext/oj/mimic_json.c +893 -0
  32. data/ext/oj/object.c +549 -620
  33. data/ext/oj/odd.c +155 -167
  34. data/ext/oj/odd.h +37 -63
  35. data/ext/oj/oj.c +1661 -2063
  36. data/ext/oj/oj.h +341 -270
  37. data/ext/oj/parse.c +974 -737
  38. data/ext/oj/parse.h +105 -97
  39. data/ext/oj/parser.c +1526 -0
  40. data/ext/oj/parser.h +90 -0
  41. data/ext/oj/rails.c +1504 -0
  42. data/ext/oj/rails.h +18 -0
  43. data/ext/oj/reader.c +141 -163
  44. data/ext/oj/reader.h +75 -113
  45. data/ext/oj/resolve.c +45 -93
  46. data/ext/oj/resolve.h +7 -34
  47. data/ext/oj/rxclass.c +143 -0
  48. data/ext/oj/rxclass.h +26 -0
  49. data/ext/oj/saj.c +447 -511
  50. data/ext/oj/saj2.c +348 -0
  51. data/ext/oj/scp.c +91 -138
  52. data/ext/oj/sparse.c +793 -644
  53. data/ext/oj/stream_writer.c +331 -0
  54. data/ext/oj/strict.c +145 -109
  55. data/ext/oj/string_writer.c +493 -0
  56. data/ext/oj/trace.c +72 -0
  57. data/ext/oj/trace.h +28 -0
  58. data/ext/oj/usual.c +1254 -0
  59. data/ext/oj/util.c +136 -0
  60. data/ext/oj/util.h +20 -0
  61. data/ext/oj/val_stack.c +62 -70
  62. data/ext/oj/val_stack.h +95 -129
  63. data/ext/oj/validate.c +51 -0
  64. data/ext/oj/wab.c +622 -0
  65. data/lib/oj/bag.rb +1 -0
  66. data/lib/oj/easy_hash.rb +17 -8
  67. data/lib/oj/error.rb +10 -11
  68. data/lib/oj/json.rb +176 -0
  69. data/lib/oj/mimic.rb +158 -19
  70. data/lib/oj/state.rb +132 -0
  71. data/lib/oj/version.rb +2 -2
  72. data/lib/oj.rb +1 -31
  73. data/pages/Advanced.md +22 -0
  74. data/pages/Compatibility.md +25 -0
  75. data/pages/Custom.md +23 -0
  76. data/pages/Encoding.md +65 -0
  77. data/pages/JsonGem.md +94 -0
  78. data/pages/Modes.md +161 -0
  79. data/pages/Options.md +327 -0
  80. data/pages/Parser.md +309 -0
  81. data/pages/Rails.md +167 -0
  82. data/pages/Security.md +20 -0
  83. data/pages/WAB.md +13 -0
  84. data/test/activerecord/result_test.rb +32 -0
  85. data/test/activesupport4/decoding_test.rb +108 -0
  86. data/test/activesupport4/encoding_test.rb +531 -0
  87. data/test/activesupport4/test_helper.rb +41 -0
  88. data/test/activesupport5/abstract_unit.rb +45 -0
  89. data/test/activesupport5/decoding_test.rb +133 -0
  90. data/test/activesupport5/encoding_test.rb +500 -0
  91. data/test/activesupport5/encoding_test_cases.rb +98 -0
  92. data/test/activesupport5/test_helper.rb +72 -0
  93. data/test/activesupport5/time_zone_test_helpers.rb +39 -0
  94. data/test/activesupport6/abstract_unit.rb +44 -0
  95. data/test/activesupport6/decoding_test.rb +133 -0
  96. data/test/activesupport6/encoding_test.rb +507 -0
  97. data/test/activesupport6/encoding_test_cases.rb +98 -0
  98. data/test/activesupport6/test_common.rb +17 -0
  99. data/test/activesupport6/test_helper.rb +163 -0
  100. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  101. data/test/activesupport7/abstract_unit.rb +49 -0
  102. data/test/activesupport7/decoding_test.rb +125 -0
  103. data/test/activesupport7/encoding_test.rb +486 -0
  104. data/test/activesupport7/encoding_test_cases.rb +104 -0
  105. data/test/activesupport7/time_zone_test_helpers.rb +47 -0
  106. data/test/bar.rb +9 -0
  107. data/test/baz.rb +16 -0
  108. data/test/bug.rb +11 -46
  109. data/test/foo.rb +69 -16
  110. data/test/helper.rb +10 -1
  111. data/test/isolated/shared.rb +12 -8
  112. data/test/isolated/test_mimic_rails_after.rb +3 -3
  113. data/test/isolated/test_mimic_rails_before.rb +3 -3
  114. data/test/json_gem/json_addition_test.rb +216 -0
  115. data/test/json_gem/json_common_interface_test.rb +153 -0
  116. data/test/json_gem/json_encoding_test.rb +107 -0
  117. data/test/json_gem/json_ext_parser_test.rb +20 -0
  118. data/test/json_gem/json_fixtures_test.rb +35 -0
  119. data/test/json_gem/json_generator_test.rb +397 -0
  120. data/test/json_gem/json_generic_object_test.rb +90 -0
  121. data/test/json_gem/json_parser_test.rb +470 -0
  122. data/test/json_gem/json_string_matching_test.rb +42 -0
  123. data/test/json_gem/test_helper.rb +26 -0
  124. data/test/mem.rb +33 -0
  125. data/test/perf.rb +1 -1
  126. data/test/perf_compat.rb +30 -28
  127. data/test/perf_dump.rb +50 -0
  128. data/test/perf_object.rb +1 -1
  129. data/test/perf_once.rb +58 -0
  130. data/test/perf_parser.rb +189 -0
  131. data/test/perf_scp.rb +11 -10
  132. data/test/perf_strict.rb +30 -19
  133. data/test/perf_wab.rb +131 -0
  134. data/test/prec.rb +23 -0
  135. data/test/sample.rb +0 -1
  136. data/test/sample_json.rb +1 -1
  137. data/test/test_compat.rb +219 -102
  138. data/test/test_custom.rb +533 -0
  139. data/test/test_fast.rb +107 -35
  140. data/test/test_file.rb +19 -25
  141. data/test/test_generate.rb +21 -0
  142. data/test/test_hash.rb +11 -1
  143. data/test/test_integer_range.rb +72 -0
  144. data/test/test_null.rb +376 -0
  145. data/test/test_object.rb +357 -70
  146. data/test/test_parser.rb +27 -0
  147. data/test/test_parser_saj.rb +245 -0
  148. data/test/test_parser_usual.rb +217 -0
  149. data/test/test_rails.rb +35 -0
  150. data/test/test_saj.rb +1 -1
  151. data/test/test_scp.rb +39 -2
  152. data/test/test_strict.rb +186 -7
  153. data/test/test_various.rb +160 -774
  154. data/test/test_wab.rb +307 -0
  155. data/test/test_writer.rb +90 -2
  156. data/test/tests.rb +24 -0
  157. data/test/tests_mimic.rb +14 -0
  158. data/test/tests_mimic_addition.rb +7 -0
  159. data/test/zoo.rb +13 -0
  160. metadata +194 -56
  161. data/ext/oj/hash.c +0 -163
  162. data/ext/oj/hash.h +0 -46
  163. data/ext/oj/hash_test.c +0 -512
  164. data/test/activesupport_datetime_test.rb +0 -23
  165. data/test/bug2.rb +0 -10
  166. data/test/bug3.rb +0 -46
  167. data/test/bug_fast.rb +0 -32
  168. data/test/bug_load.rb +0 -24
  169. data/test/crash.rb +0 -111
  170. data/test/curl/curl_oj.rb +0 -46
  171. data/test/curl/get_oj.rb +0 -24
  172. data/test/curl/just_curl.rb +0 -31
  173. data/test/curl/just_oj.rb +0 -51
  174. data/test/example.rb +0 -11
  175. data/test/io.rb +0 -48
  176. data/test/isolated/test_mimic_rails_datetime.rb +0 -27
  177. data/test/mod.rb +0 -16
  178. data/test/rails.rb +0 -50
  179. data/test/russian.rb +0 -18
  180. data/test/struct.rb +0 -29
  181. data/test/test_serializer.rb +0 -59
  182. data/test/write_timebars.rb +0 -31
data/ext/oj/saj2.c ADDED
@@ -0,0 +1,348 @@
1
+ // Copyright (c) 2021, Peter Ohler, All rights reserved.
2
+
3
+ #include "cache.h"
4
+ #include "oj.h"
5
+ #include "parser.h"
6
+
7
+ typedef struct _delegate {
8
+ VALUE handler;
9
+ VALUE * keys;
10
+ VALUE * tail;
11
+ size_t klen;
12
+ struct _cache *str_cache;
13
+ uint8_t cache_str;
14
+ bool cache_keys;
15
+ bool thread_safe;
16
+ } * Delegate;
17
+
18
+ static VALUE get_key(ojParser p) {
19
+ Delegate d = (Delegate)p->ctx;
20
+ const char * key = buf_str(&p->key);
21
+ size_t len = buf_len(&p->key);
22
+ volatile VALUE rkey;
23
+
24
+ if (d->cache_keys) {
25
+ rkey = cache_intern(d->str_cache, key, len);
26
+ } else {
27
+ rkey = rb_utf8_str_new(key, len);
28
+ }
29
+ return rkey;
30
+ }
31
+
32
+ static void push_key(Delegate d, VALUE key) {
33
+ if (d->klen <= (size_t)(d->tail - d->keys)) {
34
+ size_t off = d->tail - d->keys;
35
+
36
+ d->klen += d->klen / 2;
37
+ REALLOC_N(d->keys, VALUE, d->klen);
38
+ d->tail = d->keys + off;
39
+ }
40
+ *d->tail = key;
41
+ d->tail++;
42
+ }
43
+
44
+ static void noop(ojParser p) {
45
+ }
46
+
47
+ static void open_object(ojParser p) {
48
+ rb_funcall(((Delegate)p->ctx)->handler, oj_hash_start_id, 1, Qnil);
49
+ }
50
+
51
+ static void open_object_key(ojParser p) {
52
+ Delegate d = (Delegate)p->ctx;
53
+ volatile VALUE key = get_key(p);
54
+
55
+ push_key(d, key);
56
+ rb_funcall(d->handler, oj_hash_start_id, 1, key);
57
+ }
58
+
59
+ static void open_array(ojParser p) {
60
+ rb_funcall(((Delegate)p->ctx)->handler, oj_array_start_id, 1, Qnil);
61
+ }
62
+
63
+ static void open_array_key(ojParser p) {
64
+ Delegate d = (Delegate)p->ctx;
65
+ volatile VALUE key = get_key(p);
66
+
67
+ push_key(d, key);
68
+ rb_funcall(d->handler, oj_array_start_id, 1, key);
69
+ }
70
+
71
+ static void close_object(ojParser p) {
72
+ Delegate d = (Delegate)p->ctx;
73
+ VALUE key = Qnil;
74
+
75
+ if (OBJECT_FUN == p->stack[p->depth]) {
76
+ d->tail--;
77
+ if (d->tail < d->keys) {
78
+ rb_raise(rb_eIndexError, "accessing key stack");
79
+ }
80
+ key = *d->tail;
81
+ }
82
+ rb_funcall(d->handler, oj_hash_end_id, 1, key);
83
+ }
84
+
85
+ static void close_array(ojParser p) {
86
+ Delegate d = (Delegate)p->ctx;
87
+ VALUE key = Qnil;
88
+
89
+ if (OBJECT_FUN == p->stack[p->depth]) {
90
+ d->tail--;
91
+ if (d->tail < d->keys) {
92
+ rb_raise(rb_eIndexError, "accessing key stack");
93
+ }
94
+ key = *d->tail;
95
+ }
96
+ rb_funcall(d->handler, oj_array_end_id, 1, key);
97
+ }
98
+
99
+ static void add_null(ojParser p) {
100
+ rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qnil, Qnil);
101
+ }
102
+
103
+ static void add_null_key(ojParser p) {
104
+ rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qnil, get_key(p));
105
+ }
106
+
107
+ static void add_true(ojParser p) {
108
+ rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qtrue, Qnil);
109
+ }
110
+
111
+ static void add_true_key(ojParser p) {
112
+ rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qtrue, get_key(p));
113
+ }
114
+
115
+ static void add_false(ojParser p) {
116
+ rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qfalse, Qnil);
117
+ }
118
+
119
+ static void add_false_key(ojParser p) {
120
+ rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, Qfalse, get_key(p));
121
+ }
122
+
123
+ static void add_int(ojParser p) {
124
+ rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, LONG2NUM(p->num.fixnum), Qnil);
125
+ }
126
+
127
+ static void add_int_key(ojParser p) {
128
+ rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, LONG2NUM(p->num.fixnum), get_key(p));
129
+ }
130
+
131
+ static void add_float(ojParser p) {
132
+ rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, rb_float_new(p->num.dub), Qnil);
133
+ }
134
+
135
+ static void add_float_key(ojParser p) {
136
+ rb_funcall(((Delegate)p->ctx)->handler, oj_add_value_id, 2, rb_float_new(p->num.dub), get_key(p));
137
+ }
138
+
139
+ static void add_big(ojParser p) {
140
+ rb_funcall((VALUE)p->ctx,
141
+ oj_add_value_id,
142
+ 2,
143
+ rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
144
+ Qnil);
145
+ }
146
+
147
+ static void add_big_key(ojParser p) {
148
+ rb_funcall((VALUE)p->ctx,
149
+ oj_add_value_id,
150
+ 2,
151
+ rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
152
+ get_key(p));
153
+ }
154
+
155
+ static void add_str(ojParser p) {
156
+ Delegate d = (Delegate)p->ctx;
157
+ volatile VALUE rstr;
158
+ const char * str = buf_str(&p->buf);
159
+ size_t len = buf_len(&p->buf);
160
+
161
+ if (d->cache_str < len) {
162
+ rstr = cache_intern(d->str_cache, str, len);
163
+ } else {
164
+ rstr = rb_utf8_str_new(str, len);
165
+ }
166
+ rb_funcall(d->handler, oj_add_value_id, 2, rstr, Qnil);
167
+ }
168
+
169
+ static void add_str_key(ojParser p) {
170
+ Delegate d = (Delegate)p->ctx;
171
+ volatile VALUE rstr;
172
+ const char * str = buf_str(&p->buf);
173
+ size_t len = buf_len(&p->buf);
174
+
175
+ if (d->cache_str < len) {
176
+ rstr = cache_intern(d->str_cache, str, len);
177
+ } else {
178
+ rstr = rb_utf8_str_new(str, len);
179
+ }
180
+ rb_funcall(d->handler, oj_add_value_id, 2, rstr, get_key(p));
181
+ }
182
+
183
+ static void reset(ojParser p) {
184
+ Funcs end = p->funcs + 3;
185
+ Funcs f;
186
+
187
+ for (f = p->funcs; f < end; f++) {
188
+ f->add_null = noop;
189
+ f->add_true = noop;
190
+ f->add_false = noop;
191
+ f->add_int = noop;
192
+ f->add_float = noop;
193
+ f->add_big = noop;
194
+ f->add_str = noop;
195
+ f->open_array = noop;
196
+ f->close_array = noop;
197
+ f->open_object = noop;
198
+ f->close_object = noop;
199
+ }
200
+ }
201
+
202
+ static VALUE option(ojParser p, const char *key, VALUE value) {
203
+ Delegate d = (Delegate)p->ctx;
204
+
205
+ if (0 == strcmp(key, "handler")) {
206
+ return d->handler;
207
+ }
208
+ if (0 == strcmp(key, "handler=")) {
209
+ d->tail = d->keys;
210
+ d->handler = value;
211
+ reset(p);
212
+ if (rb_respond_to(value, oj_hash_start_id)) {
213
+ p->funcs[TOP_FUN].open_object = open_object;
214
+ p->funcs[ARRAY_FUN].open_object = open_object;
215
+ p->funcs[OBJECT_FUN].open_object = open_object_key;
216
+ }
217
+ if (rb_respond_to(value, oj_array_start_id)) {
218
+ p->funcs[TOP_FUN].open_array = open_array;
219
+ p->funcs[ARRAY_FUN].open_array = open_array;
220
+ p->funcs[OBJECT_FUN].open_array = open_array_key;
221
+ }
222
+ if (rb_respond_to(value, oj_hash_end_id)) {
223
+ p->funcs[TOP_FUN].close_object = close_object;
224
+ p->funcs[ARRAY_FUN].close_object = close_object;
225
+ p->funcs[OBJECT_FUN].close_object = close_object;
226
+ }
227
+ if (rb_respond_to(value, oj_array_end_id)) {
228
+ p->funcs[TOP_FUN].close_array = close_array;
229
+ p->funcs[ARRAY_FUN].close_array = close_array;
230
+ p->funcs[OBJECT_FUN].close_array = close_array;
231
+ }
232
+ if (rb_respond_to(value, oj_add_value_id)) {
233
+ p->funcs[TOP_FUN].add_null = add_null;
234
+ p->funcs[ARRAY_FUN].add_null = add_null;
235
+ p->funcs[OBJECT_FUN].add_null = add_null_key;
236
+
237
+ p->funcs[TOP_FUN].add_true = add_true;
238
+ p->funcs[ARRAY_FUN].add_true = add_true;
239
+ p->funcs[OBJECT_FUN].add_true = add_true_key;
240
+
241
+ p->funcs[TOP_FUN].add_false = add_false;
242
+ p->funcs[ARRAY_FUN].add_false = add_false;
243
+ p->funcs[OBJECT_FUN].add_false = add_false_key;
244
+
245
+ p->funcs[TOP_FUN].add_int = add_int;
246
+ p->funcs[ARRAY_FUN].add_int = add_int;
247
+ p->funcs[OBJECT_FUN].add_int = add_int_key;
248
+
249
+ p->funcs[TOP_FUN].add_float = add_float;
250
+ p->funcs[ARRAY_FUN].add_float = add_float;
251
+ p->funcs[OBJECT_FUN].add_float = add_float_key;
252
+
253
+ p->funcs[TOP_FUN].add_big = add_big;
254
+ p->funcs[ARRAY_FUN].add_big = add_big;
255
+ p->funcs[OBJECT_FUN].add_big = add_big_key;
256
+
257
+ p->funcs[TOP_FUN].add_str = add_str;
258
+ p->funcs[ARRAY_FUN].add_str = add_str;
259
+ p->funcs[OBJECT_FUN].add_str = add_str_key;
260
+ }
261
+ return Qnil;
262
+ }
263
+ if (0 == strcmp(key, "cache_keys")) {
264
+ return d->cache_keys ? Qtrue : Qfalse;
265
+ }
266
+ if (0 == strcmp(key, "cache_keys=")) {
267
+ d->cache_keys = (Qtrue == value);
268
+
269
+ return d->cache_keys ? Qtrue : Qfalse;
270
+ }
271
+ if (0 == strcmp(key, "cache_strings")) {
272
+ return INT2NUM((int)d->cache_str);
273
+ }
274
+ if (0 == strcmp(key, "cache_strings=")) {
275
+ int limit = NUM2INT(value);
276
+
277
+ if (CACHE_MAX_KEY < limit) {
278
+ limit = CACHE_MAX_KEY;
279
+ } else if (limit < 0) {
280
+ limit = 0;
281
+ }
282
+ d->cache_str = limit;
283
+
284
+ return INT2NUM((int)d->cache_str);
285
+ }
286
+ rb_raise(rb_eArgError, "%s is not an option for the SAJ (Simple API for JSON) delegate", key);
287
+
288
+ return Qnil; // Never reached due to the raise but required by the compiler.
289
+ }
290
+
291
+ static VALUE result(ojParser p) {
292
+ return Qnil;
293
+ }
294
+
295
+ static void start(ojParser p) {
296
+ Delegate d = (Delegate)p->ctx;
297
+
298
+ d->tail = d->keys;
299
+ }
300
+
301
+ static void dfree(ojParser p) {
302
+ Delegate d = (Delegate)p->ctx;
303
+
304
+ if (NULL != d->keys) {
305
+ xfree(d->keys);
306
+ }
307
+ cache_free(d->str_cache);
308
+ xfree(p->ctx);
309
+ }
310
+
311
+ static void mark(ojParser p) {
312
+ if (NULL == p->ctx) {
313
+ return;
314
+ }
315
+ Delegate d = (Delegate)p->ctx;
316
+ VALUE *kp;
317
+
318
+ cache_mark(d->str_cache);
319
+ if (Qnil != d->handler) {
320
+ rb_gc_mark(d->handler);
321
+ }
322
+ if (!d->cache_keys) {
323
+ for (kp = d->keys; kp < d->tail; kp++) {
324
+ rb_gc_mark(*kp);
325
+ }
326
+ }
327
+ }
328
+
329
+ static VALUE form_str(const char *str, size_t len) {
330
+ return rb_str_freeze(rb_utf8_str_new(str, len));
331
+ }
332
+
333
+ void oj_set_parser_saj(ojParser p) {
334
+ Delegate d = ALLOC(struct _delegate);
335
+
336
+ d->klen = 256;
337
+ d->keys = ALLOC_N(VALUE, d->klen);
338
+ d->tail = d->keys;
339
+ d->str_cache = cache_create(0, form_str, true, false);
340
+
341
+ p->ctx = (void *)d;
342
+ reset(p);
343
+ p->option = option;
344
+ p->result = result;
345
+ p->free = dfree;
346
+ p->mark = mark;
347
+ p->start = start;
348
+ }
data/ext/oj/scp.c CHANGED
@@ -1,67 +1,35 @@
1
- /* scp.c
2
- * Copyright (c) 2012, Peter Ohler
3
- * All rights reserved.
4
- *
5
- * Redistribution and use in source and binary forms, with or without
6
- * modification, are permitted provided that the following conditions are met:
7
- *
8
- * - Redistributions of source code must retain the above copyright notice, this
9
- * list of conditions and the following disclaimer.
10
- *
11
- * - Redistributions in binary form must reproduce the above copyright notice,
12
- * this list of conditions and the following disclaimer in the documentation
13
- * and/or other materials provided with the distribution.
14
- *
15
- * - Neither the name of Peter Ohler nor the names of its contributors may be
16
- * used to endorse or promote products derived from this software without
17
- * specific prior written permission.
18
- *
19
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
- */
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.
30
3
 
31
- #include <stdlib.h>
4
+ #include <math.h>
32
5
  #include <stdio.h>
6
+ #include <stdlib.h>
33
7
  #include <string.h>
34
- #include <math.h>
35
8
  #include <sys/types.h>
36
9
  #include <unistd.h>
37
10
 
11
+ #include "encode.h"
12
+ #include "intern.h"
38
13
  #include "oj.h"
39
14
  #include "parse.h"
40
- #include "encode.h"
41
15
 
42
- static VALUE
43
- noop_start(ParseInfo pi) {
16
+ static VALUE noop_start(ParseInfo pi) {
44
17
  return Qnil;
45
18
  }
46
19
 
47
- static void
48
- noop_end(ParseInfo pi) {
20
+ static void noop_end(ParseInfo pi) {
49
21
  }
50
22
 
51
- static void
52
- noop_add_value(ParseInfo pi, VALUE val) {
23
+ static void noop_add_value(ParseInfo pi, VALUE val) {
53
24
  }
54
25
 
55
- static void
56
- noop_add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
26
+ static void noop_add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
57
27
  }
58
28
 
59
- static void
60
- noop_add_num(ParseInfo pi, NumInfo ni) {
29
+ static void noop_add_num(ParseInfo pi, NumInfo ni) {
61
30
  }
62
31
 
63
- static VALUE
64
- noop_hash_key(struct _ParseInfo *pi, const char *key, size_t klen) {
32
+ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
65
33
  return Qundef;
66
34
  }
67
35
 
@@ -69,178 +37,163 @@ static void
69
37
  noop_hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
70
38
  }
71
39
 
72
- static void
73
- noop_hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
40
+ static void noop_hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
74
41
  }
75
42
 
76
- static void
77
- noop_hash_set_value(ParseInfo pi, Val kval, VALUE value) {
43
+ static void noop_hash_set_value(ParseInfo pi, Val kval, VALUE value) {
78
44
  }
79
45
 
80
- static void
81
- noop_array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
46
+ static void noop_array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
82
47
  }
83
48
 
84
- static void
85
- noop_array_append_num(ParseInfo pi, NumInfo ni) {
49
+ static void noop_array_append_num(ParseInfo pi, NumInfo ni) {
86
50
  }
87
51
 
88
- static void
89
- noop_array_append_value(ParseInfo pi, VALUE value) {
52
+ static void noop_array_append_value(ParseInfo pi, VALUE value) {
90
53
  }
91
54
 
92
- static void
93
- add_value(ParseInfo pi, VALUE val) {
55
+ static void add_value(ParseInfo pi, VALUE val) {
94
56
  rb_funcall(pi->handler, oj_add_value_id, 1, val);
95
57
  }
96
58
 
97
- static void
98
- add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
99
- volatile VALUE rstr = rb_str_new(str, len);
59
+ static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
60
+ volatile VALUE rstr = rb_str_new(str, len);
100
61
 
101
62
  rstr = oj_encode(rstr);
102
63
  rb_funcall(pi->handler, oj_add_value_id, 1, rstr);
103
64
  }
104
65
 
105
- static void
106
- add_num(ParseInfo pi, NumInfo ni) {
66
+ static void add_num(ParseInfo pi, NumInfo ni) {
107
67
  rb_funcall(pi->handler, oj_add_value_id, 1, oj_num_as_value(ni));
108
68
  }
109
69
 
110
- static VALUE
111
- start_hash(ParseInfo pi) {
70
+ static VALUE start_hash(ParseInfo pi) {
112
71
  return rb_funcall(pi->handler, oj_hash_start_id, 0);
113
72
  }
114
73
 
115
- static void
116
- end_hash(ParseInfo pi) {
74
+ static void end_hash(ParseInfo pi) {
117
75
  rb_funcall(pi->handler, oj_hash_end_id, 0);
118
76
  }
119
77
 
120
- static VALUE
121
- start_array(ParseInfo pi) {
78
+ static VALUE start_array(ParseInfo pi) {
122
79
  return rb_funcall(pi->handler, oj_array_start_id, 0);
123
80
  }
124
81
 
125
- static void
126
- end_array(ParseInfo pi) {
82
+ static void end_array(ParseInfo pi) {
127
83
  rb_funcall(pi->handler, oj_array_end_id, 0);
128
84
  }
129
85
 
130
- static VALUE
131
- calc_hash_key(ParseInfo pi, Val kval) {
132
- volatile VALUE rkey = kval->key_val;
133
-
134
- if (Qundef == rkey) {
135
- rkey = rb_str_new(kval->key, kval->klen);
136
- rkey = oj_encode(rkey);
137
- if (Yes == pi->options.sym_key) {
138
- rkey = rb_str_intern(rkey);
139
- }
140
- }
141
- return rkey;
142
- }
143
-
144
- static VALUE
145
- hash_key(struct _ParseInfo *pi, const char *key, size_t klen) {
86
+ static VALUE hash_key(ParseInfo pi, const char *key, size_t klen) {
146
87
  return rb_funcall(pi->handler, oj_hash_key_id, 1, rb_str_new(key, klen));
147
88
  }
148
89
 
149
- static void
150
- hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
151
- volatile VALUE rstr = rb_str_new(str, len);
90
+ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
91
+ volatile VALUE rstr = rb_str_new(str, len);
152
92
 
153
93
  rstr = oj_encode(rstr);
154
- rb_funcall(pi->handler, oj_hash_set_id, 3, stack_peek(&pi->stack)->val, calc_hash_key(pi, kval), rstr);
94
+ rb_funcall(pi->handler,
95
+ oj_hash_set_id,
96
+ 3,
97
+ stack_peek(&pi->stack)->val,
98
+ oj_calc_hash_key(pi, kval),
99
+ rstr);
155
100
  }
156
101
 
157
- static void
158
- hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
159
- rb_funcall(pi->handler, oj_hash_set_id, 3, stack_peek(&pi->stack)->val, calc_hash_key(pi, kval), oj_num_as_value(ni));
102
+ static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
103
+ rb_funcall(pi->handler,
104
+ oj_hash_set_id,
105
+ 3,
106
+ stack_peek(&pi->stack)->val,
107
+ oj_calc_hash_key(pi, kval),
108
+ oj_num_as_value(ni));
160
109
  }
161
110
 
162
- static void
163
- hash_set_value(ParseInfo pi, Val kval, VALUE value) {
164
- rb_funcall(pi->handler, oj_hash_set_id, 3, stack_peek(&pi->stack)->val, calc_hash_key(pi, kval), value);
111
+ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
112
+ rb_funcall(pi->handler,
113
+ oj_hash_set_id,
114
+ 3,
115
+ stack_peek(&pi->stack)->val,
116
+ oj_calc_hash_key(pi, kval),
117
+ value);
165
118
  }
166
119
 
167
- static void
168
- array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
169
- volatile VALUE rstr = rb_str_new(str, len);
120
+ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
121
+ volatile VALUE rstr = rb_str_new(str, len);
170
122
 
171
123
  rstr = oj_encode(rstr);
172
124
  rb_funcall(pi->handler, oj_array_append_id, 2, stack_peek(&pi->stack)->val, rstr);
173
125
  }
174
126
 
175
- static void
176
- array_append_num(ParseInfo pi, NumInfo ni) {
127
+ static void array_append_num(ParseInfo pi, NumInfo ni) {
177
128
  rb_funcall(pi->handler, oj_array_append_id, 2, stack_peek(&pi->stack)->val, oj_num_as_value(ni));
178
129
  }
179
130
 
180
- static void
181
- array_append_value(ParseInfo pi, VALUE value) {
131
+ static void array_append_value(ParseInfo pi, VALUE value) {
182
132
  rb_funcall(pi->handler, oj_array_append_id, 2, stack_peek(&pi->stack)->val, value);
183
133
  }
184
134
 
185
135
  VALUE
186
136
  oj_sc_parse(int argc, VALUE *argv, VALUE self) {
187
- struct _ParseInfo pi;
188
- VALUE input = argv[1];
137
+ struct _parseInfo pi;
138
+ VALUE input = argv[1];
189
139
 
140
+ parse_info_init(&pi);
190
141
  pi.err_class = Qnil;
191
- pi.options = oj_default_options;
142
+ pi.max_depth = 0;
143
+ pi.options = oj_default_options;
192
144
  if (3 == argc) {
193
- oj_parse_options(argv[2], &pi.options);
145
+ oj_parse_options(argv[2], &pi.options);
194
146
  }
195
147
  if (rb_block_given_p()) {
196
- pi.proc = Qnil;
148
+ pi.proc = Qnil;
197
149
  } else {
198
- pi.proc = Qundef;
150
+ pi.proc = Qundef;
199
151
  }
200
152
  pi.handler = *argv;
201
153
 
202
- pi.start_hash = rb_respond_to(pi.handler, oj_hash_start_id) ? start_hash : noop_start;
203
- pi.end_hash = rb_respond_to(pi.handler, oj_hash_end_id) ? end_hash : noop_end;
204
- pi.hash_key = rb_respond_to(pi.handler, oj_hash_key_id) ? hash_key : noop_hash_key;
154
+ pi.start_hash = rb_respond_to(pi.handler, oj_hash_start_id) ? start_hash : noop_start;
155
+ pi.end_hash = rb_respond_to(pi.handler, oj_hash_end_id) ? end_hash : noop_end;
156
+ pi.hash_key = rb_respond_to(pi.handler, oj_hash_key_id) ? hash_key : noop_hash_key;
205
157
  pi.start_array = rb_respond_to(pi.handler, oj_array_start_id) ? start_array : noop_start;
206
- pi.end_array = rb_respond_to(pi.handler, oj_array_end_id) ? end_array : noop_end;
158
+ pi.end_array = rb_respond_to(pi.handler, oj_array_end_id) ? end_array : noop_end;
207
159
  if (rb_respond_to(pi.handler, oj_hash_set_id)) {
208
- pi.hash_set_value = hash_set_value;
209
- pi.hash_set_cstr = hash_set_cstr;
210
- pi.hash_set_num = hash_set_num;
211
- pi.expect_value = 1;
160
+ pi.hash_set_value = hash_set_value;
161
+ pi.hash_set_cstr = hash_set_cstr;
162
+ pi.hash_set_num = hash_set_num;
163
+ pi.expect_value = 1;
212
164
  } else {
213
- pi.hash_set_value = noop_hash_set_value;
214
- pi.hash_set_cstr = noop_hash_set_cstr;
215
- pi.hash_set_num = noop_hash_set_num;
216
- pi.expect_value = 0;
165
+ pi.hash_set_value = noop_hash_set_value;
166
+ pi.hash_set_cstr = noop_hash_set_cstr;
167
+ pi.hash_set_num = noop_hash_set_num;
168
+ pi.expect_value = 0;
217
169
  }
218
170
  if (rb_respond_to(pi.handler, oj_array_append_id)) {
219
- pi.array_append_value = array_append_value;
220
- pi.array_append_cstr = array_append_cstr;
221
- pi.array_append_num = array_append_num;
222
- pi.expect_value = 1;
171
+ pi.array_append_value = array_append_value;
172
+ pi.array_append_cstr = array_append_cstr;
173
+ pi.array_append_num = array_append_num;
174
+ pi.expect_value = 1;
223
175
  } else {
224
- pi.array_append_value = noop_array_append_value;
225
- pi.array_append_cstr = noop_array_append_cstr;
226
- pi.array_append_num = noop_array_append_num;
227
- pi.expect_value = 0;
176
+ pi.array_append_value = noop_array_append_value;
177
+ pi.array_append_cstr = noop_array_append_cstr;
178
+ pi.array_append_num = noop_array_append_num;
179
+ pi.expect_value = 0;
228
180
  }
229
181
  if (rb_respond_to(pi.handler, oj_add_value_id)) {
230
- pi.add_cstr = add_cstr;
231
- pi.add_num = add_num;
232
- pi.add_value = add_value;
233
- pi.expect_value = 1;
182
+ pi.add_cstr = add_cstr;
183
+ pi.add_num = add_num;
184
+ pi.add_value = add_value;
185
+ pi.expect_value = 1;
234
186
  } else {
235
- pi.add_cstr = noop_add_cstr;
236
- pi.add_num = noop_add_num;
237
- pi.add_value = noop_add_value;
238
- pi.expect_value = 0;
187
+ pi.add_cstr = noop_add_cstr;
188
+ pi.add_num = noop_add_num;
189
+ pi.add_value = noop_add_value;
190
+ pi.expect_value = 0;
239
191
  }
192
+ pi.has_callbacks = true;
240
193
 
241
194
  if (T_STRING == rb_type(input)) {
242
- return oj_pi_parse(argc - 1, argv + 1, &pi, 0, 0, 1);
195
+ return oj_pi_parse(argc - 1, argv + 1, &pi, 0, 0, 1);
243
196
  } else {
244
- return oj_pi_sparse(argc - 1, argv + 1, &pi, 0);
197
+ return oj_pi_sparse(argc - 1, argv + 1, &pi, 0);
245
198
  }
246
199
  }