oj 3.11.0 → 3.16.5

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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1421 -0
  3. data/README.md +20 -5
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +48 -38
  6. data/ext/oj/cache.c +329 -0
  7. data/ext/oj/cache.h +22 -0
  8. data/ext/oj/cache8.c +60 -62
  9. data/ext/oj/cache8.h +8 -7
  10. data/ext/oj/circarray.c +35 -35
  11. data/ext/oj/circarray.h +11 -9
  12. data/ext/oj/code.c +156 -174
  13. data/ext/oj/code.h +19 -18
  14. data/ext/oj/compat.c +140 -197
  15. data/ext/oj/custom.c +737 -879
  16. data/ext/oj/debug.c +126 -0
  17. data/ext/oj/dump.c +830 -835
  18. data/ext/oj/dump.h +65 -53
  19. data/ext/oj/dump_compat.c +566 -642
  20. data/ext/oj/dump_leaf.c +95 -182
  21. data/ext/oj/dump_object.c +518 -659
  22. data/ext/oj/dump_strict.c +301 -334
  23. data/ext/oj/encode.h +3 -4
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +27 -24
  26. data/ext/oj/err.h +38 -13
  27. data/ext/oj/extconf.rb +23 -7
  28. data/ext/oj/fast.c +1043 -1073
  29. data/ext/oj/intern.c +313 -0
  30. data/ext/oj/intern.h +22 -0
  31. data/ext/oj/mem.c +318 -0
  32. data/ext/oj/mem.h +53 -0
  33. data/ext/oj/mimic_json.c +449 -423
  34. data/ext/oj/object.c +530 -576
  35. data/ext/oj/odd.c +155 -138
  36. data/ext/oj/odd.h +24 -22
  37. data/ext/oj/oj.c +1331 -993
  38. data/ext/oj/oj.h +306 -292
  39. data/ext/oj/parse.c +934 -938
  40. data/ext/oj/parse.h +73 -70
  41. data/ext/oj/parser.c +1600 -0
  42. data/ext/oj/parser.h +101 -0
  43. data/ext/oj/rails.c +795 -845
  44. data/ext/oj/rails.h +7 -7
  45. data/ext/oj/reader.c +132 -140
  46. data/ext/oj/reader.h +67 -78
  47. data/ext/oj/resolve.c +40 -59
  48. data/ext/oj/resolve.h +3 -2
  49. data/ext/oj/rxclass.c +67 -67
  50. data/ext/oj/rxclass.h +11 -9
  51. data/ext/oj/saj.c +441 -480
  52. data/ext/oj/saj2.c +584 -0
  53. data/ext/oj/saj2.h +23 -0
  54. data/ext/oj/scp.c +78 -111
  55. data/ext/oj/sparse.c +726 -730
  56. data/ext/oj/stream_writer.c +146 -165
  57. data/ext/oj/strict.c +103 -123
  58. data/ext/oj/string_writer.c +241 -253
  59. data/ext/oj/trace.c +29 -33
  60. data/ext/oj/trace.h +41 -11
  61. data/ext/oj/usual.c +1218 -0
  62. data/ext/oj/usual.h +69 -0
  63. data/ext/oj/util.c +103 -103
  64. data/ext/oj/util.h +3 -2
  65. data/ext/oj/val_stack.c +60 -49
  66. data/ext/oj/val_stack.h +79 -85
  67. data/ext/oj/validate.c +46 -0
  68. data/ext/oj/wab.c +307 -350
  69. data/lib/oj/active_support_helper.rb +1 -3
  70. data/lib/oj/bag.rb +8 -1
  71. data/lib/oj/easy_hash.rb +9 -9
  72. data/lib/oj/error.rb +1 -2
  73. data/lib/oj/json.rb +162 -150
  74. data/lib/oj/mimic.rb +9 -19
  75. data/lib/oj/saj.rb +20 -6
  76. data/lib/oj/schandler.rb +5 -4
  77. data/lib/oj/state.rb +12 -8
  78. data/lib/oj/version.rb +1 -2
  79. data/lib/oj.rb +2 -0
  80. data/pages/Compatibility.md +1 -1
  81. data/pages/InstallOptions.md +20 -0
  82. data/pages/JsonGem.md +15 -0
  83. data/pages/Modes.md +8 -3
  84. data/pages/Options.md +43 -5
  85. data/pages/Parser.md +309 -0
  86. data/pages/Rails.md +14 -2
  87. data/test/_test_active.rb +8 -9
  88. data/test/_test_active_mimic.rb +7 -8
  89. data/test/_test_mimic_rails.rb +17 -20
  90. data/test/activerecord/result_test.rb +12 -8
  91. data/test/activesupport6/encoding_test.rb +63 -28
  92. data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
  93. data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
  94. data/test/{activesupport5 → activesupport7}/encoding_test.rb +86 -50
  95. data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
  96. data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
  97. data/test/files.rb +15 -15
  98. data/test/foo.rb +17 -43
  99. data/test/helper.rb +16 -3
  100. data/test/isolated/shared.rb +3 -2
  101. data/test/json_gem/json_addition_test.rb +2 -2
  102. data/test/json_gem/json_common_interface_test.rb +8 -6
  103. data/test/json_gem/json_encoding_test.rb +0 -0
  104. data/test/json_gem/json_ext_parser_test.rb +1 -0
  105. data/test/json_gem/json_fixtures_test.rb +3 -2
  106. data/test/json_gem/json_generator_test.rb +71 -41
  107. data/test/json_gem/json_generic_object_test.rb +11 -11
  108. data/test/json_gem/json_parser_test.rb +54 -47
  109. data/test/json_gem/json_string_matching_test.rb +9 -9
  110. data/test/json_gem/test_helper.rb +12 -0
  111. data/test/mem.rb +34 -0
  112. data/test/perf.rb +22 -27
  113. data/test/perf_compat.rb +31 -33
  114. data/test/perf_dump.rb +50 -0
  115. data/test/perf_fast.rb +80 -82
  116. data/test/perf_file.rb +27 -29
  117. data/test/perf_object.rb +65 -69
  118. data/test/perf_once.rb +59 -0
  119. data/test/perf_parser.rb +183 -0
  120. data/test/perf_saj.rb +46 -54
  121. data/test/perf_scp.rb +58 -69
  122. data/test/perf_simple.rb +41 -39
  123. data/test/perf_strict.rb +74 -82
  124. data/test/perf_wab.rb +67 -69
  125. data/test/prec.rb +5 -5
  126. data/test/sample/change.rb +0 -1
  127. data/test/sample/dir.rb +0 -1
  128. data/test/sample/doc.rb +0 -1
  129. data/test/sample/file.rb +0 -1
  130. data/test/sample/group.rb +0 -1
  131. data/test/sample/hasprops.rb +0 -1
  132. data/test/sample/layer.rb +0 -1
  133. data/test/sample/rect.rb +0 -1
  134. data/test/sample/shape.rb +0 -1
  135. data/test/sample/text.rb +0 -1
  136. data/test/sample.rb +16 -16
  137. data/test/sample_json.rb +8 -8
  138. data/test/test_compat.rb +97 -45
  139. data/test/test_custom.rb +73 -51
  140. data/test/test_debian.rb +7 -10
  141. data/test/test_fast.rb +135 -79
  142. data/test/test_file.rb +41 -30
  143. data/test/test_gc.rb +16 -5
  144. data/test/test_generate.rb +21 -0
  145. data/test/test_hash.rb +15 -5
  146. data/test/test_integer_range.rb +9 -9
  147. data/test/test_null.rb +20 -20
  148. data/test/test_object.rb +99 -96
  149. data/test/test_parser.rb +11 -0
  150. data/test/test_parser_debug.rb +27 -0
  151. data/test/test_parser_saj.rb +337 -0
  152. data/test/test_parser_usual.rb +251 -0
  153. data/test/test_rails.rb +2 -2
  154. data/test/test_saj.rb +10 -8
  155. data/test/test_scp.rb +38 -40
  156. data/test/test_strict.rb +40 -32
  157. data/test/test_various.rb +165 -84
  158. data/test/test_wab.rb +48 -44
  159. data/test/test_writer.rb +47 -47
  160. data/test/tests.rb +13 -5
  161. data/test/tests_mimic.rb +12 -3
  162. data/test/tests_mimic_addition.rb +12 -3
  163. metadata +75 -127
  164. data/ext/oj/hash.c +0 -135
  165. data/ext/oj/hash.h +0 -18
  166. data/ext/oj/hash_test.c +0 -484
  167. data/test/activesupport4/decoding_test.rb +0 -108
  168. data/test/activesupport4/encoding_test.rb +0 -531
  169. data/test/activesupport4/test_helper.rb +0 -41
  170. data/test/activesupport5/test_helper.rb +0 -72
  171. data/test/bar.rb +0 -35
  172. data/test/baz.rb +0 -16
  173. data/test/zoo.rb +0 -13
data/ext/oj/dump_leaf.c CHANGED
@@ -1,249 +1,162 @@
1
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.
2
3
 
3
4
  #include <errno.h>
4
5
 
5
- #include "oj.h"
6
6
  #include "dump.h"
7
+ #include "oj.h"
7
8
 
8
- static void dump_leaf(Leaf leaf, int depth, Out out);
9
-
10
- static void
11
- grow(Out out, size_t len) {
12
- size_t size = out->end - out->buf;
13
- long pos = out->cur - out->buf;
14
- char *buf;
15
-
16
- size *= 2;
17
- if (size <= len * 2 + pos) {
18
- size += len;
19
- }
20
- if (out->allocated) {
21
- buf = REALLOC_N(out->buf, char, (size + BUFFER_EXTRA));
22
- } else {
23
- buf = ALLOC_N(char, (size + BUFFER_EXTRA));
24
- out->allocated = true;
25
- memcpy(buf, out->buf, out->end - out->buf + BUFFER_EXTRA);
26
- }
27
- if (0 == buf) {
28
- rb_raise(rb_eNoMemError, "Failed to create string. [%d:%s]\n", ENOSPC, strerror(ENOSPC));
29
- }
30
- out->buf = buf;
31
- out->end = buf + size;
32
- out->cur = out->buf + pos;
33
- }
34
-
9
+ static void dump_leaf(Leaf leaf, int depth, Out out);
35
10
 
36
- inline static void
37
- dump_chars(const char *s, size_t size, Out out) {
38
- if (out->end - out->cur <= (long)size) {
39
- grow(out, size);
40
- }
41
- memcpy(out->cur, s, size);
42
- out->cur += size;
11
+ inline static void dump_chars(const char *s, size_t size, Out out) {
12
+ assure_size(out, size);
13
+ APPEND_CHARS(out->cur, s, size);
43
14
  *out->cur = '\0';
44
15
  }
45
16
 
46
- static void
47
- dump_leaf_str(Leaf leaf, Out out) {
17
+ static void dump_leaf_str(Leaf leaf, Out out) {
48
18
  switch (leaf->value_type) {
49
- case STR_VAL:
50
- oj_dump_cstr(leaf->str, strlen(leaf->str), 0, 0, out);
51
- break;
52
- case RUBY_VAL:
53
- oj_dump_cstr(rb_string_value_cstr(&leaf->value), (int)RSTRING_LEN(leaf->value), 0, 0, out);
54
- break;
19
+ case STR_VAL: oj_dump_cstr(leaf->str, strlen(leaf->str), 0, 0, out); break;
20
+ case RUBY_VAL: oj_dump_cstr(StringValueCStr(leaf->value), (int)RSTRING_LEN(leaf->value), 0, 0, out); break;
55
21
  case COL_VAL:
56
- default:
57
- rb_raise(rb_eTypeError, "Unexpected value type %02x.\n", leaf->value_type);
58
- break;
22
+ default: rb_raise(rb_eTypeError, "Unexpected value type %02x.\n", leaf->value_type); break;
59
23
  }
60
24
  }
61
25
 
62
- static void
63
- dump_leaf_fixnum(Leaf leaf, Out out) {
26
+ static void dump_leaf_fixnum(Leaf leaf, Out out) {
64
27
  switch (leaf->value_type) {
65
- case STR_VAL:
66
- dump_chars(leaf->str, strlen(leaf->str), out);
67
- break;
28
+ case STR_VAL: dump_chars(leaf->str, strlen(leaf->str), out); break;
68
29
  case RUBY_VAL:
69
- if (T_BIGNUM == rb_type(leaf->value)) {
70
- oj_dump_bignum(leaf->value, 0, out, false);
71
- } else {
72
- oj_dump_fixnum(leaf->value, 0, out, false);
73
- }
74
- break;
30
+ if (T_BIGNUM == rb_type(leaf->value)) {
31
+ oj_dump_bignum(leaf->value, 0, out, false);
32
+ } else {
33
+ oj_dump_fixnum(leaf->value, 0, out, false);
34
+ }
35
+ break;
75
36
  case COL_VAL:
76
- default:
77
- rb_raise(rb_eTypeError, "Unexpected value type %02x.\n", leaf->value_type);
78
- break;
37
+ default: rb_raise(rb_eTypeError, "Unexpected value type %02x.\n", leaf->value_type); break;
79
38
  }
80
39
  }
81
40
 
82
- static void
83
- dump_leaf_float(Leaf leaf, Out out) {
41
+ static void dump_leaf_float(Leaf leaf, Out out) {
84
42
  switch (leaf->value_type) {
85
- case STR_VAL:
86
- dump_chars(leaf->str, strlen(leaf->str), out);
87
- break;
88
- case RUBY_VAL:
89
- oj_dump_float(leaf->value, 0, out, false);
90
- break;
43
+ case STR_VAL: dump_chars(leaf->str, strlen(leaf->str), out); break;
44
+ case RUBY_VAL: oj_dump_float(leaf->value, 0, out, false); break;
91
45
  case COL_VAL:
92
- default:
93
- rb_raise(rb_eTypeError, "Unexpected value type %02x.\n", leaf->value_type);
94
- break;
46
+ default: rb_raise(rb_eTypeError, "Unexpected value type %02x.\n", leaf->value_type); break;
95
47
  }
96
48
  }
97
49
 
98
- static void
99
- dump_leaf_array(Leaf leaf, int depth, Out out) {
100
- size_t size;
101
- int d2 = depth + 1;
50
+ static void dump_leaf_array(Leaf leaf, int depth, Out out) {
51
+ size_t size;
52
+ int d2 = depth + 1;
102
53
 
103
54
  size = 2;
104
- if (out->end - out->cur <= (long)size) {
105
- grow(out, size);
106
- }
55
+ assure_size(out, size);
107
56
  *out->cur++ = '[';
108
57
  if (0 == leaf->elements) {
109
- *out->cur++ = ']';
58
+ *out->cur++ = ']';
110
59
  } else {
111
- Leaf first = leaf->elements->next;
112
- Leaf e = first;
113
-
114
- size = d2 * out->indent + 2;
115
- do {
116
- if (out->end - out->cur <= (long)size) {
117
- grow(out, size);
118
- }
119
- fill_indent(out, d2);
120
- dump_leaf(e, d2, out);
121
- if (e->next != first) {
122
- *out->cur++ = ',';
123
- }
124
- e = e->next;
125
- } while (e != first);
126
- size = depth * out->indent + 1;
127
- if (out->end - out->cur <= (long)size) {
128
- grow(out, size);
129
- }
130
- fill_indent(out, depth);
131
- *out->cur++ = ']';
60
+ Leaf first = leaf->elements->next;
61
+ Leaf e = first;
62
+
63
+ size = d2 * out->indent + 2;
64
+ do {
65
+ assure_size(out, size);
66
+ fill_indent(out, d2);
67
+ dump_leaf(e, d2, out);
68
+ if (e->next != first) {
69
+ *out->cur++ = ',';
70
+ }
71
+ e = e->next;
72
+ } while (e != first);
73
+ size = depth * out->indent + 1;
74
+ assure_size(out, size);
75
+ fill_indent(out, depth);
76
+ *out->cur++ = ']';
132
77
  }
133
78
  *out->cur = '\0';
134
79
  }
135
80
 
136
- static void
137
- dump_leaf_hash(Leaf leaf, int depth, Out out) {
138
- size_t size;
139
- int d2 = depth + 1;
81
+ static void dump_leaf_hash(Leaf leaf, int depth, Out out) {
82
+ size_t size;
83
+ int d2 = depth + 1;
140
84
 
141
85
  size = 2;
142
- if (out->end - out->cur <= (long)size) {
143
- grow(out, size);
144
- }
86
+ assure_size(out, size);
145
87
  *out->cur++ = '{';
146
88
  if (0 == leaf->elements) {
147
- *out->cur++ = '}';
89
+ *out->cur++ = '}';
148
90
  } else {
149
- Leaf first = leaf->elements->next;
150
- Leaf e = first;
151
-
152
- size = d2 * out->indent + 2;
153
- do {
154
- if (out->end - out->cur <= (long)size) {
155
- grow(out, size);
156
- }
157
- fill_indent(out, d2);
158
- oj_dump_cstr(e->key, strlen(e->key), 0, 0, out);
159
- *out->cur++ = ':';
160
- dump_leaf(e, d2, out);
161
- if (e->next != first) {
162
- *out->cur++ = ',';
163
- }
164
- e = e->next;
165
- } while (e != first);
166
- size = depth * out->indent + 1;
167
- if (out->end - out->cur <= (long)size) {
168
- grow(out, size);
169
- }
170
- fill_indent(out, depth);
171
- *out->cur++ = '}';
91
+ Leaf first = leaf->elements->next;
92
+ Leaf e = first;
93
+
94
+ size = d2 * out->indent + 2;
95
+ do {
96
+ assure_size(out, size);
97
+ fill_indent(out, d2);
98
+ oj_dump_cstr(e->key, strlen(e->key), 0, 0, out);
99
+ *out->cur++ = ':';
100
+ dump_leaf(e, d2, out);
101
+ if (e->next != first) {
102
+ *out->cur++ = ',';
103
+ }
104
+ e = e->next;
105
+ } while (e != first);
106
+ size = depth * out->indent + 1;
107
+ assure_size(out, size);
108
+ fill_indent(out, depth);
109
+ *out->cur++ = '}';
172
110
  }
173
111
  *out->cur = '\0';
174
112
  }
175
113
 
176
- static void
177
- dump_leaf(Leaf leaf, int depth, Out out) {
114
+ static void dump_leaf(Leaf leaf, int depth, Out out) {
178
115
  switch (leaf->rtype) {
179
- case T_NIL:
180
- oj_dump_nil(Qnil, 0, out, false);
181
- break;
182
- case T_TRUE:
183
- oj_dump_true(Qtrue, 0, out, false);
184
- break;
185
- case T_FALSE:
186
- oj_dump_false(Qfalse, 0, out, false);
187
- break;
188
- case T_STRING:
189
- dump_leaf_str(leaf, out);
190
- break;
191
- case T_FIXNUM:
192
- dump_leaf_fixnum(leaf, out);
193
- break;
194
- case T_FLOAT:
195
- dump_leaf_float(leaf, out);
196
- break;
197
- case T_ARRAY:
198
- dump_leaf_array(leaf, depth, out);
199
- break;
200
- case T_HASH:
201
- dump_leaf_hash(leaf, depth, out);
202
- break;
203
- default:
204
- rb_raise(rb_eTypeError, "Unexpected type %02x.\n", leaf->rtype);
205
- break;
116
+ case T_NIL: oj_dump_nil(Qnil, 0, out, false); break;
117
+ case T_TRUE: oj_dump_true(Qtrue, 0, out, false); break;
118
+ case T_FALSE: oj_dump_false(Qfalse, 0, out, false); break;
119
+ case T_STRING: dump_leaf_str(leaf, out); break;
120
+ case T_FIXNUM: dump_leaf_fixnum(leaf, out); break;
121
+ case T_FLOAT: dump_leaf_float(leaf, out); break;
122
+ case T_ARRAY: dump_leaf_array(leaf, depth, out); break;
123
+ case T_HASH: dump_leaf_hash(leaf, depth, out); break;
124
+ default: rb_raise(rb_eTypeError, "Unexpected type %02x.\n", leaf->rtype); break;
206
125
  }
207
126
  }
208
127
 
209
- void
210
- oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out) {
128
+ void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out) {
211
129
  if (0 == out->buf) {
212
- out->buf = ALLOC_N(char, 4096);
213
- out->end = out->buf + 4095 - BUFFER_EXTRA; // 1 less than end plus extra for possible errors
214
- out->allocated = true;
130
+ oj_out_init(out);
215
131
  }
216
- out->cur = out->buf;
132
+ out->cur = out->buf;
217
133
  out->circ_cnt = 0;
218
- out->opts = copts;
134
+ out->opts = copts;
219
135
  out->hash_cnt = 0;
220
- out->indent = copts->indent;
136
+ out->indent = copts->indent;
221
137
  dump_leaf(leaf, 0, out);
222
138
  }
223
139
 
224
- void
225
- oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts) {
226
- char buf[4096];
140
+ void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts) {
227
141
  struct _out out;
228
- size_t size;
229
- FILE *f;
142
+ size_t size;
143
+ FILE *f;
144
+
145
+ oj_out_init(&out);
230
146
 
231
- out.buf = buf;
232
- out.end = buf + sizeof(buf) - BUFFER_EXTRA;
233
- out.allocated = false;
234
147
  out.omit_nil = copts->dump_opts.omit_nil;
235
148
  oj_dump_leaf_to_json(leaf, copts, &out);
236
149
  size = out.cur - out.buf;
237
150
  if (0 == (f = fopen(path, "w"))) {
238
- rb_raise(rb_eIOError, "%s\n", strerror(errno));
151
+ rb_raise(rb_eIOError, "%s\n", strerror(errno));
239
152
  }
240
153
  if (size != fwrite(out.buf, 1, size, f)) {
241
- int err = ferror(f);
154
+ int err = ferror(f);
242
155
 
243
- rb_raise(rb_eIOError, "Write failed. [%d:%s]\n", err, strerror(err));
244
- }
245
- if (out.allocated) {
246
- xfree(out.buf);
156
+ rb_raise(rb_eIOError, "Write failed. [%d:%s]\n", err, strerror(err));
247
157
  }
158
+
159
+ oj_out_free(&out);
160
+
248
161
  fclose(f);
249
162
  }