oj 3.13.6 → 3.13.10
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/README.md +9 -0
- data/RELEASE_NOTES.md +6 -0
- data/ext/oj/custom.c +4 -4
- data/ext/oj/dump.c +0 -14
- data/ext/oj/dump.h +14 -1
- data/ext/oj/dump_compat.c +1 -1
- data/ext/oj/dump_object.c +46 -39
- data/ext/oj/dump_strict.c +2 -2
- data/ext/oj/fast.c +13 -3
- data/ext/oj/intern.c +7 -1
- data/ext/oj/mimic_json.c +51 -63
- data/ext/oj/object.c +27 -46
- data/ext/oj/oj.c +109 -153
- data/ext/oj/oj.h +1 -0
- data/ext/oj/parse.c +9 -1
- data/ext/oj/rails.c +5 -5
- data/ext/oj/usual.c +4 -2
- data/ext/oj/wab.c +1 -1
- data/lib/oj/version.rb +1 -1
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +6 -3
- data/pages/Rails.md +12 -0
- data/test/bug.rb +16 -0
- data/test/foo.rb +28 -6
- data/test/test_fast.rb +37 -7
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4f2c04b24ed0dc8c781036c17371378649d1aad9b927b402b2b0f3d67f9f94b
|
4
|
+
data.tar.gz: 65b50beb64e09569e7bcdcff9675a60b146de5ed78027b90de5def8eb6b57aa8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62a4e36ea67596152899cf389502a69f4f19b354dc5980c66b31ad5163b932245030bfd338ad582ec101572b56fd280c0e784b1d20567f830933627274506503
|
7
|
+
data.tar.gz: 671d6a7066b4f74c164ce4af83acbab38fcb0743c97c13985ad4f8e7f1431f67288d1bb80f74b7e55d90d6c5e727e01dc72b138b7dfda3220cbc55ae3ebf2856
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
|
4
|
+
## 3.13.10 - 2021-12-12
|
5
|
+
|
6
|
+
- Fixed Oj::Doc re-entrant issue with each_child.
|
7
|
+
- Fixed each_child on empty Oj::Doc.
|
8
|
+
|
9
|
+
## 3.13.9 - 2021-10-06
|
10
|
+
|
11
|
+
- Fix mimic JSON load so that it honors the `:symbolize_names` option.
|
12
|
+
|
13
|
+
## 3.13.8 - 2021-09-27
|
14
|
+
|
15
|
+
- Fix `Oj::Doc` behaviour for inexisting path.
|
16
|
+
```ruby
|
17
|
+
Oj::Doc.open('{"foo":1}') do |doc|
|
18
|
+
doc.fetch('/foo/bar') # used to give `1`, now gives `nil`
|
19
|
+
doc.exists?('/foo/bar') # used to give `true`, now gives `false`
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
- Fix `Oj::Parser` handling of BigDecimal. `snprint()` does not handle `%Lg` correctly but `sprintf()` does.
|
24
|
+
|
25
|
+
## 3.13.7 - 2021-09-16
|
26
|
+
|
27
|
+
- The JSON gem allows invalid unicode so Oj, when mimicing JSON now
|
28
|
+
allows it as well. Use `:allow_invalid_unicode` to change that.
|
29
|
+
|
3
30
|
## 3.13.6 - 2021-09-11
|
4
31
|
|
5
32
|
- Fixed unicode UTF 8 parsing in string values.
|
data/README.md
CHANGED
@@ -43,6 +43,15 @@ or in Bundler:
|
|
43
43
|
gem 'oj'
|
44
44
|
```
|
45
45
|
|
46
|
+
## Rails and json quickstart
|
47
|
+
|
48
|
+
See the Quickstart sections of the [Rails](pages/Rails.md) and [json](pages/JsonGem.md) docs.
|
49
|
+
|
50
|
+
## multi_json
|
51
|
+
|
52
|
+
Code which uses [multi_json](https://github.com/intridea/multi_json)
|
53
|
+
will automatically prefer Oj if it is installed.
|
54
|
+
|
46
55
|
## Support
|
47
56
|
|
48
57
|
[Get supported Oj with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security).
|
data/RELEASE_NOTES.md
CHANGED
@@ -5,6 +5,12 @@ see the See [{file:CHANGELOG.md}](CHANGELOG.md) file. In this file are
|
|
5
5
|
the steps to take to aid in keeping things rolling after updating to
|
6
6
|
the latest version.
|
7
7
|
|
8
|
+
## 3.13.7
|
9
|
+
|
10
|
+
The default for JSON when mimicked by Oj is now to set
|
11
|
+
`:allow_invalid_unicode`. To change that behavior JSON.load, set that
|
12
|
+
option to false.
|
13
|
+
|
8
14
|
## 3.13.x
|
9
15
|
|
10
16
|
This release included a new cache that performs better than the
|
data/ext/oj/custom.c
CHANGED
@@ -282,7 +282,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
282
282
|
Out out = (Out)ov;
|
283
283
|
int depth = out->depth;
|
284
284
|
|
285
|
-
if (
|
285
|
+
if (dump_ignore(out->opts, value)) {
|
286
286
|
return ST_CONTINUE;
|
287
287
|
}
|
288
288
|
if (out->omit_nil && Qnil == value) {
|
@@ -577,7 +577,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
|
|
577
577
|
size_t size;
|
578
578
|
const char *attr;
|
579
579
|
|
580
|
-
if (
|
580
|
+
if (dump_ignore(out->opts, value)) {
|
581
581
|
return ST_CONTINUE;
|
582
582
|
}
|
583
583
|
if (out->omit_nil && Qnil == value) {
|
@@ -749,7 +749,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
749
749
|
} else {
|
750
750
|
fill_indent(out, d2);
|
751
751
|
}
|
752
|
-
oj_dump_custom_val(
|
752
|
+
oj_dump_custom_val(RARRAY_AREF(a, i), d2, out, true);
|
753
753
|
if (i < cnt) {
|
754
754
|
*out->cur++ = ',';
|
755
755
|
}
|
@@ -833,7 +833,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
833
833
|
v = rb_struct_aref(obj, INT2FIX(i));
|
834
834
|
#endif
|
835
835
|
if (ma != Qnil) {
|
836
|
-
volatile VALUE s = rb_sym2str(
|
836
|
+
volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
|
837
837
|
|
838
838
|
name = RSTRING_PTR(s);
|
839
839
|
len = (int)RSTRING_LEN(s);
|
data/ext/oj/dump.c
CHANGED
@@ -1225,17 +1225,3 @@ int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char
|
|
1225
1225
|
}
|
1226
1226
|
return cnt;
|
1227
1227
|
}
|
1228
|
-
|
1229
|
-
bool oj_dump_ignore(Options opts, VALUE obj) {
|
1230
|
-
if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
|
1231
|
-
VALUE *vp = opts->ignore;
|
1232
|
-
VALUE clas = rb_obj_class(obj);
|
1233
|
-
|
1234
|
-
for (; Qnil != *vp; vp++) {
|
1235
|
-
if (clas == *vp) {
|
1236
|
-
return true;
|
1237
|
-
}
|
1238
|
-
}
|
1239
|
-
}
|
1240
|
-
return false;
|
1241
|
-
}
|
data/ext/oj/dump.h
CHANGED
@@ -50,7 +50,6 @@ extern VALUE oj_remove_to_json(int argc, VALUE *argv, VALUE self);
|
|
50
50
|
|
51
51
|
extern int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char *format);
|
52
52
|
|
53
|
-
extern bool oj_dump_ignore(Options opts, VALUE obj);
|
54
53
|
extern time_t oj_sec_from_time_hard_way(VALUE obj);
|
55
54
|
|
56
55
|
inline static void assure_size(Out out, size_t len) {
|
@@ -69,6 +68,20 @@ inline static void fill_indent(Out out, int cnt) {
|
|
69
68
|
}
|
70
69
|
}
|
71
70
|
|
71
|
+
inline static bool dump_ignore(Options opts, VALUE obj) {
|
72
|
+
if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
|
73
|
+
VALUE *vp = opts->ignore;
|
74
|
+
VALUE clas = rb_obj_class(obj);
|
75
|
+
|
76
|
+
for (; Qnil != *vp; vp++) {
|
77
|
+
if (clas == *vp) {
|
78
|
+
return true;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
return false;
|
83
|
+
}
|
84
|
+
|
72
85
|
inline static void dump_ulong(unsigned long num, Out out) {
|
73
86
|
char buf[32];
|
74
87
|
char *b = buf + sizeof(buf) - 1;
|
data/ext/oj/dump_compat.c
CHANGED
@@ -182,7 +182,7 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
182
182
|
} else {
|
183
183
|
fill_indent(out, d2);
|
184
184
|
}
|
185
|
-
oj_dump_compat_val(
|
185
|
+
oj_dump_compat_val(RARRAY_AREF(a, i), d2, out, true);
|
186
186
|
if (i < cnt) {
|
187
187
|
*out->cur++ = ',';
|
188
188
|
}
|
data/ext/oj/dump_object.c
CHANGED
@@ -157,7 +157,7 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
|
|
157
157
|
} else {
|
158
158
|
fill_indent(out, d2);
|
159
159
|
}
|
160
|
-
oj_dump_obj_val(
|
160
|
+
oj_dump_obj_val(RARRAY_AREF(a, i), d2, out);
|
161
161
|
if (i < cnt) {
|
162
162
|
*out->cur++ = ',';
|
163
163
|
}
|
@@ -218,7 +218,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
218
218
|
int depth = out->depth;
|
219
219
|
long size = depth * out->indent + 1;
|
220
220
|
|
221
|
-
if (
|
221
|
+
if (dump_ignore(out->opts, value)) {
|
222
222
|
return ST_CONTINUE;
|
223
223
|
}
|
224
224
|
if (out->omit_nil && Qnil == value) {
|
@@ -226,47 +226,54 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
226
226
|
}
|
227
227
|
assure_size(out, size);
|
228
228
|
fill_indent(out, depth);
|
229
|
-
|
229
|
+
switch (rb_type(key)) {
|
230
|
+
case T_STRING:
|
230
231
|
dump_str_class(key, Qundef, depth, out);
|
231
232
|
*out->cur++ = ':';
|
232
233
|
oj_dump_obj_val(value, depth, out);
|
233
|
-
|
234
|
+
break;
|
235
|
+
|
236
|
+
case T_SYMBOL:
|
234
237
|
dump_sym(key, 0, out, false);
|
235
238
|
*out->cur++ = ':';
|
236
239
|
oj_dump_obj_val(value, depth, out);
|
237
|
-
|
238
|
-
int d2 = depth + 1;
|
239
|
-
long s2 = size + out->indent + 1;
|
240
|
-
int i;
|
241
|
-
int started = 0;
|
242
|
-
uint8_t b;
|
240
|
+
break;
|
243
241
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
242
|
+
default:
|
243
|
+
{
|
244
|
+
int d2 = depth + 1;
|
245
|
+
long s2 = size + out->indent + 1;
|
246
|
+
int i;
|
247
|
+
int started = 0;
|
248
|
+
uint8_t b;
|
249
|
+
|
250
|
+
assure_size(out, s2 + 15);
|
251
|
+
*out->cur++ = '"';
|
252
|
+
*out->cur++ = '^';
|
253
|
+
*out->cur++ = '#';
|
254
|
+
out->hash_cnt++;
|
255
|
+
for (i = 28; 0 <= i; i -= 4) {
|
256
|
+
b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
|
257
|
+
if ('\0' != b) {
|
258
|
+
started = 1;
|
259
|
+
}
|
260
|
+
if (started) {
|
261
|
+
*out->cur++ = hex_chars[b];
|
262
|
+
}
|
256
263
|
}
|
264
|
+
*out->cur++ = '"';
|
265
|
+
*out->cur++ = ':';
|
266
|
+
*out->cur++ = '[';
|
267
|
+
fill_indent(out, d2);
|
268
|
+
oj_dump_obj_val(key, d2, out);
|
269
|
+
assure_size(out, s2);
|
270
|
+
*out->cur++ = ',';
|
271
|
+
fill_indent(out, d2);
|
272
|
+
oj_dump_obj_val(value, d2, out);
|
273
|
+
assure_size(out, size);
|
274
|
+
fill_indent(out, depth);
|
275
|
+
*out->cur++ = ']';
|
257
276
|
}
|
258
|
-
*out->cur++ = '"';
|
259
|
-
*out->cur++ = ':';
|
260
|
-
*out->cur++ = '[';
|
261
|
-
fill_indent(out, d2);
|
262
|
-
oj_dump_obj_val(key, d2, out);
|
263
|
-
assure_size(out, s2);
|
264
|
-
*out->cur++ = ',';
|
265
|
-
fill_indent(out, d2);
|
266
|
-
oj_dump_obj_val(value, d2, out);
|
267
|
-
assure_size(out, size);
|
268
|
-
fill_indent(out, depth);
|
269
|
-
*out->cur++ = ']';
|
270
277
|
}
|
271
278
|
out->depth = depth;
|
272
279
|
*out->cur++ = ',';
|
@@ -342,7 +349,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
|
|
342
349
|
size_t size = depth * out->indent + 1;
|
343
350
|
const char *attr = rb_id2name(key);
|
344
351
|
|
345
|
-
if (
|
352
|
+
if (dump_ignore(out->opts, value)) {
|
346
353
|
return ST_CONTINUE;
|
347
354
|
}
|
348
355
|
if (out->omit_nil && Qnil == value) {
|
@@ -605,7 +612,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
605
612
|
}
|
606
613
|
value = rb_ivar_get(obj, vid);
|
607
614
|
|
608
|
-
if (
|
615
|
+
if (dump_ignore(out->opts, value)) {
|
609
616
|
continue;
|
610
617
|
}
|
611
618
|
if (out->omit_nil && Qnil == value) {
|
@@ -694,7 +701,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
694
701
|
|
695
702
|
*out->cur++ = '[';
|
696
703
|
for (i = 0; i < cnt; i++) {
|
697
|
-
volatile VALUE s = rb_sym2str(
|
704
|
+
volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
|
698
705
|
|
699
706
|
name = RSTRING_PTR(s);
|
700
707
|
len = (int)RSTRING_LEN(s);
|
@@ -730,7 +737,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
730
737
|
|
731
738
|
for (i = 0; i < cnt; i++) {
|
732
739
|
v = RSTRUCT_GET(obj, i);
|
733
|
-
if (
|
740
|
+
if (dump_ignore(out->opts, v)) {
|
734
741
|
v = Qnil;
|
735
742
|
}
|
736
743
|
assure_size(out, size);
|
@@ -748,7 +755,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
748
755
|
for (i = 0; i < slen; i++) {
|
749
756
|
assure_size(out, size);
|
750
757
|
fill_indent(out, d3);
|
751
|
-
if (
|
758
|
+
if (dump_ignore(out->opts, v)) {
|
752
759
|
v = Qnil;
|
753
760
|
}
|
754
761
|
oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
|
data/ext/oj/dump_strict.c
CHANGED
@@ -153,9 +153,9 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
153
153
|
fill_indent(out, d2);
|
154
154
|
}
|
155
155
|
if (NullMode == out->opts->mode) {
|
156
|
-
oj_dump_null_val(
|
156
|
+
oj_dump_null_val(RARRAY_AREF(a, i), d2, out);
|
157
157
|
} else {
|
158
|
-
oj_dump_strict_val(
|
158
|
+
oj_dump_strict_val(RARRAY_AREF(a, i), d2, out);
|
159
159
|
}
|
160
160
|
if (i < cnt) {
|
161
161
|
*out->cur++ = ',';
|
data/ext/oj/fast.c
CHANGED
@@ -771,7 +771,7 @@ static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) {
|
|
771
771
|
pi.doc = doc;
|
772
772
|
#if IS_WINDOWS
|
773
773
|
// assume a 1M stack and give half to ruby
|
774
|
-
pi.stack_min = (void*)((char*)&pi - (512 * 1024));
|
774
|
+
pi.stack_min = (void *)((char *)&pi - (512 * 1024));
|
775
775
|
#else
|
776
776
|
{
|
777
777
|
struct rlimit lim;
|
@@ -879,6 +879,10 @@ static Leaf get_leaf(Leaf *stack, Leaf *lp, const char *path) {
|
|
879
879
|
}
|
880
880
|
} else if (NULL == leaf->elements) {
|
881
881
|
leaf = NULL;
|
882
|
+
} else if (STR_VAL == leaf->value_type || RUBY_VAL == leaf->value_type) {
|
883
|
+
// We are trying to get a children of a leaf, which
|
884
|
+
// doesn't exist.
|
885
|
+
leaf = NULL;
|
882
886
|
} else if (COL_VAL == leaf->value_type) {
|
883
887
|
Leaf first = leaf->elements->next;
|
884
888
|
Leaf e = first;
|
@@ -1373,8 +1377,8 @@ static VALUE doc_fetch(int argc, VALUE *argv, VALUE self) {
|
|
1373
1377
|
* Returns true if the value at the location identified by the path exists.
|
1374
1378
|
* @param [String] path path to the location
|
1375
1379
|
* @example
|
1376
|
-
* Oj::Doc.open('[1,2]') { |doc| doc.exists('/1') } #=> true
|
1377
|
-
* Oj::Doc.open('[1,2]') { |doc| doc.exists('/3') } #=> false
|
1380
|
+
* Oj::Doc.open('[1,2]') { |doc| doc.exists?('/1') } #=> true
|
1381
|
+
* Oj::Doc.open('[1,2]') { |doc| doc.exists?('/3') } #=> false
|
1378
1382
|
*/
|
1379
1383
|
static VALUE doc_exists(VALUE self, VALUE str) {
|
1380
1384
|
Doc doc;
|
@@ -1488,6 +1492,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1488
1492
|
Doc doc = self_doc(self);
|
1489
1493
|
const char *path = 0;
|
1490
1494
|
size_t wlen;
|
1495
|
+
Leaf * where_orig = doc->where;
|
1491
1496
|
|
1492
1497
|
wlen = doc->where - doc->where_path;
|
1493
1498
|
if (0 < wlen) {
|
@@ -1504,9 +1509,13 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1504
1509
|
if (0 < wlen) {
|
1505
1510
|
memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
|
1506
1511
|
}
|
1512
|
+
doc->where = where_orig;
|
1507
1513
|
return Qnil;
|
1508
1514
|
}
|
1509
1515
|
}
|
1516
|
+
if (NULL == doc->where || NULL == *doc->where) {
|
1517
|
+
return Qnil;
|
1518
|
+
}
|
1510
1519
|
if (COL_VAL == (*doc->where)->value_type && 0 != (*doc->where)->elements) {
|
1511
1520
|
Leaf first = (*doc->where)->elements->next;
|
1512
1521
|
Leaf e = first;
|
@@ -1521,6 +1530,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1521
1530
|
if (0 < wlen) {
|
1522
1531
|
memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
|
1523
1532
|
}
|
1533
|
+
doc->where = where_orig;
|
1524
1534
|
}
|
1525
1535
|
return Qnil;
|
1526
1536
|
}
|
data/ext/oj/intern.c
CHANGED
@@ -186,6 +186,7 @@ static VALUE resolve_classpath(ParseInfo pi, const char *name, size_t len, int a
|
|
186
186
|
char * end = class_name + sizeof(class_name) - 1;
|
187
187
|
char * s;
|
188
188
|
const char *n = name;
|
189
|
+
size_t nlen = len;
|
189
190
|
|
190
191
|
clas = rb_cObject;
|
191
192
|
for (s = class_name; 0 < len; n++, len--) {
|
@@ -208,7 +209,12 @@ static VALUE resolve_classpath(ParseInfo pi, const char *name, size_t len, int a
|
|
208
209
|
}
|
209
210
|
*s = '\0';
|
210
211
|
if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
|
211
|
-
|
212
|
+
if (sizeof(class_name) <= nlen) {
|
213
|
+
nlen = sizeof(class_name) - 1;
|
214
|
+
}
|
215
|
+
strncpy(class_name, name, nlen);
|
216
|
+
class_name[nlen] = '\0';
|
217
|
+
oj_set_error_at(pi, error_class, __FILE__, __LINE__, "class '%s' is not defined", class_name);
|
212
218
|
if (Qnil != error_class) {
|
213
219
|
pi->err_class = error_class;
|
214
220
|
}
|
data/ext/oj/mimic_json.c
CHANGED
@@ -6,8 +6,6 @@
|
|
6
6
|
#include "oj.h"
|
7
7
|
#include "parse.h"
|
8
8
|
|
9
|
-
static VALUE symbolize_names_sym = Qundef;
|
10
|
-
|
11
9
|
extern const char oj_json_class[];
|
12
10
|
|
13
11
|
VALUE oj_array_nl_sym;
|
@@ -274,7 +272,7 @@ static int mimic_walk(VALUE key, VALUE obj, VALUE proc) {
|
|
274
272
|
size_t i;
|
275
273
|
|
276
274
|
for (i = 0; i < cnt; i++) {
|
277
|
-
mimic_walk(Qnil,
|
275
|
+
mimic_walk(Qnil, RARRAY_AREF(obj, i), proc);
|
278
276
|
}
|
279
277
|
break;
|
280
278
|
}
|
@@ -501,6 +499,52 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
|
501
499
|
return mimic_generate_core(2, rargs, &copts);
|
502
500
|
}
|
503
501
|
|
502
|
+
static int parse_options_cb(VALUE k, VALUE v, VALUE info) {
|
503
|
+
struct _parseInfo *pi = (struct _parseInfo *)info;
|
504
|
+
|
505
|
+
if (oj_symbolize_names_sym == k) {
|
506
|
+
pi->options.sym_key = (Qtrue == v) ? Yes : No;
|
507
|
+
} else if (oj_quirks_mode_sym == k) {
|
508
|
+
pi->options.quirks_mode = (Qtrue == v) ? Yes : No;
|
509
|
+
} else if (oj_create_additions_sym == k) {
|
510
|
+
pi->options.create_ok = (Qtrue == v) ? Yes : No;
|
511
|
+
} else if (oj_allow_nan_sym == k) {
|
512
|
+
pi->options.allow_nan = (Qtrue == v) ? Yes : No;
|
513
|
+
} else if (oj_hash_class_sym == k) {
|
514
|
+
if (Qnil == v) {
|
515
|
+
pi->options.hash_class = Qnil;
|
516
|
+
} else {
|
517
|
+
rb_check_type(v, T_CLASS);
|
518
|
+
pi->options.hash_class = v;
|
519
|
+
}
|
520
|
+
} else if (oj_object_class_sym == k) {
|
521
|
+
if (Qnil == v) {
|
522
|
+
pi->options.hash_class = Qnil;
|
523
|
+
} else {
|
524
|
+
rb_check_type(v, T_CLASS);
|
525
|
+
pi->options.hash_class = v;
|
526
|
+
}
|
527
|
+
} else if (oj_array_class_sym == k) {
|
528
|
+
if (Qnil == v) {
|
529
|
+
pi->options.array_class = Qnil;
|
530
|
+
} else {
|
531
|
+
rb_check_type(v, T_CLASS);
|
532
|
+
pi->options.array_class = v;
|
533
|
+
}
|
534
|
+
} else if (oj_decimal_class_sym == k) {
|
535
|
+
pi->options.compat_bigdec = (oj_bigdecimal_class == v);
|
536
|
+
} else if (oj_max_nesting_sym == k) {
|
537
|
+
if (Qtrue == v) {
|
538
|
+
pi->max_depth = 100;
|
539
|
+
} else if (Qfalse == v || Qnil == v) {
|
540
|
+
pi->max_depth = 0;
|
541
|
+
} else if (T_FIXNUM == rb_type(v)) {
|
542
|
+
pi->max_depth = NUM2INT(v);
|
543
|
+
}
|
544
|
+
}
|
545
|
+
return ST_CONTINUE;
|
546
|
+
}
|
547
|
+
|
504
548
|
static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
505
549
|
struct _parseInfo pi;
|
506
550
|
VALUE ropts;
|
@@ -516,7 +560,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
516
560
|
pi.options = oj_default_options;
|
517
561
|
pi.options.auto_define = No;
|
518
562
|
pi.options.quirks_mode = Yes;
|
519
|
-
pi.options.allow_invalid =
|
563
|
+
pi.options.allow_invalid = Yes;
|
520
564
|
pi.options.empty_string = No;
|
521
565
|
pi.options.create_ok = No;
|
522
566
|
pi.options.allow_nan = (bang ? Yes : No);
|
@@ -526,64 +570,11 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
526
570
|
pi.max_depth = 100;
|
527
571
|
|
528
572
|
if (Qnil != ropts) {
|
529
|
-
VALUE v;
|
530
|
-
|
531
573
|
if (T_HASH != rb_type(ropts)) {
|
532
574
|
rb_raise(rb_eArgError, "options must be a hash.");
|
533
575
|
}
|
534
|
-
if (Qundef == symbolize_names_sym) {
|
535
|
-
symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
|
536
|
-
rb_gc_register_address(&symbolize_names_sym);
|
537
|
-
}
|
538
|
-
if (Qnil != (v = rb_hash_lookup(ropts, symbolize_names_sym))) {
|
539
|
-
pi.options.sym_key = (Qtrue == v) ? Yes : No;
|
540
|
-
}
|
541
|
-
if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
|
542
|
-
pi.options.quirks_mode = (Qtrue == v) ? Yes : No;
|
543
|
-
}
|
544
|
-
if (Qnil != (v = rb_hash_lookup(ropts, oj_create_additions_sym))) {
|
545
|
-
pi.options.create_ok = (Qtrue == v) ? Yes : No;
|
546
|
-
}
|
547
|
-
if (Qnil != (v = rb_hash_lookup(ropts, oj_allow_nan_sym))) {
|
548
|
-
pi.options.allow_nan = (Qtrue == v) ? Yes : No;
|
549
|
-
}
|
550
576
|
|
551
|
-
|
552
|
-
if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
|
553
|
-
pi.options.hash_class = Qnil;
|
554
|
-
} else {
|
555
|
-
rb_check_type(v, T_CLASS);
|
556
|
-
pi.options.hash_class = v;
|
557
|
-
}
|
558
|
-
}
|
559
|
-
if (oj_hash_has_key(ropts, oj_object_class_sym)) {
|
560
|
-
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
|
561
|
-
pi.options.hash_class = Qnil;
|
562
|
-
} else {
|
563
|
-
rb_check_type(v, T_CLASS);
|
564
|
-
pi.options.hash_class = v;
|
565
|
-
}
|
566
|
-
}
|
567
|
-
if (oj_hash_has_key(ropts, oj_array_class_sym)) {
|
568
|
-
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
|
569
|
-
pi.options.array_class = Qnil;
|
570
|
-
} else {
|
571
|
-
rb_check_type(v, T_CLASS);
|
572
|
-
pi.options.array_class = v;
|
573
|
-
}
|
574
|
-
}
|
575
|
-
if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
|
576
|
-
pi.options.compat_bigdec = (oj_bigdecimal_class ==
|
577
|
-
rb_hash_lookup(ropts, oj_decimal_class_sym));
|
578
|
-
}
|
579
|
-
v = rb_hash_lookup(ropts, oj_max_nesting_sym);
|
580
|
-
if (Qtrue == v) {
|
581
|
-
pi.max_depth = 100;
|
582
|
-
} else if (Qfalse == v || Qnil == v) {
|
583
|
-
pi.max_depth = 0;
|
584
|
-
} else if (T_FIXNUM == rb_type(v)) {
|
585
|
-
pi.max_depth = NUM2INT(v);
|
586
|
-
}
|
577
|
+
rb_hash_foreach(ropts, parse_options_cb, (VALUE)&pi);
|
587
578
|
oj_parse_opt_match_string(&pi.options.str_rx, ropts);
|
588
579
|
if (Yes == pi.options.create_ok && Yes == pi.options.sym_key) {
|
589
580
|
rb_raise(rb_eArgError, ":symbolize_names and :create_additions can not both be true.");
|
@@ -682,7 +673,7 @@ static VALUE mimic_set_create_id(VALUE self, VALUE id) {
|
|
682
673
|
*/
|
683
674
|
static VALUE mimic_create_id(VALUE self) {
|
684
675
|
if (NULL != oj_default_options.create_id) {
|
685
|
-
return
|
676
|
+
return rb_utf8_str_new(oj_default_options.create_id, oj_default_options.create_id_len);
|
686
677
|
}
|
687
678
|
return rb_str_new_cstr(oj_json_class);
|
688
679
|
}
|
@@ -706,7 +697,7 @@ static struct _options mimic_object_to_json_options = {0, // indent
|
|
706
697
|
No, // empty_string
|
707
698
|
Yes, // allow_gc
|
708
699
|
Yes, // quirks_mode
|
709
|
-
|
700
|
+
Yes, // allow_invalid
|
710
701
|
No, // create_ok
|
711
702
|
No, // allow_nan
|
712
703
|
No, // trace
|
@@ -853,9 +844,6 @@ void oj_mimic_json_methods(VALUE json) {
|
|
853
844
|
// Pull in the JSON::State mimic file.
|
854
845
|
state_class = rb_const_get_at(generator, rb_intern("State"));
|
855
846
|
rb_gc_register_mark_object(state_class);
|
856
|
-
|
857
|
-
symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
|
858
|
-
rb_gc_register_address(&symbolize_names_sym);
|
859
847
|
}
|
860
848
|
|
861
849
|
/* Document-module: JSON
|