oj 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +17 -23
  3. data/README.md +74 -425
  4. data/ext/oj/buf.h +103 -0
  5. data/ext/oj/cache8.c +4 -0
  6. data/ext/oj/circarray.c +68 -0
  7. data/ext/oj/circarray.h +23 -0
  8. data/ext/oj/code.c +227 -0
  9. data/ext/oj/code.h +40 -0
  10. data/ext/oj/compat.c +243 -0
  11. data/ext/oj/custom.c +1097 -0
  12. data/ext/oj/dump.c +766 -1534
  13. data/ext/oj/dump.h +92 -0
  14. data/ext/oj/dump_compat.c +937 -0
  15. data/ext/oj/dump_leaf.c +254 -0
  16. data/ext/oj/dump_object.c +810 -0
  17. data/ext/oj/dump_rails.c +329 -0
  18. data/ext/oj/dump_strict.c +416 -0
  19. data/ext/oj/encode.h +51 -0
  20. data/ext/oj/err.c +57 -0
  21. data/ext/oj/err.h +70 -0
  22. data/ext/oj/extconf.rb +17 -7
  23. data/ext/oj/fast.c +213 -180
  24. data/ext/oj/hash.c +163 -0
  25. data/ext/oj/hash.h +46 -0
  26. data/ext/oj/hash_test.c +512 -0
  27. data/ext/oj/mimic_json.c +817 -0
  28. data/ext/oj/mimic_rails.c +806 -0
  29. data/ext/oj/mimic_rails.h +17 -0
  30. data/ext/oj/object.c +752 -0
  31. data/ext/oj/odd.c +230 -0
  32. data/ext/oj/odd.h +44 -0
  33. data/ext/oj/oj.c +1288 -929
  34. data/ext/oj/oj.h +240 -69
  35. data/ext/oj/parse.c +1014 -0
  36. data/ext/oj/parse.h +92 -0
  37. data/ext/oj/reader.c +223 -0
  38. data/ext/oj/reader.h +151 -0
  39. data/ext/oj/resolve.c +127 -0
  40. data/ext/oj/{cache.h → resolve.h} +6 -13
  41. data/ext/oj/rxclass.c +133 -0
  42. data/ext/oj/rxclass.h +27 -0
  43. data/ext/oj/saj.c +77 -175
  44. data/ext/oj/scp.c +224 -0
  45. data/ext/oj/sparse.c +911 -0
  46. data/ext/oj/stream_writer.c +301 -0
  47. data/ext/oj/strict.c +162 -0
  48. data/ext/oj/string_writer.c +480 -0
  49. data/ext/oj/val_stack.c +98 -0
  50. data/ext/oj/val_stack.h +188 -0
  51. data/lib/oj/active_support_helper.rb +41 -0
  52. data/lib/oj/bag.rb +6 -10
  53. data/lib/oj/easy_hash.rb +52 -0
  54. data/lib/oj/json.rb +172 -0
  55. data/lib/oj/mimic.rb +260 -5
  56. data/lib/oj/saj.rb +13 -10
  57. data/lib/oj/schandler.rb +142 -0
  58. data/lib/oj/state.rb +131 -0
  59. data/lib/oj/version.rb +1 -1
  60. data/lib/oj.rb +11 -23
  61. data/pages/Advanced.md +22 -0
  62. data/pages/Compatibility.md +25 -0
  63. data/pages/Custom.md +23 -0
  64. data/pages/Encoding.md +65 -0
  65. data/pages/JsonGem.md +79 -0
  66. data/pages/Modes.md +140 -0
  67. data/pages/Options.md +250 -0
  68. data/pages/Rails.md +60 -0
  69. data/pages/Security.md +20 -0
  70. data/test/_test_active.rb +76 -0
  71. data/test/_test_active_mimic.rb +96 -0
  72. data/test/_test_mimic_rails.rb +126 -0
  73. data/test/activesupport4/decoding_test.rb +105 -0
  74. data/test/activesupport4/encoding_test.rb +531 -0
  75. data/test/activesupport4/test_helper.rb +41 -0
  76. data/test/activesupport5/decoding_test.rb +125 -0
  77. data/test/activesupport5/encoding_test.rb +483 -0
  78. data/test/activesupport5/encoding_test_cases.rb +90 -0
  79. data/test/activesupport5/test_helper.rb +50 -0
  80. data/test/activesupport5/time_zone_test_helpers.rb +24 -0
  81. data/test/helper.rb +27 -0
  82. data/test/isolated/shared.rb +310 -0
  83. data/test/isolated/test_mimic_after.rb +13 -0
  84. data/test/isolated/test_mimic_alone.rb +12 -0
  85. data/test/isolated/test_mimic_as_json.rb +45 -0
  86. data/test/isolated/test_mimic_before.rb +13 -0
  87. data/test/isolated/test_mimic_define.rb +28 -0
  88. data/test/isolated/test_mimic_rails_after.rb +22 -0
  89. data/test/isolated/test_mimic_rails_before.rb +21 -0
  90. data/test/isolated/test_mimic_redefine.rb +15 -0
  91. data/test/json_gem/json_addition_test.rb +216 -0
  92. data/test/json_gem/json_common_interface_test.rb +143 -0
  93. data/test/json_gem/json_encoding_test.rb +109 -0
  94. data/test/json_gem/json_ext_parser_test.rb +20 -0
  95. data/test/json_gem/json_fixtures_test.rb +35 -0
  96. data/test/json_gem/json_generator_test.rb +383 -0
  97. data/test/json_gem/json_generic_object_test.rb +90 -0
  98. data/test/json_gem/json_parser_test.rb +470 -0
  99. data/test/json_gem/json_string_matching_test.rb +42 -0
  100. data/test/json_gem/test_helper.rb +18 -0
  101. data/test/perf_compat.rb +130 -0
  102. data/test/perf_fast.rb +9 -9
  103. data/test/perf_file.rb +64 -0
  104. data/test/{perf_obj.rb → perf_object.rb} +24 -10
  105. data/test/perf_scp.rb +151 -0
  106. data/test/perf_strict.rb +32 -113
  107. data/test/sample.rb +2 -3
  108. data/test/test_compat.rb +474 -0
  109. data/test/test_custom.rb +355 -0
  110. data/test/test_debian.rb +53 -0
  111. data/test/test_fast.rb +66 -16
  112. data/test/test_file.rb +237 -0
  113. data/test/test_gc.rb +49 -0
  114. data/test/test_hash.rb +29 -0
  115. data/test/test_null.rb +376 -0
  116. data/test/test_object.rb +1010 -0
  117. data/test/test_saj.rb +16 -16
  118. data/test/test_scp.rb +417 -0
  119. data/test/test_strict.rb +410 -0
  120. data/test/test_various.rb +815 -0
  121. data/test/test_writer.rb +308 -0
  122. data/test/tests.rb +9 -902
  123. data/test/tests_mimic.rb +14 -0
  124. data/test/tests_mimic_addition.rb +7 -0
  125. metadata +253 -38
  126. data/ext/oj/cache.c +0 -148
  127. data/ext/oj/foo.rb +0 -6
  128. data/ext/oj/load.c +0 -1049
  129. data/test/a.rb +0 -38
  130. data/test/perf1.rb +0 -64
  131. data/test/perf2.rb +0 -76
  132. data/test/perf_obj_old.rb +0 -213
  133. data/test/test_mimic.rb +0 -208
@@ -0,0 +1,416 @@
1
+ /* dump_strict.c
2
+ * Copyright (c) 2012, 2017, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #include <stdlib.h>
7
+ #include <time.h>
8
+ #include <stdio.h>
9
+ #include <string.h>
10
+ #include <math.h>
11
+ #include <unistd.h>
12
+ #include <errno.h>
13
+
14
+ #include "dump.h"
15
+
16
+ #if !HAS_ENCODING_SUPPORT || defined(RUBINIUS_RUBY)
17
+ #define rb_eEncodingError rb_eException
18
+ #endif
19
+
20
+ // Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
21
+ #define OJ_INFINITY (1.0/0.0)
22
+
23
+ // Extra padding at end of buffer.
24
+ #define BUFFER_EXTRA 10
25
+
26
+ typedef unsigned long ulong;
27
+
28
+ static const char inf_val[] = INF_VAL;
29
+ static const char ninf_val[] = NINF_VAL;
30
+ static const char nan_val[] = NAN_VAL;
31
+
32
+ static void
33
+ raise_strict(VALUE obj) {
34
+ rb_raise(rb_eTypeError, "Failed to dump %s Object to JSON in strict mode.\n", rb_class2name(rb_obj_class(obj)));
35
+ }
36
+
37
+ // Removed dependencies on math due to problems with CentOS 5.4.
38
+ static void
39
+ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
40
+ char buf[64];
41
+ char *b;
42
+ double d = rb_num2dbl(obj);
43
+ int cnt = 0;
44
+
45
+ if (0.0 == d) {
46
+ b = buf;
47
+ *b++ = '0';
48
+ *b++ = '.';
49
+ *b++ = '0';
50
+ *b++ = '\0';
51
+ cnt = 3;
52
+ } else {
53
+ NanDump nd = out->opts->dump_opts.nan_dump;
54
+
55
+ if (AutoNan == nd) {
56
+ nd = RaiseNan;
57
+ }
58
+ if (OJ_INFINITY == d) {
59
+ switch (nd) {
60
+ case RaiseNan:
61
+ case WordNan:
62
+ raise_strict(obj);
63
+ break;
64
+ case NullNan:
65
+ strcpy(buf, "null");
66
+ cnt = 4;
67
+ break;
68
+ case HugeNan:
69
+ default:
70
+ strcpy(buf, inf_val);
71
+ cnt = sizeof(inf_val) - 1;
72
+ break;
73
+ }
74
+ } else if (-OJ_INFINITY == d) {
75
+ switch (nd) {
76
+ case RaiseNan:
77
+ case WordNan:
78
+ raise_strict(obj);
79
+ break;
80
+ case NullNan:
81
+ strcpy(buf, "null");
82
+ cnt = 4;
83
+ break;
84
+ case HugeNan:
85
+ default:
86
+ strcpy(buf, ninf_val);
87
+ cnt = sizeof(ninf_val) - 1;
88
+ break;
89
+ }
90
+ } else if (isnan(d)) {
91
+ switch (nd) {
92
+ case RaiseNan:
93
+ case WordNan:
94
+ raise_strict(obj);
95
+ break;
96
+ case NullNan:
97
+ strcpy(buf, "null");
98
+ cnt = 4;
99
+ break;
100
+ case HugeNan:
101
+ default:
102
+ strcpy(buf, nan_val);
103
+ cnt = sizeof(nan_val) - 1;
104
+ break;
105
+ }
106
+ } else if (d == (double)(long long int)d) {
107
+ cnt = snprintf(buf, sizeof(buf), "%.1f", d);
108
+ } else if (0 == out->opts->float_prec) {
109
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
110
+
111
+ cnt = RSTRING_LEN(rstr);
112
+ if ((int)sizeof(buf) <= cnt) {
113
+ cnt = sizeof(buf) - 1;
114
+ }
115
+ strncpy(buf, rb_string_value_ptr((VALUE*)&rstr), cnt);
116
+ buf[cnt] = '\0';
117
+ } else {
118
+ cnt = snprintf(buf, sizeof(buf), out->opts->float_fmt, d);
119
+ }
120
+ }
121
+ assure_size(out, cnt);
122
+ for (b = buf; '\0' != *b; b++) {
123
+ *out->cur++ = *b;
124
+ }
125
+ *out->cur = '\0';
126
+ }
127
+
128
+ static void
129
+ dump_array(VALUE a, int depth, Out out, bool as_ok) {
130
+ size_t size;
131
+ int i, cnt;
132
+ int d2 = depth + 1;
133
+
134
+ if (Yes == out->opts->circular) {
135
+ if (0 > oj_check_circular(a, out)) {
136
+ oj_dump_nil(Qnil, 0, out, false);
137
+ return;
138
+ }
139
+ }
140
+ cnt = (int)RARRAY_LEN(a);
141
+ *out->cur++ = '[';
142
+ size = 2;
143
+ assure_size(out, size);
144
+ if (0 == cnt) {
145
+ *out->cur++ = ']';
146
+ } else {
147
+ if (out->opts->dump_opts.use) {
148
+ size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
149
+ } else {
150
+ size = d2 * out->indent + 2;
151
+ }
152
+ cnt--;
153
+ for (i = 0; i <= cnt; i++) {
154
+ assure_size(out, size);
155
+ if (out->opts->dump_opts.use) {
156
+ if (0 < out->opts->dump_opts.array_size) {
157
+ strcpy(out->cur, out->opts->dump_opts.array_nl);
158
+ out->cur += out->opts->dump_opts.array_size;
159
+ }
160
+ if (0 < out->opts->dump_opts.indent_size) {
161
+ int i;
162
+ for (i = d2; 0 < i; i--) {
163
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
164
+ out->cur += out->opts->dump_opts.indent_size;
165
+ }
166
+ }
167
+ } else {
168
+ fill_indent(out, d2);
169
+ }
170
+ oj_dump_strict_val(rb_ary_entry(a, i), d2, out);
171
+ if (i < cnt) {
172
+ *out->cur++ = ',';
173
+ }
174
+ }
175
+ size = depth * out->indent + 1;
176
+ assure_size(out, size);
177
+ if (out->opts->dump_opts.use) {
178
+ //printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size, out->opts->dump_opts->indent);
179
+ if (0 < out->opts->dump_opts.array_size) {
180
+ strcpy(out->cur, out->opts->dump_opts.array_nl);
181
+ out->cur += out->opts->dump_opts.array_size;
182
+ }
183
+ if (0 < out->opts->dump_opts.indent_size) {
184
+ int i;
185
+
186
+ for (i = depth; 0 < i; i--) {
187
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
188
+ out->cur += out->opts->dump_opts.indent_size;
189
+ }
190
+ }
191
+ } else {
192
+ fill_indent(out, depth);
193
+ }
194
+ *out->cur++ = ']';
195
+ }
196
+ *out->cur = '\0';
197
+ }
198
+
199
+ static int
200
+ hash_cb(VALUE key, VALUE value, Out out) {
201
+ int depth = out->depth;
202
+ long size;
203
+ int rtype = rb_type(key);
204
+
205
+ if (rtype != T_STRING && rtype != T_SYMBOL) {
206
+ rb_raise(rb_eTypeError, "In :strict mode all Hash keys must be Strings or Symbols, not %s.\n", rb_class2name(rb_obj_class(key)));
207
+ }
208
+ if (out->omit_nil && Qnil == value) {
209
+ return ST_CONTINUE;
210
+ }
211
+ if (!out->opts->dump_opts.use) {
212
+ size = depth * out->indent + 1;
213
+ assure_size(out, size);
214
+ fill_indent(out, depth);
215
+ if (rtype == T_STRING) {
216
+ oj_dump_str(key, 0, out, false);
217
+ } else {
218
+ oj_dump_sym(key, 0, out, false);
219
+ }
220
+ *out->cur++ = ':';
221
+ } else {
222
+ size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
223
+ assure_size(out, size);
224
+ if (0 < out->opts->dump_opts.hash_size) {
225
+ strcpy(out->cur, out->opts->dump_opts.hash_nl);
226
+ out->cur += out->opts->dump_opts.hash_size;
227
+ }
228
+ if (0 < out->opts->dump_opts.indent_size) {
229
+ int i;
230
+ for (i = depth; 0 < i; i--) {
231
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
232
+ out->cur += out->opts->dump_opts.indent_size;
233
+ }
234
+ }
235
+ if (rtype == T_STRING) {
236
+ oj_dump_str(key, 0, out, false);
237
+ } else {
238
+ oj_dump_sym(key, 0, out, false);
239
+ }
240
+ size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
241
+ assure_size(out, size);
242
+ if (0 < out->opts->dump_opts.before_size) {
243
+ strcpy(out->cur, out->opts->dump_opts.before_sep);
244
+ out->cur += out->opts->dump_opts.before_size;
245
+ }
246
+ *out->cur++ = ':';
247
+ if (0 < out->opts->dump_opts.after_size) {
248
+ strcpy(out->cur, out->opts->dump_opts.after_sep);
249
+ out->cur += out->opts->dump_opts.after_size;
250
+ }
251
+ }
252
+ oj_dump_strict_val(value, depth, out);
253
+ out->depth = depth;
254
+ *out->cur++ = ',';
255
+
256
+ return ST_CONTINUE;
257
+ }
258
+
259
+ static void
260
+ dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
261
+ int cnt;
262
+ size_t size;
263
+
264
+ if (Yes == out->opts->circular) {
265
+ if (0 > oj_check_circular(obj, out)) {
266
+ oj_dump_nil(Qnil, 0, out, false);
267
+ return;
268
+ }
269
+ }
270
+ cnt = (int)RHASH_SIZE(obj);
271
+ size = depth * out->indent + 2;
272
+ assure_size(out, 2);
273
+ *out->cur++ = '{';
274
+ if (0 == cnt) {
275
+ *out->cur++ = '}';
276
+ } else {
277
+ out->depth = depth + 1;
278
+ rb_hash_foreach(obj, hash_cb, (VALUE)out);
279
+ if (',' == *(out->cur - 1)) {
280
+ out->cur--; // backup to overwrite last comma
281
+ }
282
+ if (!out->opts->dump_opts.use) {
283
+ assure_size(out, size);
284
+ fill_indent(out, depth);
285
+ } else {
286
+ size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
287
+ assure_size(out, size);
288
+ if (0 < out->opts->dump_opts.hash_size) {
289
+ strcpy(out->cur, out->opts->dump_opts.hash_nl);
290
+ out->cur += out->opts->dump_opts.hash_size;
291
+ }
292
+ if (0 < out->opts->dump_opts.indent_size) {
293
+ int i;
294
+
295
+ for (i = depth; 0 < i; i--) {
296
+ strcpy(out->cur, out->opts->dump_opts.indent_str);
297
+ out->cur += out->opts->dump_opts.indent_size;
298
+ }
299
+ }
300
+ }
301
+ *out->cur++ = '}';
302
+ }
303
+ *out->cur = '\0';
304
+ }
305
+
306
+ static void
307
+ dump_data_strict(VALUE obj, int depth, Out out, bool as_ok) {
308
+ VALUE clas = rb_obj_class(obj);
309
+
310
+ if (oj_bigdecimal_class == clas) {
311
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
312
+
313
+ oj_dump_raw(rb_string_value_ptr((VALUE*)&rstr), RSTRING_LEN(rstr), out);
314
+ } else {
315
+ raise_strict(obj);
316
+ }
317
+ }
318
+
319
+ static void
320
+ dump_data_null(VALUE obj, int depth, Out out, bool as_ok) {
321
+ VALUE clas = rb_obj_class(obj);
322
+
323
+ if (oj_bigdecimal_class == clas) {
324
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
325
+
326
+ oj_dump_raw(rb_string_value_ptr((VALUE*)&rstr), RSTRING_LEN(rstr), out);
327
+ } else {
328
+ oj_dump_nil(Qnil, depth, out, false);
329
+ }
330
+ }
331
+
332
+ static DumpFunc strict_funcs[] = {
333
+ NULL, // RUBY_T_NONE = 0x00,
334
+ dump_data_strict, // RUBY_T_OBJECT = 0x01,
335
+ NULL, // RUBY_T_CLASS = 0x02,
336
+ NULL, // RUBY_T_MODULE = 0x03,
337
+ dump_float, // RUBY_T_FLOAT = 0x04,
338
+ oj_dump_str, // RUBY_T_STRING = 0x05,
339
+ NULL, // RUBY_T_REGEXP = 0x06,
340
+ dump_array, // RUBY_T_ARRAY = 0x07,
341
+ dump_hash, // RUBY_T_HASH = 0x08,
342
+ NULL, // RUBY_T_STRUCT = 0x09,
343
+ oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
344
+ NULL, // RUBY_T_FILE = 0x0b,
345
+ dump_data_strict, // RUBY_T_DATA = 0x0c,
346
+ NULL, // RUBY_T_MATCH = 0x0d,
347
+ NULL, // RUBY_T_COMPLEX = 0x0e,
348
+ NULL, // RUBY_T_RATIONAL = 0x0f,
349
+ NULL, // 0x10
350
+ oj_dump_nil, // RUBY_T_NIL = 0x11,
351
+ oj_dump_true, // RUBY_T_TRUE = 0x12,
352
+ oj_dump_false, // RUBY_T_FALSE = 0x13,
353
+ oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
354
+ oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
355
+ };
356
+
357
+ void
358
+ oj_dump_strict_val(VALUE obj, int depth, Out out) {
359
+ int type = rb_type(obj);
360
+
361
+ if (MAX_DEPTH < depth) {
362
+ rb_raise(rb_eNoMemError, "Too deeply nested.\n");
363
+ }
364
+ if (0 < type && type <= RUBY_T_FIXNUM) {
365
+ DumpFunc f = strict_funcs[type];
366
+
367
+ if (NULL != f) {
368
+ f(obj, depth, out, false);
369
+ return;
370
+ }
371
+ }
372
+ raise_strict(obj);
373
+ }
374
+
375
+ static DumpFunc null_funcs[] = {
376
+ NULL, // RUBY_T_NONE = 0x00,
377
+ dump_data_null, // RUBY_T_OBJECT = 0x01,
378
+ NULL, // RUBY_T_CLASS = 0x02,
379
+ NULL, // RUBY_T_MODULE = 0x03,
380
+ dump_float, // RUBY_T_FLOAT = 0x04,
381
+ oj_dump_str, // RUBY_T_STRING = 0x05,
382
+ NULL, // RUBY_T_REGEXP = 0x06,
383
+ dump_array, // RUBY_T_ARRAY = 0x07,
384
+ dump_hash, // RUBY_T_HASH = 0x08,
385
+ NULL, // RUBY_T_STRUCT = 0x09,
386
+ oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
387
+ NULL, // RUBY_T_FILE = 0x0b,
388
+ dump_data_null, // RUBY_T_DATA = 0x0c,
389
+ NULL, // RUBY_T_MATCH = 0x0d,
390
+ NULL, // RUBY_T_COMPLEX = 0x0e,
391
+ NULL, // RUBY_T_RATIONAL = 0x0f,
392
+ NULL, // 0x10
393
+ oj_dump_nil, // RUBY_T_NIL = 0x11,
394
+ oj_dump_true, // RUBY_T_TRUE = 0x12,
395
+ oj_dump_false, // RUBY_T_FALSE = 0x13,
396
+ oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
397
+ oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
398
+ };
399
+
400
+ void
401
+ oj_dump_null_val(VALUE obj, int depth, Out out) {
402
+ int type = rb_type(obj);
403
+
404
+ if (MAX_DEPTH < depth) {
405
+ rb_raise(rb_eNoMemError, "Too deeply nested.\n");
406
+ }
407
+ if (0 < type && type <= RUBY_T_FIXNUM) {
408
+ DumpFunc f = null_funcs[type];
409
+
410
+ if (NULL != f) {
411
+ f(obj, depth, out, false);
412
+ return;
413
+ }
414
+ }
415
+ oj_dump_nil(Qnil, depth, out, false);
416
+ }
data/ext/oj/encode.h ADDED
@@ -0,0 +1,51 @@
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
+ */
30
+
31
+ #ifndef __OJ_ENCODE_H__
32
+ #define __OJ_ENCODE_H__
33
+
34
+ #include "ruby.h"
35
+ #if HAS_ENCODING_SUPPORT
36
+ #include "ruby/encoding.h"
37
+ #endif
38
+
39
+ static inline VALUE
40
+ oj_encode(VALUE rstr) {
41
+ #if HAS_ENCODING_SUPPORT
42
+ 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
+ return rstr;
49
+ }
50
+
51
+ #endif /* __OJ_ENCODE_H__ */
data/ext/oj/err.c ADDED
@@ -0,0 +1,57 @@
1
+ /* err.c
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #include <stdarg.h>
7
+
8
+ #include "err.h"
9
+
10
+ void
11
+ oj_err_set(Err e, VALUE clas, const char *format, ...) {
12
+ va_list ap;
13
+
14
+ va_start(ap, format);
15
+ e->clas = clas;
16
+ vsnprintf(e->msg, sizeof(e->msg) - 1, format, ap);
17
+ va_end(ap);
18
+ }
19
+
20
+ void
21
+ oj_err_raise(Err e) {
22
+ rb_raise(e->clas, "%s", e->msg);
23
+ }
24
+
25
+ void
26
+ _oj_err_set_with_location(Err err, VALUE eclas, const char *msg, const char *json, const char *current, const char* file, int line) {
27
+ int n = 1;
28
+ int col = 1;
29
+
30
+ for (; json < current && '\n' != *current; current--) {
31
+ col++;
32
+ }
33
+ for (; json < current; current--) {
34
+ if ('\n' == *current) {
35
+ n++;
36
+ }
37
+ }
38
+ oj_err_set(err, eclas, "%s at line %d, column %d [%s:%d]", msg, n, col, file, line);
39
+ }
40
+
41
+ void
42
+ _oj_raise_error(const char *msg, const char *json, const char *current, const char* file, int line) {
43
+ struct _Err err;
44
+ int n = 1;
45
+ int col = 1;
46
+
47
+ for (; json < current && '\n' != *current; current--) {
48
+ col++;
49
+ }
50
+ for (; json < current; current--) {
51
+ if ('\n' == *current) {
52
+ n++;
53
+ }
54
+ }
55
+ oj_err_set(&err, oj_parse_error_class, "%s at line %d, column %d [%s:%d]", msg, n, col, file, line);
56
+ rb_raise(err.clas, "%s", err.msg);
57
+ }
data/ext/oj/err.h ADDED
@@ -0,0 +1,70 @@
1
+ /* err.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
+ */
30
+
31
+ #ifndef __OJ_ERR_H__
32
+ #define __OJ_ERR_H__
33
+
34
+ #include "ruby.h"
35
+ // Needed to silence 2.4.0 warnings.
36
+ #ifndef NORETURN
37
+ # define NORETURN(x) x
38
+ #endif
39
+
40
+ #define set_error(err, eclas, msg, json, current) _oj_err_set_with_location(err, eclas, msg, json, current, __FILE__, __LINE__)
41
+
42
+ typedef struct _Err {
43
+ VALUE clas;
44
+ char msg[128];
45
+ } *Err;
46
+
47
+ extern VALUE oj_parse_error_class;
48
+
49
+ extern void oj_err_set(Err e, VALUE clas, const char *format, ...);
50
+ extern void _oj_err_set_with_location(Err err, VALUE eclas, const char *msg, const char *json, const char *current, const char* file, int line);
51
+
52
+ NORETURN(extern void oj_err_raise(Err e));
53
+
54
+ #define raise_error(msg, json, current) _oj_raise_error(msg, json, current, __FILE__, __LINE__)
55
+
56
+ NORETURN(extern void _oj_raise_error(const char *msg, const char *json, const char *current, const char* file, int line));
57
+
58
+
59
+ inline static void
60
+ err_init(Err e) {
61
+ e->clas = Qnil;
62
+ *e->msg = '\0';
63
+ }
64
+
65
+ inline static int
66
+ err_has(Err e) {
67
+ return (Qnil != e->clas);
68
+ }
69
+
70
+ #endif /* __OJ_ERR_H__ */
data/ext/oj/extconf.rb CHANGED
@@ -20,17 +20,24 @@ dflags = {
20
20
  'RUBY_VERSION_MAJOR' => version[0],
21
21
  'RUBY_VERSION_MINOR' => version[1],
22
22
  'RUBY_VERSION_MICRO' => version[2],
23
- 'HAS_RB_TIME_TIMESPEC' => ('ruby' == type && ('1.9.3' == RUBY_VERSION || '2' <= version[0])) ? 1 : 0,
23
+ 'HAS_RB_TIME_TIMESPEC' => (!is_windows && 'ruby' == type && ('1.9.3' == RUBY_VERSION || '2' <= version[0])) ? 1 : 0,
24
24
  'HAS_ENCODING_SUPPORT' => (('ruby' == type || 'rubinius' == type) &&
25
25
  (('1' == version[0] && '9' == version[1]) || '2' <= version[0])) ? 1 : 0,
26
26
  'HAS_NANO_TIME' => ('ruby' == type && ('1' == version[0] && '9' == version[1]) || '2' <= version[0]) ? 1 : 0,
27
- 'HAS_RSTRUCT' => ('ruby' == type || 'ree' == type || 'tcs-ruby' == type) ? 1 : 0,
28
27
  'HAS_IVAR_HELPERS' => ('ruby' == type && !is_windows && (('1' == version[0] && '9' == version[1]) || '2' <= version[0])) ? 1 : 0,
29
- 'HAS_EXCEPTION_MAGIC' => ('ruby' == type && !is_windows && (('1' == version[0] && '9' == version[1]) || '2' <= version[0])) ? 0 : 1,
30
- 'HAS_PROC_WITH_BLOCK' => ('ruby' == type && ('1' == version[0] && '9' == version[1]) || '2' <= version[0]) ? 1 : 0,
28
+ 'HAS_EXCEPTION_MAGIC' => ('ruby' == type && ('1' == version[0] && '9' == version[1])) ? 0 : 1,
29
+ 'HAS_PROC_WITH_BLOCK' => ('ruby' == type && (('1' == version[0] && '9' == version[1]) || '2' <= version[0])) ? 1 : 0,
31
30
  'HAS_TOP_LEVEL_ST_H' => ('ree' == type || ('ruby' == type && '1' == version[0] && '8' == version[1])) ? 1 : 0,
31
+ 'NEEDS_RATIONAL' => ('1' == version[0] && '8' == version[1]) ? 1 : 0,
32
32
  'IS_WINDOWS' => is_windows ? 1 : 0,
33
- 'SAFE_CACHE' => is_windows ? 0 : 1,
33
+ 'USE_PTHREAD_MUTEX' => is_windows ? 0 : 1,
34
+ 'USE_RB_MUTEX' => (is_windows && !('1' == version[0] && '8' == version[1])) ? 1 : 0,
35
+ 'DATETIME_1_8' => ('ruby' == type && ('1' == version[0] && '8' == version[1])) ? 1 : 0,
36
+ 'NO_TIME_ROUND_PAD' => ('rubinius' == type) ? 1 : 0,
37
+ 'HAS_DATA_OBJECT_WRAP' => ('ruby' == type && '2' == version[0] && '3' <= version[1]) ? 1 : 0,
38
+ 'HAS_METHOD_ARITY' => ('rubinius' == type) ? 0 : 1,
39
+ 'HAS_STRUCT_MEMBERS' => ('rubinius' == type) ? 0 : 1,
40
+ 'UNIFY_FIXNUM_AND_BIGNUM' => ('ruby' == type && '2' == version[0] && '4' <= version[1]) ? 1 : 0,
34
41
  }
35
42
  # This is a monster hack to get around issues with 1.9.3-p0 on CentOS 5.4. SO
36
43
  # some reason math.h and string.h contents are not processed. Might be a
@@ -38,12 +45,14 @@ dflags = {
38
45
  if 'x86_64-linux' == RUBY_PLATFORM && '1.9.3' == RUBY_VERSION && '2011-10-30' == RUBY_RELEASE_DATE
39
46
  begin
40
47
  dflags['NEEDS_STPCPY'] = nil if File.read('/etc/redhat-release').include?('CentOS release 5.4')
41
- rescue Exception => e
48
+ rescue Exception
42
49
  end
43
50
  else
44
51
  dflags['NEEDS_STPCPY'] = nil if is_windows
45
52
  end
46
53
 
54
+ dflags['OJ_DEBUG'] = true unless ENV['OJ_DEBUG'].nil?
55
+
47
56
  dflags.each do |k,v|
48
57
  if v.nil?
49
58
  $CPPFLAGS += " -D#{k}"
@@ -51,8 +60,9 @@ dflags.each do |k,v|
51
60
  $CPPFLAGS += " -D#{k}=#{v}"
52
61
  end
53
62
  end
63
+
54
64
  $CPPFLAGS += ' -Wall'
55
65
  #puts "*** $CPPFLAGS: #{$CPPFLAGS}"
56
- create_makefile(extension_name)
66
+ create_makefile("#{extension_name}/#{extension_name}")
57
67
 
58
68
  %x{make clean}