oj 2.12.5 → 2.12.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -26,9 +26,9 @@ Follow [@peterohler on Twitter](http://twitter.com/#!/peterohler) for announceme
26
26
 
27
27
  [![Build Status](https://secure.travis-ci.org/ohler55/oj.png?branch=master)](http://travis-ci.org/ohler55/oj)
28
28
 
29
- ## Release 2.12.5
29
+ ## Release 2.12.6
30
30
 
31
- - In :null mode Oj now dumps Infinity and NaN as null.
31
+ - Fixed a number of 32bit related bugs.
32
32
 
33
33
  [Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
34
34
 
@@ -399,7 +399,7 @@ static void
399
399
  dump_fixnum(VALUE obj, Out out) {
400
400
  char buf[32];
401
401
  char *b = buf + sizeof(buf) - 1;
402
- long num = NUM2LONG(obj);
402
+ long long num = rb_num2ll(obj);
403
403
  int neg = 0;
404
404
 
405
405
  if (0 > num) {
@@ -1031,9 +1031,9 @@ dump_time(VALUE obj, Out out, int withZone) {
1031
1031
  #else
1032
1032
  time_t sec = NUM2LONG(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
1033
1033
  #if HAS_NANO_TIME
1034
- long nsec = NUM2LONG(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
1034
+ long long nsec = rb_num2ll((rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
1035
1035
  #else
1036
- long nsec = NUM2LONG(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
1036
+ long long nsec = rb_num2ll(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
1037
1037
  #endif
1038
1038
  #endif
1039
1039
 
@@ -1127,9 +1127,9 @@ dump_xml_time(VALUE obj, Out out) {
1127
1127
  #else
1128
1128
  time_t sec = NUM2LONG(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
1129
1129
  #if HAS_NANO_TIME
1130
- long nsec = NUM2LONG(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
1130
+ long long nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
1131
1131
  #else
1132
- long nsec = NUM2LONG(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
1132
+ long long nsec = rb_num2ll(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
1133
1133
  #endif
1134
1134
  #endif
1135
1135
  long tzsecs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
@@ -345,7 +345,7 @@ leaf_fixnum_value(Leaf leaf) {
345
345
  if (neg) {
346
346
  n = -n;
347
347
  }
348
- leaf->value = LONG2NUM(n);
348
+ leaf->value = rb_ll2inum(n);
349
349
  }
350
350
  leaf->value_type = RUBY_VAL;
351
351
  }
@@ -180,7 +180,7 @@ parse_xml_time(const char *str, int len) {
180
180
  char c = *str++;
181
181
 
182
182
  if ('.' == c) {
183
- long nsec = 0;
183
+ long long nsec = 0;
184
184
 
185
185
  for (; str < end; str++) {
186
186
  c = *str;
@@ -192,7 +192,7 @@ parse_xml_time(const char *str, int len) {
192
192
  }
193
193
  args[5] = rb_float_new((double)n + ((double)nsec + 0.5) / 1000000000.0);
194
194
  } else {
195
- args[5] = LONG2NUM(n);
195
+ args[5] = rb_ll2inum(n);
196
196
  }
197
197
  if (end < str) {
198
198
  args[6] = LONG2NUM(0);
@@ -64,15 +64,15 @@ get_datetime_secs(VALUE obj) {
64
64
  VALUE rsecs = rb_funcall(obj, sec_id, 0);
65
65
  VALUE rfrac = rb_funcall(obj, sec_fraction_id, 0);
66
66
  long sec = NUM2LONG(rsecs);
67
- long num = NUM2LONG(rb_funcall(rfrac, numerator_id, 0));
68
- long den = NUM2LONG(rb_funcall(rfrac, denominator_id, 0));
67
+ long long num = rb_num2ll(rb_funcall(rfrac, numerator_id, 0));
68
+ long long den = rb_num2ll(rb_funcall(rfrac, denominator_id, 0));
69
69
 
70
70
  #if DATETIME_1_8
71
- num *= 86400;
71
+ num *= 86400;
72
72
  #endif
73
73
  num += sec * den;
74
74
 
75
- return rb_funcall(rb_cObject, rational_id, 2, LONG2FIX(num), LONG2FIX(den));
75
+ return rb_funcall(rb_cObject, rational_id, 2, rb_ll2inum(num), rb_ll2inum(den));
76
76
  }
77
77
 
78
78
  void
@@ -1442,7 +1442,7 @@ stream_writer_push_value(int argc, VALUE *argv, VALUE self) {
1442
1442
  return Qnil;
1443
1443
  }
1444
1444
 
1445
- /* call-seq: push_value(value, key=nil)
1445
+ /* call-seq: push_json(value, key=nil)
1446
1446
  *
1447
1447
  * Pushes a string onto the JSON document. The String must be a valid JSON
1448
1448
  * encoded string. No additional checking is done to verify the validity of the
@@ -438,6 +438,7 @@ read_num(ParseInfo pi) {
438
438
  } else {
439
439
  zero_cnt = 0;
440
440
  }
441
+ // TBD move size check here
441
442
  ni.i = ni.i * 10 + d;
442
443
  if (LONG_MAX <= ni.i || DEC_MAX < ni.dec_cnt - zero_cnt) {
443
444
  ni.big = 1;
@@ -455,6 +456,7 @@ read_num(ParseInfo pi) {
455
456
  zero_cnt = 0;
456
457
  }
457
458
  ni.dec_cnt++;
459
+ // TBD move size check here
458
460
  ni.num = ni.num * 10 + d;
459
461
  ni.div *= 10;
460
462
  if (LONG_MAX <= ni.div || DEC_MAX < ni.dec_cnt - zero_cnt) {
@@ -702,9 +704,9 @@ oj_num_as_value(NumInfo ni) {
702
704
  }
703
705
  } else {
704
706
  if (ni->neg) {
705
- rnum = LONG2NUM(-ni->i);
707
+ rnum = rb_ll2inum(-ni->i);
706
708
  } else {
707
- rnum = LONG2NUM(ni->i);
709
+ rnum = rb_ll2inum(ni->i);
708
710
  }
709
711
  }
710
712
  } else { // decimal
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '2.12.5'
4
+ VERSION = '2.12.6'
5
5
  end
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env ruby
2
-
3
1
  #!/usr/bin/env ruby
4
2
  # encoding: UTF-8
5
3
 
@@ -7,47 +5,60 @@ $: << File.dirname(__FILE__)
7
5
 
8
6
  require 'helper'
9
7
 
10
- class Handler
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)
26
- end
27
-
28
- def array_start
29
- @state << []
30
- @state.last
31
- end
32
-
8
+ require 'oj'
9
+ require 'securerandom'
33
10
 
34
- def array_end
35
- @state.pop
11
+ class Handler
12
+ def hash_start() {} end
13
+ def hash_set(h,k,v) h.store(k,v) end
14
+ def array_start() [] end
15
+ def array_append(a,v) a << v end
16
+ def error(message, line, column)
17
+ raise Exception.new(message, line, column)
36
18
  end
19
+ end
37
20
 
38
- def array_append(a,v)
39
- a << v
21
+ json = Oj.dump({"this"=>"object"})
22
+
23
+ if true
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
40
46
  end
41
-
42
- def add_value(v)
43
- p v
47
+ else
48
+ IO.pipe do |read_io, write_io|
49
+ if fork
50
+ write_io.close
51
+ p "start reading #{read_io.stat.ftype}"
52
+ Oj.sc_parse(Handler.new, read_io) {|v| p v}
53
+ p "stop reading"
54
+ read_io.close
55
+ else
56
+ read_io.close
57
+ p "start writing #{write_io.stat.ftype}"
58
+ write_io.write json
59
+ write_io.write json
60
+ p "stop writing"
61
+ write_io.close
62
+ end
44
63
  end
45
-
46
- def error(message, line, column); p "ERROR: #{message}" end
47
64
  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) }
@@ -0,0 +1,64 @@
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
@@ -0,0 +1,76 @@
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
@@ -0,0 +1,213 @@
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
@@ -0,0 +1,63 @@
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
@@ -1,16 +1,19 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: UTF-8
3
3
 
4
+ $VERBOSE = true
5
+
4
6
  %w(lib ext test).each do |dir|
5
7
  $LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
6
8
  end
7
9
 
10
+ require 'rubygems' if RUBY_VERSION.start_with?('1.8.')
8
11
  require 'oj'
9
12
 
13
+ Oj.mimic_JSON
14
+
15
+ #puts Oj.default_options
16
+
17
+ range = ("01".."12")
10
18
 
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
19
+ puts Oj.dump(range)
metadata CHANGED
@@ -1,58 +1,65 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.12.5
4
+ version: 2.12.6
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Peter Ohler
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-04-27 00:00:00.000000000 Z
12
+ date: 2015-05-05 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rake-compiler
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - "~>"
19
+ - - ~>
18
20
  - !ruby/object:Gem::Version
19
21
  version: '0.9'
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - "~>"
27
+ - - ~>
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0.9'
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: minitest
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
- - - "~>"
35
+ - - ~>
32
36
  - !ruby/object:Gem::Version
33
37
  version: '5'
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - "~>"
43
+ - - ~>
39
44
  - !ruby/object:Gem::Version
40
45
  version: '5'
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: rails
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
- - - "~>"
51
+ - - ~>
46
52
  - !ruby/object:Gem::Version
47
53
  version: '4'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
- - - "~>"
59
+ - - ~>
53
60
  - !ruby/object:Gem::Version
54
61
  version: '4'
55
- description: 'The fastest JSON parser and object serializer. '
62
+ description: ! 'The fastest JSON parser and object serializer. '
56
63
  email: peter@ohler.com
57
64
  executables: []
58
65
  extensions:
@@ -60,60 +67,52 @@ extensions:
60
67
  extra_rdoc_files:
61
68
  - README.md
62
69
  files:
63
- - LICENSE
64
- - README.md
70
+ - lib/oj/active_support_helper.rb
71
+ - lib/oj/bag.rb
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
65
79
  - ext/oj/buf.h
66
- - ext/oj/cache8.c
67
80
  - ext/oj/cache8.h
68
- - ext/oj/circarray.c
69
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
+ - ext/oj/cache8.c
92
+ - ext/oj/circarray.c
70
93
  - ext/oj/compat.c
71
94
  - ext/oj/dump.c
72
- - ext/oj/encode.h
73
95
  - ext/oj/err.c
74
- - ext/oj/err.h
75
- - ext/oj/extconf.rb
76
96
  - ext/oj/fast.c
77
97
  - ext/oj/hash.c
78
- - ext/oj/hash.h
79
98
  - ext/oj/hash_test.c
80
99
  - ext/oj/object.c
81
100
  - ext/oj/odd.c
82
- - ext/oj/odd.h
83
101
  - ext/oj/oj.c
84
- - ext/oj/oj.h
85
102
  - ext/oj/parse.c
86
- - ext/oj/parse.h
87
103
  - ext/oj/reader.c
88
- - ext/oj/reader.h
89
104
  - ext/oj/resolve.c
90
- - ext/oj/resolve.h
91
105
  - ext/oj/saj.c
92
106
  - ext/oj/scp.c
93
107
  - ext/oj/sparse.c
94
108
  - ext/oj/strict.c
95
109
  - 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
105
110
  - test/_test_active.rb
106
111
  - test/_test_active_mimic.rb
107
112
  - test/_test_mimic_rails.rb
108
113
  - 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
117
116
  - test/isolated/shared.rb
118
117
  - test/isolated/test_mimic_after.rb
119
118
  - test/isolated/test_mimic_alone.rb
@@ -121,17 +120,18 @@ files:
121
120
  - test/isolated/test_mimic_define.rb
122
121
  - test/isolated/test_mimic_rails_after.rb
123
122
  - test/isolated/test_mimic_rails_before.rb
124
- - test/mod.rb
125
123
  - 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
129
130
  - test/perf_object.rb
130
131
  - test/perf_saj.rb
131
132
  - test/perf_scp.rb
132
133
  - test/perf_simple.rb
133
134
  - 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,47 +144,49 @@ files:
144
144
  - test/sample/rect.rb
145
145
  - test/sample/shape.rb
146
146
  - test/sample/text.rb
147
+ - test/sample.rb
147
148
  - test/sample_json.rb
148
- - test/struct.rb
149
+ - test/test_bigd.rb
149
150
  - test/test_compat.rb
150
151
  - test/test_debian.rb
151
152
  - test/test_fast.rb
152
153
  - test/test_file.rb
153
154
  - test/test_gc.rb
154
155
  - test/test_object.rb
156
+ - test/test_range.rb
155
157
  - test/test_saj.rb
156
158
  - test/test_scp.rb
157
- - test/test_serializer.rb
158
159
  - test/test_strict.rb
159
160
  - test/test_various.rb
160
161
  - test/test_writer.rb
161
- - test/write_timebars.rb
162
- - test/zip.rb
162
+ - LICENSE
163
+ - README.md
163
164
  homepage: http://www.ohler.com/oj
164
165
  licenses:
165
166
  - 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
175
176
  requirements:
176
- - - ">="
177
+ - - ! '>='
177
178
  - !ruby/object:Gem::Version
178
179
  version: '0'
179
180
  required_rubygems_version: !ruby/object:Gem::Requirement
181
+ none: false
180
182
  requirements:
181
- - - ">="
183
+ - - ! '>='
182
184
  - !ruby/object:Gem::Version
183
185
  version: '0'
184
186
  requirements: []
185
187
  rubyforge_project: oj
186
- rubygems_version: 2.4.5
188
+ rubygems_version: 1.8.23.2
187
189
  signing_key:
188
- specification_version: 4
190
+ specification_version: 3
189
191
  summary: A fast JSON parser and serializer.
190
192
  test_files: []
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: e34ba8c73f9262974880d2fcf2be2b7d541b636b
4
- data.tar.gz: 11828007a4ddd9c8817e0039e86ff7c8e555a0d2
5
- SHA512:
6
- metadata.gz: 45f5d1cc476dded1921261dbb4ab1eda551ade35d6f66a97174167fed2b09f05d9c6fa8b1c3a1daa8a6f73238a5b48aad8cd81609aa2c5cf99dd696f71be46ce
7
- data.tar.gz: 9e89459bceb129fd3607b938c304ebcd6a7c92fdd1aa055b9cea9086a1cdcfa2768c2015c15128840be049e9dac91c76227d4f3b46a5761339babb397a62f183
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- #!/usr/bin/env ruby
4
- # encoding: UTF-8
5
-
6
- $: << File.dirname(__FILE__)
7
-
8
- require 'helper'
9
-
10
-
@@ -1,46 +0,0 @@
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
@@ -1,32 +0,0 @@
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
- }
@@ -1,24 +0,0 @@
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
- }
@@ -1,11 +0,0 @@
1
- %w(lib ext test).each do |dir|
2
- $LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
3
- end
4
- require 'oj'
5
- require 'json'
6
-
7
- Oj::Doc.open([{:name => "T-Shirt"}].to_json) do |doc|
8
- doc.each_child do |child|
9
- p child.fetch("name")
10
- end
11
- end
data/test/io.rb DELETED
@@ -1,48 +0,0 @@
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,29 +0,0 @@
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
@@ -1,59 +0,0 @@
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
@@ -1,31 +0,0 @@
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
-
@@ -1,34 +0,0 @@
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