oj 3.11.5 → 3.16.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1421 -0
  3. data/README.md +19 -5
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +20 -6
  6. data/ext/oj/cache.c +329 -0
  7. data/ext/oj/cache.h +22 -0
  8. data/ext/oj/cache8.c +10 -9
  9. data/ext/oj/circarray.c +8 -6
  10. data/ext/oj/circarray.h +2 -2
  11. data/ext/oj/code.c +19 -33
  12. data/ext/oj/code.h +2 -2
  13. data/ext/oj/compat.c +27 -77
  14. data/ext/oj/custom.c +86 -179
  15. data/ext/oj/debug.c +126 -0
  16. data/ext/oj/dump.c +256 -249
  17. data/ext/oj/dump.h +26 -12
  18. data/ext/oj/dump_compat.c +565 -642
  19. data/ext/oj/dump_leaf.c +17 -63
  20. data/ext/oj/dump_object.c +65 -187
  21. data/ext/oj/dump_strict.c +27 -51
  22. data/ext/oj/encoder.c +43 -0
  23. data/ext/oj/err.c +2 -13
  24. data/ext/oj/err.h +24 -8
  25. data/ext/oj/extconf.rb +21 -6
  26. data/ext/oj/fast.c +149 -149
  27. data/ext/oj/intern.c +313 -0
  28. data/ext/oj/intern.h +22 -0
  29. data/ext/oj/mem.c +318 -0
  30. data/ext/oj/mem.h +53 -0
  31. data/ext/oj/mimic_json.c +121 -106
  32. data/ext/oj/object.c +85 -162
  33. data/ext/oj/odd.c +89 -67
  34. data/ext/oj/odd.h +15 -15
  35. data/ext/oj/oj.c +542 -411
  36. data/ext/oj/oj.h +99 -73
  37. data/ext/oj/parse.c +175 -187
  38. data/ext/oj/parse.h +26 -24
  39. data/ext/oj/parser.c +1600 -0
  40. data/ext/oj/parser.h +101 -0
  41. data/ext/oj/rails.c +112 -159
  42. data/ext/oj/rails.h +1 -1
  43. data/ext/oj/reader.c +11 -14
  44. data/ext/oj/reader.h +4 -2
  45. data/ext/oj/resolve.c +5 -24
  46. data/ext/oj/rxclass.c +7 -6
  47. data/ext/oj/rxclass.h +1 -1
  48. data/ext/oj/saj.c +22 -33
  49. data/ext/oj/saj2.c +584 -0
  50. data/ext/oj/saj2.h +23 -0
  51. data/ext/oj/scp.c +5 -28
  52. data/ext/oj/sparse.c +28 -72
  53. data/ext/oj/stream_writer.c +50 -40
  54. data/ext/oj/strict.c +56 -61
  55. data/ext/oj/string_writer.c +72 -39
  56. data/ext/oj/trace.h +31 -4
  57. data/ext/oj/usual.c +1218 -0
  58. data/ext/oj/usual.h +69 -0
  59. data/ext/oj/util.h +1 -1
  60. data/ext/oj/val_stack.c +14 -3
  61. data/ext/oj/val_stack.h +8 -7
  62. data/ext/oj/validate.c +46 -0
  63. data/ext/oj/wab.c +63 -88
  64. data/lib/oj/active_support_helper.rb +1 -3
  65. data/lib/oj/bag.rb +7 -1
  66. data/lib/oj/easy_hash.rb +4 -5
  67. data/lib/oj/error.rb +1 -2
  68. data/lib/oj/json.rb +162 -150
  69. data/lib/oj/mimic.rb +9 -7
  70. data/lib/oj/saj.rb +20 -6
  71. data/lib/oj/schandler.rb +5 -4
  72. data/lib/oj/state.rb +12 -8
  73. data/lib/oj/version.rb +1 -2
  74. data/lib/oj.rb +2 -0
  75. data/pages/Compatibility.md +1 -1
  76. data/pages/InstallOptions.md +20 -0
  77. data/pages/JsonGem.md +15 -0
  78. data/pages/Modes.md +8 -3
  79. data/pages/Options.md +43 -5
  80. data/pages/Parser.md +309 -0
  81. data/pages/Rails.md +14 -2
  82. data/test/_test_active.rb +8 -9
  83. data/test/_test_active_mimic.rb +7 -8
  84. data/test/_test_mimic_rails.rb +17 -20
  85. data/test/activerecord/result_test.rb +5 -6
  86. data/test/activesupport6/encoding_test.rb +63 -28
  87. data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
  88. data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
  89. data/test/{activesupport5 → activesupport7}/encoding_test.rb +86 -50
  90. data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
  91. data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
  92. data/test/files.rb +15 -15
  93. data/test/foo.rb +16 -45
  94. data/test/helper.rb +11 -8
  95. data/test/isolated/shared.rb +3 -2
  96. data/test/json_gem/json_addition_test.rb +2 -2
  97. data/test/json_gem/json_common_interface_test.rb +8 -6
  98. data/test/json_gem/json_encoding_test.rb +0 -0
  99. data/test/json_gem/json_ext_parser_test.rb +1 -0
  100. data/test/json_gem/json_fixtures_test.rb +3 -2
  101. data/test/json_gem/json_generator_test.rb +56 -38
  102. data/test/json_gem/json_generic_object_test.rb +11 -11
  103. data/test/json_gem/json_parser_test.rb +54 -47
  104. data/test/json_gem/json_string_matching_test.rb +9 -9
  105. data/test/json_gem/test_helper.rb +7 -3
  106. data/test/mem.rb +34 -0
  107. data/test/perf.rb +22 -27
  108. data/test/perf_compat.rb +31 -33
  109. data/test/perf_dump.rb +50 -0
  110. data/test/perf_fast.rb +80 -82
  111. data/test/perf_file.rb +27 -29
  112. data/test/perf_object.rb +65 -69
  113. data/test/perf_once.rb +59 -0
  114. data/test/perf_parser.rb +183 -0
  115. data/test/perf_saj.rb +46 -54
  116. data/test/perf_scp.rb +58 -69
  117. data/test/perf_simple.rb +41 -39
  118. data/test/perf_strict.rb +74 -82
  119. data/test/perf_wab.rb +67 -69
  120. data/test/prec.rb +5 -5
  121. data/test/sample/change.rb +0 -1
  122. data/test/sample/dir.rb +0 -1
  123. data/test/sample/doc.rb +0 -1
  124. data/test/sample/file.rb +0 -1
  125. data/test/sample/group.rb +0 -1
  126. data/test/sample/hasprops.rb +0 -1
  127. data/test/sample/layer.rb +0 -1
  128. data/test/sample/rect.rb +0 -1
  129. data/test/sample/shape.rb +0 -1
  130. data/test/sample/text.rb +0 -1
  131. data/test/sample.rb +16 -16
  132. data/test/sample_json.rb +8 -8
  133. data/test/test_compat.rb +95 -43
  134. data/test/test_custom.rb +73 -51
  135. data/test/test_debian.rb +7 -10
  136. data/test/test_fast.rb +135 -79
  137. data/test/test_file.rb +41 -30
  138. data/test/test_gc.rb +16 -5
  139. data/test/test_generate.rb +5 -5
  140. data/test/test_hash.rb +5 -5
  141. data/test/test_integer_range.rb +9 -9
  142. data/test/test_null.rb +20 -20
  143. data/test/test_object.rb +99 -96
  144. data/test/test_parser.rb +11 -0
  145. data/test/test_parser_debug.rb +27 -0
  146. data/test/test_parser_saj.rb +337 -0
  147. data/test/test_parser_usual.rb +251 -0
  148. data/test/test_rails.rb +2 -2
  149. data/test/test_saj.rb +10 -8
  150. data/test/test_scp.rb +37 -39
  151. data/test/test_strict.rb +40 -32
  152. data/test/test_various.rb +165 -84
  153. data/test/test_wab.rb +48 -44
  154. data/test/test_writer.rb +47 -47
  155. data/test/tests.rb +13 -5
  156. data/test/tests_mimic.rb +12 -3
  157. data/test/tests_mimic_addition.rb +12 -3
  158. metadata +74 -128
  159. data/ext/oj/hash.c +0 -131
  160. data/ext/oj/hash.h +0 -19
  161. data/ext/oj/hash_test.c +0 -491
  162. data/test/activesupport4/decoding_test.rb +0 -108
  163. data/test/activesupport4/encoding_test.rb +0 -531
  164. data/test/activesupport4/test_helper.rb +0 -41
  165. data/test/activesupport5/test_helper.rb +0 -72
  166. data/test/bar.rb +0 -35
  167. data/test/baz.rb +0 -16
  168. data/test/zoo.rb +0 -13
data/ext/oj/odd.c CHANGED
@@ -5,28 +5,29 @@
5
5
 
6
6
  #include <string.h>
7
7
 
8
- static struct _odd _odds[4]; // bump up if new initial Odd classes are added
9
- static struct _odd *odds = _odds;
10
- static long odd_cnt = 0;
11
- static ID sec_id;
12
- static ID sec_fraction_id;
13
- static ID to_f_id;
14
- static ID numerator_id;
15
- static ID denominator_id;
16
- static ID rational_id;
17
- static VALUE rational_class;
8
+ #include "mem.h"
9
+
10
+ static Odd odds = NULL;
11
+ static ID sec_id;
12
+ static ID sec_fraction_id;
13
+ static ID to_f_id;
14
+ static ID numerator_id;
15
+ static ID denominator_id;
16
+ static ID rational_id;
18
17
 
19
18
  static void set_class(Odd odd, const char *classname) {
20
19
  const char **np;
21
- ID * idp;
20
+ ID *idp;
22
21
 
23
- odd->classname = classname;
24
- odd->clen = strlen(classname);
25
- odd->clas = rb_const_get(rb_cObject, rb_intern(classname));
22
+ odd->classname = classname;
23
+ odd->clen = strlen(classname);
24
+ odd->clas = rb_const_get(rb_cObject, rb_intern(classname));
25
+ rb_gc_register_mark_object(odd->clas);
26
26
  odd->create_obj = odd->clas;
27
- odd->create_op = rb_intern("new");
28
- odd->is_module = (T_MODULE == rb_type(odd->clas));
29
- odd->raw = 0;
27
+ rb_gc_register_mark_object(odd->create_obj);
28
+ odd->create_op = rb_intern("new");
29
+ odd->is_module = (T_MODULE == rb_type(odd->clas));
30
+ odd->raw = 0;
30
31
  for (np = odd->attr_names, idp = odd->attrs; 0 != *np; np++, idp++) {
31
32
  *idp = rb_intern(*np);
32
33
  }
@@ -37,15 +38,48 @@ static VALUE get_datetime_secs(VALUE obj) {
37
38
  volatile VALUE rsecs = rb_funcall(obj, sec_id, 0);
38
39
  volatile VALUE rfrac = rb_funcall(obj, sec_fraction_id, 0);
39
40
  long sec = NUM2LONG(rsecs);
40
- long long num = rb_num2ll(rb_funcall(rfrac, numerator_id, 0));
41
- long long den = rb_num2ll(rb_funcall(rfrac, denominator_id, 0));
41
+ long long num = NUM2LL(rb_funcall(rfrac, numerator_id, 0));
42
+ long long den = NUM2LL(rb_funcall(rfrac, denominator_id, 0));
42
43
 
43
44
  num += sec * den;
44
45
 
45
46
  return rb_funcall(rb_cObject, rational_id, 2, rb_ll2inum(num), rb_ll2inum(den));
46
47
  }
47
48
 
48
- void oj_odd_init() {
49
+ static void print_odd(Odd odd) {
50
+ const char **np;
51
+ int i;
52
+
53
+ printf(" %s {\n", odd->classname);
54
+ printf(" attr_cnt: %d %p\n", odd->attr_cnt, (void *)odd->attr_names);
55
+ printf(" attr_names: %p\n", (void *)*odd->attr_names);
56
+ printf(" attr_names: %c\n", **odd->attr_names);
57
+ for (i = odd->attr_cnt, np = odd->attr_names; 0 < i; i--, np++) {
58
+ printf(" %d %s\n", i, *np);
59
+ }
60
+ printf(" }\n");
61
+ }
62
+
63
+ void print_all_odds(const char *label) {
64
+ Odd odd;
65
+ printf("@ %s {\n", label);
66
+ for (odd = odds; NULL != odd; odd = odd->next) {
67
+ print_odd(odd);
68
+ }
69
+ printf("}\n");
70
+ }
71
+
72
+ static Odd odd_create(void) {
73
+ Odd odd = OJ_R_ALLOC(struct _odd);
74
+
75
+ memset(odd, 0, sizeof(struct _odd));
76
+ odd->next = odds;
77
+ odds = odd;
78
+
79
+ return odd;
80
+ }
81
+
82
+ void oj_odd_init(void) {
49
83
  Odd odd;
50
84
  const char **np;
51
85
 
@@ -55,11 +89,9 @@ void oj_odd_init() {
55
89
  numerator_id = rb_intern("numerator");
56
90
  denominator_id = rb_intern("denominator");
57
91
  rational_id = rb_intern("Rational");
58
- rational_class = rb_const_get(rb_cObject, rational_id);
59
92
 
60
- memset(_odds, 0, sizeof(_odds));
61
- odd = odds;
62
93
  // Rational
94
+ odd = odd_create();
63
95
  np = odd->attr_names;
64
96
  *np++ = "numerator";
65
97
  *np++ = "denominator";
@@ -68,8 +100,9 @@ void oj_odd_init() {
68
100
  odd->create_obj = rb_cObject;
69
101
  odd->create_op = rational_id;
70
102
  odd->attr_cnt = 2;
103
+
71
104
  // Date
72
- odd++;
105
+ odd = odd_create();
73
106
  np = odd->attr_names;
74
107
  *np++ = "year";
75
108
  *np++ = "month";
@@ -78,8 +111,9 @@ void oj_odd_init() {
78
111
  *np++ = 0;
79
112
  set_class(odd, "Date");
80
113
  odd->attr_cnt = 4;
114
+
81
115
  // DateTime
82
- odd++;
116
+ odd = odd_create();
83
117
  np = odd->attr_names;
84
118
  *np++ = "year";
85
119
  *np++ = "month";
@@ -93,8 +127,9 @@ void oj_odd_init() {
93
127
  set_class(odd, "DateTime");
94
128
  odd->attr_cnt = 8;
95
129
  odd->attrFuncs[5] = get_datetime_secs;
130
+
96
131
  // Range
97
- odd++;
132
+ odd = odd_create();
98
133
  np = odd->attr_names;
99
134
  *np++ = "begin";
100
135
  *np++ = "end";
@@ -102,15 +137,13 @@ void oj_odd_init() {
102
137
  *np++ = 0;
103
138
  set_class(odd, "Range");
104
139
  odd->attr_cnt = 3;
105
-
106
- odd_cnt = odd - odds + 1;
107
140
  }
108
141
 
109
142
  Odd oj_get_odd(VALUE clas) {
110
143
  Odd odd;
111
144
  const char *classname = NULL;
112
145
 
113
- for (odd = odds + odd_cnt - 1; odds <= odd; odd--) {
146
+ for (odd = odds; NULL != odd; odd = odd->next) {
114
147
  if (clas == odd->clas) {
115
148
  return odd;
116
149
  }
@@ -129,21 +162,20 @@ Odd oj_get_odd(VALUE clas) {
129
162
  Odd oj_get_oddc(const char *classname, size_t len) {
130
163
  Odd odd;
131
164
 
132
- for (odd = odds + odd_cnt - 1; odds <= odd; odd--) {
165
+ for (odd = odds; NULL != odd; odd = odd->next) {
133
166
  if (len == odd->clen && 0 == strncmp(classname, odd->classname, len)) {
134
167
  return odd;
135
168
  }
136
- if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) &&
137
- ':' == classname[odd->clen]) {
169
+ if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) && ':' == classname[odd->clen]) {
138
170
  return odd;
139
171
  }
140
172
  }
141
- return 0;
173
+ return NULL;
142
174
  }
143
175
 
144
176
  OddArgs oj_odd_alloc_args(Odd odd) {
145
- OddArgs oa = ALLOC_N(struct _oddArgs, 1);
146
- VALUE * a;
177
+ OddArgs oa = OJ_R_ALLOC_N(struct _oddArgs, 1);
178
+ VALUE *a;
147
179
  int i;
148
180
 
149
181
  oa->odd = odd;
@@ -154,16 +186,15 @@ OddArgs oj_odd_alloc_args(Odd odd) {
154
186
  }
155
187
 
156
188
  void oj_odd_free(OddArgs args) {
157
- xfree(args);
189
+ OJ_R_FREE(args);
158
190
  }
159
191
 
160
192
  int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
161
193
  const char **np;
162
- VALUE * vp;
194
+ VALUE *vp;
163
195
  int i;
164
196
 
165
- for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i;
166
- i--, np++, vp++) {
197
+ for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i; i--, np++, vp++) {
167
198
  if (0 == strncmp(key, *np, klen) && '\0' == *((*np) + klen)) {
168
199
  *vp = value;
169
200
  return 0;
@@ -172,52 +203,43 @@ int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
172
203
  return -1;
173
204
  }
174
205
 
175
- void oj_reg_odd(VALUE clas,
176
- VALUE create_object,
177
- VALUE create_method,
178
- int mcnt,
179
- VALUE *members,
180
- bool raw) {
206
+ void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw) {
181
207
  Odd odd;
182
208
  const char **np;
183
- ID * ap;
209
+ ID *ap;
184
210
  AttrGetFunc *fp;
185
211
 
186
- if (_odds == odds) {
187
- odds = ALLOC_N(struct _odd, odd_cnt + 1);
188
-
189
- memcpy(odds, _odds, sizeof(struct _odd) * odd_cnt);
190
- } else {
191
- REALLOC_N(odds, struct _odd, odd_cnt + 1);
192
- }
193
- odd = odds + odd_cnt;
212
+ odd = odd_create();
194
213
  odd->clas = clas;
195
- if (NULL == (odd->classname = strdup(rb_class2name(clas)))) {
196
- rb_raise(rb_eNoMemError, "for attribute name.");
214
+ rb_gc_register_mark_object(odd->clas);
215
+ if (NULL == (odd->classname = OJ_STRDUP(rb_class2name(clas)))) {
216
+ rb_raise(rb_eNoMemError, "for class name.");
197
217
  }
198
218
  odd->clen = strlen(odd->classname);
199
219
  odd->create_obj = create_object;
200
- odd->create_op = SYM2ID(create_method);
201
- odd->attr_cnt = mcnt;
202
- odd->is_module = (T_MODULE == rb_type(clas));
203
- odd->raw = raw;
204
- for (ap = odd->attrs, np = odd->attr_names, fp = odd->attrFuncs; 0 < mcnt;
205
- mcnt--, ap++, np++, members++, fp++) {
220
+ rb_gc_register_mark_object(odd->create_obj);
221
+ odd->create_op = SYM2ID(create_method);
222
+ odd->attr_cnt = mcnt;
223
+ odd->is_module = (T_MODULE == rb_type(clas));
224
+ odd->raw = raw;
225
+ for (ap = odd->attrs, np = odd->attr_names, fp = odd->attrFuncs; 0 < mcnt; mcnt--, ap++, np++, members++, fp++) {
206
226
  *fp = 0;
207
227
  switch (rb_type(*members)) {
208
228
  case T_STRING:
209
- if (NULL == (*np = strdup(rb_string_value_ptr(members)))) {
229
+ if (NULL == (*np = OJ_STRDUP(RSTRING_PTR(*members)))) {
210
230
  rb_raise(rb_eNoMemError, "for attribute name.");
211
231
  }
212
232
  break;
213
- case T_SYMBOL: *np = rb_id2name(SYM2ID(*members)); break;
214
- default:
215
- rb_raise(rb_eArgError, "registered member identifiers must be Strings or Symbols.");
233
+ case T_SYMBOL:
234
+ // The symbol can move and invalidate the name so make a copy.
235
+ if (NULL == (*np = OJ_STRDUP(rb_id2name(SYM2ID(*members))))) {
236
+ rb_raise(rb_eNoMemError, "for attribute name.");
237
+ }
216
238
  break;
239
+ default: rb_raise(rb_eArgError, "registered member identifiers must be Strings or Symbols."); break;
217
240
  }
218
241
  *ap = rb_intern(*np);
219
242
  }
220
243
  *np = 0;
221
244
  *ap = 0;
222
- odd_cnt++;
223
245
  }
data/ext/oj/odd.h CHANGED
@@ -13,23 +13,24 @@
13
13
  typedef VALUE (*AttrGetFunc)(VALUE obj);
14
14
 
15
15
  typedef struct _odd {
16
- const char *classname;
17
- size_t clen;
18
- VALUE clas; // Ruby class or module
19
- VALUE create_obj;
20
- ID create_op;
21
- int attr_cnt;
22
- bool is_module;
23
- bool raw;
24
- const char *attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
25
- ID attrs[MAX_ODD_ARGS]; // 0 terminated attr IDs
26
- AttrGetFunc attrFuncs[MAX_ODD_ARGS];
27
- } * Odd;
16
+ struct _odd *next;
17
+ const char *classname;
18
+ size_t clen;
19
+ VALUE clas; // Ruby class or module
20
+ VALUE create_obj;
21
+ ID create_op;
22
+ int attr_cnt;
23
+ bool is_module;
24
+ bool raw;
25
+ const char *attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
26
+ ID attrs[MAX_ODD_ARGS]; // 0 terminated attr IDs
27
+ AttrGetFunc attrFuncs[MAX_ODD_ARGS];
28
+ } *Odd;
28
29
 
29
30
  typedef struct _oddArgs {
30
31
  Odd odd;
31
32
  VALUE args[MAX_ODD_ARGS];
32
- } * OddArgs;
33
+ } *OddArgs;
33
34
 
34
35
  extern void oj_odd_init(void);
35
36
  extern Odd oj_get_odd(VALUE clas);
@@ -37,7 +38,6 @@ extern Odd oj_get_oddc(const char *classname, size_t len);
37
38
  extern OddArgs oj_odd_alloc_args(Odd odd);
38
39
  extern void oj_odd_free(OddArgs args);
39
40
  extern int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value);
40
- extern void
41
- oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw);
41
+ extern void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw);
42
42
 
43
43
  #endif /* OJ_ODD_H */