oj 1.4.5 → 1.4.6a2
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.
- data/README.md +8 -6
- data/ext/oj/cache8.c +1 -1
- data/ext/oj/dump.c +14 -14
- data/ext/oj/fast.c +6 -1
- data/ext/oj/foo.rb +6 -0
- data/ext/oj/load.c +4 -0
- data/ext/oj/oj.c +23 -6
- data/lib/oj/mimic.rb +2 -1
- data/lib/oj/version.rb +1 -1
- data/test/test_mimic.rb +13 -5
- data/test/tests.rb +8 -2
- metadata +6 -5
data/README.md
CHANGED
@@ -32,9 +32,11 @@ 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 1.4.
|
35
|
+
### Release 1.4.6
|
36
36
|
|
37
|
-
-
|
37
|
+
- Silently ignores BOM on files and Strings.
|
38
|
+
|
39
|
+
- Now works with JRuby 1.7.0 to the extent possible with the unsupported C extension in JRuby.
|
38
40
|
|
39
41
|
## <a name="description">Description</a>
|
40
42
|
|
@@ -63,10 +65,10 @@ to_hash() is more flexible and produces more consistent output so it has a
|
|
63
65
|
preference over the to_json() method. If neither the to_json() or to_hash()
|
64
66
|
methods exist then the Oj internal Object variable encoding is used.
|
65
67
|
|
66
|
-
Oj is compatible with Ruby 1.8.7, 1.9.2, 1.9.3, JRuby, RBX, and the latest
|
67
|
-
|
68
|
-
|
69
|
-
installs in your environment.
|
68
|
+
Oj is compatible with Ruby 1.8.7, 1.9.2, 1.9.3, JRuby, RBX, and the latest 2.0dev. Note that JRuby now disables support
|
69
|
+
for extentions by default and is no longer supporting C extensions. Bugs reported in the JRuby MRI are no longer being
|
70
|
+
fixed and there is at least one that has caused a test to be commented out for JRuby in the Oj test suite. JRuby can be
|
71
|
+
build with extensions enabled. Check the documenation for JRuby installs in your environment.
|
70
72
|
|
71
73
|
Oj is also compatible with Rails. Just make sure the Oj gem is installed and
|
72
74
|
[multi_json](https://github.com/intridea/multi_json) will pick it up and use it.
|
data/ext/oj/cache8.c
CHANGED
@@ -94,7 +94,7 @@ slot_print(Cache8 c, sid_t key, unsigned int depth) {
|
|
94
94
|
k = (k8 << BITS) | i;
|
95
95
|
/*printf("*** key: 0x%016llx depth: %u i: %u\n", k, depth, i); */
|
96
96
|
if (DEPTH - 1 == depth) {
|
97
|
-
printf("0x%016llx: %4llu\n", k, b->value);
|
97
|
+
printf("0x%016llx: %4llu\n", (long long unsigned int)k, (long long unsigned int)b->value);
|
98
98
|
} else {
|
99
99
|
slot_print(b->child, k, depth + 1);
|
100
100
|
}
|
data/ext/oj/dump.c
CHANGED
@@ -76,7 +76,7 @@ static void dump_bignum(VALUE obj, Out out);
|
|
76
76
|
static void dump_float(VALUE obj, Out out);
|
77
77
|
static void dump_raw(const char *str, size_t cnt, Out out);
|
78
78
|
static void dump_cstr(const char *str, size_t cnt, int is_sym, int escape1, Out out);
|
79
|
-
static void dump_hex(
|
79
|
+
static void dump_hex(uint8_t c, Out out);
|
80
80
|
static void dump_str_comp(VALUE obj, Out out);
|
81
81
|
static void dump_str_obj(VALUE obj, Out out);
|
82
82
|
static void dump_sym_comp(VALUE obj, Out out);
|
@@ -108,8 +108,8 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
108
108
|
static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out);
|
109
109
|
|
110
110
|
static void grow(Out out, size_t len);
|
111
|
-
static size_t hibit_friendly_size(const
|
112
|
-
static size_t ascii_friendly_size(const
|
111
|
+
static size_t hibit_friendly_size(const uint8_t *str, size_t len);
|
112
|
+
static size_t ascii_friendly_size(const uint8_t *str, size_t len);
|
113
113
|
|
114
114
|
static void dump_leaf_to_json(Leaf leaf, Options copts, Out out);
|
115
115
|
static void dump_leaf(Leaf leaf, int depth, Out out);
|
@@ -145,7 +145,7 @@ static char ascii_friendly_chars[256] = "\
|
|
145
145
|
33333333333333333333333333333333";
|
146
146
|
|
147
147
|
inline static size_t
|
148
|
-
hibit_friendly_size(const
|
148
|
+
hibit_friendly_size(const uint8_t *str, size_t len) {
|
149
149
|
size_t size = 0;
|
150
150
|
|
151
151
|
for (; 0 < len; str++, len--) {
|
@@ -155,7 +155,7 @@ hibit_friendly_size(const u_char *str, size_t len) {
|
|
155
155
|
}
|
156
156
|
|
157
157
|
inline static size_t
|
158
|
-
ascii_friendly_size(const
|
158
|
+
ascii_friendly_size(const uint8_t *str, size_t len) {
|
159
159
|
size_t size = 0;
|
160
160
|
|
161
161
|
for (; 0 < len; str++, len--) {
|
@@ -228,8 +228,8 @@ grow(Out out, size_t len) {
|
|
228
228
|
}
|
229
229
|
|
230
230
|
inline static void
|
231
|
-
dump_hex(
|
232
|
-
|
231
|
+
dump_hex(uint8_t c, Out out) {
|
232
|
+
uint8_t d = (c >> 4) & 0x0F;
|
233
233
|
|
234
234
|
*out->cur++ = hex_chars[d];
|
235
235
|
d = c & 0x0F;
|
@@ -455,10 +455,10 @@ dump_cstr(const char *str, size_t cnt, int is_sym, int escape1, Out out) {
|
|
455
455
|
|
456
456
|
if (Yes == out->opts->ascii_only) {
|
457
457
|
cmap = ascii_friendly_chars;
|
458
|
-
size = ascii_friendly_size((
|
458
|
+
size = ascii_friendly_size((uint8_t*)str, cnt);
|
459
459
|
} else {
|
460
460
|
cmap = hibit_friendly_chars;
|
461
|
-
size = hibit_friendly_size((
|
461
|
+
size = hibit_friendly_size((uint8_t*)str, cnt);
|
462
462
|
}
|
463
463
|
if (out->end - out->cur <= (long)size + 10) { // extra 10 for escaped first char, quotes, and sym
|
464
464
|
grow(out, size + 10);
|
@@ -469,7 +469,7 @@ dump_cstr(const char *str, size_t cnt, int is_sym, int escape1, Out out) {
|
|
469
469
|
*out->cur++ = 'u';
|
470
470
|
*out->cur++ = '0';
|
471
471
|
*out->cur++ = '0';
|
472
|
-
dump_hex((
|
472
|
+
dump_hex((uint8_t)*str, out);
|
473
473
|
cnt--;
|
474
474
|
size--;
|
475
475
|
str++;
|
@@ -490,7 +490,7 @@ dump_cstr(const char *str, size_t cnt, int is_sym, int escape1, Out out) {
|
|
490
490
|
*out->cur++ = ':';
|
491
491
|
}
|
492
492
|
for (; str < end; str++) {
|
493
|
-
switch (cmap[(
|
493
|
+
switch (cmap[(uint8_t)*str]) {
|
494
494
|
case '1':
|
495
495
|
*out->cur++ = *str;
|
496
496
|
break;
|
@@ -513,7 +513,7 @@ dump_cstr(const char *str, size_t cnt, int is_sym, int escape1, Out out) {
|
|
513
513
|
*out->cur++ = 'u';
|
514
514
|
*out->cur++ = '0';
|
515
515
|
*out->cur++ = '0';
|
516
|
-
dump_hex((
|
516
|
+
dump_hex((uint8_t)*str, out);
|
517
517
|
break;
|
518
518
|
default:
|
519
519
|
break; // ignore, should never happen if the table is correct
|
@@ -809,7 +809,7 @@ hash_cb_object(VALUE key, VALUE value, Out out) {
|
|
809
809
|
long s2 = size + out->indent + 1;
|
810
810
|
int i;
|
811
811
|
int started = 0;
|
812
|
-
|
812
|
+
uint8_t b;
|
813
813
|
|
814
814
|
if (out->end - out->cur <= s2 + 15) {
|
815
815
|
grow(out, s2 + 15);
|
@@ -819,7 +819,7 @@ hash_cb_object(VALUE key, VALUE value, Out out) {
|
|
819
819
|
*out->cur++ = '#';
|
820
820
|
out->hash_cnt++;
|
821
821
|
for (i = 28; 0 <= i; i -= 4) {
|
822
|
-
b = (
|
822
|
+
b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
|
823
823
|
if ('\0' != b) {
|
824
824
|
started = 1;
|
825
825
|
}
|
data/ext/oj/fast.c
CHANGED
@@ -840,7 +840,12 @@ parse_json(VALUE clas, char *json, int given, int allocated) {
|
|
840
840
|
} else {
|
841
841
|
doc = ALLOC_N(struct _Doc, 1);
|
842
842
|
}
|
843
|
-
|
843
|
+
/* skip UTF-8 BOM if present */
|
844
|
+
if (0xEF == (uint8_t)*json && 0xBB == (uint8_t)json[1] && 0xBF == (uint8_t)json[2]) {
|
845
|
+
pi.str = json + 3;
|
846
|
+
} else {
|
847
|
+
pi.str = json;
|
848
|
+
}
|
844
849
|
pi.s = pi.str;
|
845
850
|
doc_init(doc);
|
846
851
|
pi.doc = doc;
|
data/ext/oj/foo.rb
ADDED
data/ext/oj/load.c
CHANGED
@@ -1009,6 +1009,10 @@ oj_parse(char *json, Options options) {
|
|
1009
1009
|
if (0 == json) {
|
1010
1010
|
raise_error("Invalid arg, xml string can not be null", json, 0);
|
1011
1011
|
}
|
1012
|
+
/* skip UTF-8 BOM if present */
|
1013
|
+
if (0xEF == (uint8_t)*json && 0xBB == (uint8_t)json[1] && 0xBF == (uint8_t)json[2]) {
|
1014
|
+
json += 3;
|
1015
|
+
}
|
1012
1016
|
/* initialize parse info */
|
1013
1017
|
pi.str = json;
|
1014
1018
|
pi.s = json;
|
data/ext/oj/oj.c
CHANGED
@@ -125,9 +125,8 @@ struct _Options oj_default_options = {
|
|
125
125
|
0, // dump_opts
|
126
126
|
};
|
127
127
|
|
128
|
-
static VALUE define_mimic_json(VALUE self);
|
129
|
-
|
130
|
-
static struct _Odd odds[4]; // bump up if new Odd classes are added
|
128
|
+
static VALUE define_mimic_json(int argc, VALUE *argv, VALUE self);
|
129
|
+
static struct _Odd odds[5]; // bump up if new Odd classes are added
|
131
130
|
|
132
131
|
Odd
|
133
132
|
oj_get_odd(VALUE clas) {
|
@@ -800,7 +799,7 @@ mimic_create_id(VALUE self, VALUE id) {
|
|
800
799
|
* or generator will not raise an Exception but will not have any effect.
|
801
800
|
*/
|
802
801
|
static VALUE
|
803
|
-
define_mimic_json(VALUE self) {
|
802
|
+
define_mimic_json(int argc, VALUE *argv, VALUE self) {
|
804
803
|
if (Qnil == mimic) {
|
805
804
|
VALUE ext;
|
806
805
|
VALUE dummy;
|
@@ -817,7 +816,14 @@ define_mimic_json(VALUE self) {
|
|
817
816
|
dummy = rb_gv_get("$LOADED_FEATURES");
|
818
817
|
if (rb_type(dummy) == T_ARRAY) {
|
819
818
|
rb_ary_push(dummy, rb_str_new2("json"));
|
820
|
-
|
819
|
+
if (0 < argc) {
|
820
|
+
VALUE mimic_args[1];
|
821
|
+
|
822
|
+
*mimic_args = *argv;
|
823
|
+
rb_funcall2(Oj, rb_intern("mimic_loaded"), 1, mimic_args);
|
824
|
+
} else {
|
825
|
+
rb_funcall2(Oj, rb_intern("mimic_loaded"), 0, 0);
|
826
|
+
}
|
821
827
|
}
|
822
828
|
|
823
829
|
rb_define_module_function(mimic, "parser=", no_op1, 1);
|
@@ -868,7 +874,7 @@ void Init_oj() {
|
|
868
874
|
rb_define_module_function(Oj, "default_options", get_def_opts, 0);
|
869
875
|
rb_define_module_function(Oj, "default_options=", set_def_opts, 1);
|
870
876
|
|
871
|
-
rb_define_module_function(Oj, "mimic_JSON", define_mimic_json,
|
877
|
+
rb_define_module_function(Oj, "mimic_JSON", define_mimic_json, -1);
|
872
878
|
rb_define_module_function(Oj, "load", load, -1);
|
873
879
|
rb_define_module_function(Oj, "load_file", load_file, -1);
|
874
880
|
rb_define_module_function(Oj, "dump", dump, -1);
|
@@ -964,8 +970,19 @@ void Init_oj() {
|
|
964
970
|
*idp++ = rb_intern("offset");
|
965
971
|
*idp++ = rb_intern("start");
|
966
972
|
*idp++ = 0;
|
973
|
+
// Range
|
967
974
|
odd++;
|
975
|
+
idp = odd->attrs;
|
976
|
+
odd->clas = rb_const_get(rb_cObject, rb_intern("Range"));
|
977
|
+
odd->create_obj = odd->clas;
|
978
|
+
odd->create_op = oj_new_id;
|
979
|
+
odd->attr_cnt = 3;
|
980
|
+
*idp++ = rb_intern("begin");
|
981
|
+
*idp++ = rb_intern("end");
|
982
|
+
*idp++ = rb_intern("exclude_end?");
|
983
|
+
*idp++ = 0;
|
968
984
|
// The end. bump up the size of odds if a new class is added.
|
985
|
+
odd++;
|
969
986
|
odd->clas = Qundef;
|
970
987
|
|
971
988
|
#if SAFE_CACHE
|
data/lib/oj/mimic.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
|
2
2
|
module Oj
|
3
3
|
|
4
|
-
def self.mimic_loaded()
|
4
|
+
def self.mimic_loaded(mimic_paths=[])
|
5
5
|
gems_dir = File.dirname(File.dirname(File.dirname(File.dirname(__FILE__))))
|
6
6
|
Dir.foreach(gems_dir) do |gem|
|
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
|
+
mimic_paths.each { |p| $LOADED_FEATURES << p }
|
10
11
|
end
|
11
12
|
end
|
data/lib/oj/version.rb
CHANGED
data/test/test_mimic.rb
CHANGED
@@ -76,6 +76,7 @@ class Mimic < ::Test::Unit::TestCase
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def test_load_proc
|
79
|
+
Oj.mimic_JSON # TBD
|
79
80
|
children = []
|
80
81
|
json = %{{"a":1,"b":[true,false]}}
|
81
82
|
if 'rubinius' == $ruby || 'jruby' == $ruby || '1.8.7' == RUBY_VERSION
|
@@ -85,8 +86,12 @@ class Mimic < ::Test::Unit::TestCase
|
|
85
86
|
obj = JSON.load(json, p)
|
86
87
|
end
|
87
88
|
assert_equal({ 'a' => 1, 'b' => [true, false]}, obj)
|
88
|
-
|
89
|
-
|
89
|
+
# JRuby 1.7.0 rb_yield() is broken and converts the [true, falser] array into true
|
90
|
+
unless 'jruby' == $ruby && '1.9.3' == RUBY_VERSION
|
91
|
+
assert([1, true, false, [true, false], { 'a' => 1, 'b' => [true, false]}] == children ||
|
92
|
+
[true, false, [true, false], 1, { 'a' => 1, 'b' => [true, false]}] == children,
|
93
|
+
"children don't match")
|
94
|
+
end
|
90
95
|
end
|
91
96
|
|
92
97
|
# []
|
@@ -192,9 +197,12 @@ class Mimic < ::Test::Unit::TestCase
|
|
192
197
|
# recurse_proc
|
193
198
|
def test_recurse_proc
|
194
199
|
children = []
|
195
|
-
|
196
|
-
|
197
|
-
|
200
|
+
JSON.recurse_proc({ 'a' => 1, 'b' => [true, false]}) { |x| children << x }
|
201
|
+
# JRuby 1.7.0 rb_yield() is broken and converts the [true, falser] array into true
|
202
|
+
unless 'jruby' == $ruby && '1.9.3' == RUBY_VERSION
|
203
|
+
assert([1, true, false, [true, false], { 'a' => 1, 'b' => [true, false]}] == children ||
|
204
|
+
[true, false, [true, false], 1, { 'b' => [true, false], 'a' => 1}] == children)
|
205
|
+
end
|
198
206
|
end
|
199
207
|
|
200
208
|
end # Mimic
|
data/test/tests.rb
CHANGED
@@ -192,11 +192,15 @@ class Juice < ::Test::Unit::TestCase
|
|
192
192
|
def test_encode
|
193
193
|
opts = Oj.default_options
|
194
194
|
Oj.default_options = { :ascii_only => false }
|
195
|
-
|
195
|
+
unless 'jruby' == $ruby
|
196
|
+
dump_and_load("ぴーたー", false)
|
197
|
+
end
|
196
198
|
Oj.default_options = { :ascii_only => true }
|
197
199
|
json = Oj.dump("ぴーたー")
|
198
200
|
assert_equal(%{"\\u3074\\u30fc\\u305f\\u30fc"}, json)
|
199
|
-
|
201
|
+
unless 'jruby' == $ruby
|
202
|
+
dump_and_load("ぴーたー", false)
|
203
|
+
end
|
200
204
|
Oj.default_options = opts
|
201
205
|
end
|
202
206
|
|
@@ -623,6 +627,8 @@ class Juice < ::Test::Unit::TestCase
|
|
623
627
|
if 'rubinius' == $ruby
|
624
628
|
assert(%{{"^o":"Range","excl":false,"begin":1,"end":7}} == json ||
|
625
629
|
%{{"^o":"Range","begin":1,"end":7,"excl":false}} == json)
|
630
|
+
elsif 'jruby' == $ruby
|
631
|
+
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
626
632
|
else
|
627
633
|
assert_equal(%{{"^u":["Range",1,7,false]}}, json)
|
628
634
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
5
|
-
prerelease:
|
4
|
+
version: 1.4.6a2
|
5
|
+
prerelease: 5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Peter Ohler
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-03 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! 'The fastest JSON parser and object serializer. '
|
15
15
|
email: peter@ohler.com
|
@@ -25,6 +25,7 @@ files:
|
|
25
25
|
- lib/oj/version.rb
|
26
26
|
- lib/oj.rb
|
27
27
|
- ext/oj/extconf.rb
|
28
|
+
- ext/oj/foo.rb
|
28
29
|
- ext/oj/cache.h
|
29
30
|
- ext/oj/cache8.h
|
30
31
|
- ext/oj/oj.h
|
@@ -80,9 +81,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
82
|
none: false
|
82
83
|
requirements:
|
83
|
-
- - ! '
|
84
|
+
- - ! '>'
|
84
85
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
86
|
+
version: 1.3.1
|
86
87
|
requirements: []
|
87
88
|
rubyforge_project: oj
|
88
89
|
rubygems_version: 1.8.23
|