oj 2.12.9 → 2.12.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 +7 -0
- data/README.md +5 -12
- data/ext/oj/parse.c +18 -8
- data/ext/oj/sparse.c +18 -10
- data/lib/oj/version.rb +1 -1
- data/test/bug.rb +40 -51
- data/test/bug2.rb +10 -0
- data/test/bug3.rb +46 -0
- data/test/bug_fast.rb +32 -0
- data/test/bug_load.rb +24 -0
- data/test/example.rb +11 -0
- data/test/io.rb +48 -0
- data/test/{test_range.rb → mod.rb} +6 -9
- data/test/struct.rb +29 -0
- data/test/test_scp.rb +2 -4
- data/test/test_serializer.rb +59 -0
- data/test/test_various.rb +14 -0
- data/test/write_timebars.rb +31 -0
- data/test/zip.rb +34 -0
- metadata +49 -51
- data/test/perf1.rb +0 -64
- data/test/perf2.rb +0 -76
- data/test/perf_obj_old.rb +0 -213
- data/test/test_bigd.rb +0 -63
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9329b3314cabafb4851906568563da14cf57d738
|
4
|
+
data.tar.gz: b17b93f74fc2dc61a8e99d79c8d68ec5158aab50
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 952f10cd94991fa3a5e37f7984b2c3ec721db85ddba7dd6e0755fc82f73cabce106c77dbce957da5bf248886435cd57c51f9cfa4ea641cbc68ed6936af69d09d
|
7
|
+
data.tar.gz: f5c83b5202de374776f799cec68f62cb182ba5128bb0c1b8e43e5f97126eeba5c3e181cc34db1d62c476c19028ab838d5493bb965e4fafa77402d85e2f2b0999
|
data/README.md
CHANGED
@@ -26,17 +26,10 @@ Follow [@peterohler on Twitter](http://twitter.com/#!/peterohler) for announceme
|
|
26
26
|
|
27
27
|
[](http://travis-ci.org/ohler55/oj)
|
28
28
|
|
29
|
-
## Release 2.12.
|
29
|
+
## Future Release 2.12.10
|
30
30
|
|
31
|
-
-
|
32
|
-
|
33
|
-
- Changed mimic_JSON to support the global/kernel function JSON even when the
|
34
|
-
json gem is loaded first.
|
35
|
-
|
36
|
-
## Release 2.12.8
|
37
|
-
|
38
|
-
- mimic_JSON now supports the global/kernel JSON function that will either
|
39
|
-
parse a string argument or dump an array or object argument.
|
31
|
+
- An exception is now raised if there are multiple JSON documents in a string
|
32
|
+
or file if there is no proc or block associated with the parse call.
|
40
33
|
|
41
34
|
[Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
|
42
35
|
|
@@ -103,8 +96,8 @@ gem 'oj_mimic_json'
|
|
103
96
|
## Proper Use
|
104
97
|
|
105
98
|
Two settings in Oj are useful for parsing but do expose a vulnerability if used from an untrusted source. Symbolized
|
106
|
-
keys can cause memory to be filled
|
107
|
-
defining classes; memory will also be exhausted if too many classes are automatically defined. Auto defining is a useful
|
99
|
+
keys can cause memory to be filled with previous versions of ruby. Ruby 2.1 and below does not garbage collect Symbols. The same is true for auto
|
100
|
+
defining classes in all versions of ruby; memory will also be exhausted if too many classes are automatically defined. Auto defining is a useful
|
108
101
|
feature during development and from trusted sources but it allows too many classes to be created in the object load
|
109
102
|
mode and auto defined is used with an untrusted source. The `Oj.strict_load()` method sets and uses the most strict and safest options. It should be used by developers who find it difficult to understand the options available in Oj.
|
110
103
|
|
data/ext/oj/parse.c
CHANGED
@@ -587,10 +587,15 @@ colon(ParseInfo pi) {
|
|
587
587
|
|
588
588
|
void
|
589
589
|
oj_parse2(ParseInfo pi) {
|
590
|
+
int first = 1;
|
591
|
+
|
590
592
|
pi->cur = pi->json;
|
591
593
|
err_init(&pi->err);
|
592
594
|
while (1) {
|
593
595
|
next_non_white(pi);
|
596
|
+
if (!first && '\0' != *pi->cur) {
|
597
|
+
rb_raise(rb_eSyntaxError, "Extra characters after the JSON document.");
|
598
|
+
}
|
594
599
|
switch (*pi->cur++) {
|
595
600
|
case '{':
|
596
601
|
hash_start(pi);
|
@@ -657,18 +662,23 @@ oj_parse2(ParseInfo pi) {
|
|
657
662
|
if (err_has(&pi->err)) {
|
658
663
|
return;
|
659
664
|
}
|
660
|
-
if (
|
661
|
-
if (
|
662
|
-
|
663
|
-
|
665
|
+
if (stack_empty(&pi->stack)) {
|
666
|
+
if (Qundef != pi->proc) {
|
667
|
+
if (Qnil == pi->proc) {
|
668
|
+
rb_yield(stack_head_val(&pi->stack));
|
669
|
+
} else {
|
664
670
|
#if HAS_PROC_WITH_BLOCK
|
665
|
-
|
671
|
+
VALUE args[1];
|
666
672
|
|
667
|
-
|
668
|
-
|
673
|
+
*args = stack_head_val(&pi->stack);
|
674
|
+
rb_proc_call_with_block(pi->proc, 1, args, Qnil);
|
669
675
|
#else
|
670
|
-
|
676
|
+
rb_raise(rb_eNotImpError,
|
677
|
+
"Calling a Proc with a block not supported in this version. Use func() {|x| } syntax instead.");
|
671
678
|
#endif
|
679
|
+
}
|
680
|
+
} else {
|
681
|
+
first = 0;
|
672
682
|
}
|
673
683
|
}
|
674
684
|
}
|
data/ext/oj/sparse.c
CHANGED
@@ -602,11 +602,15 @@ colon(ParseInfo pi) {
|
|
602
602
|
|
603
603
|
void
|
604
604
|
oj_sparse2(ParseInfo pi) {
|
605
|
+
int first = 1;
|
605
606
|
char c;
|
606
607
|
|
607
608
|
err_init(&pi->err);
|
608
609
|
while (1) {
|
609
610
|
c = reader_next_non_white(&pi->rd);
|
611
|
+
if (!first && '\0' != c) {
|
612
|
+
rb_raise(rb_eSyntaxError, "Extra characters after the JSON document.");
|
613
|
+
}
|
610
614
|
switch (c) {
|
611
615
|
case '{':
|
612
616
|
hash_start(pi);
|
@@ -701,20 +705,24 @@ oj_sparse2(ParseInfo pi) {
|
|
701
705
|
if (err_has(&pi->err)) {
|
702
706
|
return;
|
703
707
|
}
|
704
|
-
if (
|
705
|
-
if (
|
706
|
-
|
707
|
-
|
708
|
+
if (stack_empty(&pi->stack)) {
|
709
|
+
if (Qundef != pi->proc) {
|
710
|
+
if (Qnil == pi->proc) {
|
711
|
+
rb_yield(stack_head_val(&pi->stack));
|
712
|
+
} else {
|
708
713
|
#if HAS_PROC_WITH_BLOCK
|
709
|
-
|
714
|
+
VALUE args[1];
|
710
715
|
|
711
|
-
|
712
|
-
|
716
|
+
*args = stack_head_val(&pi->stack);
|
717
|
+
rb_proc_call_with_block(pi->proc, 1, args, Qnil);
|
713
718
|
#else
|
714
|
-
|
715
|
-
|
716
|
-
|
719
|
+
oj_set_error_at(pi, rb_eNotImpError, __FILE__, __LINE__,
|
720
|
+
"Calling a Proc with a block not supported in this version. Use func() {|x| } syntax instead.");
|
721
|
+
return;
|
717
722
|
#endif
|
723
|
+
}
|
724
|
+
} else {
|
725
|
+
first = 0;
|
718
726
|
}
|
719
727
|
}
|
720
728
|
}
|
data/lib/oj/version.rb
CHANGED
data/test/bug.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
1
3
|
#!/usr/bin/env ruby
|
2
4
|
# encoding: UTF-8
|
3
5
|
|
@@ -5,60 +7,47 @@ $: << File.dirname(__FILE__)
|
|
5
7
|
|
6
8
|
require 'helper'
|
7
9
|
|
8
|
-
require 'oj'
|
9
|
-
require 'securerandom'
|
10
|
-
|
11
10
|
class Handler
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def
|
17
|
-
|
11
|
+
def initialize
|
12
|
+
@state = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def hash_start
|
16
|
+
@state << {}
|
17
|
+
@state.last
|
18
|
+
end
|
19
|
+
|
20
|
+
def hash_end
|
21
|
+
@state.pop
|
22
|
+
end
|
23
|
+
|
24
|
+
def hash_set(h,k,v)
|
25
|
+
h.store(k,v)
|
18
26
|
end
|
19
|
-
end
|
20
27
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
name = "/tmp/#{SecureRandom.uuid}"
|
25
|
-
`mkfifo #{name}`
|
26
|
-
if fork
|
27
|
-
open(name, 'r+') do |read_io|
|
28
|
-
p "start reading #{read_io.stat.ftype}"
|
29
|
-
Oj.sc_parse(Handler.new, read_io) {|v| p v}
|
30
|
-
p "stop reading"
|
31
|
-
end
|
32
|
-
else
|
33
|
-
open(name, 'w+') do |write_io|
|
34
|
-
p "start writing #{write_io.stat.ftype} autoclose: #{write_io.autoclose?}"
|
35
|
-
write_io.write json
|
36
|
-
write_io.write json
|
37
|
-
p "stop writing"
|
38
|
-
end
|
39
|
-
sleep(1) # make it obvious that there are two threads
|
40
|
-
open(name, 'w+') do |write_io|
|
41
|
-
p "start writing #{write_io.stat.ftype}"
|
42
|
-
write_io.write json
|
43
|
-
write_io.write json
|
44
|
-
p "stop writing"
|
45
|
-
end
|
28
|
+
def array_start
|
29
|
+
@state << []
|
30
|
+
@state.last
|
46
31
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
write_io.write json
|
60
|
-
p "stop writing"
|
61
|
-
write_io.close
|
62
|
-
end
|
32
|
+
|
33
|
+
|
34
|
+
def array_end
|
35
|
+
@state.pop
|
36
|
+
end
|
37
|
+
|
38
|
+
def array_append(a,v)
|
39
|
+
a << v
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_value(v)
|
43
|
+
p v
|
63
44
|
end
|
45
|
+
|
46
|
+
def error(message, line, column); p "ERROR: #{message}" end
|
64
47
|
end
|
48
|
+
|
49
|
+
$handler = Handler.new
|
50
|
+
|
51
|
+
IO.popen("cat tst") { |p| puts Oj.sc_parse($handler, p) }
|
52
|
+
|
53
|
+
#File.open('tst', 'r') { |file| Oj.sc_parse($handler, file) }
|
data/test/bug2.rb
ADDED
data/test/bug3.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#!/usr/bin/env ruby
|
4
|
+
# encoding: UTF-8
|
5
|
+
|
6
|
+
$: << File.dirname(__FILE__)
|
7
|
+
%w(lib ext test).each do |dir|
|
8
|
+
$LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'oj'
|
12
|
+
require 'stringio'
|
13
|
+
|
14
|
+
class Parser < Oj::Saj
|
15
|
+
|
16
|
+
def parse(json)
|
17
|
+
Oj.saj_parse(self, StringIO.new(json))
|
18
|
+
end
|
19
|
+
|
20
|
+
def hash_start(key)
|
21
|
+
puts "START: #{key}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def error(message, line, column)
|
25
|
+
puts "Error callback: #{message}"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
parser = Parser.new
|
31
|
+
|
32
|
+
begin
|
33
|
+
# truncated JSON, Oj.saj_parse raises, #error not called
|
34
|
+
parser.parse('{"foo{"bar":')
|
35
|
+
rescue Exception => e
|
36
|
+
puts "*** #{e.class}: #{e.message}"
|
37
|
+
end
|
38
|
+
|
39
|
+
puts "\n\n"
|
40
|
+
|
41
|
+
begin
|
42
|
+
# invalid JSON, doesn't raise an error
|
43
|
+
parser.parse('{"foo":{"bar":}')
|
44
|
+
rescue Exception => e
|
45
|
+
puts "*** #{e.class}: #{e.message}"
|
46
|
+
end
|
data/test/bug_fast.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
%w(lib ext test).each do |dir|
|
5
|
+
$LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'oj'
|
9
|
+
|
10
|
+
def create_item(doc)
|
11
|
+
#puts "#{doc.fetch('/id')}: #{doc.fetch('/labels/it/value')} - #{doc.fetch('/descriptions/it/value')}"
|
12
|
+
doc.fetch('/id')
|
13
|
+
doc.fetch('/labels/it/value')
|
14
|
+
doc.fetch('/descriptions/it/value')
|
15
|
+
end
|
16
|
+
|
17
|
+
100.times { |i|
|
18
|
+
File.open('dump_10k.json') { |f|
|
19
|
+
f.each { |line|
|
20
|
+
#Oj::Doc.open(line) { |doc|
|
21
|
+
doc = Oj::Doc.open(line)
|
22
|
+
begin
|
23
|
+
create_item(doc) if doc.fetch('/type') == 'item'
|
24
|
+
rescue Exception => e
|
25
|
+
puts "*** #{e.class}: #{e.message}"
|
26
|
+
end
|
27
|
+
doc.close
|
28
|
+
#}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
puts i
|
32
|
+
}
|
data/test/bug_load.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
%w(lib ext test).each do |dir|
|
5
|
+
$LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'oj'
|
9
|
+
|
10
|
+
def create_item(doc)
|
11
|
+
item_id = doc['source']
|
12
|
+
# ...
|
13
|
+
puts item_id
|
14
|
+
end
|
15
|
+
|
16
|
+
File.open('log.json') { |f|
|
17
|
+
Oj::load(f, mode: :compat) { |doc|
|
18
|
+
begin
|
19
|
+
create_item(doc) if doc['msgType'] == 1
|
20
|
+
rescue Exception => e
|
21
|
+
puts "*** #{e.class}: #{e.message}"
|
22
|
+
end
|
23
|
+
}
|
24
|
+
}
|
data/test/example.rb
ADDED
data/test/io.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << File.dirname(__FILE__)
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
class Handler
|
9
|
+
def initialize
|
10
|
+
@state = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def hash_start
|
14
|
+
@state << {}
|
15
|
+
@state.last
|
16
|
+
end
|
17
|
+
|
18
|
+
def hash_end
|
19
|
+
@state.pop
|
20
|
+
end
|
21
|
+
|
22
|
+
def hash_set(h,k,v)
|
23
|
+
h.store(k,v)
|
24
|
+
end
|
25
|
+
|
26
|
+
def array_start
|
27
|
+
@state << []
|
28
|
+
@state.last
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def array_end
|
33
|
+
@state.pop
|
34
|
+
end
|
35
|
+
|
36
|
+
def array_append(a,v)
|
37
|
+
a << v
|
38
|
+
end
|
39
|
+
|
40
|
+
def error(message, line, column); p "ERROR: #{message}" end
|
41
|
+
end
|
42
|
+
|
43
|
+
handler = Handler.new
|
44
|
+
def handler.add_value(v)
|
45
|
+
p v
|
46
|
+
end
|
47
|
+
|
48
|
+
Oj.sc_parse(handler, StringIO.new('{"a":"b","c":[1,2,{"d":"e"}]}[4,5,6]'))
|
@@ -1,19 +1,16 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: UTF-8
|
3
3
|
|
4
|
-
$VERBOSE = true
|
5
|
-
|
6
4
|
%w(lib ext test).each do |dir|
|
7
5
|
$LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
|
8
6
|
end
|
9
7
|
|
10
|
-
require 'rubygems' if RUBY_VERSION.start_with?('1.8.')
|
11
8
|
require 'oj'
|
12
9
|
|
13
|
-
Oj.mimic_JSON
|
14
|
-
|
15
|
-
#puts Oj.default_options
|
16
|
-
|
17
|
-
range = ("01".."12")
|
18
10
|
|
19
|
-
|
11
|
+
Thread.new do
|
12
|
+
string_io = StringIO.new('{"foo":"bar"}')
|
13
|
+
Oj.load(string_io)
|
14
|
+
string_io.rewind
|
15
|
+
puts string_io.read
|
16
|
+
end.join
|
data/test/struct.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
# Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is
|
5
|
+
# required. That can be set in the RUBYOPT environment variable.
|
6
|
+
# export RUBYOPT=-w
|
7
|
+
|
8
|
+
$VERBOSE = true
|
9
|
+
|
10
|
+
$: << File.join(File.dirname(__FILE__), "../lib")
|
11
|
+
$: << File.join(File.dirname(__FILE__), "../ext")
|
12
|
+
|
13
|
+
require 'oj'
|
14
|
+
|
15
|
+
A = Struct.new(:a,:b,:c,:d)
|
16
|
+
B = Struct.new(:e,:f)
|
17
|
+
|
18
|
+
obj = [A.new(55, B.new(1, 'X'), B.new(2, 'Y'), 3)]
|
19
|
+
|
20
|
+
s = Oj.dump(obj, :mode => :object)
|
21
|
+
|
22
|
+
100000.times do
|
23
|
+
Oj.load(s, :mode => :object)
|
24
|
+
# ds = Oj.dump(o, :mode => :object)
|
25
|
+
# if ds != s
|
26
|
+
# puts ds
|
27
|
+
# raise "holy crap"
|
28
|
+
# end
|
29
|
+
end
|
data/test/test_scp.rb
CHANGED
@@ -259,7 +259,7 @@ class ScpTest < Minitest::Test
|
|
259
259
|
def test_double
|
260
260
|
handler = AllHandler.new()
|
261
261
|
json = %{{"one":true,"two":false}{"three":true,"four":false}}
|
262
|
-
Oj.sc_parse(handler, json)
|
262
|
+
Oj.sc_parse(handler, json) { |j| j }
|
263
263
|
assert_equal([[:hash_start],
|
264
264
|
[:hash_key, 'one'],
|
265
265
|
[:hash_set, 'one', true],
|
@@ -284,10 +284,8 @@ class ScpTest < Minitest::Test
|
|
284
284
|
def test_fixnum_bad
|
285
285
|
handler = AllHandler.new()
|
286
286
|
json = %{12345xyz}
|
287
|
-
|
287
|
+
assert_raises SyntaxError do
|
288
288
|
Oj.sc_parse(handler, json)
|
289
|
-
rescue Exception => e
|
290
|
-
assert_match(%r{unexpected character at line 1, column 6 \[(?:[a-z\.]+/)*parse\.c:\d+\]}, e.message)
|
291
289
|
end
|
292
290
|
end
|
293
291
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << File.dirname(__FILE__)
|
5
|
+
|
6
|
+
%w(lib ext test).each do |dir|
|
7
|
+
$LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'minitest'
|
11
|
+
require 'minitest/autorun'
|
12
|
+
require 'oj'
|
13
|
+
|
14
|
+
Oj.mimic_JSON
|
15
|
+
|
16
|
+
require 'rails/all'
|
17
|
+
require 'active_model'
|
18
|
+
require 'active_model_serializers'
|
19
|
+
require 'active_support/json'
|
20
|
+
|
21
|
+
#Oj.mimic_JSON
|
22
|
+
|
23
|
+
class Category
|
24
|
+
include ActiveModel::Model
|
25
|
+
include ActiveModel::SerializerSupport
|
26
|
+
|
27
|
+
attr_accessor :id, :name
|
28
|
+
|
29
|
+
def initialize(id, name)
|
30
|
+
@id = id
|
31
|
+
@name = name
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class CategorySerializer < ActiveModel::Serializer
|
36
|
+
attributes :id, :name
|
37
|
+
end
|
38
|
+
|
39
|
+
class MimicRails < Minitest::Test
|
40
|
+
|
41
|
+
def test_dump_object
|
42
|
+
Oj.default_options= {:indent => 0}
|
43
|
+
category = Category.new(1, 'test')
|
44
|
+
serializer = CategorySerializer.new(category)
|
45
|
+
|
46
|
+
json = serializer.to_json()
|
47
|
+
puts "*** serializer.to_json() #{serializer.to_json()}"
|
48
|
+
assert_equal(%|{"category":{"id":1,"name":"test"}}|, json)
|
49
|
+
|
50
|
+
json = serializer.as_json()
|
51
|
+
puts "*** serializer.as_json() #{serializer.as_json()}"
|
52
|
+
assert_equal({"category" => {:id => 1, :name => "test"}}, json)
|
53
|
+
|
54
|
+
json = JSON.dump(serializer)
|
55
|
+
puts "*** JSON.dump(serializer) #{JSON.dump(serializer)}"
|
56
|
+
assert_equal(%|{"category":{"id":1,"name":"test"}}|, json)
|
57
|
+
end
|
58
|
+
|
59
|
+
end # MimicRails
|
data/test/test_various.rb
CHANGED
@@ -294,6 +294,20 @@ class Juice < Minitest::Test
|
|
294
294
|
assert_equal([{"a"=>1}, [1,2], [3,4], {"b"=>2}], results)
|
295
295
|
end
|
296
296
|
|
297
|
+
def test_multiple_json_no_callback
|
298
|
+
json = %{{"a":1}
|
299
|
+
[1,2][3,4]
|
300
|
+
{"b":2}
|
301
|
+
}
|
302
|
+
begin
|
303
|
+
Oj.load(json)
|
304
|
+
rescue Exception
|
305
|
+
assert(true)
|
306
|
+
return
|
307
|
+
end
|
308
|
+
assert(false, "*** expected an exception")
|
309
|
+
end
|
310
|
+
|
297
311
|
# encoding tests
|
298
312
|
def test_does_not_escape_entities_by_default
|
299
313
|
Oj.default_options = { :escape_mode => :ascii } # set in mimic mode
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
%w(lib ext).each do |dir|
|
5
|
+
$LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'stringio'
|
9
|
+
require 'oj'
|
10
|
+
|
11
|
+
|
12
|
+
filename = File.join(File.dirname(__FILE__), 'day.json')
|
13
|
+
File.open(filename, "w") do |f|
|
14
|
+
w = Oj::StreamWriter.new(f, :indent => -1)
|
15
|
+
390.times do |i|
|
16
|
+
w.push_object()
|
17
|
+
w.push_value(12, 'msgType')
|
18
|
+
w.push_value(1, 'version')
|
19
|
+
w.push_value(1_400_074_200 + i * 60, 'bar')
|
20
|
+
w.push_value('TBC', 'source')
|
21
|
+
w.push_array('timebars')
|
22
|
+
w.push_object()
|
23
|
+
w.push_value('aapl_24', 'asset')
|
24
|
+
w.push_value(91.87, 'close')
|
25
|
+
w.pop()
|
26
|
+
w.pop()
|
27
|
+
w.pop()
|
28
|
+
end
|
29
|
+
f.write("\n")
|
30
|
+
end
|
31
|
+
|
data/test/zip.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << File.dirname(__FILE__)
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
require 'zlib'
|
9
|
+
|
10
|
+
File.open('test.json.gz', 'r') do |file|
|
11
|
+
Zlib::GzipReader.wrap(file) do |f2|
|
12
|
+
puts "*** f2: #{f2}"
|
13
|
+
Oj.load(f2) do |val|
|
14
|
+
puts val
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
=begin
|
20
|
+
And a json file with the following contents (then gzipped):
|
21
|
+
|
22
|
+
{"a":2}
|
23
|
+
{"b":2}
|
24
|
+
The output is:
|
25
|
+
|
26
|
+
{"a"=>2}
|
27
|
+
{"b"=>2}
|
28
|
+
bin/test:8:in `load': undefined method `new' for #<EOFError: end of file reached> (NoMethodError)
|
29
|
+
from bin/test:8:in `block (2 levels) in <main>'
|
30
|
+
from bin/test:7:in `wrap'
|
31
|
+
from bin/test:7:in `block in <main>'
|
32
|
+
from bin/test:6:in `open'
|
33
|
+
from bin/test:6:in `<main>'
|
34
|
+
=end
|
metadata
CHANGED
@@ -1,65 +1,58 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.12.
|
5
|
-
prerelease:
|
4
|
+
version: 2.12.10
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Peter Ohler
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2015-
|
11
|
+
date: 2015-07-12 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake-compiler
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0.9'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0.9'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: minitest
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '5'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '5'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rails
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- - ~>
|
45
|
+
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '4'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- - ~>
|
52
|
+
- - "~>"
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '4'
|
62
|
-
description:
|
55
|
+
description: 'The fastest JSON parser and object serializer. '
|
63
56
|
email: peter@ohler.com
|
64
57
|
executables: []
|
65
58
|
extensions:
|
@@ -67,52 +60,60 @@ extensions:
|
|
67
60
|
extra_rdoc_files:
|
68
61
|
- README.md
|
69
62
|
files:
|
70
|
-
-
|
71
|
-
-
|
72
|
-
- lib/oj/error.rb
|
73
|
-
- lib/oj/mimic.rb
|
74
|
-
- lib/oj/saj.rb
|
75
|
-
- lib/oj/schandler.rb
|
76
|
-
- lib/oj/version.rb
|
77
|
-
- lib/oj.rb
|
78
|
-
- ext/oj/extconf.rb
|
63
|
+
- LICENSE
|
64
|
+
- README.md
|
79
65
|
- ext/oj/buf.h
|
80
|
-
- ext/oj/cache8.h
|
81
|
-
- ext/oj/circarray.h
|
82
|
-
- ext/oj/encode.h
|
83
|
-
- ext/oj/err.h
|
84
|
-
- ext/oj/hash.h
|
85
|
-
- ext/oj/odd.h
|
86
|
-
- ext/oj/oj.h
|
87
|
-
- ext/oj/parse.h
|
88
|
-
- ext/oj/reader.h
|
89
|
-
- ext/oj/resolve.h
|
90
|
-
- ext/oj/val_stack.h
|
91
66
|
- ext/oj/cache8.c
|
67
|
+
- ext/oj/cache8.h
|
92
68
|
- ext/oj/circarray.c
|
69
|
+
- ext/oj/circarray.h
|
93
70
|
- ext/oj/compat.c
|
94
71
|
- ext/oj/dump.c
|
72
|
+
- ext/oj/encode.h
|
95
73
|
- ext/oj/err.c
|
74
|
+
- ext/oj/err.h
|
75
|
+
- ext/oj/extconf.rb
|
96
76
|
- ext/oj/fast.c
|
97
77
|
- ext/oj/hash.c
|
78
|
+
- ext/oj/hash.h
|
98
79
|
- ext/oj/hash_test.c
|
99
80
|
- ext/oj/object.c
|
100
81
|
- ext/oj/odd.c
|
82
|
+
- ext/oj/odd.h
|
101
83
|
- ext/oj/oj.c
|
84
|
+
- ext/oj/oj.h
|
102
85
|
- ext/oj/parse.c
|
86
|
+
- ext/oj/parse.h
|
103
87
|
- ext/oj/reader.c
|
88
|
+
- ext/oj/reader.h
|
104
89
|
- ext/oj/resolve.c
|
90
|
+
- ext/oj/resolve.h
|
105
91
|
- ext/oj/saj.c
|
106
92
|
- ext/oj/scp.c
|
107
93
|
- ext/oj/sparse.c
|
108
94
|
- ext/oj/strict.c
|
109
95
|
- ext/oj/val_stack.c
|
96
|
+
- ext/oj/val_stack.h
|
97
|
+
- lib/oj.rb
|
98
|
+
- lib/oj/active_support_helper.rb
|
99
|
+
- lib/oj/bag.rb
|
100
|
+
- lib/oj/error.rb
|
101
|
+
- lib/oj/mimic.rb
|
102
|
+
- lib/oj/saj.rb
|
103
|
+
- lib/oj/schandler.rb
|
104
|
+
- lib/oj/version.rb
|
110
105
|
- test/_test_active.rb
|
111
106
|
- test/_test_active_mimic.rb
|
112
107
|
- test/_test_mimic_rails.rb
|
113
108
|
- test/bug.rb
|
109
|
+
- test/bug2.rb
|
110
|
+
- test/bug3.rb
|
111
|
+
- test/bug_fast.rb
|
112
|
+
- test/bug_load.rb
|
113
|
+
- test/example.rb
|
114
114
|
- test/files.rb
|
115
115
|
- test/helper.rb
|
116
|
+
- test/io.rb
|
116
117
|
- test/isolated/shared.rb
|
117
118
|
- test/isolated/test_mimic_after.rb
|
118
119
|
- test/isolated/test_mimic_alone.rb
|
@@ -120,18 +121,17 @@ files:
|
|
120
121
|
- test/isolated/test_mimic_define.rb
|
121
122
|
- test/isolated/test_mimic_rails_after.rb
|
122
123
|
- test/isolated/test_mimic_rails_before.rb
|
124
|
+
- test/mod.rb
|
123
125
|
- test/perf.rb
|
124
|
-
- test/perf1.rb
|
125
|
-
- test/perf2.rb
|
126
126
|
- test/perf_compat.rb
|
127
127
|
- test/perf_fast.rb
|
128
128
|
- test/perf_file.rb
|
129
|
-
- test/perf_obj_old.rb
|
130
129
|
- test/perf_object.rb
|
131
130
|
- test/perf_saj.rb
|
132
131
|
- test/perf_scp.rb
|
133
132
|
- test/perf_simple.rb
|
134
133
|
- test/perf_strict.rb
|
134
|
+
- test/sample.rb
|
135
135
|
- test/sample/change.rb
|
136
136
|
- test/sample/dir.rb
|
137
137
|
- test/sample/doc.rb
|
@@ -144,49 +144,47 @@ files:
|
|
144
144
|
- test/sample/rect.rb
|
145
145
|
- test/sample/shape.rb
|
146
146
|
- test/sample/text.rb
|
147
|
-
- test/sample.rb
|
148
147
|
- test/sample_json.rb
|
149
|
-
- test/
|
148
|
+
- test/struct.rb
|
150
149
|
- test/test_compat.rb
|
151
150
|
- test/test_debian.rb
|
152
151
|
- test/test_fast.rb
|
153
152
|
- test/test_file.rb
|
154
153
|
- test/test_gc.rb
|
155
154
|
- test/test_object.rb
|
156
|
-
- test/test_range.rb
|
157
155
|
- test/test_saj.rb
|
158
156
|
- test/test_scp.rb
|
157
|
+
- test/test_serializer.rb
|
159
158
|
- test/test_strict.rb
|
160
159
|
- test/test_various.rb
|
161
160
|
- test/test_writer.rb
|
162
|
-
-
|
163
|
-
-
|
161
|
+
- test/write_timebars.rb
|
162
|
+
- test/zip.rb
|
164
163
|
homepage: http://www.ohler.com/oj
|
165
164
|
licenses:
|
166
165
|
- MIT
|
166
|
+
metadata: {}
|
167
167
|
post_install_message:
|
168
168
|
rdoc_options:
|
169
|
-
- --main
|
169
|
+
- "--main"
|
170
170
|
- README.md
|
171
171
|
require_paths:
|
172
172
|
- lib
|
173
173
|
- ext
|
174
174
|
required_ruby_version: !ruby/object:Gem::Requirement
|
175
|
-
none: false
|
176
175
|
requirements:
|
177
|
-
- -
|
176
|
+
- - ">="
|
178
177
|
- !ruby/object:Gem::Version
|
179
178
|
version: '0'
|
180
179
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
|
-
none: false
|
182
180
|
requirements:
|
183
|
-
- -
|
181
|
+
- - ">="
|
184
182
|
- !ruby/object:Gem::Version
|
185
183
|
version: '0'
|
186
184
|
requirements: []
|
187
185
|
rubyforge_project: oj
|
188
|
-
rubygems_version:
|
186
|
+
rubygems_version: 2.4.5
|
189
187
|
signing_key:
|
190
|
-
specification_version:
|
188
|
+
specification_version: 4
|
191
189
|
summary: A fast JSON parser and serializer.
|
192
190
|
test_files: []
|
data/test/perf1.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -wW1
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
$: << File.join(File.dirname(__FILE__), "../lib")
|
5
|
-
$: << File.join(File.dirname(__FILE__), "../ext")
|
6
|
-
|
7
|
-
#require 'test/unit'
|
8
|
-
require 'optparse'
|
9
|
-
require 'oj'
|
10
|
-
require 'ox'
|
11
|
-
|
12
|
-
$indent = 2
|
13
|
-
|
14
|
-
opts = OptionParser.new
|
15
|
-
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
16
|
-
files = opts.parse(ARGV)
|
17
|
-
|
18
|
-
iter = 100000
|
19
|
-
s = %{
|
20
|
-
{ "class": "Foo::Bar",
|
21
|
-
"attr1": [ true, [false, [12345, null], 3.967, ["something", false], null]],
|
22
|
-
"attr2": { "one": 1 }
|
23
|
-
}
|
24
|
-
}
|
25
|
-
#s = File.read('sample.json')
|
26
|
-
|
27
|
-
Oj.default_options = { :indent => 0 }
|
28
|
-
|
29
|
-
obj = Oj.load(s)
|
30
|
-
xml = Ox.dump(obj, :indent => 0)
|
31
|
-
|
32
|
-
puts xml
|
33
|
-
|
34
|
-
start = Time.now
|
35
|
-
iter.times do
|
36
|
-
Oj.load(s)
|
37
|
-
end
|
38
|
-
dt = Time.now - start
|
39
|
-
puts "%d Oj.load()s in %0.3f seconds or %0.1f loads/msec" % [iter, dt, iter/dt/1000.0]
|
40
|
-
|
41
|
-
start = Time.now
|
42
|
-
iter.times do
|
43
|
-
Ox.load(xml)
|
44
|
-
end
|
45
|
-
dt = Time.now - start
|
46
|
-
puts "%d Ox.load()s in %0.3f seconds or %0.1f loads/msec" % [iter, dt, iter/dt/1000.0]
|
47
|
-
|
48
|
-
puts
|
49
|
-
|
50
|
-
start = Time.now
|
51
|
-
iter.times do
|
52
|
-
Oj.dump(obj)
|
53
|
-
end
|
54
|
-
dt = Time.now - start
|
55
|
-
puts "%d Oj.dump()s in %0.3f seconds or %0.1f dumps/msec" % [iter, dt, iter/dt/1000.0]
|
56
|
-
|
57
|
-
start = Time.now
|
58
|
-
iter.times do
|
59
|
-
Ox.dump(obj)
|
60
|
-
end
|
61
|
-
dt = Time.now - start
|
62
|
-
puts "%d Ox.dump()s in %0.3f seconds or %0.1f dumps/msec" % [iter, dt, iter/dt/1000.0]
|
63
|
-
|
64
|
-
puts
|
data/test/perf2.rb
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -wW1
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
$: << File.join(File.dirname(__FILE__), "../lib")
|
5
|
-
$: << File.join(File.dirname(__FILE__), "../ext")
|
6
|
-
|
7
|
-
#require 'test/unit'
|
8
|
-
require 'optparse'
|
9
|
-
require 'yajl'
|
10
|
-
require 'oj'
|
11
|
-
|
12
|
-
$indent = 2
|
13
|
-
|
14
|
-
opts = OptionParser.new
|
15
|
-
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
16
|
-
files = opts.parse(ARGV)
|
17
|
-
|
18
|
-
class Foo
|
19
|
-
def initialize()
|
20
|
-
@x = true
|
21
|
-
@y = 58
|
22
|
-
end
|
23
|
-
def to_json()
|
24
|
-
%{{"x":#{@x},"y":#{@y}}}
|
25
|
-
end
|
26
|
-
def to_hash()
|
27
|
-
{ 'x' => @x, 'y' => @y }
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
iter = 100000
|
32
|
-
s = %{
|
33
|
-
{ "class": "Foo::Bar",
|
34
|
-
"attr1": [ true, [false, [12345, null], 3.967, ["something", false], null]],
|
35
|
-
"attr2": { "one": 1 }
|
36
|
-
}
|
37
|
-
}
|
38
|
-
|
39
|
-
obj = Oj.load(s)
|
40
|
-
obj["foo"] = Foo.new()
|
41
|
-
|
42
|
-
Oj.default_options = { :indent => 0, :effort => :internal }
|
43
|
-
|
44
|
-
puts
|
45
|
-
|
46
|
-
start = Time.now
|
47
|
-
iter.times do
|
48
|
-
Oj.load(s)
|
49
|
-
end
|
50
|
-
dt = Time.now - start
|
51
|
-
puts "%d Oj.load()s in %0.3f seconds or %0.1f loads/msec" % [iter, dt, iter/dt/1000.0]
|
52
|
-
|
53
|
-
start = Time.now
|
54
|
-
iter.times do
|
55
|
-
Yajl::Parser.parse(s)
|
56
|
-
end
|
57
|
-
dt = Time.now - start
|
58
|
-
puts "%d Yajl::Parser.parse()s in %0.3f seconds or %0.1f parses/msec" % [iter, dt, iter/dt/1000.0]
|
59
|
-
|
60
|
-
puts
|
61
|
-
|
62
|
-
start = Time.now
|
63
|
-
iter.times do
|
64
|
-
Oj.dump(obj)
|
65
|
-
end
|
66
|
-
dt = Time.now - start
|
67
|
-
puts "%d Oj.dump()s in %0.3f seconds or %0.1f dumps/msec" % [iter, dt, iter/dt/1000.0]
|
68
|
-
|
69
|
-
start = Time.now
|
70
|
-
iter.times do
|
71
|
-
Yajl::Encoder.encode(obj)
|
72
|
-
end
|
73
|
-
dt = Time.now - start
|
74
|
-
puts "%d Yajl::Encoder.encode()s in %0.3f seconds or %0.1f encodes/msec" % [iter, dt, iter/dt/1000.0]
|
75
|
-
|
76
|
-
puts
|
data/test/perf_obj_old.rb
DELETED
@@ -1,213 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -wW1
|
2
|
-
|
3
|
-
$: << '.'
|
4
|
-
$: << '..'
|
5
|
-
$: << '../lib'
|
6
|
-
$: << '../ext'
|
7
|
-
|
8
|
-
if __FILE__ == $0
|
9
|
-
if (i = ARGV.index('-I'))
|
10
|
-
x,path = ARGV.slice!(i, 2)
|
11
|
-
$: << path
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
require 'optparse'
|
16
|
-
require 'ox'
|
17
|
-
require 'oj'
|
18
|
-
require 'perf'
|
19
|
-
require 'sample'
|
20
|
-
require 'files'
|
21
|
-
|
22
|
-
$verbose = 0
|
23
|
-
$circular = false
|
24
|
-
$indent = 0
|
25
|
-
|
26
|
-
do_sample = false
|
27
|
-
do_files = false
|
28
|
-
|
29
|
-
do_load = false
|
30
|
-
do_dump = false
|
31
|
-
do_read = false
|
32
|
-
do_write = false
|
33
|
-
$iter = 1000
|
34
|
-
|
35
|
-
opts = OptionParser.new
|
36
|
-
opts.on("-v", "increase verbosity") { $verbose += 1 }
|
37
|
-
|
38
|
-
opts.on("-c", "circular options") { $circular = true }
|
39
|
-
|
40
|
-
opts.on("-s", "load and dump as sample Ruby object") { do_sample = true }
|
41
|
-
opts.on("-f", "load and dump as files Ruby object") { do_files = true }
|
42
|
-
|
43
|
-
opts.on("-l", "load") { do_load = true }
|
44
|
-
opts.on("-d", "dump") { do_dump = true }
|
45
|
-
opts.on("-r", "read") { do_read = true }
|
46
|
-
opts.on("-w", "write") { do_write = true }
|
47
|
-
opts.on("-a", "load, dump, read and write") { do_load = true; do_dump = true; do_read = true; do_write = true }
|
48
|
-
|
49
|
-
opts.on("-i", "--iterations [Int]", Integer, "iterations") { |i| $iter = i }
|
50
|
-
|
51
|
-
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
52
|
-
files = opts.parse(ARGV)
|
53
|
-
|
54
|
-
if files.empty?
|
55
|
-
data = []
|
56
|
-
obj = do_sample ? sample_doc(2) : files('..')
|
57
|
-
mars = Marshal.dump(obj)
|
58
|
-
xml = Ox.dump(obj, :indent => $indent, circular: $circular)
|
59
|
-
json = Oj.dump(obj, :indent => $indent, circular: $circular)
|
60
|
-
File.open('sample.xml', 'w') { |f| f.write(xml) }
|
61
|
-
File.open('sample.json', 'w') { |f| f.write(json) }
|
62
|
-
File.open('sample.marshal', 'w') { |f| f.write(mars) }
|
63
|
-
data << { :file => 'sample.xml', :obj => obj, :xml => xml, :marshal => mars, :json => json }
|
64
|
-
else
|
65
|
-
puts "loading and parsing #{files}\n\n"
|
66
|
-
# TBD change to allow xml and json
|
67
|
-
data = files.map do |f|
|
68
|
-
xml = File.read(f)
|
69
|
-
obj = Ox.load(xml);
|
70
|
-
mars = Marshal.dump(obj)
|
71
|
-
json = Oj.dump(obj, :indent => $indent, circular: $circular)
|
72
|
-
{ :file => f, :obj => obj, :xml => xml, :marshal => mars, :json => json }
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
$ox_load_time = 0
|
77
|
-
$mars_load_time = 0
|
78
|
-
$ox_dump_time = 0
|
79
|
-
$oj_dump_time = 0
|
80
|
-
$mars_dump_time = 0
|
81
|
-
|
82
|
-
def perf_load(d)
|
83
|
-
filename = d[:file]
|
84
|
-
marshal_filename = 'sample.marshal'
|
85
|
-
xml = d[:xml]
|
86
|
-
mars = d[:marshal]
|
87
|
-
json = d[:json]
|
88
|
-
|
89
|
-
if 0 < $verbose
|
90
|
-
obj = Ox.load(xml, :mode => :object, :trace => $verbose)
|
91
|
-
return
|
92
|
-
end
|
93
|
-
start = Time.now
|
94
|
-
(1..$iter).each do
|
95
|
-
obj = Ox.load(xml, :mode => :object)
|
96
|
-
end
|
97
|
-
$ox_load_time = Time.now - start
|
98
|
-
puts "Parsing #{$iter} times with Ox took #{$ox_load_time} seconds."
|
99
|
-
|
100
|
-
start = Time.now
|
101
|
-
(1..$iter).each do
|
102
|
-
obj = Oj.load(json, :mode => :object)
|
103
|
-
end
|
104
|
-
$oj_load_time = Time.now - start
|
105
|
-
puts "Parsing #{$iter} times with Oj took #{$oj_load_time} seconds."
|
106
|
-
|
107
|
-
start = Time.now
|
108
|
-
(1..$iter).each do
|
109
|
-
obj = Marshal.load(mars)
|
110
|
-
end
|
111
|
-
$mars_load_time = Time.now - start
|
112
|
-
puts "Marshalling #{$iter} times took #{$mars_load_time} seconds."
|
113
|
-
puts ">>> Ox is %0.1f faster than Marshal loading.\n\n" % [$mars_load_time/$ox_load_time]
|
114
|
-
end
|
115
|
-
|
116
|
-
def perf_dump(d)
|
117
|
-
obj = d[:obj]
|
118
|
-
|
119
|
-
start = Time.now
|
120
|
-
(1..$iter).each do
|
121
|
-
xml = Ox.dump(obj, :indent => $indent, :circular => $circular)
|
122
|
-
#puts "*** ox:\n#{xml}"
|
123
|
-
end
|
124
|
-
$ox_dump_time = Time.now - start
|
125
|
-
puts "Ox dumping #{$iter} times with ox took #{$ox_dump_time} seconds."
|
126
|
-
|
127
|
-
Oj.default_options = {:indent => $indent}
|
128
|
-
start = Time.now
|
129
|
-
(1..$iter).each do
|
130
|
-
json = Oj.dump(obj)
|
131
|
-
end
|
132
|
-
$oj_dump_time = Time.now - start
|
133
|
-
puts "Oj dumping #{$iter} times with oj took #{$oj_dump_time} seconds."
|
134
|
-
|
135
|
-
obj = d[:obj]
|
136
|
-
start = Time.now
|
137
|
-
(1..$iter).each do
|
138
|
-
m = Marshal.dump(obj)
|
139
|
-
end
|
140
|
-
$mars_dump_time = Time.now - start
|
141
|
-
puts "Marshal dumping #{$iter} times took #{$mars_dump_time} seconds."
|
142
|
-
puts ">>> Ox is %0.1f faster than Marshal dumping.\n\n" % [$mars_dump_time/$ox_dump_time]
|
143
|
-
end
|
144
|
-
|
145
|
-
def perf_read(d)
|
146
|
-
ox_read_time = 0
|
147
|
-
mars_read_time = 0
|
148
|
-
|
149
|
-
filename = d[:file]
|
150
|
-
marshal_filename = 'sample.marshal'
|
151
|
-
xml = d[:xml]
|
152
|
-
mars = d[:marshal]
|
153
|
-
|
154
|
-
# now load from the file
|
155
|
-
start = Time.now
|
156
|
-
(1..$iter).each do
|
157
|
-
obj = Ox.load_file(filename, :mode => :object)
|
158
|
-
end
|
159
|
-
ox_read_time = Time.now - start
|
160
|
-
puts "Loading and parsing #{$iter} times with ox took #{ox_read_time} seconds."
|
161
|
-
|
162
|
-
start = Time.now
|
163
|
-
(1..$iter).each do
|
164
|
-
m = File.read(marshal_filename)
|
165
|
-
obj = Marshal.load(m)
|
166
|
-
end
|
167
|
-
mars_read_time = Time.now - start
|
168
|
-
puts "Reading and marshalling #{$iter} times took #{mars_read_time} seconds."
|
169
|
-
puts ">>> Ox is %0.1f faster than Marshal loading and parsing.\n\n" % [mars_read_time/ox_read_time]
|
170
|
-
|
171
|
-
end
|
172
|
-
|
173
|
-
def perf_write(d)
|
174
|
-
ox_write_time = 0
|
175
|
-
mars_write_time = 0
|
176
|
-
|
177
|
-
ox_filename = 'out.xml'
|
178
|
-
marshal_filename = 'out.marshal'
|
179
|
-
obj = d[:obj]
|
180
|
-
|
181
|
-
start = Time.now
|
182
|
-
(1..$iter).each do
|
183
|
-
xml = Ox.to_file(ox_filename, obj, :indent => $indent)
|
184
|
-
end
|
185
|
-
ox_write_time = Time.now - start
|
186
|
-
puts "Ox dumping #{$iter} times with ox took #{ox_write_time} seconds."
|
187
|
-
|
188
|
-
start = Time.now
|
189
|
-
(1..$iter).each do
|
190
|
-
m = Marshal.dump(obj, circular: $circular)
|
191
|
-
File.open(marshal_filename, "w") { |f| f.write(m) }
|
192
|
-
end
|
193
|
-
mars_write_time = Time.now - start
|
194
|
-
puts "Marshal dumping and writing #{$iter} times took #{mars_write_time} seconds."
|
195
|
-
puts ">>> Ox is %0.1f faster than Marshal dumping.\n\n" % [mars_write_time/ox_write_time]
|
196
|
-
|
197
|
-
end
|
198
|
-
|
199
|
-
#if do_sample or do_files
|
200
|
-
data.each do |d|
|
201
|
-
puts "Using file #{d[:file]}."
|
202
|
-
|
203
|
-
perf_load(d) if do_load
|
204
|
-
perf_dump(d) if do_dump
|
205
|
-
if do_load and do_dump
|
206
|
-
puts ">>> Ox is %0.1f faster than Marshal dumping and loading.\n\n" % [($mars_load_time + $mars_dump_time)/($ox_load_time + $ox_dump_time)] unless 0 == $mars_load_time
|
207
|
-
end
|
208
|
-
|
209
|
-
perf_read(d) if do_read
|
210
|
-
perf_write(d) if do_write
|
211
|
-
|
212
|
-
end
|
213
|
-
#end
|
data/test/test_bigd.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
$VERBOSE = true
|
5
|
-
|
6
|
-
%w(lib ext test).each do |dir|
|
7
|
-
$LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
|
8
|
-
end
|
9
|
-
|
10
|
-
require 'rubygems' if RUBY_VERSION.start_with?('1.8.')
|
11
|
-
|
12
|
-
#require "minitest/spec"
|
13
|
-
require "minitest/autorun"
|
14
|
-
|
15
|
-
require "oj"
|
16
|
-
|
17
|
-
# Uncomment this line and test_big_decimal will fail
|
18
|
-
require "active_support/json"
|
19
|
-
|
20
|
-
# With ActiveSupport 4.0, neither of these settings affect BigDecimal#to_json,
|
21
|
-
# only BigDecimal#as_json
|
22
|
-
#
|
23
|
-
# ActiveSupport.encode_big_decimal_as_string = false
|
24
|
-
# ActiveSupport::JSON::Encoding.encode_big_decimal_as_string = false
|
25
|
-
|
26
|
-
describe Oj do
|
27
|
-
|
28
|
-
# Options set by default in Rails 4.0 / Rabl
|
29
|
-
def options
|
30
|
-
{
|
31
|
-
:bigdecimal_as_decimal=>true, # default = true
|
32
|
-
:use_to_json=>true, # default = false
|
33
|
-
:mode=>:compat, # default = object
|
34
|
-
:time_format=>:ruby, # default = unix
|
35
|
-
}
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_big_decimal
|
39
|
-
orig = BigDecimal.new("3.14159265359")
|
40
|
-
puts "*** to_s: #{orig.to_s}"
|
41
|
-
puts "*** to_json: #{orig.to_json}"
|
42
|
-
puts "*** JSON.dump: #{JSON.dump(orig)}"
|
43
|
-
json = Oj.dump(orig, options)
|
44
|
-
puts "*** json: #{json}"
|
45
|
-
|
46
|
-
value = Oj.load(json)
|
47
|
-
puts "*** value: #{value.class}"
|
48
|
-
assert_equal(value, orig)
|
49
|
-
|
50
|
-
# by default, without active support
|
51
|
-
# assert_equal("0.314159265359E1", json)
|
52
|
-
# in Rails 4.1, with active support
|
53
|
-
# assert_equal("3.14159265359", json)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Floats are unaffected
|
57
|
-
def test_float
|
58
|
-
orig = 3.14159265359
|
59
|
-
json = Oj.dump(orig, options)
|
60
|
-
assert_equal("3.14159265359", json)
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|