oj 2.18.3 → 3.13.14

Sign up to get free protection for your applications and to get access to all the features.
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
  }