oj 3.10.6 → 3.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -1
  3. data/ext/oj/buf.h +36 -68
  4. data/ext/oj/cache8.c +59 -62
  5. data/ext/oj/cache8.h +9 -36
  6. data/ext/oj/circarray.c +36 -42
  7. data/ext/oj/circarray.h +12 -13
  8. data/ext/oj/code.c +172 -179
  9. data/ext/oj/code.h +22 -24
  10. data/ext/oj/compat.c +168 -181
  11. data/ext/oj/custom.c +800 -864
  12. data/ext/oj/dump.c +774 -776
  13. data/ext/oj/dump.h +50 -55
  14. data/ext/oj/dump_compat.c +2 -4
  15. data/ext/oj/dump_leaf.c +118 -162
  16. data/ext/oj/dump_object.c +610 -632
  17. data/ext/oj/dump_strict.c +319 -331
  18. data/ext/oj/encode.h +4 -33
  19. data/ext/oj/err.c +40 -29
  20. data/ext/oj/err.h +25 -44
  21. data/ext/oj/extconf.rb +2 -1
  22. data/ext/oj/fast.c +1054 -1081
  23. data/ext/oj/hash.c +78 -95
  24. data/ext/oj/hash.h +10 -35
  25. data/ext/oj/hash_test.c +451 -472
  26. data/ext/oj/mimic_json.c +415 -402
  27. data/ext/oj/object.c +588 -532
  28. data/ext/oj/odd.c +124 -132
  29. data/ext/oj/odd.h +28 -29
  30. data/ext/oj/oj.c +1178 -905
  31. data/ext/oj/oj.h +289 -298
  32. data/ext/oj/parse.c +946 -870
  33. data/ext/oj/parse.h +81 -79
  34. data/ext/oj/rails.c +837 -842
  35. data/ext/oj/rails.h +8 -11
  36. data/ext/oj/reader.c +139 -147
  37. data/ext/oj/reader.h +68 -84
  38. data/ext/oj/resolve.c +44 -47
  39. data/ext/oj/resolve.h +4 -6
  40. data/ext/oj/rxclass.c +69 -73
  41. data/ext/oj/rxclass.h +13 -14
  42. data/ext/oj/saj.c +453 -484
  43. data/ext/oj/scp.c +88 -113
  44. data/ext/oj/sparse.c +783 -714
  45. data/ext/oj/stream_writer.c +123 -157
  46. data/ext/oj/strict.c +133 -106
  47. data/ext/oj/string_writer.c +199 -247
  48. data/ext/oj/trace.c +34 -41
  49. data/ext/oj/trace.h +15 -15
  50. data/ext/oj/util.c +104 -104
  51. data/ext/oj/util.h +4 -3
  52. data/ext/oj/val_stack.c +48 -76
  53. data/ext/oj/val_stack.h +80 -115
  54. data/ext/oj/wab.c +317 -328
  55. data/lib/oj.rb +0 -8
  56. data/lib/oj/bag.rb +1 -0
  57. data/lib/oj/easy_hash.rb +5 -4
  58. data/lib/oj/mimic.rb +45 -13
  59. data/lib/oj/version.rb +1 -1
  60. data/pages/Modes.md +1 -0
  61. data/pages/Options.md +23 -11
  62. data/test/activerecord/result_test.rb +7 -2
  63. data/test/foo.rb +8 -40
  64. data/test/helper.rb +10 -0
  65. data/test/json_gem/json_common_interface_test.rb +8 -3
  66. data/test/json_gem/json_generator_test.rb +15 -3
  67. data/test/json_gem/test_helper.rb +8 -0
  68. data/test/perf.rb +1 -1
  69. data/test/perf_scp.rb +11 -10
  70. data/test/perf_strict.rb +17 -23
  71. data/test/prec.rb +23 -0
  72. data/test/sample_json.rb +1 -1
  73. data/test/test_compat.rb +16 -3
  74. data/test/test_custom.rb +11 -0
  75. data/test/test_fast.rb +32 -2
  76. data/test/test_generate.rb +21 -0
  77. data/test/test_hash.rb +10 -0
  78. data/test/test_rails.rb +9 -0
  79. data/test/test_scp.rb +1 -1
  80. data/test/test_various.rb +4 -2
  81. metadata +89 -85
data/ext/oj/circarray.h CHANGED
@@ -1,7 +1,6 @@
1
- /* circarray.h
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
3
+ // license details.
5
4
 
6
5
  #ifndef OJ_CIRCARRAY_H
7
6
  #define OJ_CIRCARRAY_H
@@ -9,15 +8,15 @@
9
8
  #include "ruby.h"
10
9
 
11
10
  typedef struct _circArray {
12
- VALUE obj_array[1024];
13
- VALUE *objs;
14
- unsigned long size; // allocated size or initial array size
15
- unsigned long cnt;
16
- } *CircArray;
11
+ VALUE obj_array[1024];
12
+ VALUE * objs;
13
+ unsigned long size; // allocated size or initial array size
14
+ unsigned long cnt;
15
+ } * CircArray;
17
16
 
18
- extern CircArray oj_circ_array_new(void);
19
- extern void oj_circ_array_free(CircArray ca);
20
- extern void oj_circ_array_set(CircArray ca, VALUE obj, unsigned long id);
21
- extern VALUE oj_circ_array_get(CircArray ca, unsigned long id);
17
+ extern CircArray oj_circ_array_new(void);
18
+ extern void oj_circ_array_free(CircArray ca);
19
+ extern void oj_circ_array_set(CircArray ca, VALUE obj, unsigned long id);
20
+ extern VALUE oj_circ_array_get(CircArray ca, unsigned long id);
22
21
 
23
22
  #endif /* OJ_CIRCARRAY_H */
data/ext/oj/code.c CHANGED
@@ -1,235 +1,228 @@
1
- /* code.c
2
- * Copyright (c) 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2017 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
5
3
 
6
4
  #include "code.h"
5
+
7
6
  #include "dump.h"
8
7
 
9
- inline static VALUE
10
- resolve_classname(VALUE mod, const char *classname) {
11
- VALUE clas = Qundef;
12
- ID ci = rb_intern(classname);
8
+ inline static VALUE resolve_classname(VALUE mod, const char *classname) {
9
+ VALUE clas = Qundef;
10
+ ID ci = rb_intern(classname);
13
11
 
14
12
  if (rb_const_defined_at(mod, ci)) {
15
- clas = rb_const_get_at(mod, ci);
13
+ clas = rb_const_get_at(mod, ci);
16
14
  }
17
15
  return clas;
18
16
  }
19
17
 
20
- static VALUE
21
- path2class(const char *name) {
22
- char class_name[1024];
23
- VALUE clas;
24
- char *end = class_name + sizeof(class_name) - 1;
25
- char *s;
26
- const char *n = name;
18
+ static VALUE path2class(const char *name) {
19
+ char class_name[1024];
20
+ VALUE clas;
21
+ char * end = class_name + sizeof(class_name) - 1;
22
+ char * s;
23
+ const char *n = name;
27
24
 
28
25
  clas = rb_cObject;
29
26
  for (s = class_name; '\0' != *n; n++) {
30
- if (':' == *n) {
31
- *s = '\0';
32
- n++;
33
- if (':' != *n) {
34
- return Qundef;
35
- }
36
- if (Qundef == (clas = resolve_classname(clas, class_name))) {
37
- return Qundef;
38
- }
39
- s = class_name;
40
- } else if (end <= s) {
41
- return Qundef;
42
- } else {
43
- *s++ = *n;
44
- }
27
+ if (':' == *n) {
28
+ *s = '\0';
29
+ n++;
30
+ if (':' != *n) {
31
+ return Qundef;
32
+ }
33
+ if (Qundef == (clas = resolve_classname(clas, class_name))) {
34
+ return Qundef;
35
+ }
36
+ s = class_name;
37
+ } else if (end <= s) {
38
+ return Qundef;
39
+ } else {
40
+ *s++ = *n;
41
+ }
45
42
  }
46
43
  *s = '\0';
47
44
 
48
45
  return resolve_classname(clas, class_name);
49
46
  }
50
47
 
51
- bool
52
- oj_code_dump(Code codes, VALUE obj, int depth, Out out) {
53
- VALUE clas = rb_obj_class(obj);
54
- Code c = codes;
48
+ bool oj_code_dump(Code codes, VALUE obj, int depth, Out out) {
49
+ VALUE clas = rb_obj_class(obj);
50
+ Code c = codes;
55
51
 
56
52
  for (; NULL != c->name; c++) {
57
- if (Qundef == c->clas) { // indicates not defined
58
- continue;
59
- }
60
- if (Qnil == c->clas) {
61
- c->clas = path2class(c->name);
62
- }
63
- if (clas == c->clas && c->active) {
64
- c->encode(obj, depth, out);
65
- return true;
66
- }
53
+ if (Qundef == c->clas) { // indicates not defined
54
+ continue;
55
+ }
56
+ if (Qnil == c->clas) {
57
+ c->clas = path2class(c->name);
58
+ }
59
+ if (clas == c->clas && c->active) {
60
+ c->encode(obj, depth, out);
61
+ return true;
62
+ }
67
63
  }
68
64
  return false;
69
65
  }
70
66
 
71
67
  VALUE
72
68
  oj_code_load(Code codes, VALUE clas, VALUE args) {
73
- Code c = codes;
69
+ Code c = codes;
74
70
 
75
71
  for (; NULL != c->name; c++) {
76
- if (Qundef == c->clas) { // indicates not defined
77
- continue;
78
- }
79
- if (Qnil == c->clas) {
80
- c->clas = path2class(c->name);
81
- }
82
- if (clas == c->clas) {
83
- if (NULL == c->decode) {
84
- break;
85
- }
86
- return c->decode(clas, args);
87
- }
72
+ if (Qundef == c->clas) { // indicates not defined
73
+ continue;
74
+ }
75
+ if (Qnil == c->clas) {
76
+ c->clas = path2class(c->name);
77
+ }
78
+ if (clas == c->clas) {
79
+ if (NULL == c->decode) {
80
+ break;
81
+ }
82
+ return c->decode(clas, args);
83
+ }
88
84
  }
89
85
  return Qnil;
90
86
  }
91
87
 
92
- void
93
- oj_code_set_active(Code codes, VALUE clas, bool active) {
94
- Code c = codes;
88
+ void oj_code_set_active(Code codes, VALUE clas, bool active) {
89
+ Code c = codes;
95
90
 
96
91
  for (; NULL != c->name; c++) {
97
- if (Qundef == c->clas) { // indicates not defined
98
- continue;
99
- }
100
- if (Qnil == c->clas) {
101
- c->clas = path2class(c->name);
102
- }
103
- if (clas == c->clas || Qnil == clas) {
104
- c->active = active;
105
- if (Qnil != clas) {
106
- break;
107
- }
108
- }
92
+ if (Qundef == c->clas) { // indicates not defined
93
+ continue;
94
+ }
95
+ if (Qnil == c->clas) {
96
+ c->clas = path2class(c->name);
97
+ }
98
+ if (clas == c->clas || Qnil == clas) {
99
+ c->active = active;
100
+ if (Qnil != clas) {
101
+ break;
102
+ }
103
+ }
109
104
  }
110
105
  }
111
106
 
112
- bool
113
- oj_code_has(Code codes, VALUE clas, bool encode) {
114
- Code c = codes;
107
+ bool oj_code_has(Code codes, VALUE clas, bool encode) {
108
+ Code c = codes;
115
109
 
116
110
  for (; NULL != c->name; c++) {
117
- if (Qundef == c->clas) { // indicates not defined
118
- continue;
119
- }
120
- if (Qnil == c->clas) {
121
- c->clas = path2class(c->name);
122
- }
123
- if (clas == c->clas) {
124
- if (encode) {
125
- return c->active && NULL != c->encode;
126
- } else {
127
- return c->active && NULL != c->decode;
128
- }
129
- }
111
+ if (Qundef == c->clas) { // indicates not defined
112
+ continue;
113
+ }
114
+ if (Qnil == c->clas) {
115
+ c->clas = path2class(c->name);
116
+ }
117
+ if (clas == c->clas) {
118
+ if (encode) {
119
+ return c->active && NULL != c->encode;
120
+ } else {
121
+ return c->active && NULL != c->decode;
122
+ }
123
+ }
130
124
  }
131
125
  return false;
132
126
  }
133
127
 
134
- void
135
- oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out, bool with_class) {
136
- int d2 = depth + 1;
137
- int d3 = d2 + 1;
138
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
139
- const char *classname = rb_obj_classname(obj);
140
- size_t len = strlen(classname);
141
- size_t size = d2 * out->indent + 10 + len + out->opts->create_id_len + sep_len;
142
- bool no_comma = true;
143
-
128
+ void oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out, bool with_class) {
129
+ int d2 = depth + 1;
130
+ int d3 = d2 + 1;
131
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
132
+ const char *classname = rb_obj_classname(obj);
133
+ size_t len = strlen(classname);
134
+ size_t size = d2 * out->indent + 10 + len + out->opts->create_id_len + sep_len;
135
+ bool no_comma = true;
136
+
144
137
  assure_size(out, size);
145
138
  *out->cur++ = '{';
146
139
 
147
140
  if (with_class) {
148
- fill_indent(out, d2);
149
- *out->cur++ = '"';
150
- memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
151
- out->cur += out->opts->create_id_len;
152
- *out->cur++ = '"';
153
- if (0 < out->opts->dump_opts.before_size) {
154
- strcpy(out->cur, out->opts->dump_opts.before_sep);
155
- out->cur += out->opts->dump_opts.before_size;
156
- }
157
- *out->cur++ = ':';
158
- if (0 < out->opts->dump_opts.after_size) {
159
- strcpy(out->cur, out->opts->dump_opts.after_sep);
160
- out->cur += out->opts->dump_opts.after_size;
161
- }
162
- *out->cur++ = '"';
163
- memcpy(out->cur, classname, len);
164
- out->cur += len;
165
- *out->cur++ = '"';
166
- no_comma = false;
141
+ fill_indent(out, d2);
142
+ *out->cur++ = '"';
143
+ memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
144
+ out->cur += out->opts->create_id_len;
145
+ *out->cur++ = '"';
146
+ if (0 < out->opts->dump_opts.before_size) {
147
+ strcpy(out->cur, out->opts->dump_opts.before_sep);
148
+ out->cur += out->opts->dump_opts.before_size;
149
+ }
150
+ *out->cur++ = ':';
151
+ if (0 < out->opts->dump_opts.after_size) {
152
+ strcpy(out->cur, out->opts->dump_opts.after_sep);
153
+ out->cur += out->opts->dump_opts.after_size;
154
+ }
155
+ *out->cur++ = '"';
156
+ memcpy(out->cur, classname, len);
157
+ out->cur += len;
158
+ *out->cur++ = '"';
159
+ no_comma = false;
167
160
  }
168
161
  size = d3 * out->indent + 2;
169
162
  for (; NULL != attrs->name; attrs++) {
170
- assure_size(out, size + attrs->len + sep_len + 2);
171
- if (no_comma) {
172
- no_comma = false;
173
- } else {
174
- *out->cur++ = ',';
175
- }
176
- fill_indent(out, d2);
177
- *out->cur++ = '"';
178
- memcpy(out->cur, attrs->name, attrs->len);
179
- out->cur += attrs->len;
180
- *out->cur++ = '"';
181
- if (0 < out->opts->dump_opts.before_size) {
182
- strcpy(out->cur, out->opts->dump_opts.before_sep);
183
- out->cur += out->opts->dump_opts.before_size;
184
- }
185
- *out->cur++ = ':';
186
- if (0 < out->opts->dump_opts.after_size) {
187
- strcpy(out->cur, out->opts->dump_opts.after_sep);
188
- out->cur += out->opts->dump_opts.after_size;
189
- }
190
- if (Qundef == attrs->value) {
191
- if (Qundef != attrs->time) {
192
- switch (out->opts->time_format) {
193
- case RubyTime: oj_dump_ruby_time(attrs->time, out); break;
194
- case XmlTime: oj_dump_xml_time(attrs->time, out); break;
195
- case UnixZTime: oj_dump_time(attrs->time, out, true); break;
196
- case UnixTime:
197
- default: oj_dump_time(attrs->time, out, false); break;
198
- }
199
- } else {
200
- char buf[32];
201
- char *b = buf + sizeof(buf) - 1;
202
- int neg = 0;
203
- long num = attrs->num;
204
-
205
- if (0 > num) {
206
- neg = 1;
207
- num = -num;
208
- }
209
- *b-- = '\0';
210
- if (0 < num) {
211
- for (; 0 < num; num /= 10, b--) {
212
- *b = (num % 10) + '0';
213
- }
214
- if (neg) {
215
- *b = '-';
216
- } else {
217
- b++;
218
- }
219
- } else {
220
- *b = '0';
221
- }
222
- assure_size(out, (sizeof(buf) - (b - buf)));
223
- for (; '\0' != *b; b++) {
224
- *out->cur++ = *b;
225
- }
226
- }
227
- } else {
228
- oj_dump_compat_val(attrs->value, d3, out, true);
229
- }
163
+ assure_size(out, size + attrs->len + sep_len + 2);
164
+ if (no_comma) {
165
+ no_comma = false;
166
+ } else {
167
+ *out->cur++ = ',';
168
+ }
169
+ fill_indent(out, d2);
170
+ *out->cur++ = '"';
171
+ memcpy(out->cur, attrs->name, attrs->len);
172
+ out->cur += attrs->len;
173
+ *out->cur++ = '"';
174
+ if (0 < out->opts->dump_opts.before_size) {
175
+ strcpy(out->cur, out->opts->dump_opts.before_sep);
176
+ out->cur += out->opts->dump_opts.before_size;
177
+ }
178
+ *out->cur++ = ':';
179
+ if (0 < out->opts->dump_opts.after_size) {
180
+ strcpy(out->cur, out->opts->dump_opts.after_sep);
181
+ out->cur += out->opts->dump_opts.after_size;
182
+ }
183
+ if (Qundef == attrs->value) {
184
+ if (Qundef != attrs->time) {
185
+ switch (out->opts->time_format) {
186
+ case RubyTime: oj_dump_ruby_time(attrs->time, out); break;
187
+ case XmlTime: oj_dump_xml_time(attrs->time, out); break;
188
+ case UnixZTime: oj_dump_time(attrs->time, out, true); break;
189
+ case UnixTime:
190
+ default: oj_dump_time(attrs->time, out, false); break;
191
+ }
192
+ } else {
193
+ char buf[32];
194
+ char *b = buf + sizeof(buf) - 1;
195
+ int neg = 0;
196
+ long num = attrs->num;
197
+
198
+ if (0 > num) {
199
+ neg = 1;
200
+ num = -num;
201
+ }
202
+ *b-- = '\0';
203
+ if (0 < num) {
204
+ for (; 0 < num; num /= 10, b--) {
205
+ *b = (num % 10) + '0';
206
+ }
207
+ if (neg) {
208
+ *b = '-';
209
+ } else {
210
+ b++;
211
+ }
212
+ } else {
213
+ *b = '0';
214
+ }
215
+ assure_size(out, (sizeof(buf) - (b - buf)));
216
+ for (; '\0' != *b; b++) {
217
+ *out->cur++ = *b;
218
+ }
219
+ }
220
+ } else {
221
+ oj_dump_compat_val(attrs->value, d3, out, true);
222
+ }
230
223
  }
231
224
  assure_size(out, depth * out->indent + 2);
232
225
  fill_indent(out, depth);
233
226
  *out->cur++ = '}';
234
- *out->cur = '\0';
227
+ *out->cur = '\0';
235
228
  }
data/ext/oj/code.h CHANGED
@@ -1,7 +1,5 @@
1
- /* code.h
2
- * Copyright (c) 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2017 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
5
3
 
6
4
  #ifndef OJ_CODE_H
7
5
  #define OJ_CODE_H
@@ -10,33 +8,33 @@
10
8
 
11
9
  #include "oj.h"
12
10
 
13
- typedef void (*EncodeFunc)(VALUE obj, int depth, Out out);
14
- typedef VALUE (*DecodeFunc)(VALUE clas, VALUE args);
11
+ typedef void (*EncodeFunc)(VALUE obj, int depth, Out out);
12
+ typedef VALUE (*DecodeFunc)(VALUE clas, VALUE args);
15
13
 
16
14
  typedef struct _code {
17
- const char *name;
18
- VALUE clas;
19
- EncodeFunc encode;
20
- DecodeFunc decode;
21
- bool active; // For compat mode.
22
- } *Code;
15
+ const char *name;
16
+ VALUE clas;
17
+ EncodeFunc encode;
18
+ DecodeFunc decode;
19
+ bool active; // For compat mode.
20
+ } * Code;
23
21
 
24
22
  // Used by encode functions.
25
23
  typedef struct _attr {
26
- const char *name;
27
- int len;
28
- VALUE value;
29
- long num;
30
- VALUE time;
31
- } *Attr;
24
+ const char *name;
25
+ int len;
26
+ VALUE value;
27
+ long num;
28
+ VALUE time;
29
+ } * Attr;
32
30
 
33
- extern bool oj_code_dump(Code codes, VALUE obj, int depth, Out out);
34
- extern VALUE oj_code_load(Code codes, VALUE clas, VALUE args);
35
- extern void oj_code_set_active(Code codes, VALUE clas, bool active);
36
- extern bool oj_code_has(Code codes, VALUE clas, bool encode);
31
+ extern bool oj_code_dump(Code codes, VALUE obj, int depth, Out out);
32
+ extern VALUE oj_code_load(Code codes, VALUE clas, VALUE args);
33
+ extern void oj_code_set_active(Code codes, VALUE clas, bool active);
34
+ extern bool oj_code_has(Code codes, VALUE clas, bool encode);
37
35
 
38
- extern void oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out, bool with_class);
36
+ extern void oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out, bool with_class);
39
37
 
40
- extern struct _code oj_compat_codes[];
38
+ extern struct _code oj_compat_codes[];
41
39
 
42
40
  #endif /* OJ_CODE_H */