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
@@ -0,0 +1,410 @@
1
+ // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
+
4
+ #include <errno.h>
5
+ #include <math.h>
6
+ #include <stdio.h>
7
+ #include <stdlib.h>
8
+ #include <string.h>
9
+ #include <time.h>
10
+ #include <unistd.h>
11
+
12
+ #include "dump.h"
13
+ #include "trace.h"
14
+
15
+ // Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
16
+ #define OJ_INFINITY (1.0 / 0.0)
17
+
18
+ typedef unsigned long ulong;
19
+
20
+ static const char inf_val[] = INF_VAL;
21
+ static const char ninf_val[] = NINF_VAL;
22
+ static const char nan_val[] = NAN_VAL;
23
+
24
+ static void raise_strict(VALUE obj) {
25
+ rb_raise(rb_eTypeError,
26
+ "Failed to dump %s Object to JSON in strict mode.\n",
27
+ rb_class2name(rb_obj_class(obj)));
28
+ }
29
+
30
+ // Removed dependencies on math due to problems with CentOS 5.4.
31
+ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
32
+ char buf[64];
33
+ char * b;
34
+ double d = rb_num2dbl(obj);
35
+ int cnt = 0;
36
+
37
+ if (0.0 == d) {
38
+ b = buf;
39
+ *b++ = '0';
40
+ *b++ = '.';
41
+ *b++ = '0';
42
+ *b++ = '\0';
43
+ cnt = 3;
44
+ } else {
45
+ NanDump nd = out->opts->dump_opts.nan_dump;
46
+
47
+ if (AutoNan == nd) {
48
+ nd = RaiseNan;
49
+ }
50
+ if (OJ_INFINITY == d) {
51
+ switch (nd) {
52
+ case RaiseNan:
53
+ case WordNan: raise_strict(obj); break;
54
+ case NullNan:
55
+ strcpy(buf, "null");
56
+ cnt = 4;
57
+ break;
58
+ case HugeNan:
59
+ default:
60
+ strcpy(buf, inf_val);
61
+ cnt = sizeof(inf_val) - 1;
62
+ break;
63
+ }
64
+ } else if (-OJ_INFINITY == d) {
65
+ switch (nd) {
66
+ case RaiseNan:
67
+ case WordNan: raise_strict(obj); break;
68
+ case NullNan:
69
+ strcpy(buf, "null");
70
+ cnt = 4;
71
+ break;
72
+ case HugeNan:
73
+ default:
74
+ strcpy(buf, ninf_val);
75
+ cnt = sizeof(ninf_val) - 1;
76
+ break;
77
+ }
78
+ } else if (isnan(d)) {
79
+ switch (nd) {
80
+ case RaiseNan:
81
+ case WordNan: raise_strict(obj); break;
82
+ case NullNan:
83
+ strcpy(buf, "null");
84
+ cnt = 4;
85
+ break;
86
+ case HugeNan:
87
+ default:
88
+ strcpy(buf, nan_val);
89
+ cnt = sizeof(nan_val) - 1;
90
+ break;
91
+ }
92
+ } else if (d == (double)(long long int)d) {
93
+ cnt = snprintf(buf, sizeof(buf), "%.1f", d);
94
+ } else if (0 == out->opts->float_prec) {
95
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
96
+
97
+ cnt = (int)RSTRING_LEN(rstr);
98
+ if ((int)sizeof(buf) <= cnt) {
99
+ cnt = sizeof(buf) - 1;
100
+ }
101
+ memcpy(buf, RSTRING_PTR(rstr), cnt);
102
+ buf[cnt] = '\0';
103
+ } else {
104
+ cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
105
+ }
106
+ }
107
+ assure_size(out, cnt);
108
+ APPEND_CHARS(out->cur, buf, cnt);
109
+ *out->cur = '\0';
110
+ }
111
+
112
+ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
113
+ size_t size;
114
+ int i, cnt;
115
+ int d2 = depth + 1;
116
+
117
+ if (Yes == out->opts->circular) {
118
+ if (0 > oj_check_circular(a, out)) {
119
+ oj_dump_nil(Qnil, 0, out, false);
120
+ return;
121
+ }
122
+ }
123
+ cnt = (int)RARRAY_LEN(a);
124
+ *out->cur++ = '[';
125
+ size = 2;
126
+ assure_size(out, size);
127
+ if (0 == cnt) {
128
+ *out->cur++ = ']';
129
+ } else {
130
+ if (out->opts->dump_opts.use) {
131
+ size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
132
+ } else {
133
+ size = d2 * out->indent + 2;
134
+ }
135
+ assure_size(out, size * cnt);
136
+ cnt--;
137
+ for (i = 0; i <= cnt; i++) {
138
+ if (out->opts->dump_opts.use) {
139
+ if (0 < out->opts->dump_opts.array_size) {
140
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
141
+ }
142
+ if (0 < out->opts->dump_opts.indent_size) {
143
+ int i;
144
+ for (i = d2; 0 < i; i--) {
145
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
146
+ }
147
+ }
148
+ } else {
149
+ fill_indent(out, d2);
150
+ }
151
+ if (NullMode == out->opts->mode) {
152
+ oj_dump_null_val(RARRAY_AREF(a, i), d2, out);
153
+ } else {
154
+ oj_dump_strict_val(RARRAY_AREF(a, i), d2, out);
155
+ }
156
+ if (i < cnt) {
157
+ *out->cur++ = ',';
158
+ }
159
+ }
160
+ size = depth * out->indent + 1;
161
+ assure_size(out, size);
162
+ if (out->opts->dump_opts.use) {
163
+ // printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size,
164
+ // out->opts->dump_opts->indent);
165
+ if (0 < out->opts->dump_opts.array_size) {
166
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
167
+ }
168
+ if (0 < out->opts->dump_opts.indent_size) {
169
+ int i;
170
+
171
+ for (i = depth; 0 < i; i--) {
172
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
173
+ }
174
+ }
175
+ } else {
176
+ fill_indent(out, depth);
177
+ }
178
+ *out->cur++ = ']';
179
+ }
180
+ *out->cur = '\0';
181
+ }
182
+
183
+ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
184
+ Out out = (Out)ov;
185
+ int depth = out->depth;
186
+ long size;
187
+ int rtype = rb_type(key);
188
+
189
+ if (rtype != T_STRING && rtype != T_SYMBOL) {
190
+ rb_raise(rb_eTypeError,
191
+ "In :strict and :null mode all Hash keys must be Strings or Symbols, not %s.\n",
192
+ rb_class2name(rb_obj_class(key)));
193
+ }
194
+ if (out->omit_nil && Qnil == value) {
195
+ return ST_CONTINUE;
196
+ }
197
+ if (!out->opts->dump_opts.use) {
198
+ size = depth * out->indent + 1;
199
+ assure_size(out, size);
200
+ fill_indent(out, depth);
201
+ if (rtype == T_STRING) {
202
+ oj_dump_str(key, 0, out, false);
203
+ } else {
204
+ oj_dump_sym(key, 0, out, false);
205
+ }
206
+ *out->cur++ = ':';
207
+ } else {
208
+ size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
209
+ assure_size(out, size);
210
+ if (0 < out->opts->dump_opts.hash_size) {
211
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
212
+ }
213
+ if (0 < out->opts->dump_opts.indent_size) {
214
+ int i;
215
+ for (i = depth; 0 < i; i--) {
216
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
217
+ }
218
+ }
219
+ if (rtype == T_STRING) {
220
+ oj_dump_str(key, 0, out, false);
221
+ } else {
222
+ oj_dump_sym(key, 0, out, false);
223
+ }
224
+ size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
225
+ assure_size(out, size);
226
+ if (0 < out->opts->dump_opts.before_size) {
227
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
228
+ }
229
+ *out->cur++ = ':';
230
+ if (0 < out->opts->dump_opts.after_size) {
231
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
232
+ }
233
+ }
234
+ if (NullMode == out->opts->mode) {
235
+ oj_dump_null_val(value, depth, out);
236
+ } else {
237
+ oj_dump_strict_val(value, depth, out);
238
+ }
239
+ out->depth = depth;
240
+ *out->cur++ = ',';
241
+
242
+ return ST_CONTINUE;
243
+ }
244
+
245
+ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
246
+ int cnt;
247
+ size_t size;
248
+
249
+ if (Yes == out->opts->circular) {
250
+ if (0 > oj_check_circular(obj, out)) {
251
+ oj_dump_nil(Qnil, 0, out, false);
252
+ return;
253
+ }
254
+ }
255
+ cnt = (int)RHASH_SIZE(obj);
256
+ size = depth * out->indent + 2;
257
+ assure_size(out, 2);
258
+ *out->cur++ = '{';
259
+ if (0 == cnt) {
260
+ *out->cur++ = '}';
261
+ } else {
262
+ out->depth = depth + 1;
263
+ rb_hash_foreach(obj, hash_cb, (VALUE)out);
264
+ if (',' == *(out->cur - 1)) {
265
+ out->cur--; // backup to overwrite last comma
266
+ }
267
+ if (!out->opts->dump_opts.use) {
268
+ assure_size(out, size);
269
+ fill_indent(out, depth);
270
+ } else {
271
+ size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
272
+ assure_size(out, size);
273
+ if (0 < out->opts->dump_opts.hash_size) {
274
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
275
+ }
276
+ if (0 < out->opts->dump_opts.indent_size) {
277
+ int i;
278
+
279
+ for (i = depth; 0 < i; i--) {
280
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
281
+ }
282
+ }
283
+ }
284
+ *out->cur++ = '}';
285
+ }
286
+ *out->cur = '\0';
287
+ }
288
+
289
+ static void dump_data_strict(VALUE obj, int depth, Out out, bool as_ok) {
290
+ VALUE clas = rb_obj_class(obj);
291
+
292
+ if (oj_bigdecimal_class == clas) {
293
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
294
+
295
+ oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
296
+ } else {
297
+ raise_strict(obj);
298
+ }
299
+ }
300
+
301
+ static void dump_data_null(VALUE obj, int depth, Out out, bool as_ok) {
302
+ VALUE clas = rb_obj_class(obj);
303
+
304
+ if (oj_bigdecimal_class == clas) {
305
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
306
+
307
+ oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
308
+ } else {
309
+ oj_dump_nil(Qnil, depth, out, false);
310
+ }
311
+ }
312
+
313
+ static DumpFunc strict_funcs[] = {
314
+ NULL, // RUBY_T_NONE = 0x00,
315
+ dump_data_strict, // RUBY_T_OBJECT = 0x01,
316
+ NULL, // RUBY_T_CLASS = 0x02,
317
+ NULL, // RUBY_T_MODULE = 0x03,
318
+ dump_float, // RUBY_T_FLOAT = 0x04,
319
+ oj_dump_str, // RUBY_T_STRING = 0x05,
320
+ NULL, // RUBY_T_REGEXP = 0x06,
321
+ dump_array, // RUBY_T_ARRAY = 0x07,
322
+ dump_hash, // RUBY_T_HASH = 0x08,
323
+ NULL, // RUBY_T_STRUCT = 0x09,
324
+ oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
325
+ NULL, // RUBY_T_FILE = 0x0b,
326
+ dump_data_strict, // RUBY_T_DATA = 0x0c,
327
+ NULL, // RUBY_T_MATCH = 0x0d,
328
+ NULL, // RUBY_T_COMPLEX = 0x0e,
329
+ NULL, // RUBY_T_RATIONAL = 0x0f,
330
+ NULL, // 0x10
331
+ oj_dump_nil, // RUBY_T_NIL = 0x11,
332
+ oj_dump_true, // RUBY_T_TRUE = 0x12,
333
+ oj_dump_false, // RUBY_T_FALSE = 0x13,
334
+ oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
335
+ oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
336
+ };
337
+
338
+ void oj_dump_strict_val(VALUE obj, int depth, Out out) {
339
+ int type = rb_type(obj);
340
+
341
+ if (Yes == out->opts->trace) {
342
+ oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
343
+ }
344
+ if (MAX_DEPTH < depth) {
345
+ rb_raise(rb_eNoMemError, "Too deeply nested.\n");
346
+ }
347
+ if (0 < type && type <= RUBY_T_FIXNUM) {
348
+ DumpFunc f = strict_funcs[type];
349
+
350
+ if (NULL != f) {
351
+ f(obj, depth, out, false);
352
+ if (Yes == out->opts->trace) {
353
+ oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
354
+ }
355
+ return;
356
+ }
357
+ }
358
+ raise_strict(obj);
359
+ }
360
+
361
+ static DumpFunc null_funcs[] = {
362
+ NULL, // RUBY_T_NONE = 0x00,
363
+ dump_data_null, // RUBY_T_OBJECT = 0x01,
364
+ NULL, // RUBY_T_CLASS = 0x02,
365
+ NULL, // RUBY_T_MODULE = 0x03,
366
+ dump_float, // RUBY_T_FLOAT = 0x04,
367
+ oj_dump_str, // RUBY_T_STRING = 0x05,
368
+ NULL, // RUBY_T_REGEXP = 0x06,
369
+ dump_array, // RUBY_T_ARRAY = 0x07,
370
+ dump_hash, // RUBY_T_HASH = 0x08,
371
+ NULL, // RUBY_T_STRUCT = 0x09,
372
+ oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
373
+ NULL, // RUBY_T_FILE = 0x0b,
374
+ dump_data_null, // RUBY_T_DATA = 0x0c,
375
+ NULL, // RUBY_T_MATCH = 0x0d,
376
+ NULL, // RUBY_T_COMPLEX = 0x0e,
377
+ NULL, // RUBY_T_RATIONAL = 0x0f,
378
+ NULL, // 0x10
379
+ oj_dump_nil, // RUBY_T_NIL = 0x11,
380
+ oj_dump_true, // RUBY_T_TRUE = 0x12,
381
+ oj_dump_false, // RUBY_T_FALSE = 0x13,
382
+ oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
383
+ oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
384
+ };
385
+
386
+ void oj_dump_null_val(VALUE obj, int depth, Out out) {
387
+ int type = rb_type(obj);
388
+
389
+ if (Yes == out->opts->trace) {
390
+ oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
391
+ }
392
+ if (MAX_DEPTH < depth) {
393
+ rb_raise(rb_eNoMemError, "Too deeply nested.\n");
394
+ }
395
+ if (0 < type && type <= RUBY_T_FIXNUM) {
396
+ DumpFunc f = null_funcs[type];
397
+
398
+ if (NULL != f) {
399
+ f(obj, depth, out, false);
400
+ if (Yes == out->opts->trace) {
401
+ oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
402
+ }
403
+ return;
404
+ }
405
+ }
406
+ oj_dump_nil(Qnil, depth, out, false);
407
+ if (Yes == out->opts->trace) {
408
+ oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
409
+ }
410
+ }
data/ext/oj/encode.h CHANGED
@@ -1,51 +1,16 @@
1
- /* encode.h
2
- * Copyright (c) 2011, 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) 2011 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
30
3
 
31
- #ifndef __OJ_ENCODE_H__
32
- #define __OJ_ENCODE_H__
4
+ #ifndef OJ_ENCODE_H
5
+ #define OJ_ENCODE_H
33
6
 
7
+ #include "oj.h"
34
8
  #include "ruby.h"
35
- #if HAS_ENCODING_SUPPORT
36
9
  #include "ruby/encoding.h"
37
- #endif
38
10
 
39
- static inline VALUE
40
- oj_encode(VALUE rstr) {
41
- #if HAS_ENCODING_SUPPORT
11
+ static inline VALUE oj_encode(VALUE rstr) {
42
12
  rb_enc_associate(rstr, oj_utf8_encoding);
43
- #else
44
- if (Qnil != oj_utf8_encoding) {
45
- rstr = rb_funcall(oj_utf8_encoding, oj_iconv_id, 1, rstr);
46
- }
47
- #endif
48
13
  return rstr;
49
14
  }
50
15
 
51
- #endif /* __OJ_ENCODE_H__ */
16
+ #endif /* OJ_ENCODE_H */
data/ext/oj/encoder.c ADDED
@@ -0,0 +1,43 @@
1
+ // Copyright (c) 2011, 2022 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
+
4
+ #include "oj.h"
5
+
6
+ typedef struct _encoder {
7
+ int indent; // indention for dump, default 2
8
+ char circular; // YesNo
9
+ char escape_mode; // Escape_Mode
10
+ char mode; // Mode
11
+ char time_format; // TimeFormat
12
+ char bigdec_as_num; // YesNo
13
+ char to_hash; // YesNo
14
+ char to_json; // YesNo
15
+ char as_json; // YesNo
16
+ char raw_json; // YesNo
17
+ char trace; // YesNo
18
+ char sec_prec_set; // boolean (0 or 1)
19
+ char ignore_under; // YesNo - ignore attrs starting with _ if true in object and custom modes
20
+ int64_t int_range_min; // dump numbers below as string
21
+ int64_t int_range_max; // dump numbers above as string
22
+ const char* create_id; // 0 or string
23
+ size_t create_id_len; // length of create_id
24
+ int sec_prec; // second precision when dumping time
25
+ char float_prec; // float precision, linked to float_fmt
26
+ char float_fmt[7]; // float format for dumping, if empty use Ruby
27
+ struct _dumpOpts dump_opts;
28
+ struct _rxClass str_rx;
29
+ VALUE* ignore; // Qnil terminated array of classes or NULL
30
+ } * Encoder;
31
+
32
+ /*
33
+ rb_define_module_function(Oj, "encode", encode, -1);
34
+ rb_define_module_function(Oj, "to_file", to_file, -1); // or maybe just write
35
+ rb_define_module_function(Oj, "to_stream", to_stream, -1);
36
+ */
37
+
38
+ // write(to, obj)
39
+ // if to is a string then open file
40
+ // else if stream then write to stream
41
+ // handle non-blocking
42
+
43
+ // should each mode have a different encoder or use delegates like the parser?
data/ext/oj/err.c CHANGED
@@ -1,40 +1,12 @@
1
- /* err.c
2
- * Copyright (c) 2011, 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
- */
30
-
31
- #include <stdarg.h>
1
+ // Copyright (c) 2011 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
32
3
 
33
4
  #include "err.h"
34
5
 
35
- void
36
- oj_err_set(Err e, VALUE clas, const char *format, ...) {
37
- va_list ap;
6
+ #include <stdarg.h>
7
+
8
+ void oj_err_set(Err e, VALUE clas, const char *format, ...) {
9
+ va_list ap;
38
10
 
39
11
  va_start(ap, format);
40
12
  e->clas = clas;
@@ -42,41 +14,55 @@ oj_err_set(Err e, VALUE clas, const char *format, ...) {
42
14
  va_end(ap);
43
15
  }
44
16
 
45
- void
46
- oj_err_raise(Err e) {
17
+ void oj_err_raise(Err e) {
47
18
  rb_raise(e->clas, "%s", e->msg);
48
19
  }
49
20
 
50
- void
51
- _oj_err_set_with_location(Err err, VALUE eclas, const char *msg, const char *json, const char *current, const char* file, int line) {
52
- int n = 1;
53
- int col = 1;
21
+ void _oj_err_set_with_location(Err err,
22
+ VALUE eclas,
23
+ const char *msg,
24
+ const char *json,
25
+ const char *current,
26
+ const char *file,
27
+ int line) {
28
+ int n = 1;
29
+ int col = 1;
54
30
 
55
31
  for (; json < current && '\n' != *current; current--) {
56
- col++;
32
+ col++;
57
33
  }
58
34
  for (; json < current; current--) {
59
- if ('\n' == *current) {
60
- n++;
61
- }
35
+ if ('\n' == *current) {
36
+ n++;
37
+ }
62
38
  }
63
39
  oj_err_set(err, eclas, "%s at line %d, column %d [%s:%d]", msg, n, col, file, line);
64
40
  }
65
41
 
66
- void
67
- _oj_raise_error(const char *msg, const char *json, const char *current, const char* file, int line) {
68
- struct _Err err;
69
- int n = 1;
70
- int col = 1;
42
+ void _oj_raise_error(const char *msg,
43
+ const char *json,
44
+ const char *current,
45
+ const char *file,
46
+ int line) {
47
+ struct _err err;
48
+ int n = 1;
49
+ int col = 1;
71
50
 
72
51
  for (; json < current && '\n' != *current; current--) {
73
- col++;
52
+ col++;
74
53
  }
75
54
  for (; json < current; current--) {
76
- if ('\n' == *current) {
77
- n++;
78
- }
55
+ if ('\n' == *current) {
56
+ n++;
57
+ }
79
58
  }
80
- oj_err_set(&err, oj_parse_error_class, "%s at line %d, column %d [%s:%d]", msg, n, col, file, line);
59
+ oj_err_set(&err,
60
+ oj_parse_error_class,
61
+ "%s at line %d, column %d [%s:%d]",
62
+ msg,
63
+ n,
64
+ col,
65
+ file,
66
+ line);
81
67
  rb_raise(err.clas, "%s", err.msg);
82
68
  }