oj 3.9.1 → 3.16.11

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.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1452 -0
  3. data/README.md +21 -6
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +50 -68
  6. data/ext/oj/cache.c +329 -0
  7. data/ext/oj/cache.h +22 -0
  8. data/ext/oj/cache8.c +60 -62
  9. data/ext/oj/cache8.h +9 -36
  10. data/ext/oj/circarray.c +38 -42
  11. data/ext/oj/circarray.h +12 -13
  12. data/ext/oj/code.c +158 -179
  13. data/ext/oj/code.h +20 -22
  14. data/ext/oj/compat.c +145 -205
  15. data/ext/oj/custom.c +740 -880
  16. data/ext/oj/debug.c +126 -0
  17. data/ext/oj/dump.c +1145 -844
  18. data/ext/oj/dump.h +71 -57
  19. data/ext/oj/dump_compat.c +575 -655
  20. data/ext/oj/dump_leaf.c +96 -186
  21. data/ext/oj/dump_object.c +533 -660
  22. data/ext/oj/dump_strict.c +306 -340
  23. data/ext/oj/encode.h +4 -33
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +28 -28
  26. data/ext/oj/err.h +39 -42
  27. data/ext/oj/extconf.rb +28 -7
  28. data/ext/oj/fast.c +1052 -1113
  29. data/ext/oj/intern.c +313 -0
  30. data/ext/oj/intern.h +22 -0
  31. data/ext/oj/mem.c +318 -0
  32. data/ext/oj/mem.h +53 -0
  33. data/ext/oj/mimic_json.c +471 -430
  34. data/ext/oj/object.c +532 -580
  35. data/ext/oj/odd.c +156 -142
  36. data/ext/oj/odd.h +25 -26
  37. data/ext/oj/oj.c +1346 -961
  38. data/ext/oj/oj.h +307 -290
  39. data/ext/oj/parse.c +954 -858
  40. data/ext/oj/parse.h +74 -72
  41. data/ext/oj/parser.c +1600 -0
  42. data/ext/oj/parser.h +103 -0
  43. data/ext/oj/rails.c +819 -836
  44. data/ext/oj/rails.h +8 -11
  45. data/ext/oj/reader.c +136 -147
  46. data/ext/oj/reader.h +69 -83
  47. data/ext/oj/resolve.c +41 -63
  48. data/ext/oj/resolve.h +4 -6
  49. data/ext/oj/rxclass.c +69 -72
  50. data/ext/oj/rxclass.h +12 -13
  51. data/ext/oj/saj.c +440 -485
  52. data/ext/oj/saj2.c +584 -0
  53. data/ext/oj/saj2.h +23 -0
  54. data/ext/oj/scp.c +79 -118
  55. data/ext/oj/simd.h +10 -0
  56. data/ext/oj/sparse.c +739 -709
  57. data/ext/oj/stream_writer.c +141 -175
  58. data/ext/oj/strict.c +103 -128
  59. data/ext/oj/string_writer.c +244 -261
  60. data/ext/oj/trace.c +34 -41
  61. data/ext/oj/trace.h +42 -15
  62. data/ext/oj/usual.c +1218 -0
  63. data/ext/oj/usual.h +69 -0
  64. data/ext/oj/util.c +107 -107
  65. data/ext/oj/util.h +4 -3
  66. data/ext/oj/val_stack.c +61 -78
  67. data/ext/oj/val_stack.h +80 -114
  68. data/ext/oj/validate.c +46 -0
  69. data/ext/oj/wab.c +316 -361
  70. data/lib/oj/active_support_helper.rb +1 -3
  71. data/lib/oj/bag.rb +8 -1
  72. data/lib/oj/easy_hash.rb +9 -9
  73. data/lib/oj/error.rb +1 -2
  74. data/lib/oj/json.rb +162 -150
  75. data/lib/oj/mimic.rb +54 -20
  76. data/lib/oj/saj.rb +20 -6
  77. data/lib/oj/schandler.rb +5 -4
  78. data/lib/oj/state.rb +12 -8
  79. data/lib/oj/version.rb +1 -2
  80. data/lib/oj.rb +2 -8
  81. data/pages/Compatibility.md +1 -1
  82. data/pages/Encoding.md +1 -1
  83. data/pages/InstallOptions.md +20 -0
  84. data/pages/JsonGem.md +15 -0
  85. data/pages/Modes.md +9 -3
  86. data/pages/Options.md +62 -12
  87. data/pages/Parser.md +309 -0
  88. data/pages/Rails.md +73 -22
  89. metadata +68 -192
  90. data/ext/oj/hash.c +0 -163
  91. data/ext/oj/hash.h +0 -46
  92. data/ext/oj/hash_test.c +0 -512
  93. data/test/_test_active.rb +0 -76
  94. data/test/_test_active_mimic.rb +0 -96
  95. data/test/_test_mimic_rails.rb +0 -126
  96. data/test/activerecord/result_test.rb +0 -27
  97. data/test/activesupport4/decoding_test.rb +0 -108
  98. data/test/activesupport4/encoding_test.rb +0 -531
  99. data/test/activesupport4/test_helper.rb +0 -41
  100. data/test/activesupport5/decoding_test.rb +0 -125
  101. data/test/activesupport5/encoding_test.rb +0 -485
  102. data/test/activesupport5/encoding_test_cases.rb +0 -90
  103. data/test/activesupport5/test_helper.rb +0 -50
  104. data/test/activesupport5/time_zone_test_helpers.rb +0 -24
  105. data/test/bar.rb +0 -25
  106. data/test/files.rb +0 -29
  107. data/test/foo.rb +0 -21
  108. data/test/helper.rb +0 -26
  109. data/test/isolated/shared.rb +0 -308
  110. data/test/isolated/test_mimic_after.rb +0 -13
  111. data/test/isolated/test_mimic_alone.rb +0 -12
  112. data/test/isolated/test_mimic_as_json.rb +0 -45
  113. data/test/isolated/test_mimic_before.rb +0 -13
  114. data/test/isolated/test_mimic_define.rb +0 -28
  115. data/test/isolated/test_mimic_rails_after.rb +0 -22
  116. data/test/isolated/test_mimic_rails_before.rb +0 -21
  117. data/test/isolated/test_mimic_redefine.rb +0 -15
  118. data/test/json_gem/json_addition_test.rb +0 -216
  119. data/test/json_gem/json_common_interface_test.rb +0 -148
  120. data/test/json_gem/json_encoding_test.rb +0 -107
  121. data/test/json_gem/json_ext_parser_test.rb +0 -20
  122. data/test/json_gem/json_fixtures_test.rb +0 -35
  123. data/test/json_gem/json_generator_test.rb +0 -383
  124. data/test/json_gem/json_generic_object_test.rb +0 -90
  125. data/test/json_gem/json_parser_test.rb +0 -470
  126. data/test/json_gem/json_string_matching_test.rb +0 -42
  127. data/test/json_gem/test_helper.rb +0 -18
  128. data/test/perf.rb +0 -107
  129. data/test/perf_compat.rb +0 -130
  130. data/test/perf_fast.rb +0 -164
  131. data/test/perf_file.rb +0 -64
  132. data/test/perf_object.rb +0 -138
  133. data/test/perf_saj.rb +0 -109
  134. data/test/perf_scp.rb +0 -151
  135. data/test/perf_simple.rb +0 -287
  136. data/test/perf_strict.rb +0 -145
  137. data/test/perf_wab.rb +0 -131
  138. data/test/sample/change.rb +0 -14
  139. data/test/sample/dir.rb +0 -19
  140. data/test/sample/doc.rb +0 -36
  141. data/test/sample/file.rb +0 -48
  142. data/test/sample/group.rb +0 -16
  143. data/test/sample/hasprops.rb +0 -16
  144. data/test/sample/layer.rb +0 -12
  145. data/test/sample/line.rb +0 -20
  146. data/test/sample/oval.rb +0 -10
  147. data/test/sample/rect.rb +0 -10
  148. data/test/sample/shape.rb +0 -35
  149. data/test/sample/text.rb +0 -20
  150. data/test/sample.rb +0 -54
  151. data/test/sample_json.rb +0 -37
  152. data/test/test_compat.rb +0 -509
  153. data/test/test_custom.rb +0 -503
  154. data/test/test_debian.rb +0 -53
  155. data/test/test_fast.rb +0 -470
  156. data/test/test_file.rb +0 -239
  157. data/test/test_gc.rb +0 -49
  158. data/test/test_hash.rb +0 -29
  159. data/test/test_integer_range.rb +0 -73
  160. data/test/test_null.rb +0 -376
  161. data/test/test_object.rb +0 -1018
  162. data/test/test_saj.rb +0 -186
  163. data/test/test_scp.rb +0 -433
  164. data/test/test_strict.rb +0 -410
  165. data/test/test_various.rb +0 -741
  166. data/test/test_wab.rb +0 -307
  167. data/test/test_writer.rb +0 -380
  168. data/test/tests.rb +0 -24
  169. data/test/tests_mimic.rb +0 -14
  170. data/test/tests_mimic_addition.rb +0 -7
  171. data/test/zoo.rb +0 -13
@@ -1,16 +1,14 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  require 'active_support/time'
3
4
 
4
5
  module Oj
5
-
6
6
  # Exists only to handle the ActiveSupport::TimeWithZone.
7
7
  class ActiveSupportHelper
8
-
9
8
  def self.createTimeWithZone(utc, zone)
10
9
  ActiveSupport::TimeWithZone.new(utc - utc.gmt_offset, ActiveSupport::TimeZone[zone])
11
10
  end
12
11
  end
13
-
14
12
  end
15
13
 
16
14
  Oj.register_odd(ActiveSupport::TimeWithZone, Oj::ActiveSupportHelper, :createTimeWithZone, :utc, 'time_zone.name')
data/lib/oj/bag.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module Oj
3
4
 
@@ -14,7 +15,7 @@ module Oj
14
15
  # @example Oj::Bag.new(:@x => 42, :@y => 57)
15
16
  # @param [Hash] args instance variable symbols and their values
16
17
  def initialize(args = {})
17
- args.each do |k,v|
18
+ args.each do |k, v|
18
19
  self.instance_variable_set(k, v)
19
20
  end
20
21
  end
@@ -25,6 +26,7 @@ module Oj
25
26
  # variable reader, otherwise false.
26
27
  def respond_to?(m)
27
28
  return true if super
29
+
28
30
  instance_variables.include?(:"@#{m}")
29
31
  end
30
32
 
@@ -36,8 +38,10 @@ module Oj
36
38
  # @raise [NoMethodError] if the instance variable is not defined.
37
39
  def method_missing(m, *args, &block)
38
40
  raise ArgumentError.new("wrong number of arguments (#{args.size} for 0) to method #{m}") unless args.nil? or args.empty?
41
+
39
42
  at_m = :"@#{m}"
40
43
  raise NoMethodError.new("undefined method #{m}", m) unless instance_variable_defined?(at_m)
44
+
41
45
  instance_variable_get(at_m)
42
46
  end
43
47
 
@@ -46,9 +50,11 @@ module Oj
46
50
  # @return [Boolean] true if each variable and value are the same, otherwise false.
47
51
  def eql?(other)
48
52
  return false if (other.nil? or self.class != other.class)
53
+
49
54
  ova = other.instance_variables
50
55
  iv = instance_variables
51
56
  return false if ova.size != iv.size
57
+
52
58
  iv.all? { |vid| instance_variable_get(vid) != other.instance_variable_get(vid) }
53
59
  end
54
60
  alias == eql?
@@ -64,6 +70,7 @@ module Oj
64
70
  classname = classname.to_s unless classname.is_a?(String)
65
71
  tokens = classname.split('::').map(&:to_sym)
66
72
  raise NameError.new("Invalid classname '#{classname}") if tokens.empty?
73
+
67
74
  m = Object
68
75
  tokens[0..-2].each do |sym|
69
76
  if m.const_defined?(sym)
data/lib/oj/easy_hash.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  module Oj
3
2
 
4
3
  # A Hash subclass that normalizes the hash keys to allow lookup by the
@@ -6,24 +5,23 @@ module Oj
6
5
  # that match the keys.
7
6
  class EasyHash < Hash
8
7
 
9
- # Initializes the instance to an empty Hash.
10
- def initialize()
11
- end
12
-
13
8
  # Replaces the Object.respond_to?() method.
14
9
  # @param [Symbol] m method symbol
10
+ # @param [Boolean] include_all whether to include private and protected methods in the search
15
11
  # @return [Boolean] true for any method that matches an instance
16
12
  # variable reader, otherwise false.
17
- def respond_to?(m)
13
+ def respond_to?(m, include_all = false)
18
14
  return true if super
19
- return true if has_key?(key)
20
- return true if has_key?(key.to_s)
21
- has_key?(key.to_sym)
15
+ return true if has_key?(m)
16
+ return true if has_key?(m.to_s)
17
+
18
+ has_key?(m.to_sym)
22
19
  end
23
20
 
24
21
  def [](key)
25
22
  return fetch(key, nil) if has_key?(key)
26
23
  return fetch(key.to_s, nil) if has_key?(key.to_s)
24
+
27
25
  fetch(key.to_sym, nil)
28
26
  end
29
27
 
@@ -35,9 +33,11 @@ module Oj
35
33
  def method_missing(m, *args, &block)
36
34
  if m.to_s.end_with?('=')
37
35
  raise ArgumentError.new("wrong number of arguments (#{args.size} for 1 with #{m}) to method #{m}") if args.nil? or 1 != args.length
36
+
38
37
  m = m[0..-2]
39
38
  return store(m.to_s, args[0]) if has_key?(m.to_s)
40
39
  return store(m.to_sym, args[0]) if has_key?(m.to_sym)
40
+
41
41
  return store(m, args[0])
42
42
  else
43
43
  raise ArgumentError.new("wrong number of arguments (#{args.size} for 0 with #{m}) to method #{m}") unless args.nil? or args.empty?
data/lib/oj/error.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  module Oj
3
2
 
4
3
  # Inherit Error class from StandardError.
@@ -16,7 +15,7 @@ module Oj
16
15
  # An Exception that is raised if a file fails to load.
17
16
  LoadError = Class.new(Error)
18
17
 
19
- # An Exception that is raised if there is a conflict with mimicing JSON
18
+ # An Exception that is raised if there is a conflict with mimicking JSON
20
19
  MimicError = Class.new(Error)
21
20
 
22
21
  end # Oj
data/lib/oj/json.rb CHANGED
@@ -1,176 +1,188 @@
1
-
2
1
  require 'ostruct'
3
2
  require 'oj/state'
4
3
 
5
- module JSON
6
- NaN = 0.0/0.0 unless defined?(::JSON::NaN)
7
- Infinity = 1.0/0.0 unless defined?(::JSON::Infinity)
8
- MinusInfinity = -1.0/0.0 unless defined?(::JSON::MinusInfinity)
9
- # Taken from the unit test. Note that items like check_circular? are not
10
- # present.
11
- PRETTY_STATE_PROTOTYPE = Ext::Generator::State.from_state({
12
- :allow_nan => false,
13
- :array_nl => "\n",
14
- :ascii_only => false,
15
- :buffer_initial_length => 1024,
16
- :depth => 0,
17
- :indent => " ",
18
- :max_nesting => 100,
19
- :object_nl => "\n",
20
- :space => " ",
21
- :space_before => "",
22
- }) unless defined?(::JSON::PRETTY_STATE_PROTOTYPE)
23
- SAFE_STATE_PROTOTYPE = Ext::Generator::State.from_state({
24
- :allow_nan => false,
25
- :array_nl => "",
26
- :ascii_only => false,
27
- :buffer_initial_length => 1024,
28
- :depth => 0,
29
- :indent => "",
30
- :max_nesting => 100,
31
- :object_nl => "",
32
- :space => "",
33
- :space_before => "",
34
- }) unless defined?(::JSON::SAFE_STATE_PROTOTYPE)
35
- FAST_STATE_PROTOTYPE = Ext::Generator::State.from_state({
36
- :allow_nan => false,
37
- :array_nl => "",
38
- :ascii_only => false,
39
- :buffer_initial_length => 1024,
40
- :depth => 0,
41
- :indent => "",
42
- :max_nesting => 0,
43
- :object_nl => "",
44
- :space => "",
45
- :space_before => "",
46
- }) unless defined?(::JSON::FAST_STATE_PROTOTYPE)
47
-
48
- def self.dump_default_options
49
- Oj::MimicDumpOption.new
50
- end
51
-
52
- def self.dump_default_options=(h)
53
- m = Oj::MimicDumpOption.new
54
- h.each do |k,v|
55
- m[k] = v
4
+ if defined?(JSON::PRETTY_STATE_PROTOTYPE)
5
+ # There are enough people that try to use both the json gen and oj in mimic
6
+ # mode so don't display the warning.
7
+
8
+ # warn "WARNING: oj/json is a compatability shim used by Oj. Requiring the file explicitly is not recommended."
9
+ end
10
+
11
+ unless defined?(JSON::PRETTY_STATE_PROTOTYPE)
12
+ module JSON
13
+ NaN = 0.0/0.0 unless defined?(::JSON::NaN)
14
+ Infinity = 1.0/0.0 unless defined?(::JSON::Infinity)
15
+ MinusInfinity = -1.0/0.0 unless defined?(::JSON::MinusInfinity)
16
+ # Taken from the unit test. Note that items like check_circular? are not
17
+ # present.
18
+ PRETTY_STATE_PROTOTYPE = Ext::Generator::State.from_state({
19
+ :allow_nan => false,
20
+ :array_nl => "\n",
21
+ :ascii_only => false,
22
+ :buffer_initial_length => 1024,
23
+ :depth => 0,
24
+ :indent => " ",
25
+ :max_nesting => 100,
26
+ :object_nl => "\n",
27
+ :space => " ",
28
+ :space_before => "",
29
+ }) unless defined?(::JSON::PRETTY_STATE_PROTOTYPE)
30
+ SAFE_STATE_PROTOTYPE = Ext::Generator::State.from_state({
31
+ :allow_nan => false,
32
+ :array_nl => "",
33
+ :ascii_only => false,
34
+ :buffer_initial_length => 1024,
35
+ :depth => 0,
36
+ :indent => "",
37
+ :max_nesting => 100,
38
+ :object_nl => "",
39
+ :space => "",
40
+ :space_before => "",
41
+ }) unless defined?(::JSON::SAFE_STATE_PROTOTYPE)
42
+ FAST_STATE_PROTOTYPE = Ext::Generator::State.from_state({
43
+ :allow_nan => false,
44
+ :array_nl => "",
45
+ :ascii_only => false,
46
+ :buffer_initial_length => 1024,
47
+ :depth => 0,
48
+ :indent => "",
49
+ :max_nesting => 0,
50
+ :object_nl => "",
51
+ :space => "",
52
+ :space_before => "",
53
+ }) unless defined?(::JSON::FAST_STATE_PROTOTYPE)
54
+
55
+ def self.dump_default_options
56
+ Oj::MimicDumpOption.new
56
57
  end
57
- end
58
58
 
59
- def self.parser=(p)
60
- @@parser = p
61
- end
59
+ def self.dump_default_options=(h)
60
+ m = Oj::MimicDumpOption.new
61
+ h.each do |k, v|
62
+ m[k] = v
63
+ end
64
+ end
62
65
 
63
- def self.parser()
64
- @@parser
65
- end
66
+ def self.parser=(p)
67
+ @@parser = p
68
+ end
66
69
 
67
- def self.generator=(g)
68
- @@generator = g
69
- end
70
+ def self.parser()
71
+ @@parser
72
+ end
70
73
 
71
- def self.generator()
72
- @@generator
73
- end
74
+ def self.generator=(g)
75
+ @@generator = g
76
+ end
74
77
 
75
- module Ext
76
- class Parser
77
- def initialize(src)
78
- raise TypeError.new("already initialized") unless @source.nil?
79
- @source = src
80
- end
78
+ def self.generator()
79
+ @@generator
80
+ end
81
81
 
82
- def source()
83
- raise TypeError.new("already initialized") if @source.nil?
84
- @source
85
- end
86
-
87
- def parse()
88
- raise TypeError.new("already initialized") if @source.nil?
89
- JSON.parse(@source)
90
- end
91
-
92
- end # Parser
93
- end # Ext
94
-
95
- State = ::JSON::Ext::Generator::State unless defined?(::JSON::State)
96
-
97
- begin
98
- send(:remove_const, :Parser)
99
- rescue
100
- end
101
- Parser = ::JSON::Ext::Parser unless defined?(::JSON::Parser)
102
- self.parser = ::JSON::Ext::Parser
103
- self.generator = ::JSON::Ext::Generator
104
-
105
- # Taken directly from the json gem. Shamelessly copied. It is similar in
106
- # some ways to the Oj::Bag class or the Oj::EasyHash class.
107
- class GenericObject < OpenStruct
108
- class << self
109
- alias [] new
110
-
111
- def json_creatable?
112
- @json_creatable
113
- end
82
+ module Ext
83
+ class Parser
84
+ def initialize(src)
85
+ raise TypeError.new("already initialized") unless @source.nil?
114
86
 
115
- attr_writer :json_creatable
87
+ @source = src
88
+ end
116
89
 
117
- def json_create(data)
118
- data = data.dup
119
- data.delete JSON.create_id
120
- self[data]
121
- end
90
+ def source()
91
+ raise TypeError.new("already initialized") if @source.nil?
122
92
 
123
- def from_hash(object)
124
- case
125
- when object.respond_to?(:to_hash)
126
- result = new
127
- object.to_hash.each do |key, value|
128
- result[key] = from_hash(value)
129
- end
130
- result
131
- when object.respond_to?(:to_ary)
132
- object.to_ary.map { |a| from_hash(a) }
133
- else
134
- object
93
+ @source
135
94
  end
136
- end
137
95
 
138
- def load(source, proc = nil, opts = {})
139
- result = ::JSON.load(source, proc, opts.merge(:object_class => self))
140
- result.nil? ? new : result
141
- end
96
+ def parse()
97
+ raise TypeError.new("already initialized") if @source.nil?
142
98
 
143
- def dump(obj, *args)
144
- ::JSON.dump(obj, *args)
145
- end
99
+ JSON.parse(@source)
100
+ end
146
101
 
147
- end # self
102
+ end # Parser
103
+ end # Ext
148
104
 
149
- self.json_creatable = false
105
+ State = ::JSON::Ext::Generator::State unless defined?(::JSON::State)
150
106
 
151
- def to_hash
152
- table
107
+ begin
108
+ send(:remove_const, :Parser)
109
+ rescue
110
+ # ignore and move on
153
111
  end
112
+ Parser = ::JSON::Ext::Parser unless defined?(::JSON::Parser)
113
+ self.parser = ::JSON::Ext::Parser
114
+ self.generator = ::JSON::Ext::Generator
115
+
116
+ # Taken directly from the json gem. Shamelessly copied. It is similar in
117
+ # some ways to the Oj::Bag class or the Oj::EasyHash class.
118
+ class GenericObject < OpenStruct
119
+ class << self
120
+ alias [] new
121
+
122
+ def json_creatable?
123
+ @json_creatable
124
+ end
154
125
 
155
- def [](name)
156
- __send__(name)
157
- end unless method_defined?(:[])
126
+ attr_writer :json_creatable
158
127
 
159
- def []=(name, value)
160
- __send__("#{name}=", value)
161
- end unless method_defined?(:[]=)
128
+ def json_create(data)
129
+ data = data.dup
130
+ data.delete JSON.create_id
131
+ self[data]
132
+ end
162
133
 
163
- def |(other)
164
- self.class[other.to_hash.merge(to_hash)]
165
- end
134
+ def from_hash(object)
135
+ case
136
+ when object.respond_to?(:to_hash)
137
+ result = new
138
+ object.to_hash.each do |key, value|
139
+ result[key] = from_hash(value)
140
+ end
141
+ result
142
+ when object.respond_to?(:to_ary)
143
+ object.to_ary.map { |a| from_hash(a) }
144
+ else
145
+ object
146
+ end
147
+ end
166
148
 
167
- def as_json(*)
168
- { JSON.create_id => self.class.name }.merge to_hash
169
- end
149
+ def load(source, proc = nil, opts = {})
150
+ result = ::JSON.load(source, proc, opts.merge(:object_class => self))
151
+ result.nil? ? new : result
152
+ end
170
153
 
171
- def to_json(*a)
172
- as_json.to_json(*a)
154
+ def dump(obj, *args)
155
+ ::JSON.dump(obj, *args)
156
+ end
157
+
158
+ end # self
159
+
160
+ self.json_creatable = false
161
+
162
+ def to_hash
163
+ table
164
+ end
165
+
166
+ def [](name)
167
+ __send__(name)
168
+ end unless method_defined?(:[])
169
+
170
+ def []=(name, value)
171
+ __send__("#{name}=", value)
172
+ end unless method_defined?(:[]=)
173
+
174
+ def |(other)
175
+ self.class[other.to_hash.merge(to_hash)]
176
+ end
177
+
178
+ def as_json(*)
179
+ { JSON.create_id => self.class.name }.merge to_hash
180
+ end
181
+
182
+ def to_json(*a)
183
+ as_json.to_json(*a)
184
+ end
173
185
  end
174
- end
175
-
176
- end # JSON
186
+
187
+ end # JSON
188
+ end
data/lib/oj/mimic.rb CHANGED
@@ -1,13 +1,56 @@
1
+ # frozen_string_literal: false
1
2
 
2
3
  require 'bigdecimal'
3
- begin
4
- require 'ostruct'
5
- rescue Exception
6
- # ignore
7
- end
4
+ require 'ostruct'
8
5
 
9
6
  module Oj
10
7
 
8
+ ##
9
+ # Custom mode can be used to emulate the compat mode with some minor
10
+ # differences. These are the options that setup the custom mode to be like
11
+ # the compat mode.
12
+ CUSTOM_MIMIC_JSON_OPTIONS = {
13
+ allow_gc: true,
14
+ allow_invalid_unicode: false,
15
+ allow_nan: false,
16
+ array_class: nil,
17
+ array_nl: nil,
18
+ auto_define: false,
19
+ bigdecimal_as_decimal: false,
20
+ bigdecimal_load: :auto,
21
+ circular: false,
22
+ class_cache: false,
23
+ cache_keys: true,
24
+ cache_str: 5,
25
+ create_additions: false,
26
+ create_id: "json_class",
27
+ empty_string: false,
28
+ escape_mode: :unicode_xss,
29
+ float_precision: 0,
30
+ hash_class: nil,
31
+ ignore: nil,
32
+ ignore_under: false,
33
+ indent: 0,
34
+ integer_range: nil,
35
+ mode: :custom,
36
+ nan: :raise,
37
+ nilnil: false,
38
+ object_nl: nil,
39
+ omit_nil: false,
40
+ quirks_mode: true,
41
+ safe: false,
42
+ second_precision: 3,
43
+ space: nil,
44
+ space_before: nil,
45
+ symbol_keys: false,
46
+ time_format: :ruby,
47
+ trace: false,
48
+ use_as_json: false,
49
+ use_raw_json: false,
50
+ use_to_hash: false,
51
+ use_to_json: true,
52
+ }
53
+
11
54
  # A bit hack-ish but does the trick. The JSON.dump_default_options is a Hash
12
55
  # but in mimic we use a C struct to store defaults. This class creates a view
13
56
  # onto that struct.
@@ -18,6 +61,8 @@ module Oj
18
61
  self.store(:allow_nan, true)
19
62
  self.store(:quirks_mode, oo[:quirks_mode])
20
63
  self.store(:ascii_only, (:ascii == oo[:escape_mode]))
64
+
65
+ super
21
66
  end
22
67
 
23
68
  def []=(key, value)
@@ -38,7 +83,7 @@ module Oj
38
83
 
39
84
  jfile = File.join(d, 'json.rb')
40
85
  $LOADED_FEATURES << jfile unless $LOADED_FEATURES.include?(jfile) if File.exist?(jfile)
41
-
86
+
42
87
  Dir.glob(File.join(d, 'json', '**', '*.rb')).each do |file|
43
88
  # allow json/add/xxx to be loaded. User can override with Oj.add_to_json(xxx).
44
89
  $LOADED_FEATURES << file unless $LOADED_FEATURES.include?(file) unless file.include?('add')
@@ -56,6 +101,7 @@ module Oj
56
101
  def as_json(*)
57
102
  name = self.class.name.to_s
58
103
  raise JSON::JSONError, "Only named structs are supported!" if 0 == name.length
104
+
59
105
  { JSON.create_id => name, 't' => table }
60
106
  end
61
107
  end
@@ -89,18 +135,6 @@ module Oj
89
135
  end
90
136
  end
91
137
 
92
- Date.class_eval do
93
- # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
94
- unless defined?(self.as_json)
95
- def as_json(*)
96
- { JSON.create_id => 'Date', 'y' => year, 'm' => month, 'd' => day, 'sg' => start }
97
- end
98
- end
99
- def self.json_create(h)
100
- civil(h['y'], h['m'], h['d'], h['sg'])
101
- end
102
- end
103
-
104
138
  DateTime.class_eval do
105
139
  # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
106
140
  unless defined?(self.as_json)
@@ -198,6 +232,7 @@ module Oj
198
232
  def as_json(*)
199
233
  name = self.class.name.to_s
200
234
  raise JSON::JSONError, "Only named structs are supported!" if 0 == name.length
235
+
201
236
  { JSON.create_id => name, 'v' => values }
202
237
  end
203
238
  end
@@ -229,7 +264,7 @@ module Oj
229
264
  end
230
265
  end
231
266
  def self.json_create(h)
232
- if usec = h.delete('u')
267
+ if (usec = h.delete('u'))
233
268
  h['n'] = usec * 1000
234
269
  end
235
270
  if instance_methods.include?(:tv_nsec)
@@ -239,7 +274,6 @@ module Oj
239
274
  end
240
275
  end
241
276
  end
242
-
243
277
  end # self.mimic_loaded
244
278
 
245
279
  end # Oj
data/lib/oj/saj.rb CHANGED
@@ -1,11 +1,17 @@
1
1
  module Oj
2
- # A SAX style parse handler for JSON hence the acronym SAJ for Simple API for
3
- # JSON. The Oj::Saj handler class should be subclassed and then used with the
4
- # Oj::Saj key_parse() method. The Saj methods will then be called as the file
5
- # is parsed.
2
+ # A SAX style parse handler for JSON hence the acronym SAJ for Simple API
3
+ # for JSON. The Oj::Saj handler class can be subclassed and then used with
4
+ # the Oj::Saj key_parse() method or with the more resent
5
+ # Oj::Parser.new(:saj). The Saj methods will then be called as the file is
6
+ # parsed.
7
+ #
8
+ # With Oj::Parser.new(:saj) each method can also include a line and column
9
+ # argument so hash_start(key) could also be hash_start(key, line,
10
+ # column). The error() method is no used with Oj::Parser.new(:saj) so it
11
+ # will never be called.
6
12
  #
7
13
  # @example
8
- #
14
+ #
9
15
  # require 'oj'
10
16
  #
11
17
  # class MySaj < ::Oj::Saj
@@ -23,6 +29,14 @@ module Oj
23
29
  # Oj.saj_parse(cnt, f)
24
30
  # end
25
31
  #
32
+ # or
33
+ #
34
+ # p = Oj::Parser.new(:saj)
35
+ # p.handler = MySaj.new()
36
+ # File.open('any.json', 'r') do |f|
37
+ # p.parse(f.read)
38
+ # end
39
+ #
26
40
  # To make the desired methods active while parsing the desired method should
27
41
  # be made public in the subclasses. If the methods remain private they will
28
42
  # not be called during parsing.
@@ -61,6 +75,6 @@ module Oj
61
75
 
62
76
  def error(message, line, column)
63
77
  end
64
-
78
+
65
79
  end # Saj
66
80
  end # Oj
data/lib/oj/schandler.rb CHANGED
@@ -64,13 +64,14 @@ module Oj
64
64
  #
65
65
  # hash_end
66
66
  #
67
- # When a hash key is encountered the hash_key method is called with the parsed
68
- # hash value key. The return value from the call is then used as the key in
69
- # the key-value pair that follows.
67
+ # At the end of a JSON object element the hash_end() callback is called if
68
+ # public.
70
69
  #
71
70
  # hash_key
72
71
  #
73
- # At the end of a JSON object element the hash_end() callback is called if public.
72
+ # When a hash key is encountered the hash_key() method is called with the
73
+ # parsed hash value key. The return value from the call is then used as the
74
+ # key in the key-value pair that follows.
74
75
  #
75
76
  # hash_set
76
77
  #