oj 2.1.3 → 2.1.4

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.

Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -4
  3. data/ext/oj/compat.c +3 -4
  4. data/ext/oj/encode.h +51 -0
  5. data/ext/oj/fast.c +4 -9
  6. data/ext/oj/object.c +7 -19
  7. data/ext/oj/oj.c +32 -12
  8. data/ext/oj/oj.h +3 -0
  9. data/ext/oj/parse.c +2 -3
  10. data/ext/oj/saj.c +4 -9
  11. data/ext/oj/scp.c +5 -12
  12. data/ext/oj/strict.c +5 -12
  13. data/lib/oj/version.rb +1 -1
  14. data/test/a.rb +38 -0
  15. data/test/bug.rb +15 -0
  16. data/test/e.rb +12 -0
  17. data/test/files.rb +29 -0
  18. data/test/foo.rb +24 -0
  19. data/test/mj.rb +48 -0
  20. data/test/perf.rb +107 -0
  21. data/test/perf_compat.rb +128 -0
  22. data/test/perf_fast.rb +164 -0
  23. data/test/perf_object.rb +136 -0
  24. data/test/perf_saj.rb +109 -0
  25. data/test/perf_scp.rb +151 -0
  26. data/test/perf_simple.rb +287 -0
  27. data/test/perf_strict.rb +127 -0
  28. data/test/sample.rb +55 -0
  29. data/test/sample/change.rb +14 -0
  30. data/test/sample/dir.rb +19 -0
  31. data/test/sample/doc.rb +36 -0
  32. data/test/sample/file.rb +48 -0
  33. data/test/sample/group.rb +16 -0
  34. data/test/sample/hasprops.rb +16 -0
  35. data/test/sample/layer.rb +12 -0
  36. data/test/sample/line.rb +20 -0
  37. data/test/sample/oval.rb +10 -0
  38. data/test/sample/rect.rb +10 -0
  39. data/test/sample/shape.rb +35 -0
  40. data/test/sample/text.rb +20 -0
  41. data/test/sample_json.rb +37 -0
  42. data/test/test_compat.rb +342 -0
  43. data/test/test_fast.rb +416 -0
  44. data/test/test_mimic.rb +208 -0
  45. data/test/test_mimic_after.rb +35 -0
  46. data/test/test_object.rb +390 -0
  47. data/test/test_saj.rb +184 -0
  48. data/test/test_scp.rb +224 -0
  49. data/test/test_strict.rb +259 -0
  50. data/test/tests.rb +1017 -0
  51. data/test/x.rb +59 -0
  52. metadata +41 -2
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env ruby -wW1
2
+ # encoding: UTF-8
3
+
4
+ $: << '.'
5
+ $: << File.join(File.dirname(__FILE__), "../lib")
6
+ $: << File.join(File.dirname(__FILE__), "../ext")
7
+
8
+ require 'optparse'
9
+ require 'yajl'
10
+ require 'perf'
11
+ require 'json'
12
+ require 'json/ext'
13
+ require 'oj'
14
+
15
+ $verbose = false
16
+ $indent = 0
17
+ $iter = 10000
18
+ $gets = 0
19
+ $fetch = false
20
+ $write = false
21
+ $read = false
22
+
23
+ opts = OptionParser.new
24
+ opts.on("-v", "verbose") { $verbose = true }
25
+ opts.on("-c", "--count [Int]", Integer, "iterations") { |i| $iter = i }
26
+ opts.on("-i", "--indent [Int]", Integer, "indentation") { |i| $indent = i }
27
+ opts.on("-g", "--gets [Int]", Integer, "number of gets") { |i| $gets = i }
28
+ opts.on("-f", "fetch") { $fetch = true }
29
+ opts.on("-w", "write") { $write = true }
30
+ opts.on("-r", "read") { $read = true }
31
+ opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
32
+ files = opts.parse(ARGV)
33
+
34
+ # This just navigates to each leaf of the JSON structure.
35
+ def dig(obj, &blk)
36
+ case obj
37
+ when Array
38
+ obj.each { |e| dig(e, &blk) }
39
+ when Hash
40
+ obj.values.each { |e| dig(e, &blk) }
41
+ else
42
+ blk.yield(obj)
43
+ end
44
+ end
45
+
46
+ $obj = {
47
+ 'a' => 'Alpha', # string
48
+ 'b' => true, # boolean
49
+ 'c' => 12345, # number
50
+ 'd' => [ true, [false, {'12345' => 12345, 'nil' => nil}, 3.967, { 'x' => 'something', 'y' => false, 'z' => true}, nil]], # mix it up array
51
+ 'e' => { 'one' => 1, 'two' => 2 }, # hash
52
+ 'f' => nil, # nil
53
+ 'g' => 12345678901234567890123456789, # big number
54
+ 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
55
+ 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
56
+ }
57
+
58
+ Oj.default_options = { :indent => $indent, :mode => :compat }
59
+
60
+ $json = Oj.dump($obj)
61
+ $failed = {} # key is same as String used in tests later
62
+
63
+ def capture_error(tag, orig, load_key, dump_key, &blk)
64
+ begin
65
+ obj = blk.call(orig)
66
+ raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
67
+ rescue Exception => e
68
+ $failed[tag] = "#{e.class}: #{e.message}"
69
+ end
70
+ end
71
+
72
+ # Verify that all packages dump and load correctly and return the same Object as the original.
73
+ capture_error('Oj::Doc', $obj, 'load', 'dump') { |o| Oj::Doc.open(Oj.dump(o, :mode => :strict)) { |f| f.fetch() } }
74
+ capture_error('Yajl', $obj, 'encode', 'parse') { |o| Yajl::Parser.parse(Yajl::Encoder.encode(o)) }
75
+ capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o| JSON.generator = JSON::Ext::Generator; JSON::Ext::Parser.new(JSON.generate(o)).parse }
76
+
77
+ if $verbose
78
+ puts "json:\n#{$json}\n"
79
+ end
80
+
81
+ puts '-' * 80
82
+ puts "Parse Performance"
83
+ perf = Perf.new()
84
+ perf.add('Oj::Doc', 'parse') { Oj::Doc.open($json) {|f| } } unless $failed.has_key?('Oj::Doc')
85
+ perf.add('Yajl', 'parse') { Yajl::Parser.parse($json) } unless $failed.has_key?('Yajl')
86
+ perf.add('JSON::Ext', 'parse') { JSON::Ext::Parser.new($json).parse } unless $failed.has_key?('JSON::Ext')
87
+ perf.run($iter)
88
+
89
+ puts '-' * 80
90
+ puts "JSON generation Performance"
91
+ Oj::Doc.open($json) do |doc|
92
+ perf = Perf.new()
93
+ perf.add('Oj::Doc', 'dump') { doc.dump() }
94
+ perf.add('Yajl', 'encode') { Yajl::Encoder.encode($obj) }
95
+ perf.add('JSON::Ext', 'fast_generate') { JSON.fast_generate($obj) }
96
+ perf.before('JSON::Ext') { JSON.generator = JSON::Ext::Generator }
97
+ perf.run($iter)
98
+ end
99
+
100
+ if 0 < $gets
101
+ puts '-' * 80
102
+ puts "Parse and get all values Performance"
103
+ perf = Perf.new()
104
+ perf.add('Oj::Doc', 'parse') { Oj::Doc.open($json) {|f| $gets.times { f.each_value() {} } } } unless $failed.has_key?('Oj::Doc')
105
+ perf.add('Yajl', 'parse') { $gets.times { dig(Yajl::Parser.parse($json)) {} } } unless $failed.has_key?('Yajl')
106
+ perf.add('JSON::Ext', 'parse') { $gets.times { dig(JSON::Ext::Parser.new($json).parse) {} } } unless $failed.has_key?('JSON::Ext')
107
+ perf.run($iter)
108
+ end
109
+
110
+ if $fetch
111
+ puts '-' * 80
112
+ puts "fetch nested Performance"
113
+ json_hash = Oj.load($json, :mode => :strict)
114
+ Oj::Doc.open($json) do |fast|
115
+ #puts "*** C fetch: #{fast.fetch('/d/2/4/y')}"
116
+ #puts "*** Ruby fetch: #{json_hash.fetch('d', []).fetch(1, []).fetch(3, []).fetch('x', nil)}"
117
+ perf = Perf.new()
118
+ perf.add('Oj::Doc', 'fetch') { fast.fetch('/d/2/4/x'); fast.fetch('/h/a/b/c/d/e/f/g'); fast.fetch('/i/1/1/1/1/1/1/1') }
119
+ # version that fails gracefully
120
+ perf.add('Ruby', 'fetch') do
121
+ json_hash.fetch('d', []).fetch(1, []).fetch(3, []).fetch('x', nil)
122
+ json_hash.fetch('h', {}).fetch('a', {}).fetch('b', {}).fetch('c', {}).fetch('d', {}).fetch('e', {}).fetch('f', {}).fetch('g', {})
123
+ json_hash.fetch('i', []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, nil)
124
+ end
125
+ # version that raises if the path is incorrect
126
+ # perf.add('Ruby', 'fetch') { $fetch.times { json_hash['d'][1][3][1] } }
127
+ perf.run($iter)
128
+ end
129
+ end
130
+
131
+ if $write
132
+ puts '-' * 80
133
+ puts "JSON write to file Performance"
134
+ Oj::Doc.open($json) do |doc|
135
+ perf = Perf.new()
136
+ perf.add('Oj::Doc', 'dump') { doc.dump(nil, 'oj.json') }
137
+ perf.add('Yajl', 'encode') { File.open('yajl.json', 'w') { |f| Yajl::Encoder.encode($obj, f) } }
138
+ perf.add('JSON::Ext', 'fast_generate') { File.open('json_ext.json', 'w') { |f| f.write(JSON.fast_generate($obj)) } }
139
+ perf.before('JSON::Ext') { JSON.generator = JSON::Ext::Generator }
140
+ perf.run($iter)
141
+ end
142
+ end
143
+
144
+ if $read
145
+ puts '-' * 80
146
+ puts "JSON read from file Performance"
147
+ Oj::Doc.open($json) { |doc| doc.dump(nil, 'oj.json') }
148
+ File.open('yajl.json', 'w') { |f| Yajl::Encoder.encode($obj, f) }
149
+ JSON.generator = JSON::Ext::Generator
150
+ File.open('json_ext.json', 'w') { |f| f.write(JSON.fast_generate($obj)) }
151
+ Oj::Doc.open($json) do |doc|
152
+ perf = Perf.new()
153
+ perf.add('Oj::Doc', 'open_file') { ::Oj::Doc.open_file('oj.json') }
154
+ perf.add('Yajl', 'decode') { Yajl::decoder.decode(File.read('yajl.json')) }
155
+ perf.add('JSON::Ext', '') { JSON.parse(File.read('json_ext.json')) }
156
+ perf.before('JSON::Ext') { JSON.parser = JSON::Ext::Parser }
157
+ perf.run($iter)
158
+ end
159
+ end
160
+
161
+ unless $failed.empty?
162
+ puts "The following packages were not included for the reason listed"
163
+ $failed.each { |tag,msg| puts "***** #{tag}: #{msg}" }
164
+ end
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env ruby -wW1
2
+
3
+ $: << '.'
4
+ $: << '../lib'
5
+ $: << '../ext'
6
+
7
+ if __FILE__ == $0
8
+ if (i = ARGV.index('-I'))
9
+ x,path = ARGV.slice!(i, 2)
10
+ $: << path
11
+ end
12
+ end
13
+
14
+ require 'optparse'
15
+ require 'ox'
16
+ require 'oj'
17
+ require 'perf'
18
+ require 'sample'
19
+ require 'files'
20
+
21
+ $circular = false
22
+ $indent = 0
23
+
24
+ do_sample = false
25
+ do_files = false
26
+
27
+ do_load = false
28
+ do_dump = false
29
+ do_read = false
30
+ do_write = false
31
+ $iter = 1000
32
+ $mult = 1
33
+
34
+ opts = OptionParser.new
35
+ opts.on("-c", "circular options") { $circular = true }
36
+
37
+ opts.on("-x", "use sample instead of files") { do_sample = true }
38
+
39
+ opts.on("-s", "load and dump as sample Ruby object") { do_sample = true }
40
+ opts.on("-f", "load and dump as files Ruby object") { do_files = true }
41
+
42
+ opts.on("-l", "load") { do_load = true }
43
+ opts.on("-d", "dump") { do_dump = true }
44
+ opts.on("-r", "read") { do_read = true }
45
+ opts.on("-w", "write") { do_write = true }
46
+ opts.on("-a", "load, dump, read and write") { do_load = true; do_dump = true; do_read = true; do_write = true }
47
+
48
+ opts.on("-i", "--iterations [Int]", Integer, "iterations") { |i| $iter = i }
49
+ opts.on("-m", "--multiply [Int]", Integer, "multiplier") { |i| $mult = i }
50
+
51
+ opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
52
+ files = opts.parse(ARGV)
53
+
54
+ $obj = nil
55
+ $xml = nil
56
+ $mars = nil
57
+ $json = nil
58
+
59
+ unless do_load || do_dump || do_read || do_write
60
+ do_load = true
61
+ do_dump = true
62
+ do_read = true
63
+ do_write = true
64
+ end
65
+
66
+ # prepare all the formats for input
67
+ if files.empty?
68
+ $obj = []
69
+ $mult.times do
70
+ $obj << (do_sample ? sample_doc(2) : files('..'))
71
+ end
72
+
73
+ $mars = Marshal.dump($obj)
74
+ $xml = Ox.dump($obj, :indent => $indent, :circular => $circular)
75
+ $json = Oj.dump($obj, :indent => $indent, :circular => $circular)
76
+ File.open('sample.xml', 'w') { |f| f.write($xml) }
77
+ File.open('sample.json', 'w') { |f| f.write($json) }
78
+ File.open('sample.marshal', 'w') { |f| f.write($mars) }
79
+ else
80
+ puts "loading and parsing #{files}\n\n"
81
+ # TBD change to allow xml and json
82
+ data = files.map do |f|
83
+ $xml = File.read(f)
84
+ $obj = Ox.load($xml);
85
+ $mars = Marshal.dump($obj)
86
+ $json = Oj.dump($obj, :indent => $indent, :circular => $circular)
87
+ end
88
+ end
89
+
90
+ Oj.default_options = { :mode => :object, :indent => $indent, :circular => $circular }
91
+ #puts "json: #{$json.size}"
92
+ #puts "xml: #{$xml.size}"
93
+ #puts "marshal: #{$mars.size}"
94
+
95
+
96
+ if do_load
97
+ puts '-' * 80
98
+ puts "Load Performance"
99
+ perf = Perf.new()
100
+ perf.add('Oj.object', 'load') { Oj.object_load($json) }
101
+ perf.add('Ox', 'load') { Ox.load($xml, :mode => :object) }
102
+ perf.add('Marshal', 'load') { Marshal.load($mars) }
103
+ perf.run($iter)
104
+ end
105
+
106
+ if do_dump
107
+ puts '-' * 80
108
+ puts "Dump Performance"
109
+ perf = Perf.new()
110
+ perf.add('Oj', 'dump') { Oj.dump($obj) }
111
+ perf.add('Ox', 'dump') { Ox.dump($obj, :indent => $indent, :circular => $circular) }
112
+ perf.add('Marshal', 'dump') { Marshal.dump($obj) }
113
+ perf.run($iter)
114
+ end
115
+
116
+ if do_read
117
+ puts '-' * 80
118
+ puts "Read from file Performance"
119
+ perf = Perf.new()
120
+ perf.add('Oj', 'load') { Oj.load_file('sample.json') }
121
+ perf.add('Ox', 'load_file') { Ox.load_file('sample.xml', :mode => :object) }
122
+ perf.add('Marshal', 'load') { Marshal.load(File.new('sample.marshal')) }
123
+ perf.run($iter)
124
+ end
125
+
126
+ if do_write
127
+ puts '-' * 80
128
+ puts "Write to file Performance"
129
+ perf = Perf.new()
130
+ perf.add('Oj', 'to_file') { Oj.to_file('sample.json', $obj) }
131
+ perf.add('Ox', 'to_file') { Ox.to_file('sample.xml', $obj, :indent => $indent, :circular => $circular) }
132
+ perf.add('Marshal', 'dump') { Marshal.dump($obj, File.new('sample.marshal', 'w')) }
133
+ perf.run($iter)
134
+ end
135
+
136
+
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby -wW1
2
+ # encoding: UTF-8
3
+
4
+ $: << '.'
5
+ $: << File.join(File.dirname(__FILE__), "../lib")
6
+ $: << File.join(File.dirname(__FILE__), "../ext")
7
+
8
+ require 'optparse'
9
+ require 'yajl'
10
+ require 'perf'
11
+ require 'json'
12
+ require 'json/ext'
13
+ require 'oj'
14
+
15
+ $verbose = false
16
+ $indent = 0
17
+ $iter = 10000
18
+ $gets = 0
19
+ $fetch = false
20
+ $write = false
21
+ $read = false
22
+
23
+ opts = OptionParser.new
24
+ opts.on("-v", "verbose") { $verbose = true }
25
+ opts.on("-c", "--count [Int]", Integer, "iterations") { |i| $iter = i }
26
+ opts.on("-i", "--indent [Int]", Integer, "indentation") { |i| $indent = i }
27
+ opts.on("-g", "--gets [Int]", Integer, "number of gets") { |i| $gets = i }
28
+ opts.on("-f", "fetch") { $fetch = true }
29
+ opts.on("-w", "write") { $write = true }
30
+ opts.on("-r", "read") { $read = true }
31
+ opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
32
+ files = opts.parse(ARGV)
33
+
34
+ class AllSaj < Oj::Saj
35
+ def initialize()
36
+ end
37
+
38
+ def hash_start(key)
39
+ end
40
+
41
+ def hash_end(key)
42
+ end
43
+
44
+ def array_start(key)
45
+ end
46
+
47
+ def array_end(key)
48
+ end
49
+
50
+ def add_value(value, key)
51
+ end
52
+ end # AllSaj
53
+
54
+ class NoSaj < Oj::Saj
55
+ def initialize()
56
+ end
57
+ end # NoSaj
58
+
59
+ saj_handler = AllSaj.new()
60
+ no_saj = NoSaj.new()
61
+
62
+ $obj = {
63
+ 'a' => 'Alpha', # string
64
+ 'b' => true, # boolean
65
+ 'c' => 12345, # number
66
+ 'd' => [ true, [false, {'12345' => 12345, 'nil' => nil}, 3.967, { 'x' => 'something', 'y' => false, 'z' => true}, nil]], # mix it up array
67
+ 'e' => { 'one' => 1, 'two' => 2 }, # hash
68
+ 'f' => nil, # nil
69
+ 'g' => 12345678901234567890123456789, # big number
70
+ 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
71
+ 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
72
+ }
73
+
74
+ Oj.default_options = { :indent => $indent, :mode => :compat }
75
+
76
+ $json = Oj.dump($obj)
77
+ $failed = {} # key is same as String used in tests later
78
+
79
+ def capture_error(tag, orig, load_key, dump_key, &blk)
80
+ begin
81
+ obj = blk.call(orig)
82
+ raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
83
+ rescue Exception => e
84
+ $failed[tag] = "#{e.class}: #{e.message}"
85
+ end
86
+ end
87
+
88
+ # Verify that all packages dump and load correctly and return the same Object as the original.
89
+ capture_error('Yajl', $obj, 'encode', 'parse') { |o| Yajl::Parser.parse(Yajl::Encoder.encode(o)) }
90
+ capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o| JSON.generator = JSON::Ext::Generator; JSON::Ext::Parser.new(JSON.generate(o)).parse }
91
+
92
+ if $verbose
93
+ puts "json:\n#{$json}\n"
94
+ end
95
+
96
+
97
+ puts '-' * 80
98
+ puts "Parse Performance"
99
+ perf = Perf.new()
100
+ perf.add('Oj::Saj', 'all') { Oj.saj_parse(saj_handler, $json) }
101
+ perf.add('Oj::Saj', 'none') { Oj.saj_parse(no_saj, $json) }
102
+ perf.add('Yajl', 'parse') { Yajl::Parser.parse($json) } unless $failed.has_key?('Yajl')
103
+ perf.add('JSON::Ext', 'parse') { JSON::Ext::Parser.new($json).parse } unless $failed.has_key?('JSON::Ext')
104
+ perf.run($iter)
105
+
106
+ unless $failed.empty?
107
+ puts "The following packages were not included for the reason listed"
108
+ $failed.each { |tag,msg| puts "***** #{tag}: #{msg}" }
109
+ end
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env ruby -wW1
2
+ # encoding: UTF-8
3
+
4
+ $: << '.'
5
+ $: << File.join(File.dirname(__FILE__), "../lib")
6
+ $: << File.join(File.dirname(__FILE__), "../ext")
7
+
8
+ require 'optparse'
9
+ require 'yajl'
10
+ require 'perf'
11
+ require 'json'
12
+ require 'json/ext'
13
+ require 'oj'
14
+
15
+ $verbose = false
16
+ $indent = 0
17
+ $iter = 50000
18
+ $with_bignum = false
19
+ $size = 0
20
+
21
+ opts = OptionParser.new
22
+ opts.on("-v", "verbose") { $verbose = true }
23
+ opts.on("-c", "--count [Int]", Integer, "iterations") { |i| $iter = i }
24
+ opts.on("-i", "--indent [Int]", Integer, "indentation") { |i| $indent = i }
25
+ opts.on("-s", "--size [Int]", Integer, "size (~Kbytes)") { |i| $size = i }
26
+ opts.on("-b", "with bignum") { $with_bignum = true }
27
+ opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
28
+ files = opts.parse(ARGV)
29
+
30
+ $obj = {
31
+ 'a' => 'Alpha', # string
32
+ 'b' => true, # boolean
33
+ 'c' => 12345, # number
34
+ 'd' => [ true, [false, [-123456789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
35
+ 'e' => { 'zero' => nil, 'one' => 1, 'two' => 2, 'three' => [3], 'four' => [0, 1, 2, 3, 4] }, # hash
36
+ 'f' => nil, # nil
37
+ 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
38
+ 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
39
+ }
40
+ $obj['g'] = 12345678901234567890123456789 if $with_bignum
41
+
42
+ if 0 < $size
43
+ o = $obj
44
+ $obj = []
45
+ (4 * $size).times do
46
+ $obj << o
47
+ end
48
+ end
49
+
50
+ Oj.default_options = { :indent => $indent, :mode => :compat }
51
+
52
+ $json = Oj.dump($obj)
53
+ $failed = {} # key is same as String used in tests later
54
+
55
+ class AllSaj < Oj::Saj
56
+ def initialize()
57
+ end
58
+
59
+ def hash_start(key)
60
+ end
61
+
62
+ def hash_end(key)
63
+ end
64
+
65
+ def array_start(key)
66
+ end
67
+
68
+ def array_end(key)
69
+ end
70
+
71
+ def add_value(value, key)
72
+ end
73
+ end # AllSaj
74
+
75
+ class NoSaj < Oj::Saj
76
+ def initialize()
77
+ end
78
+ end # NoSaj
79
+
80
+ class NoHandler < Oj::ScHandler
81
+ def initialize()
82
+ end
83
+ end # NoHandler
84
+
85
+ class AllHandler < Oj::ScHandler
86
+ def initialize()
87
+ end
88
+
89
+ def hash_start()
90
+ return nil
91
+ end
92
+
93
+ def hash_end()
94
+ end
95
+
96
+ def array_start()
97
+ return nil
98
+ end
99
+
100
+ def array_end()
101
+ end
102
+
103
+ def add_value(value)
104
+ end
105
+
106
+ def hash_set(h, key, value)
107
+ end
108
+
109
+ def array_append(a, value)
110
+ end
111
+
112
+ end # AllHandler
113
+
114
+ saj_handler = AllSaj.new()
115
+ no_saj = NoSaj.new()
116
+
117
+ sc_handler = AllHandler.new()
118
+ no_handler = NoHandler.new()
119
+
120
+ def capture_error(tag, orig, load_key, dump_key, &blk)
121
+ begin
122
+ obj = blk.call(orig)
123
+ raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
124
+ rescue Exception => e
125
+ $failed[tag] = "#{e.class}: #{e.message}"
126
+ end
127
+ end
128
+
129
+ # Verify that all packages dump and load correctly and return the same Object as the original.
130
+ capture_error('Yajl', $obj, 'encode', 'parse') { |o| Yajl::Parser.parse(Yajl::Encoder.encode(o)) }
131
+ capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o| JSON.generator = JSON::Ext::Generator; JSON::Ext::Parser.new(JSON.generate(o)).parse }
132
+
133
+ if $verbose
134
+ puts "json:\n#{$json}\n"
135
+ end
136
+
137
+ puts '-' * 80
138
+ puts "Parse Performance"
139
+ perf = Perf.new()
140
+ perf.add('Oj::Saj', 'all') { Oj.saj_parse(saj_handler, $json) }
141
+ perf.add('Oj::Saj', 'none') { Oj.saj_parse(no_saj, $json) }
142
+ perf.add('Oj::Scp', 'all') { Oj.sc_parse(sc_handler, $json) }
143
+ perf.add('Oj::Scp', 'none') { Oj.sc_parse(no_handler, $json) }
144
+ perf.add('Yajl', 'parse') { Yajl::Parser.parse($json) } unless $failed.has_key?('Yajl')
145
+ perf.add('JSON::Ext', 'parse') { JSON::Ext::Parser.new($json).parse } unless $failed.has_key?('JSON::Ext')
146
+ perf.run($iter)
147
+
148
+ unless $failed.empty?
149
+ puts "The following packages were not included for the reason listed"
150
+ $failed.each { |tag,msg| puts "***** #{tag}: #{msg}" }
151
+ end