oj 2.0.10 → 2.0.11
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of oj might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/ext/oj/dump.c +1 -1
- data/ext/oj/load.c +38 -29
- data/ext/oj/oj.c +8 -0
- data/ext/oj/oj.h +1 -0
- data/lib/oj/mimic.rb +8 -0
- data/lib/oj/version.rb +1 -1
- data/test/tests.rb +20 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 451501e86625385b0362d776ad531e20f8be0aa5
|
4
|
+
data.tar.gz: fc691b28aba6381bec1aebe7acfe25f0483f0b82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f779275172ff00267a5c7d9398b831253c0582abc2eb93f1e9b1f74d7863bf0e16156a9926d5008006329bb5d78549f799e8f54bf9d4b6effa422849171d767
|
7
|
+
data.tar.gz: 0d971692dce841116f198fc6c190c906ce613784b647908e706d8a8e76d965b4e9d7fc16a960e776da5dbb5426a8f53dd4d5b0744aafe36a0831532f1cf97490
|
data/README.md
CHANGED
@@ -32,15 +32,15 @@ A fast JSON parser and Object marshaller as a Ruby gem.
|
|
32
32
|
|
33
33
|
## <a name="release">Release Notes</a>
|
34
34
|
|
35
|
-
### Release 2.0.
|
35
|
+
### Release 2.0.11
|
36
36
|
|
37
|
-
-
|
37
|
+
- Fixed mimic issue with Debian
|
38
38
|
|
39
|
-
-
|
39
|
+
- Added option to not cache classes when loading. This should be used when classes are dynamically unloaded and the redefined.
|
40
40
|
|
41
|
-
|
41
|
+
- Float rounding improved by limiting decimal places to 15 places.
|
42
42
|
|
43
|
-
- Fixed
|
43
|
+
- Fixed xml time dumping test.
|
44
44
|
|
45
45
|
## <a name="description">Description</a>
|
46
46
|
|
data/ext/oj/dump.c
CHANGED
@@ -429,7 +429,7 @@ dump_float(VALUE obj, Out out) {
|
|
429
429
|
} else if (d == (double)(long long int)d) {
|
430
430
|
cnt = sprintf(buf, "%.1f", d); // used sprintf due to bug in snprintf
|
431
431
|
} else {
|
432
|
-
cnt = sprintf(buf, "%0.
|
432
|
+
cnt = sprintf(buf, "%0.15g", d); // used sprintf due to bug in snprintf
|
433
433
|
}
|
434
434
|
if (out->end - out->cur <= (long)cnt) {
|
435
435
|
grow(out, cnt);
|
data/ext/oj/load.c
CHANGED
@@ -158,44 +158,53 @@ classname2obj(const char *name, ParseInfo pi) {
|
|
158
158
|
}
|
159
159
|
}
|
160
160
|
|
161
|
+
static VALUE
|
162
|
+
resolve_classpath(const char *name, ParseInfo pi) {
|
163
|
+
char class_name[1024];
|
164
|
+
VALUE clas;
|
165
|
+
int auto_define = (Yes == pi->options->auto_define);
|
166
|
+
char *end = class_name + sizeof(class_name) - 1;
|
167
|
+
char *s;
|
168
|
+
const char *n = name;
|
169
|
+
|
170
|
+
clas = rb_cObject;
|
171
|
+
for (s = class_name; '\0' != *n; n++) {
|
172
|
+
if (':' == *n) {
|
173
|
+
*s = '\0';
|
174
|
+
n++;
|
175
|
+
if (':' != *n) {
|
176
|
+
raise_error("Invalid classname, expected another ':'", pi->str, pi->s);
|
177
|
+
}
|
178
|
+
if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
|
179
|
+
char buf[1024];
|
180
|
+
|
181
|
+
snprintf(buf, sizeof(buf) - 1, "Class %s not defined", class_name);
|
182
|
+
raise_error(buf, pi->str, pi->s);
|
183
|
+
}
|
184
|
+
s = class_name;
|
185
|
+
} else if (end <= s) {
|
186
|
+
raise_error("Invalid classname, limit is 1024 characters", pi->str, pi->s);
|
187
|
+
} else {
|
188
|
+
*s++ = *n;
|
189
|
+
}
|
190
|
+
}
|
191
|
+
*s = '\0';
|
192
|
+
return resolve_classname(clas, class_name, auto_define);
|
193
|
+
}
|
194
|
+
|
161
195
|
static VALUE
|
162
196
|
classname2class(const char *name, ParseInfo pi) {
|
163
197
|
VALUE clas;
|
164
198
|
VALUE *slot;
|
165
|
-
int auto_define = (Yes == pi->options->auto_define);
|
166
199
|
|
200
|
+
if (No == pi->options->class_cache) {
|
201
|
+
return resolve_classpath(name, pi);
|
202
|
+
}
|
167
203
|
#if SAFE_CACHE
|
168
204
|
pthread_mutex_lock(&oj_cache_mutex);
|
169
205
|
#endif
|
170
206
|
if (Qundef == (clas = oj_cache_get(oj_class_cache, name, &slot))) {
|
171
|
-
|
172
|
-
char *end = class_name + sizeof(class_name) - 1;
|
173
|
-
char *s;
|
174
|
-
const char *n = name;
|
175
|
-
|
176
|
-
clas = rb_cObject;
|
177
|
-
for (s = class_name; '\0' != *n; n++) {
|
178
|
-
if (':' == *n) {
|
179
|
-
*s = '\0';
|
180
|
-
n++;
|
181
|
-
if (':' != *n) {
|
182
|
-
raise_error("Invalid classname, expected another ':'", pi->str, pi->s);
|
183
|
-
}
|
184
|
-
if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
|
185
|
-
char buf[1024];
|
186
|
-
|
187
|
-
snprintf(buf, sizeof(buf) - 1, "Class %s not defined", class_name);
|
188
|
-
raise_error(buf, pi->str, pi->s);
|
189
|
-
}
|
190
|
-
s = class_name;
|
191
|
-
} else if (end <= s) {
|
192
|
-
raise_error("Invalid classname, limit is 1024 characters", pi->str, pi->s);
|
193
|
-
} else {
|
194
|
-
*s++ = *n;
|
195
|
-
}
|
196
|
-
}
|
197
|
-
*s = '\0';
|
198
|
-
if (Qundef != (clas = resolve_classname(clas, class_name, auto_define))) {
|
207
|
+
if (Qundef != (clas = resolve_classpath(name, pi))) {
|
199
208
|
*slot = clas;
|
200
209
|
}
|
201
210
|
}
|
data/ext/oj/oj.c
CHANGED
@@ -87,6 +87,7 @@ static VALUE auto_define_sym;
|
|
87
87
|
static VALUE bigdecimal_as_decimal_sym;
|
88
88
|
static VALUE bigdecimal_load_sym;
|
89
89
|
static VALUE circular_sym;
|
90
|
+
static VALUE class_cache_sym;
|
90
91
|
static VALUE compat_sym;
|
91
92
|
static VALUE create_id_sym;
|
92
93
|
static VALUE indent_sym;
|
@@ -130,6 +131,7 @@ struct _Options oj_default_options = {
|
|
130
131
|
No, // sym_key
|
131
132
|
No, // ascii_only
|
132
133
|
ObjectMode, // mode
|
134
|
+
Yes, // class_cache
|
133
135
|
UnixTime, // time_format
|
134
136
|
Yes, // bigdec_as_num
|
135
137
|
No, // bigdec_load
|
@@ -161,6 +163,7 @@ oj_get_odd(VALUE clas) {
|
|
161
163
|
* - circular: [true|false|nil] support circular references while dumping
|
162
164
|
* - auto_define: [true|false|nil] automatically define classes if they do not exist
|
163
165
|
* - symbol_keys: [true|false|nil] use symbols instead of strings for hash keys
|
166
|
+
* - class_cache: [true|false|nil] cache classes for faster parsing (if dynamically modifying classes or reloading classes then don't use this)
|
164
167
|
* - mode: [:object|:strict|:compat|:null] load and dump modes to use for JSON
|
165
168
|
* - time_format: [:unix|:xmlschema|:ruby] time format when dumping in :compat mode
|
166
169
|
* - bigdecimal_as_decimal: [true|false|nil] dump BigDecimal as a decimal number or as a String
|
@@ -178,6 +181,7 @@ get_def_opts(VALUE self) {
|
|
178
181
|
rb_hash_aset(opts, sec_prec_sym, INT2FIX(oj_default_options.sec_prec));
|
179
182
|
rb_hash_aset(opts, max_stack_sym, INT2FIX(oj_default_options.max_stack));
|
180
183
|
rb_hash_aset(opts, circular_sym, (Yes == oj_default_options.circular) ? Qtrue : ((No == oj_default_options.circular) ? Qfalse : Qnil));
|
184
|
+
rb_hash_aset(opts, class_cache_sym, (Yes == oj_default_options.class_cache) ? Qtrue : ((No == oj_default_options.class_cache) ? Qfalse : Qnil));
|
181
185
|
rb_hash_aset(opts, auto_define_sym, (Yes == oj_default_options.auto_define) ? Qtrue : ((No == oj_default_options.auto_define) ? Qfalse : Qnil));
|
182
186
|
rb_hash_aset(opts, ascii_only_sym, (Yes == oj_default_options.ascii_only) ? Qtrue : ((No == oj_default_options.ascii_only) ? Qfalse : Qnil));
|
183
187
|
rb_hash_aset(opts, symbol_keys_sym, (Yes == oj_default_options.sym_key) ? Qtrue : ((No == oj_default_options.sym_key) ? Qfalse : Qnil));
|
@@ -209,6 +213,7 @@ get_def_opts(VALUE self) {
|
|
209
213
|
* @param [true|false|nil] :circular support circular references while dumping
|
210
214
|
* @param [true|false|nil] :auto_define automatically define classes if they do not exist
|
211
215
|
* @param [true|false|nil] :symbol_keys convert hash keys to symbols
|
216
|
+
* @param [true|false|nil] :class_cache cache classes for faster parsing
|
212
217
|
* @param [true|false|nil] :ascii_only encode all high-bit characters as escaped sequences if true
|
213
218
|
* @param [true|false|nil] :bigdecimal_as_decimal dump BigDecimal as a decimal number or as a String
|
214
219
|
* @param [true|false|nil] :bigdecimal_load load decimals as a BigDecimal instead of as a Float
|
@@ -235,6 +240,7 @@ set_def_opts(VALUE self, VALUE opts) {
|
|
235
240
|
{ circular_sym, &oj_default_options.circular },
|
236
241
|
{ auto_define_sym, &oj_default_options.auto_define },
|
237
242
|
{ symbol_keys_sym, &oj_default_options.sym_key },
|
243
|
+
{ class_cache_sym, &oj_default_options.class_cache },
|
238
244
|
{ ascii_only_sym, &oj_default_options.ascii_only },
|
239
245
|
{ bigdecimal_as_decimal_sym, &oj_default_options.bigdec_as_num },
|
240
246
|
{ bigdecimal_load_sym, &oj_default_options.bigdec_load },
|
@@ -341,6 +347,7 @@ parse_options(VALUE ropts, Options copts) {
|
|
341
347
|
{ circular_sym, &copts->circular },
|
342
348
|
{ auto_define_sym, &copts->auto_define },
|
343
349
|
{ symbol_keys_sym, &copts->sym_key },
|
350
|
+
{ class_cache_sym, &copts->class_cache },
|
344
351
|
{ ascii_only_sym, &copts->ascii_only },
|
345
352
|
{ bigdecimal_as_decimal_sym, &copts->bigdec_as_num },
|
346
353
|
{ bigdecimal_load_sym, &copts->bigdec_load },
|
@@ -1090,6 +1097,7 @@ void Init_oj() {
|
|
1090
1097
|
bigdecimal_as_decimal_sym = ID2SYM(rb_intern("bigdecimal_as_decimal"));rb_gc_register_address(&bigdecimal_as_decimal_sym);
|
1091
1098
|
bigdecimal_load_sym = ID2SYM(rb_intern("bigdecimal_load"));rb_gc_register_address(&bigdecimal_load_sym);
|
1092
1099
|
circular_sym = ID2SYM(rb_intern("circular")); rb_gc_register_address(&circular_sym);
|
1100
|
+
class_cache_sym = ID2SYM(rb_intern("class_cache")); rb_gc_register_address(&class_cache_sym);
|
1093
1101
|
compat_sym = ID2SYM(rb_intern("compat")); rb_gc_register_address(&compat_sym);
|
1094
1102
|
create_id_sym = ID2SYM(rb_intern("create_id")); rb_gc_register_address(&create_id_sym);
|
1095
1103
|
indent_sym = ID2SYM(rb_intern("indent")); rb_gc_register_address(&indent_sym);
|
data/ext/oj/oj.h
CHANGED
data/lib/oj/mimic.rb
CHANGED
@@ -7,6 +7,14 @@ module Oj
|
|
7
7
|
next unless (gem.start_with?('json-') || gem.start_with?('json_pure'))
|
8
8
|
$LOADED_FEATURES << File.join(gems_dir, gem, 'lib', 'json.rb')
|
9
9
|
end
|
10
|
+
# and another approach in case the first did not get all
|
11
|
+
$LOAD_PATH.each do |d|
|
12
|
+
next unless File.exist?(d)
|
13
|
+
Dir.entries(d) do |file|
|
14
|
+
next unless file.ends_with?('jsob.rb')
|
15
|
+
$LOADED_FEATURES << file unless $LOADED_FEATURES.include?(file)
|
16
|
+
end
|
17
|
+
end
|
10
18
|
mimic_paths.each { |p| $LOADED_FEATURES << p }
|
11
19
|
end
|
12
20
|
end
|
data/lib/oj/version.rb
CHANGED
data/test/tests.rb
CHANGED
@@ -114,6 +114,7 @@ class Juice < ::Test::Unit::TestCase
|
|
114
114
|
:circular=>false,
|
115
115
|
:auto_define=>false,
|
116
116
|
:symbol_keys=>false,
|
117
|
+
:class_cache=>true,
|
117
118
|
:ascii_only=>false,
|
118
119
|
:mode=>:object,
|
119
120
|
:time_format=>:unix,
|
@@ -130,6 +131,7 @@ class Juice < ::Test::Unit::TestCase
|
|
130
131
|
:circular=>false,
|
131
132
|
:auto_define=>false,
|
132
133
|
:symbol_keys=>false,
|
134
|
+
:class_cache=>true,
|
133
135
|
:ascii_only=>false,
|
134
136
|
:mode=>:object,
|
135
137
|
:time_format=>:unix,
|
@@ -143,6 +145,7 @@ class Juice < ::Test::Unit::TestCase
|
|
143
145
|
:circular=>true,
|
144
146
|
:auto_define=>true,
|
145
147
|
:symbol_keys=>true,
|
148
|
+
:class_cache=>false,
|
146
149
|
:ascii_only=>true,
|
147
150
|
:mode=>:compat,
|
148
151
|
:time_format=>:ruby,
|
@@ -180,6 +183,7 @@ class Juice < ::Test::Unit::TestCase
|
|
180
183
|
def test_float
|
181
184
|
dump_and_load(0.0, false)
|
182
185
|
dump_and_load(12345.6789, false)
|
186
|
+
dump_and_load(70.35, false)
|
183
187
|
dump_and_load(-54321.012, false)
|
184
188
|
dump_and_load(2.48e16, false)
|
185
189
|
dump_and_load(2.48e100 * 1.0e10, false)
|
@@ -360,7 +364,7 @@ class Juice < ::Test::Unit::TestCase
|
|
360
364
|
begin
|
361
365
|
t = Time.new(2012, 1, 5, 23, 58, 7.9996, 32400)
|
362
366
|
json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema, :second_precision => 3)
|
363
|
-
assert_equal(%{"2012-01-05T23:58:08
|
367
|
+
assert_equal(%{"2012-01-05T23:58:08+09:00"}, json)
|
364
368
|
rescue Exception
|
365
369
|
# some Rubies (1.8.7) do not allow the timezome to be set
|
366
370
|
t = Time.local(2012, 1, 5, 23, 58, 7, 999600)
|
@@ -641,6 +645,21 @@ class Juice < ::Test::Unit::TestCase
|
|
641
645
|
assert_equal(obj, obj2)
|
642
646
|
end
|
643
647
|
|
648
|
+
def test_object_object_no_cache
|
649
|
+
obj = Jam.new(true, 58)
|
650
|
+
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
651
|
+
assert(%{{
|
652
|
+
"^o":"Jam",
|
653
|
+
"x":true,
|
654
|
+
"y":58}} == json ||
|
655
|
+
%{{
|
656
|
+
"^o":"Jam",
|
657
|
+
"y":58,
|
658
|
+
"x":true}} == json)
|
659
|
+
obj2 = Oj.load(json, :mode => :object, :class_cache => false)
|
660
|
+
assert_equal(obj, obj2)
|
661
|
+
end
|
662
|
+
|
644
663
|
# Exception
|
645
664
|
def test_exception
|
646
665
|
err = nil
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'The fastest JSON parser and object serializer. '
|
14
14
|
email: peter@ohler.com
|