oj 2.1.2 → 2.1.3

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59068b284af14e2585b85c69b1cc182f3dd0195d
4
- data.tar.gz: 963f274f3d866a2230b674fbab5890a5d2b86dcd
3
+ metadata.gz: 8f2645663d6b76de56402dc004a41b2299c3eb09
4
+ data.tar.gz: 2df5a5fdca36bb28f69130f249500cbe7ea9a148
5
5
  SHA512:
6
- metadata.gz: 32d43a8666dc8f16857a7ddee5ec4080a979c3cfc12d3834b3a832f40e323e742c4ecdac97f42400805983a2c448619a5f7a5e75f79221d8c0943551d0ec7591
7
- data.tar.gz: 5113342958ca4a32bdd43af03ccba31c31c588967a40bd0e6cac1846e52db25a4a15231dcd16c82bb6c7507e2a9788fe4bff74b1ec56b957f55934e99e4e511a
6
+ metadata.gz: b8b3d8d7a4437b06cb2b7c509042bcd83f5ad6af6dba92e05b40af29b49d89b98608ffcb0668807201ce152b13ca702276bcf8492afe04adb2a8594bafcfecc0
7
+ data.tar.gz: 3daeb161d0402dcdbffd7aad76551ae39203e9b797fcff261d32c8b38a63d175c270e1f0ad7f9e2db6fbd86af5de81f564cac5e9415a74a7f84e2f2f29a6c01c
data/README.md CHANGED
@@ -20,31 +20,11 @@ Follow [@peterohler on Twitter](http://twitter.com/#!/peterohler) for announceme
20
20
 
21
21
  [![Build Status](https://secure.travis-ci.org/ohler55/oj.png?branch=master)](http://travis-ci.org/ohler55/oj)
22
22
 
23
- ### Current Release 2.1.2
23
+ ### Current Release 2.1.3
24
24
 
25
- - Fixed support for Windows.
25
+ - Fixed bug that did not deserialize all attributes in an Exception subclass.
26
26
 
27
- ### Current Release 2.1.1
28
-
29
- - Fixed off by 1 error in buffer for escaped strings.
30
-
31
- ### Current Release 2.1.0
32
-
33
- - This version is a major rewrite of the parser. The parser now uses a constant
34
- stack size no matter how deeply nested the JSON document is. The parser is
35
- also slightly faster for larger documents and 30% faster for object parsing.
36
-
37
- - Oj.strict_load() was renamed to Oj.safe_load() to better represent its
38
- functionality. A new Oj.strict_load() is simply Oj.load() with :mode set to
39
- :strict.
40
-
41
- - Oj.compat_load() and Oj.object_load() added.
42
-
43
- - A new Simple Callback Parser was added invoked by Oj.sc_parse().
44
-
45
- - Eliminated :max_stack option as it is no longer needed.
46
-
47
- - Handle cleanup after exceptions better.
27
+ - Added a sample to demonstrate how to write Exception subclasses that will automatically serialize and deserialize.
48
28
 
49
29
  [Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
50
30
 
@@ -1344,7 +1344,6 @@ dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
1344
1344
  }
1345
1345
  {
1346
1346
  int cnt;
1347
- // use encoding as the indicator for Ruby 1.8.7 or 1.9.x
1348
1347
  #if HAS_IVAR_HELPERS
1349
1348
  cnt = (int)rb_ivar_count(obj);
1350
1349
  #else
@@ -29,6 +29,7 @@
29
29
  */
30
30
 
31
31
  #include "hash.h"
32
+ #include <stdint.h>
32
33
 
33
34
  #define HASH_MASK 0x000003FF
34
35
  #define HASH_SLOT_CNT 1024
@@ -28,11 +28,16 @@
28
28
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
  */
30
30
 
31
+ // if windows, comment out the whole file. It's only a performance test.
31
32
  #ifndef _WIN32
32
33
  #include <sys/time.h>
33
34
  #include <time.h>
34
- #endif
35
35
  #include "hash.h"
36
+ #include <stdint.h>
37
+
38
+ /* Define printf formats for standard types, like PRIu64 for uint64_t. */
39
+ #define __STDC_FORMAT_MACROS
40
+ #include <inttypes.h>
36
41
 
37
42
  typedef struct _StrLen {
38
43
  const char *str;
@@ -473,7 +478,7 @@ perf() {
473
478
  #if IS_WINDOWS
474
479
  printf("%d iterations took %ld msecs\n", iter, (long)(dt / 1000));
475
480
  #else
476
- printf("%d iterations took %lld msecs\n", iter, dt / 1000);
481
+ printf("%d iterations took %"PRIu64" msecs\n", iter, dt / 1000);
477
482
  #endif
478
483
  }
479
484
 
@@ -505,3 +510,4 @@ oj_hash_test() {
505
510
  oj_hash_print();
506
511
  perf();
507
512
  }
513
+ #endif
@@ -241,6 +241,23 @@ hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, VALUE value) {
241
241
  return 0;
242
242
  }
243
243
 
244
+ static void
245
+ copy_ivars(VALUE target, VALUE src) {
246
+ VALUE vars = rb_funcall(src, oj_instance_variables_id, 0);
247
+ VALUE *np = RARRAY_PTR(vars);
248
+ ID vid;
249
+ int i, cnt = (int)RARRAY_LEN(vars);
250
+ const char *attr;
251
+
252
+ for (i = cnt; 0 < i; i--, np++) {
253
+ vid = rb_to_id(*np);
254
+ attr = rb_id2name(vid);
255
+ if ('@' == *attr) {
256
+ rb_ivar_set(target, vid, rb_ivar_get(src, vid));
257
+ }
258
+ }
259
+ }
260
+
244
261
  static void
245
262
  set_obj_ivar(Val parent, const char *key, size_t klen, VALUE value) {
246
263
  ID var_id;
@@ -249,9 +266,11 @@ set_obj_ivar(Val parent, const char *key, size_t klen, VALUE value) {
249
266
  if ('~' == *key && Qtrue == rb_obj_is_kind_of(parent->val, rb_eException)) {
250
267
  if (5 == klen && 0 == strncmp("~mesg", key, klen)) {
251
268
  VALUE args[1];
269
+ VALUE prev = parent->val;
252
270
 
253
271
  args[0] = value;
254
272
  parent->val = rb_class_new_instance(1, args, rb_class_of(parent->val));
273
+ copy_ivars(parent->val, prev);
255
274
  } else if (3 == klen && 0 == strncmp("~bt", key, klen)) {
256
275
  rb_funcall(parent->val, rb_intern("set_backtrace"), 1, value);
257
276
  }
@@ -462,6 +462,22 @@ oj_parse_options(VALUE ropts, Options copts) {
462
462
  * valid. If the input is not a valid JSON document (an empty string is not a
463
463
  * valid JSON document) an exception is raised.
464
464
  *
465
+ * Note: Oj is not able to automatically deserialize all classes that are a
466
+ * subclass of a Ruby Exception. Only exception that take one required string
467
+ * argument in the initialize() method are supported. This is an example of how
468
+ * to write an Exception subclass that supports both a single string intializer
469
+ * and an Exception as an argument. Additional optional arguments can be added
470
+ * as well.
471
+ *
472
+ * The reason for this restriction has to do with a design decision on the part
473
+ * of the Ruby developers. Exceptions are special Objects. They do not follow the
474
+ * rules of other Objects. Exceptions have 'mesg' and a 'bt' attribute. Note that
475
+ * these are not '@mesg' and '@bt'. They can not be set using the normal C or
476
+ * Ruby calls. The only way I have found to set the 'mesg' attribute is through
477
+ * the initializer. Unfortunately that means any subclass that provides a
478
+ * different initializer can not be automatically decoded. A way around this is
479
+ * to use a create function but this example shows an alternative.
480
+ *
465
481
  * @param [String|IO] json JSON String or an Object that responds to read()
466
482
  * @param [Hash] options load options (same as default_options)
467
483
  */
@@ -1046,6 +1062,16 @@ define_mimic_json(int argc, VALUE *argv, VALUE self) {
1046
1062
  return mimic;
1047
1063
  }
1048
1064
 
1065
+ /*
1066
+ extern void oj_hash_test();
1067
+
1068
+ static VALUE
1069
+ hash_test(VALUE self) {
1070
+ oj_hash_test();
1071
+ return Qnil;
1072
+ }
1073
+ */
1074
+
1049
1075
  void Init_oj() {
1050
1076
  Oj = rb_define_module("Oj");
1051
1077
 
@@ -1054,6 +1080,8 @@ void Init_oj() {
1054
1080
  rb_require("bigdecimal");
1055
1081
  rb_require("stringio");
1056
1082
 
1083
+ //rb_define_module_function(Oj, "hash_test", hash_test, 0);
1084
+
1057
1085
  rb_define_module_function(Oj, "default_options", get_def_opts, 0);
1058
1086
  rb_define_module_function(Oj, "default_options=", set_def_opts, 1);
1059
1087
 
@@ -1140,9 +1168,6 @@ void Init_oj() {
1140
1168
  pthread_mutex_init(&oj_cache_mutex, 0);
1141
1169
  #endif
1142
1170
  oj_init_doc();
1143
-
1144
- //rb_define_module_function(Oj, "hash_test", hash_test, 0);
1145
-
1146
1171
  }
1147
1172
 
1148
1173
  // mimic JSON documentation
@@ -33,6 +33,7 @@
33
33
 
34
34
  #include "ruby.h"
35
35
  #include "odd.h"
36
+ #include <stdint.h>
36
37
 
37
38
  #define STACK_INC 32
38
39
 
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '2.1.2'
4
+ VERSION = '2.1.3'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-19 00:00:00.000000000 Z
11
+ date: 2013-06-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: 'The fastest JSON parser and object serializer. '
14
14
  email: peter@ohler.com
@@ -53,42 +53,6 @@ files:
53
53
  - ext/oj/scp.c
54
54
  - ext/oj/strict.c
55
55
  - ext/oj/val_stack.c
56
- - test/a.rb
57
- - test/bug.rb
58
- - test/files.rb
59
- - test/foo.rb
60
- - test/mj.rb
61
- - test/perf.rb
62
- - test/perf_compat.rb
63
- - test/perf_fast.rb
64
- - test/perf_object.rb
65
- - test/perf_saj.rb
66
- - test/perf_scp.rb
67
- - test/perf_simple.rb
68
- - test/perf_strict.rb
69
- - test/sample/change.rb
70
- - test/sample/dir.rb
71
- - test/sample/doc.rb
72
- - test/sample/file.rb
73
- - test/sample/group.rb
74
- - test/sample/hasprops.rb
75
- - test/sample/layer.rb
76
- - test/sample/line.rb
77
- - test/sample/oval.rb
78
- - test/sample/rect.rb
79
- - test/sample/shape.rb
80
- - test/sample/text.rb
81
- - test/sample.rb
82
- - test/sample_json.rb
83
- - test/test_compat.rb
84
- - test/test_fast.rb
85
- - test/test_mimic.rb
86
- - test/test_mimic_after.rb
87
- - test/test_object.rb
88
- - test/test_saj.rb
89
- - test/test_scp.rb
90
- - test/test_strict.rb
91
- - test/tests.rb
92
56
  - LICENSE
93
57
  - README.md
94
58
  homepage: http://www.ohler.com/oj
data/test/a.rb DELETED
@@ -1,38 +0,0 @@
1
- #!/usr/bin/env ruby -wW1
2
- # encoding: UTF-8
3
-
4
- $: << File.dirname(__FILE__)
5
- $: << File.join(File.dirname(__FILE__), "../lib")
6
- $: << File.join(File.dirname(__FILE__), "../ext")
7
-
8
- require 'pp'
9
- require 'oj'
10
- require 'perf'
11
-
12
- obj = [[1],[2],[3],[4],[5],[6],[7],[8],[9]]
13
- obj = [[],[],[],[],[],[],[],[],[]]
14
- obj = {
15
- 'a' => 'Alpha', # string
16
- 'b' => true, # boolean
17
- 'c' => 12345, # number
18
- 'd' => [ true, [false, [12345, nil], 3.967, ['something', false], nil]], # mix it up array
19
- 'e' => { 'one' => 1, 'two' => 2 }, # hash
20
- 'f' => nil, # nil
21
- 'g' => 12345678901234567890123456789, # big number
22
- 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
23
- 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
24
- }
25
-
26
- json = Oj.dump(obj, mode: :compat)
27
-
28
- puts json
29
- #pp Oj.saj_parse(nil, json)
30
- pp Oj.t_parse(json)
31
-
32
- if true
33
- perf = Perf.new()
34
- perf.add('SAJ', 'oj') { Oj.saj_parse(nil, json) }
35
- perf.add('T', 'oj') { Oj.t_parse(json) }
36
- perf.add('load', 'oj') { Oj.load(json) }
37
- perf.run(10000)
38
- end
@@ -1,15 +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
- Oj.load_file('josh2.json', :mode => :strict)
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby -wW2
2
-
3
- if $0 == __FILE__
4
- $: << '.'
5
- $: << '..'
6
- $: << '../lib'
7
- $: << '../ext'
8
- end
9
-
10
- require 'pp'
11
- require 'sample/file'
12
- require 'sample/dir'
13
-
14
- def files(dir)
15
- d = ::Sample::Dir.new(dir)
16
- Dir.new(dir).each do |fn|
17
- next if fn.start_with?('.')
18
- filename = File.join(dir, fn)
19
- #filename = '.' == dir ? fn : File.join(dir, fn)
20
- if File.directory?(filename)
21
- d << files(filename)
22
- else
23
- d << ::Sample::File.new(filename)
24
- end
25
- end
26
- #pp d
27
- d
28
- end
29
-
@@ -1,24 +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
- reltypes={}
16
- Oj::Doc.open_file('foo.json') do |doc|
17
- doc.each_child do |target|
18
- puts "#{target.local_key} is #{target.local_key.class}"
19
- target.each_leaf do |score|
20
- reltype=score.local_key
21
- reltypes[reltype] = (reltypes[reltype] || 0) + 1
22
- end
23
- end
24
- end
data/test/mj.rb DELETED
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- $: << File.join(File.dirname(__FILE__), "../lib")
5
- $: << File.join(File.dirname(__FILE__), "../ext")
6
- # $: << File.join(File.dirname(__FILE__), "../../multi_json/lib")
7
-
8
- require 'multi_json'
9
- require 'benchmark'
10
- require 'yajl'
11
- require 'json'
12
- require 'oj'
13
-
14
- iter = 1_000_000
15
- iter = 100_000
16
-
17
- json = %({"k1":"val1","k2":"val2","k3":"val3"})
18
- obj = { k1: "val1", k2: "val2", k3: "val3" }
19
-
20
- puts "Benchmarks for different JSON handlers with MultiJson."
21
- puts " Ruby #{RUBY_VERSION}"
22
- puts " #{iter} iterations"
23
-
24
- MultiJson.engine = :oj
25
- dt = Benchmark.realtime { iter.times { MultiJson.decode(json) }}
26
- et = Benchmark.realtime { iter.times { MultiJson.encode(obj) }}
27
- puts " Oj decode: #{dt} encode: #{et}"
28
-
29
- MultiJson.engine = :yajl
30
- dt = Benchmark.realtime { iter.times { MultiJson.decode(json) }}
31
- et = Benchmark.realtime { iter.times { MultiJson.encode(obj) }}
32
- puts " Yajl decode: #{dt} encode: #{et}"
33
-
34
- MultiJson.engine = :json_gem
35
- dt = Benchmark.realtime { iter.times { MultiJson.decode(json) }}
36
- et = Benchmark.realtime { iter.times { MultiJson.encode(obj) }}
37
- puts " Json decode: #{dt} encode: #{et}"
38
-
39
- Oj.default_options = { :mode => :compat, :time_format => :ruby }
40
- dt = Benchmark.realtime { iter.times { Oj.load(json) }}
41
- et = Benchmark.realtime { iter.times { Oj.dump(obj) }}
42
- puts "Raw Oj decode: #{dt} encode: #{et}"
43
-
44
- ye = Yajl::Encoder.new
45
- dt = Benchmark.realtime { iter.times { Yajl::Parser.parse(json) }}
46
- et = Benchmark.realtime { iter.times { Yajl::Encoder.encode(obj) }}
47
- e2 = Benchmark.realtime { iter.times { ye.encode(obj) }}
48
- puts "Raw Yajl decode: #{dt} encode: #{et}, encoder: #{e2}"
@@ -1,107 +0,0 @@
1
-
2
- class Perf
3
-
4
- def initialize()
5
- @items = []
6
- end
7
-
8
- def add(title, op, &blk)
9
- @items << Item.new(title, op, &blk)
10
- end
11
-
12
- def before(title, &blk)
13
- @items.each do |i|
14
- if title == i.title
15
- i.set_before(&blk)
16
- break
17
- end
18
- end
19
- end
20
-
21
- def run(iter)
22
- base = Item.new(nil, nil) { }
23
- base.run(iter, 0.0)
24
- @items.each do |i|
25
- i.run(iter, base.duration)
26
- if i.error.nil?
27
- puts "#{i.title}.#{i.op} #{iter} times in %0.3f seconds or %0.3f #{i.op}/sec." % [i.duration, iter / i.duration]
28
- else
29
- puts "***** #{i.title}.#{i.op} failed! #{i.error}"
30
- end
31
- end
32
- summary()
33
- end
34
-
35
- def summary()
36
- fastest = nil
37
- slowest = nil
38
- width = 6
39
- @items.each do |i|
40
- next if i.duration.nil?
41
- width = i.title.size if width < i.title.size
42
- end
43
- iva = @items.clone
44
- iva.delete_if { |i| i.duration.nil? }
45
- iva = iva.sort_by { |i| i.duration }
46
- puts
47
- puts "Summary:"
48
- puts "%*s time (secs) rate (ops/sec)" % [width, 'System']
49
- puts "#{'-' * width} ----------- --------------"
50
- iva.each do |i|
51
- if i.duration.nil?
52
- else
53
- puts "%*s %11.3f %14.3f" % [width, i.title, i.duration, i.rate ]
54
- end
55
- end
56
- puts
57
- puts "Comparison Matrix\n(performance factor, 2.0 means row is twice as fast as column)"
58
- puts ([' ' * width] + iva.map { |i| "%*s" % [width, i.title] }).join(' ')
59
- puts (['-' * width] + iva.map { |i| '-' * width }).join(' ')
60
- iva.each do |i|
61
- line = ["%*s" % [width, i.title]]
62
- iva.each do |o|
63
- line << "%*.2f" % [width, o.duration / i.duration]
64
- end
65
- puts line.join(' ')
66
- end
67
- puts
68
- end
69
-
70
- class Item
71
- attr_accessor :title
72
- attr_accessor :op
73
- attr_accessor :blk
74
- attr_accessor :duration
75
- attr_accessor :rate
76
- attr_accessor :error
77
-
78
- def initialize(title, op, &blk)
79
- @title = title
80
- @blk = blk
81
- @op = op
82
- @duration = nil
83
- @rate = nil
84
- @error = nil
85
- @before = nil
86
- end
87
-
88
- def set_before(&blk)
89
- @before = blk
90
- end
91
-
92
- def run(iter, base)
93
- begin
94
- GC.start
95
- @before.call unless @before.nil?
96
- start = Time.now
97
- iter.times { @blk.call }
98
- @duration = Time.now - start - base
99
- @duration = 0.0 if @duration < 0.0
100
- @rate = iter / @duration
101
- rescue Exception => e
102
- @error = "#{e.class}: #{e.message}"
103
- end
104
- end
105
-
106
- end # Item
107
- end # Perf