oj 1.3.0 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of oj might be problematic. Click here for more details.

data/README.md CHANGED
@@ -32,9 +32,9 @@ A fast JSON parser and Object marshaller as a Ruby gem.
32
32
 
33
33
  ## <a name="release">Release Notes</a>
34
34
 
35
- ### Release 1.3.0
35
+ ### Release 1.3.2
36
36
 
37
- - Added an option to control the time format output when in :compat mode.
37
+ - Fixed compile problems with native Ruby on OS X 10.8 (Mountain Lion)
38
38
 
39
39
  ## <a name="description">Description</a>
40
40
 
data/ext/oj/dump.c CHANGED
@@ -34,6 +34,7 @@
34
34
  #include <time.h>
35
35
  #include <stdio.h>
36
36
  #include <string.h>
37
+ #include <math.h>
37
38
 
38
39
  #include "oj.h"
39
40
  #include "cache8.h"
@@ -42,8 +43,6 @@
42
43
  #define rb_eEncodingError rb_eException
43
44
  #endif
44
45
 
45
- #define DBL_INF 1.e500
46
-
47
46
  typedef unsigned long ulong;
48
47
 
49
48
  typedef struct _Out {
@@ -421,10 +420,10 @@ dump_float(VALUE obj, Out out) {
421
420
  *b++ = '0';
422
421
  *b++ = '\0';
423
422
  cnt = 3;
424
- } else if (DBL_INF == d) {
423
+ } else if (INFINITY == d) {
425
424
  strcpy(buf, "Infinity");
426
425
  cnt = 8;
427
- } else if (-DBL_INF == d) {
426
+ } else if (-INFINITY == d) {
428
427
  strcpy(buf, "-Infinity");
429
428
  cnt = 9;
430
429
  } else {
@@ -970,6 +969,7 @@ dump_xml_time(VALUE obj, Out out) {
970
969
  long nsec = NUM2LONG(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
971
970
  #endif
972
971
  #endif
972
+ long tz_secs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
973
973
  int tzhour, tzmin;
974
974
  char tzsign = '+';
975
975
 
@@ -977,7 +977,19 @@ dump_xml_time(VALUE obj, Out out) {
977
977
  grow(out, 36);
978
978
  }
979
979
  // 2012-01-05T23:58:07.123456000+09:00
980
- tm = localtime(&sec);
980
+ //tm = localtime(&sec);
981
+ sec += tz_secs;
982
+ tm = gmtime(&sec);
983
+ #if 1
984
+ if (0 > tz_secs) {
985
+ tzsign = '-';
986
+ tzhour = (int)(tz_secs / -3600);
987
+ tzmin = (int)(tz_secs / -60) - (tzhour * 60);
988
+ } else {
989
+ tzhour = (int)(tz_secs / 3600);
990
+ tzmin = (int)(tz_secs / 60) - (tzhour * 60);
991
+ }
992
+ #else
981
993
  if (0 > tm->tm_gmtoff) {
982
994
  tzsign = '-';
983
995
  tzhour = (int)(tm->tm_gmtoff / -3600);
@@ -986,11 +998,27 @@ dump_xml_time(VALUE obj, Out out) {
986
998
  tzhour = (int)(tm->tm_gmtoff / 3600);
987
999
  tzmin = (int)(tm->tm_gmtoff / 60) - (tzhour * 60);
988
1000
  }
989
- sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02d.%09ld%c%02d:%02d",
990
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
991
- tm->tm_hour, tm->tm_min, tm->tm_sec, nsec,
992
- tzsign, tzhour, tzmin);
993
- dump_cstr(buf, 35, 0, 0, out);
1001
+ #endif
1002
+ if (0 == nsec) {
1003
+ if (0 == tzhour && 0 == tzmin) {
1004
+ sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ",
1005
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1006
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
1007
+ dump_cstr(buf, 20, 0, 0, out);
1008
+ } else {
1009
+ sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
1010
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1011
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
1012
+ tzsign, tzhour, tzmin);
1013
+ dump_cstr(buf, 25, 0, 0, out);
1014
+ }
1015
+ } else {
1016
+ sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02d.%09ld%c%02d:%02d",
1017
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1018
+ tm->tm_hour, tm->tm_min, tm->tm_sec, nsec,
1019
+ tzsign, tzhour, tzmin);
1020
+ dump_cstr(buf, 35, 0, 0, out);
1021
+ }
994
1022
  }
995
1023
 
996
1024
  static void
data/ext/oj/extconf.rb CHANGED
@@ -32,7 +32,7 @@ dflags = {
32
32
  # missing #define. This is the quick and easy way around it.
33
33
  if 'x86_64-linux' == RUBY_PLATFORM && '1.9.3' == RUBY_VERSION && '2011-10-30' == RUBY_RELEASE_DATE
34
34
  begin
35
- dflags['NEEDS_STPCPY'] = nil if `more /etc/issue`.include?('CentOS release 5.4')
35
+ dflags['NEEDS_STPCPY'] = nil if File.read('/etc/redhat-release').include?('CentOS release 5.4')
36
36
  rescue Exception => e
37
37
  end
38
38
  end
data/ext/oj/load.c CHANGED
@@ -28,7 +28,9 @@
28
28
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
  */
30
30
 
31
+ #ifdef SAFE_CACHE
31
32
  #include <pthread.h> // TBD LOCK
33
+ #endif
32
34
  #include <stdlib.h>
33
35
  #include <stdio.h>
34
36
  #include <string.h>
data/ext/oj/oj.c CHANGED
@@ -29,7 +29,6 @@
29
29
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
  */
31
31
 
32
- #include <pthread.h>
33
32
  #include <stdlib.h>
34
33
  #include <errno.h>
35
34
  #include <stdio.h>
@@ -64,6 +63,7 @@ ID oj_to_time_id;
64
63
  ID oj_tv_nsec_id;
65
64
  ID oj_tv_sec_id;
66
65
  ID oj_tv_usec_id;
66
+ ID oj_utc_offset_id;
67
67
  ID oj_write_id;
68
68
 
69
69
  VALUE oj_bag_class;
@@ -107,8 +107,9 @@ Cache oj_attr_cache = 0;
107
107
  rb_encoding *oj_utf8_encoding = 0;
108
108
  #endif
109
109
 
110
+ #ifdef SAFE_CACHE
110
111
  pthread_mutex_t oj_cache_mutex; // only used if SAFE_CACHE defined
111
-
112
+ #endif
112
113
  static const char json_class[] = "json_class";
113
114
 
114
115
  struct _Options oj_default_options = {
@@ -628,6 +629,7 @@ mimic_dump_load(int argc, VALUE *argv, VALUE self) {
628
629
  } else {
629
630
  return mimic_dump(argc, argv, self);
630
631
  }
632
+ return Qnil;
631
633
  }
632
634
 
633
635
  static VALUE
@@ -872,6 +874,7 @@ void Init_oj() {
872
874
  oj_tv_nsec_id = rb_intern("tv_nsec");
873
875
  oj_tv_sec_id = rb_intern("tv_sec");
874
876
  oj_tv_usec_id = rb_intern("tv_usec");
877
+ oj_utc_offset_id = rb_intern("utc_offset");
875
878
  oj_write_id = rb_intern("write");
876
879
 
877
880
  oj_bag_class = rb_const_get_at(Oj, rb_intern("Bag"));
data/ext/oj/oj.h CHANGED
@@ -46,8 +46,9 @@ extern "C" {
46
46
  #endif
47
47
 
48
48
  #include "stdint.h"
49
- #include <pthread.h> // for SAFE_CACHE
50
-
49
+ #ifdef SAFE_CACHE
50
+ #include <pthread.h>
51
+ #endif
51
52
  #include "cache.h"
52
53
 
53
54
  #ifdef RUBINIUS_RUBY
@@ -182,12 +183,14 @@ extern ID oj_to_time_id;
182
183
  extern ID oj_tv_nsec_id;
183
184
  extern ID oj_tv_sec_id;
184
185
  extern ID oj_tv_usec_id;
186
+ extern ID oj_utc_offset_id;
185
187
 
186
188
  extern Cache oj_class_cache;
187
189
  extern Cache oj_attr_cache;
188
190
 
191
+ #ifdef SAFE_CACHE
189
192
  extern pthread_mutex_t oj_cache_mutex;
190
-
193
+ #endif
191
194
  #if defined(__cplusplus)
192
195
  #if 0
193
196
  { /* satisfy cc-mode */
data/lib/oj/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '1.3.0'
4
+ VERSION = '1.3.2'
5
5
  end
data/test/perf1.rb ADDED
@@ -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
@@ -15,6 +15,19 @@ opts = OptionParser.new
15
15
  opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
16
16
  files = opts.parse(ARGV)
17
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
+
18
31
  iter = 100000
19
32
  s = %{
20
33
  { "class": "Foo::Bar",
@@ -23,36 +36,41 @@ s = %{
23
36
  }
24
37
  }
25
38
 
39
+ obj = Oj.load(s)
40
+ obj["foo"] = Foo.new()
41
+
42
+ Oj.default_options = { :indent => 0, :effort => :internal }
43
+
44
+ puts
45
+
26
46
  start = Time.now
27
47
  iter.times do
28
48
  Oj.load(s)
29
49
  end
30
- oj_dt = Time.now - start
31
- puts "%d Oj.load()s in %0.3f seconds or %0.1f loads/msec" % [iter, oj_dt, iter/oj_dt/1000.0]
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]
32
52
 
33
53
  start = Time.now
34
54
  iter.times do
35
55
  Yajl::Parser.parse(s)
36
56
  end
37
- yajl_dt = Time.now - start
38
- puts "%d Yajl::Parser.parse()s in %0.3f seconds or %0.1f parses/msec" % [iter, yajl_dt, iter/yajl_dt/1000.0]
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]
39
59
 
40
- puts "Oj is %0.1f times faster than YAJL at parsing." % [yajl_dt / oj_dt]
60
+ puts
41
61
 
42
-
43
- obj = Oj.load(s)
44
62
  start = Time.now
45
63
  iter.times do
46
64
  Oj.dump(obj)
47
65
  end
48
- oj_dt = Time.now - start
49
- puts "%d Oj.dump()s in %0.3f seconds or %0.1f dumps/msec" % [iter, oj_dt, iter/oj_dt/1000.0]
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]
50
68
 
51
69
  start = Time.now
52
70
  iter.times do
53
71
  Yajl::Encoder.encode(obj)
54
72
  end
55
- yajl_dt = Time.now - start
56
- puts "%d Yajl::Encoder.encode()s in %0.3f seconds or %0.1f encodes/msec" % [iter, yajl_dt, iter/yajl_dt/1000.0]
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]
57
75
 
58
- puts "Oj is %0.1f times faster than YAJL at dumping." % [yajl_dt / oj_dt]
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
data/test/tests.rb CHANGED
@@ -266,9 +266,43 @@ class Juice < ::Test::Unit::TestCase
266
266
  assert_equal(%{"#{t.to_s}"}, json)
267
267
  end
268
268
  def test_xml_time_compat
269
- t = Time.xmlschema("2012-01-05T23:58:07.123456000+09:00")
270
- json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
271
- assert_equal(%{"2012-01-05T23:58:07.123456000+09:00"}, json)
269
+ begin
270
+ t = Time.new(2012, 1, 5, 23, 58, 7.123456000, 34200)
271
+ json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
272
+ assert_equal(%{"2012-01-05T23:58:07.123456000+09:30"}, json)
273
+ rescue Exception => e
274
+ # some Rubies (1.8.7) do not allow the timezome to be set
275
+ t = Time.local(2012, 1, 5, 23, 58, 7, 123456)
276
+ json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
277
+ tz = t.utc_offset
278
+ assert_equal(%{"2012-01-05T23:58:07.123456000+%02d:%02d"} % [tz / 3600, tz / 60 % 60], json)
279
+ end
280
+ end
281
+ def test_xml_time_compat_no_secs
282
+ begin
283
+ t = Time.new(2012, 1, 5, 23, 58, 7.0, 34200)
284
+ json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
285
+ assert_equal(%{"2012-01-05T23:58:07+09:30"}, json)
286
+ rescue Exception => e
287
+ # some Rubies (1.8.7) do not allow the timezome to be set
288
+ t = Time.local(2012, 1, 5, 23, 58, 7, 0)
289
+ json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
290
+ tz = t.utc_offset
291
+ assert_equal(%{"2012-01-05T23:58:07+%02d:%02d"} % [tz / 3600, tz / 60 % 60], json)
292
+ end
293
+ end
294
+ def test_xml_time_compat_zulu
295
+ begin
296
+ t = Time.new(2012, 1, 5, 23, 58, 7.0, 0)
297
+ json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
298
+ assert_equal(%{"2012-01-05T23:58:07Z"}, json)
299
+ rescue Exception => e
300
+ # some Rubies (1.8.7) do not allow the timezome to be set
301
+ t = Time.utc(2012, 1, 5, 23, 58, 7, 0)
302
+ json = Oj.dump(t, :mode => :compat, :time_format => :xmlschema)
303
+ tz = t.utc_offset
304
+ assert_equal(%{"2012-01-05T23:58:07Z"}, json)
305
+ end
272
306
  end
273
307
  def test_time_object
274
308
  t = Time.now()
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-09 00:00:00.000000000 Z
12
+ date: 2012-07-28 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! 'The fastest JSON parser and object serializer. '
15
15
  email: peter@ohler.com
@@ -32,14 +32,13 @@ files:
32
32
  - ext/oj/fast.c
33
33
  - ext/oj/load.c
34
34
  - ext/oj/oj.c
35
- - test/boo.rb
36
- - test/bug.rb
37
35
  - test/files.rb
38
- - test/foo.rb
39
- - test/oj-test/test.rb
40
36
  - test/perf.rb
37
+ - test/perf1.rb
38
+ - test/perf2.rb
41
39
  - test/perf_fast.rb
42
40
  - test/perf_obj.rb
41
+ - test/perf_obj_old.rb
43
42
  - test/perf_simple.rb
44
43
  - test/perf_strict.rb
45
44
  - test/sample/change.rb
@@ -59,7 +58,6 @@ files:
59
58
  - test/test_fast.rb
60
59
  - test/test_mimic.rb
61
60
  - test/tests.rb
62
- - test/where.rb
63
61
  - LICENSE
64
62
  - README.md
65
63
  homepage: http://www.ohler.com/oj
data/test/boo.rb DELETED
@@ -1,26 +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 'yajl'
8
- require 'oj'
9
-
10
- iter = 100
11
- s = File.read("boo.json")
12
- start = Time.now
13
- iter.times do
14
- Oj.load(s)
15
- end
16
- oj_dt = Time.now - start
17
- puts "%d Oj.load()s in %0.3f seconds or %0.1f loads/second" % [iter, oj_dt, iter/oj_dt]
18
-
19
- start = Time.now
20
- iter.times do
21
- Yajl::Parser.parse(s)
22
- end
23
- yajl_dt = Time.now - start
24
- puts "%d Yajl::Parser.parse()s in %0.3f seconds or %0.1f parsed/second" % [iter, yajl_dt, iter/yajl_dt]
25
-
26
- puts "Oj is %0.1f times faster than YAJL" % [yajl_dt / oj_dt]
data/test/bug.rb DELETED
@@ -1,18 +0,0 @@
1
-
2
- $: << File.join(File.dirname(__FILE__), "../lib")
3
- $: << File.join(File.dirname(__FILE__), "../ext")
4
-
5
- require 'oj'
6
- require 'bigdecimal'
7
-
8
- stuff = [
9
- BigDecimal.new('10'),
10
- Date.today,
11
- Time.now,
12
- DateTime.now
13
- ]
14
-
15
- puts Oj.dump(stuff, :mode => :strict)
16
- puts Oj.dump(stuff, :mode => :compat)
17
- puts Oj.dump(stuff, :mode => :object)
18
-
data/test/oj-test/test.rb DELETED
@@ -1,137 +0,0 @@
1
- require 'cgi'
2
- require 'oj'
3
-
4
- AD_MARKUP = CGI.escape("asdf" * 100)
5
-
6
- SEATBID = '{
7
- "bid" : [{
8
- "id": "1",
9
- "impid" : "102",
10
- "price": 9.43,
11
- "adid" : "314",
12
- "nurl": "http://adserver.com/winnotice?impid=102",
13
- "adm" : "' + AD_MARKUP + '",
14
- "adomain" : ["advertiserdomain.com"],
15
- "iurl" : "http://adserver.com/pathtosampleimage",
16
- "cid" : "campaign111",
17
- "crid" : "creative112",
18
- "attr" : [1,2,3,4,5,6,7,12]
19
- }],
20
- "seat" : "512",
21
- "group" : "128"
22
- }'
23
-
24
-
25
- LARGE_JSON = '{
26
- "id": "1234567890",
27
- "units" : 0,
28
- "bidid": "abc1123",
29
- "cur": "EUR",
30
- "seatbid": [' + ([SEATBID] * 100).join(', ') + ']
31
- }'
32
-
33
-
34
- class Bid
35
-
36
- attr_accessor :id,
37
- :bidid,
38
- :cur,
39
- :seat,
40
- :group,
41
- :impid,
42
- :price,
43
- :units,
44
- :adid,
45
- :nurl,
46
- :adm,
47
- :adomain,
48
- :iurl,
49
- :cid,
50
- :crid,
51
- :attr,
52
- :nbr,
53
- :partner_id
54
-
55
- alias :currency :cur
56
- alias :auction_id :id
57
-
58
- def parsed_adm
59
- return replace_macros(self.adm)
60
- end
61
-
62
- def parsed_nurl
63
- return replace_macros(self.nurl)
64
- end
65
-
66
- def replace_macros(template)
67
- return nil if !template
68
- {
69
- '${AUCTION_ID}' => self.id,
70
- '${AUCTION_BID_ID}' => self.bidid,
71
- '${AUCTION_IMP_ID}' => self.impid,
72
- '${AUCTION_SEAT_ID}' => self.seat,
73
- '${AUCTION_AD_ID}' => self.adid,
74
- '${AUCTION_PRICE}' => self.price,
75
- '${AUCTION_CURRENCY}' => self.cur,
76
- '${AUCTION_UNITS}' => self.units,
77
- }.each do |macro, v|
78
- template = template.gsub(macro, v.to_s)
79
- end
80
- template
81
- end
82
- end
83
-
84
- class BidResponseParser
85
- REQUIRED_ATTRIBUTES = [:id, :impid, :price].freeze
86
-
87
- def self.parse(json)
88
- return nil if !json
89
- extract_fast(json)
90
- end
91
-
92
- def self.extract_fast(json)
93
- bid = nil
94
- Oj::Doc.open(json) do |doc|
95
- bid = Bid.new
96
-
97
- # bid-response object
98
- bid.id = doc.fetch '/id'
99
-
100
- bid.bidid = doc.fetch '/bidid'
101
- bid.units = doc.fetch('/units') || 0
102
- bid.cur = doc.fetch '/cur'
103
- bid.nbr = doc.fetch('/nbr') || 0 # Mobile RTB 1.0 only
104
-
105
- # EM: we do not expect more than 1 bid object in the response,
106
- # as we only send single ads in the bid-request (no multi-ad-auctions) atm.
107
- # seatbid-obj
108
- bid.seat = doc.fetch '/seatbid/0/seat'
109
- bid.group = doc.fetch '/seatbid/0/group'
110
-
111
- # bid-obj
112
- bid_path = '/seatbid/0/bid/0'
113
- bid.impid = doc.fetch "#{bid_path}/impid"
114
- bid.adid = doc.fetch "#{bid_path}/adid"
115
- bid.nurl = doc.fetch "#{bid_path}/nurl"
116
- bid.adm = doc.fetch "#{bid_path}/adm"
117
- bid.adomain = doc.fetch "#{bid_path}/adomain"
118
- bid.iurl = doc.fetch "#{bid_path}/iurl"
119
- bid.cid = doc.fetch "#{bid_path}/cid"
120
- bid.crid = doc.fetch "#{bid_path}/crid"
121
- bid.attr = doc.fetch "#{bid_path}/attr"
122
-
123
- # sadly we need to check this explicitly, because nil.to_f returns 0.0
124
- if doc.fetch("#{bid_path}/price") == nil
125
- raise "required attribute price missing"
126
- end
127
-
128
- bid.price = doc.fetch("#{bid_path}/price").to_f
129
- end
130
-
131
- return bid
132
- end
133
- end
134
-
135
- 1000.times do
136
- BidResponseParser.parse(LARGE_JSON)
137
- end
data/test/where.rb DELETED
@@ -1,54 +0,0 @@
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 'perf'
10
- require 'oj'
11
-
12
- $verbose = false
13
- $indent = 0
14
- $iter = 1000000
15
-
16
- opts = OptionParser.new
17
- opts.on("-v", "verbose") { $verbose = true }
18
- opts.on("-c", "--count [Int]", Integer, "iterations") { |i| $iter = i }
19
- opts.on("-i", "--indent [Int]", Integer, "indentation") { |i| $indent = i }
20
- opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
21
- files = opts.parse(ARGV)
22
-
23
- $obj = {
24
- 'a' => 'Alpha', # string
25
- 'b' => true, # boolean
26
- 'c' => 12345, # number
27
- 'd' => [ true, [false, [12345, nil], 3.967, ['something', false], nil]], # mix it up array
28
- 'e' => { 'one' => 1, 'two' => 2 }, # hash
29
- 'f' => nil, # nil
30
- 'g' => 12345678901234567890123456789, # big number
31
- 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
32
- 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
33
- }
34
-
35
- Oj.default_options = { :indent => $indent, :mode => :strict }
36
-
37
- $json = Oj.dump($obj)
38
-
39
- if $verbose
40
- puts "json:\n#{$json}\n"
41
- end
42
-
43
- puts '-' * 80
44
- puts "Parse Performance"
45
- Oj::Fast.open($json) do |fast|
46
- fast.move('/d/2/4/2')
47
- puts fast.where2?
48
- puts fast.where?
49
- perf = Perf.new()
50
- perf.add('Oj:fast', 'where') { fast.where? }
51
- perf.add('Oj:fast2', 'where2') { fast.where2? }
52
- perf.run($iter)
53
- end
54
- puts