oj 3.9.1 → 3.16.11

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 (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1452 -0
  3. data/README.md +21 -6
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +50 -68
  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 +9 -36
  10. data/ext/oj/circarray.c +38 -42
  11. data/ext/oj/circarray.h +12 -13
  12. data/ext/oj/code.c +158 -179
  13. data/ext/oj/code.h +20 -22
  14. data/ext/oj/compat.c +145 -205
  15. data/ext/oj/custom.c +740 -880
  16. data/ext/oj/debug.c +126 -0
  17. data/ext/oj/dump.c +1145 -844
  18. data/ext/oj/dump.h +71 -57
  19. data/ext/oj/dump_compat.c +575 -655
  20. data/ext/oj/dump_leaf.c +96 -186
  21. data/ext/oj/dump_object.c +533 -660
  22. data/ext/oj/dump_strict.c +306 -340
  23. data/ext/oj/encode.h +4 -33
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +28 -28
  26. data/ext/oj/err.h +39 -42
  27. data/ext/oj/extconf.rb +28 -7
  28. data/ext/oj/fast.c +1052 -1113
  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 +471 -430
  34. data/ext/oj/object.c +532 -580
  35. data/ext/oj/odd.c +156 -142
  36. data/ext/oj/odd.h +25 -26
  37. data/ext/oj/oj.c +1346 -961
  38. data/ext/oj/oj.h +307 -290
  39. data/ext/oj/parse.c +954 -858
  40. data/ext/oj/parse.h +74 -72
  41. data/ext/oj/parser.c +1600 -0
  42. data/ext/oj/parser.h +103 -0
  43. data/ext/oj/rails.c +819 -836
  44. data/ext/oj/rails.h +8 -11
  45. data/ext/oj/reader.c +136 -147
  46. data/ext/oj/reader.h +69 -83
  47. data/ext/oj/resolve.c +41 -63
  48. data/ext/oj/resolve.h +4 -6
  49. data/ext/oj/rxclass.c +69 -72
  50. data/ext/oj/rxclass.h +12 -13
  51. data/ext/oj/saj.c +440 -485
  52. data/ext/oj/saj2.c +584 -0
  53. data/ext/oj/saj2.h +23 -0
  54. data/ext/oj/scp.c +79 -118
  55. data/ext/oj/simd.h +10 -0
  56. data/ext/oj/sparse.c +739 -709
  57. data/ext/oj/stream_writer.c +141 -175
  58. data/ext/oj/strict.c +103 -128
  59. data/ext/oj/string_writer.c +244 -261
  60. data/ext/oj/trace.c +34 -41
  61. data/ext/oj/trace.h +42 -15
  62. data/ext/oj/usual.c +1218 -0
  63. data/ext/oj/usual.h +69 -0
  64. data/ext/oj/util.c +107 -107
  65. data/ext/oj/util.h +4 -3
  66. data/ext/oj/val_stack.c +61 -78
  67. data/ext/oj/val_stack.h +80 -114
  68. data/ext/oj/validate.c +46 -0
  69. data/ext/oj/wab.c +316 -361
  70. data/lib/oj/active_support_helper.rb +1 -3
  71. data/lib/oj/bag.rb +8 -1
  72. data/lib/oj/easy_hash.rb +9 -9
  73. data/lib/oj/error.rb +1 -2
  74. data/lib/oj/json.rb +162 -150
  75. data/lib/oj/mimic.rb +54 -20
  76. data/lib/oj/saj.rb +20 -6
  77. data/lib/oj/schandler.rb +5 -4
  78. data/lib/oj/state.rb +12 -8
  79. data/lib/oj/version.rb +1 -2
  80. data/lib/oj.rb +2 -8
  81. data/pages/Compatibility.md +1 -1
  82. data/pages/Encoding.md +1 -1
  83. data/pages/InstallOptions.md +20 -0
  84. data/pages/JsonGem.md +15 -0
  85. data/pages/Modes.md +9 -3
  86. data/pages/Options.md +62 -12
  87. data/pages/Parser.md +309 -0
  88. data/pages/Rails.md +73 -22
  89. metadata +68 -192
  90. data/ext/oj/hash.c +0 -163
  91. data/ext/oj/hash.h +0 -46
  92. data/ext/oj/hash_test.c +0 -512
  93. data/test/_test_active.rb +0 -76
  94. data/test/_test_active_mimic.rb +0 -96
  95. data/test/_test_mimic_rails.rb +0 -126
  96. data/test/activerecord/result_test.rb +0 -27
  97. data/test/activesupport4/decoding_test.rb +0 -108
  98. data/test/activesupport4/encoding_test.rb +0 -531
  99. data/test/activesupport4/test_helper.rb +0 -41
  100. data/test/activesupport5/decoding_test.rb +0 -125
  101. data/test/activesupport5/encoding_test.rb +0 -485
  102. data/test/activesupport5/encoding_test_cases.rb +0 -90
  103. data/test/activesupport5/test_helper.rb +0 -50
  104. data/test/activesupport5/time_zone_test_helpers.rb +0 -24
  105. data/test/bar.rb +0 -25
  106. data/test/files.rb +0 -29
  107. data/test/foo.rb +0 -21
  108. data/test/helper.rb +0 -26
  109. data/test/isolated/shared.rb +0 -308
  110. data/test/isolated/test_mimic_after.rb +0 -13
  111. data/test/isolated/test_mimic_alone.rb +0 -12
  112. data/test/isolated/test_mimic_as_json.rb +0 -45
  113. data/test/isolated/test_mimic_before.rb +0 -13
  114. data/test/isolated/test_mimic_define.rb +0 -28
  115. data/test/isolated/test_mimic_rails_after.rb +0 -22
  116. data/test/isolated/test_mimic_rails_before.rb +0 -21
  117. data/test/isolated/test_mimic_redefine.rb +0 -15
  118. data/test/json_gem/json_addition_test.rb +0 -216
  119. data/test/json_gem/json_common_interface_test.rb +0 -148
  120. data/test/json_gem/json_encoding_test.rb +0 -107
  121. data/test/json_gem/json_ext_parser_test.rb +0 -20
  122. data/test/json_gem/json_fixtures_test.rb +0 -35
  123. data/test/json_gem/json_generator_test.rb +0 -383
  124. data/test/json_gem/json_generic_object_test.rb +0 -90
  125. data/test/json_gem/json_parser_test.rb +0 -470
  126. data/test/json_gem/json_string_matching_test.rb +0 -42
  127. data/test/json_gem/test_helper.rb +0 -18
  128. data/test/perf.rb +0 -107
  129. data/test/perf_compat.rb +0 -130
  130. data/test/perf_fast.rb +0 -164
  131. data/test/perf_file.rb +0 -64
  132. data/test/perf_object.rb +0 -138
  133. data/test/perf_saj.rb +0 -109
  134. data/test/perf_scp.rb +0 -151
  135. data/test/perf_simple.rb +0 -287
  136. data/test/perf_strict.rb +0 -145
  137. data/test/perf_wab.rb +0 -131
  138. data/test/sample/change.rb +0 -14
  139. data/test/sample/dir.rb +0 -19
  140. data/test/sample/doc.rb +0 -36
  141. data/test/sample/file.rb +0 -48
  142. data/test/sample/group.rb +0 -16
  143. data/test/sample/hasprops.rb +0 -16
  144. data/test/sample/layer.rb +0 -12
  145. data/test/sample/line.rb +0 -20
  146. data/test/sample/oval.rb +0 -10
  147. data/test/sample/rect.rb +0 -10
  148. data/test/sample/shape.rb +0 -35
  149. data/test/sample/text.rb +0 -20
  150. data/test/sample.rb +0 -54
  151. data/test/sample_json.rb +0 -37
  152. data/test/test_compat.rb +0 -509
  153. data/test/test_custom.rb +0 -503
  154. data/test/test_debian.rb +0 -53
  155. data/test/test_fast.rb +0 -470
  156. data/test/test_file.rb +0 -239
  157. data/test/test_gc.rb +0 -49
  158. data/test/test_hash.rb +0 -29
  159. data/test/test_integer_range.rb +0 -73
  160. data/test/test_null.rb +0 -376
  161. data/test/test_object.rb +0 -1018
  162. data/test/test_saj.rb +0 -186
  163. data/test/test_scp.rb +0 -433
  164. data/test/test_strict.rb +0 -410
  165. data/test/test_various.rb +0 -741
  166. data/test/test_wab.rb +0 -307
  167. data/test/test_writer.rb +0 -380
  168. data/test/tests.rb +0 -24
  169. data/test/tests_mimic.rb +0 -14
  170. data/test/tests_mimic_addition.rb +0 -7
  171. data/test/zoo.rb +0 -13
data/ext/oj/strict.c CHANGED
@@ -1,210 +1,185 @@
1
- /* strict.c
2
- * Copyright (c) 2012, Peter Ohler
3
- * All rights reserved.
4
- */
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.
5
3
 
6
- #include <stdlib.h>
7
4
  #include <stdio.h>
5
+ #include <stdlib.h>
8
6
  #include <string.h>
9
7
  #include <unistd.h>
10
8
 
11
- #include "oj.h"
9
+ #include "encode.h"
12
10
  #include "err.h"
11
+ #include "intern.h"
12
+ #include "oj.h"
13
13
  #include "parse.h"
14
- #include "encode.h"
15
14
  #include "trace.h"
16
15
 
17
- static void
18
- hash_end(ParseInfo pi) {
19
- if (Yes == pi->options.trace) {
20
- oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
16
+ VALUE oj_cstr_to_value(const char *str, size_t len, size_t cache_str) {
17
+ volatile VALUE rstr = Qnil;
18
+
19
+ if (len < cache_str) {
20
+ rstr = oj_str_intern(str, len);
21
+ } else {
22
+ rstr = rb_utf8_str_new(str, len);
21
23
  }
24
+ return rstr;
22
25
  }
23
26
 
24
- static void
25
- array_end(ParseInfo pi) {
26
- if (Yes == pi->options.trace) {
27
- oj_trace_parse_array_end(pi, __FILE__, __LINE__);
27
+ VALUE oj_calc_hash_key(ParseInfo pi, Val parent) {
28
+ volatile VALUE rkey = parent->key_val;
29
+
30
+ if (Qundef != rkey) {
31
+ return rkey;
32
+ }
33
+ if (Yes != pi->options.cache_keys) {
34
+ if (Yes == pi->options.sym_key) {
35
+ rkey = ID2SYM(rb_intern3(parent->key, parent->klen, oj_utf8_encoding));
36
+ } else {
37
+ rkey = rb_utf8_str_new(parent->key, parent->klen);
38
+ OBJ_FREEZE(rkey); // frozen when used as a Hash key anyway
39
+ }
40
+ return rkey;
28
41
  }
42
+ if (Yes == pi->options.sym_key) {
43
+ rkey = oj_sym_intern(parent->key, parent->klen);
44
+ } else {
45
+ rkey = oj_str_intern(parent->key, parent->klen);
46
+ }
47
+ return rkey;
29
48
  }
30
49
 
31
- static VALUE
32
- noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
50
+ static void hash_end(ParseInfo pi) {
51
+ TRACE_PARSE_HASH_END(pi->options.trace, pi);
52
+ }
53
+
54
+ static void array_end(ParseInfo pi) {
55
+ TRACE_PARSE_ARRAY_END(pi->options.trace, pi);
56
+ }
57
+
58
+ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
33
59
  return Qundef;
34
60
  }
35
61
 
36
- static void
37
- add_value(ParseInfo pi, VALUE val) {
38
- if (Yes == pi->options.trace) {
39
- oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
40
- }
62
+ static void add_value(ParseInfo pi, VALUE val) {
63
+ TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, val);
41
64
  pi->stack.head->val = val;
42
65
  }
43
66
 
44
- static void
45
- add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
46
- volatile VALUE rstr = rb_str_new(str, len);
67
+ static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
68
+ volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
47
69
 
48
- rstr = oj_encode(rstr);
49
70
  pi->stack.head->val = rstr;
50
- if (Yes == pi->options.trace) {
51
- oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, rstr);
52
- }
71
+ TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, rstr);
53
72
  }
54
73
 
55
- static void
56
- add_num(ParseInfo pi, NumInfo ni) {
74
+ static void add_num(ParseInfo pi, NumInfo ni) {
57
75
  if (ni->infinity || ni->nan) {
58
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
76
+ oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
59
77
  }
60
78
  pi->stack.head->val = oj_num_as_value(ni);
61
- if (Yes == pi->options.trace) {
62
- oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
63
- }
79
+ TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, pi->stack.head->val);
64
80
  }
65
81
 
66
- static VALUE
67
- start_hash(ParseInfo pi) {
82
+ static VALUE start_hash(ParseInfo pi) {
68
83
  if (Qnil != pi->options.hash_class) {
69
- return rb_class_new_instance(0, NULL, pi->options.hash_class);
70
- }
71
- if (Yes == pi->options.trace) {
72
- oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
84
+ return rb_class_new_instance(0, NULL, pi->options.hash_class);
73
85
  }
86
+ TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
74
87
  return rb_hash_new();
75
88
  }
76
89
 
77
- static VALUE
78
- calc_hash_key(ParseInfo pi, Val parent) {
79
- volatile VALUE rkey = parent->key_val;
90
+ static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char *orig) {
91
+ volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
80
92
 
81
- if (Qundef == rkey) {
82
- rkey = rb_str_new(parent->key, parent->klen);
83
- }
84
- rkey = oj_encode(rkey);
85
- if (Yes == pi->options.sym_key) {
86
- rkey = rb_str_intern(rkey);
87
- }
88
- return rkey;
93
+ rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), rstr);
94
+ TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rstr);
89
95
  }
90
96
 
91
- static void
92
- hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char *orig) {
93
- volatile VALUE rstr = rb_str_new(str, len);
94
-
95
- rstr = oj_encode(rstr);
96
- rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rstr);
97
- if (Yes == pi->options.trace) {
98
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
99
- }
100
- }
97
+ static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
98
+ volatile VALUE v;
101
99
 
102
- static void
103
- hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
104
- volatile VALUE v;
105
-
106
100
  if (ni->infinity || ni->nan) {
107
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
101
+ oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
108
102
  }
109
103
  v = oj_num_as_value(ni);
110
- rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), v);
111
- if (Yes == pi->options.trace) {
112
- oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, v);
113
- }
104
+ rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), v);
105
+ TRACE_PARSE_CALL(pi->options.trace, "set_number", pi, v);
114
106
  }
115
107
 
116
- static void
117
- hash_set_value(ParseInfo pi, Val parent, VALUE value) {
118
- rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), value);
119
- if (Yes == pi->options.trace) {
120
- oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
121
- }
108
+ static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
109
+ rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), value);
110
+ TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
122
111
  }
123
112
 
124
- static VALUE
125
- start_array(ParseInfo pi) {
126
- if (Yes == pi->options.trace) {
127
- oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
128
- }
113
+ static VALUE start_array(ParseInfo pi) {
114
+ TRACE_PARSE_IN(pi->options.trace, "start_array", pi);
129
115
  return rb_ary_new();
130
116
  }
131
117
 
132
- static void
133
- array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
134
- volatile VALUE rstr = rb_str_new(str, len);
118
+ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
119
+ volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
135
120
 
136
- rstr = oj_encode(rstr);
137
121
  rb_ary_push(stack_peek(&pi->stack)->val, rstr);
138
- if (Yes == pi->options.trace) {
139
- oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
140
- }
122
+ TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rstr);
141
123
  }
142
124
 
143
- static void
144
- array_append_num(ParseInfo pi, NumInfo ni) {
145
- volatile VALUE v;
146
-
125
+ static void array_append_num(ParseInfo pi, NumInfo ni) {
126
+ volatile VALUE v;
127
+
147
128
  if (ni->infinity || ni->nan) {
148
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
129
+ oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
149
130
  }
150
131
  v = oj_num_as_value(ni);
151
132
  rb_ary_push(stack_peek(&pi->stack)->val, v);
152
- if (Yes == pi->options.trace) {
153
- oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, v);
154
- }
133
+ TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, v);
155
134
  }
156
135
 
157
- static void
158
- array_append_value(ParseInfo pi, VALUE value) {
136
+ static void array_append_value(ParseInfo pi, VALUE value) {
159
137
  rb_ary_push(stack_peek(&pi->stack)->val, value);
160
- if (Yes == pi->options.trace) {
161
- oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
162
- }
163
- }
164
-
165
- void
166
- oj_set_strict_callbacks(ParseInfo pi) {
167
- pi->start_hash = start_hash;
168
- pi->end_hash = hash_end;
169
- pi->hash_key = noop_hash_key;
170
- pi->hash_set_cstr = hash_set_cstr;
171
- pi->hash_set_num = hash_set_num;
172
- pi->hash_set_value = hash_set_value;
173
- pi->start_array = start_array;
174
- pi->end_array = array_end;
175
- pi->array_append_cstr = array_append_cstr;
176
- pi->array_append_num = array_append_num;
138
+ TRACE_PARSE_CALL(pi->options.trace, "append_value", pi, value);
139
+ }
140
+
141
+ void oj_set_strict_callbacks(ParseInfo pi) {
142
+ pi->start_hash = start_hash;
143
+ pi->end_hash = hash_end;
144
+ pi->hash_key = noop_hash_key;
145
+ pi->hash_set_cstr = hash_set_cstr;
146
+ pi->hash_set_num = hash_set_num;
147
+ pi->hash_set_value = hash_set_value;
148
+ pi->start_array = start_array;
149
+ pi->end_array = array_end;
150
+ pi->array_append_cstr = array_append_cstr;
151
+ pi->array_append_num = array_append_num;
177
152
  pi->array_append_value = array_append_value;
178
- pi->add_cstr = add_cstr;
179
- pi->add_num = add_num;
180
- pi->add_value = add_value;
181
- pi->expect_value = 1;
153
+ pi->add_cstr = add_cstr;
154
+ pi->add_num = add_num;
155
+ pi->add_value = add_value;
156
+ pi->expect_value = 1;
182
157
  }
183
158
 
184
159
  VALUE
185
160
  oj_strict_parse(int argc, VALUE *argv, VALUE self) {
186
- struct _parseInfo pi;
161
+ struct _parseInfo pi;
187
162
 
188
163
  parse_info_init(&pi);
189
- pi.options = oj_default_options;
190
- pi.handler = Qnil;
164
+ pi.options = oj_default_options;
165
+ pi.handler = Qnil;
191
166
  pi.err_class = Qnil;
192
167
  oj_set_strict_callbacks(&pi);
193
168
 
194
169
  if (T_STRING == rb_type(*argv)) {
195
- return oj_pi_parse(argc, argv, &pi, 0, 0, true);
170
+ return oj_pi_parse(argc, argv, &pi, 0, 0, true);
196
171
  } else {
197
- return oj_pi_sparse(argc, argv, &pi, 0);
172
+ return oj_pi_sparse(argc, argv, &pi, 0);
198
173
  }
199
174
  }
200
175
 
201
176
  VALUE
202
177
  oj_strict_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
203
- struct _parseInfo pi;
178
+ struct _parseInfo pi;
204
179
 
205
180
  parse_info_init(&pi);
206
- pi.options = oj_default_options;
207
- pi.handler = Qnil;
181
+ pi.options = oj_default_options;
182
+ pi.handler = Qnil;
208
183
  pi.err_class = Qnil;
209
184
  oj_set_strict_callbacks(&pi);
210
185