oj 2.12.5 → 2.12.6

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.
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