oj 3.13.6 → 3.13.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|