nano-safe-gem 0.0.1

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 (97) hide show
  1. checksums.yaml +7 -0
  2. data/nano-safe-gem.gemspec +12 -0
  3. data/oj-3.17.3/CHANGELOG.md +1506 -0
  4. data/oj-3.17.3/LICENSE +21 -0
  5. data/oj-3.17.3/README.md +103 -0
  6. data/oj-3.17.3/RELEASE_NOTES.md +61 -0
  7. data/oj-3.17.3/ext/oj/buf.h +85 -0
  8. data/oj-3.17.3/ext/oj/cache.c +329 -0
  9. data/oj-3.17.3/ext/oj/cache.h +22 -0
  10. data/oj-3.17.3/ext/oj/cache8.c +105 -0
  11. data/oj-3.17.3/ext/oj/cache8.h +21 -0
  12. data/oj-3.17.3/ext/oj/circarray.c +64 -0
  13. data/oj-3.17.3/ext/oj/circarray.h +22 -0
  14. data/oj-3.17.3/ext/oj/code.c +214 -0
  15. data/oj-3.17.3/ext/oj/code.h +40 -0
  16. data/oj-3.17.3/ext/oj/compat.c +239 -0
  17. data/oj-3.17.3/ext/oj/custom.c +1079 -0
  18. data/oj-3.17.3/ext/oj/debug.c +126 -0
  19. data/oj-3.17.3/ext/oj/dump.c +1765 -0
  20. data/oj-3.17.3/ext/oj/dump.h +112 -0
  21. data/oj-3.17.3/ext/oj/dump_compat.c +902 -0
  22. data/oj-3.17.3/ext/oj/dump_leaf.c +162 -0
  23. data/oj-3.17.3/ext/oj/dump_object.c +715 -0
  24. data/oj-3.17.3/ext/oj/dump_strict.c +404 -0
  25. data/oj-3.17.3/ext/oj/encode.h +16 -0
  26. data/oj-3.17.3/ext/oj/encoder.c +43 -0
  27. data/oj-3.17.3/ext/oj/err.c +57 -0
  28. data/oj-3.17.3/ext/oj/err.h +67 -0
  29. data/oj-3.17.3/ext/oj/extconf.rb +72 -0
  30. data/oj-3.17.3/ext/oj/fast.c +1730 -0
  31. data/oj-3.17.3/ext/oj/intern.c +313 -0
  32. data/oj-3.17.3/ext/oj/intern.h +22 -0
  33. data/oj-3.17.3/ext/oj/mem.c +318 -0
  34. data/oj-3.17.3/ext/oj/mem.h +53 -0
  35. data/oj-3.17.3/ext/oj/mimic_json.c +922 -0
  36. data/oj-3.17.3/ext/oj/object.c +726 -0
  37. data/oj-3.17.3/ext/oj/odd.c +245 -0
  38. data/oj-3.17.3/ext/oj/odd.h +43 -0
  39. data/oj-3.17.3/ext/oj/oj.c +2332 -0
  40. data/oj-3.17.3/ext/oj/oj.h +405 -0
  41. data/oj-3.17.3/ext/oj/parse.c +1367 -0
  42. data/oj-3.17.3/ext/oj/parse.h +113 -0
  43. data/oj-3.17.3/ext/oj/parser.c +1676 -0
  44. data/oj-3.17.3/ext/oj/parser.h +103 -0
  45. data/oj-3.17.3/ext/oj/rails.c +1480 -0
  46. data/oj-3.17.3/ext/oj/rails.h +18 -0
  47. data/oj-3.17.3/ext/oj/reader.c +220 -0
  48. data/oj-3.17.3/ext/oj/reader.h +137 -0
  49. data/oj-3.17.3/ext/oj/resolve.c +80 -0
  50. data/oj-3.17.3/ext/oj/resolve.h +12 -0
  51. data/oj-3.17.3/ext/oj/rxclass.c +144 -0
  52. data/oj-3.17.3/ext/oj/rxclass.h +26 -0
  53. data/oj-3.17.3/ext/oj/safe.c +230 -0
  54. data/oj-3.17.3/ext/oj/safe.h +79 -0
  55. data/oj-3.17.3/ext/oj/saj.c +677 -0
  56. data/oj-3.17.3/ext/oj/saj2.c +584 -0
  57. data/oj-3.17.3/ext/oj/saj2.h +23 -0
  58. data/oj-3.17.3/ext/oj/scp.c +185 -0
  59. data/oj-3.17.3/ext/oj/simd.h +219 -0
  60. data/oj-3.17.3/ext/oj/sparse.c +943 -0
  61. data/oj-3.17.3/ext/oj/stream_writer.c +329 -0
  62. data/oj-3.17.3/ext/oj/strict.c +187 -0
  63. data/oj-3.17.3/ext/oj/string_writer.c +517 -0
  64. data/oj-3.17.3/ext/oj/trace.c +72 -0
  65. data/oj-3.17.3/ext/oj/trace.h +55 -0
  66. data/oj-3.17.3/ext/oj/usual.c +1231 -0
  67. data/oj-3.17.3/ext/oj/usual.h +69 -0
  68. data/oj-3.17.3/ext/oj/util.c +136 -0
  69. data/oj-3.17.3/ext/oj/util.h +20 -0
  70. data/oj-3.17.3/ext/oj/val_stack.c +101 -0
  71. data/oj-3.17.3/ext/oj/val_stack.h +151 -0
  72. data/oj-3.17.3/ext/oj/validate.c +46 -0
  73. data/oj-3.17.3/ext/oj/wab.c +586 -0
  74. data/oj-3.17.3/lib/oj/active_support_helper.rb +39 -0
  75. data/oj-3.17.3/lib/oj/bag.rb +95 -0
  76. data/oj-3.17.3/lib/oj/easy_hash.rb +52 -0
  77. data/oj-3.17.3/lib/oj/error.rb +21 -0
  78. data/oj-3.17.3/lib/oj/json.rb +188 -0
  79. data/oj-3.17.3/lib/oj/mimic.rb +301 -0
  80. data/oj-3.17.3/lib/oj/saj.rb +80 -0
  81. data/oj-3.17.3/lib/oj/schandler.rb +143 -0
  82. data/oj-3.17.3/lib/oj/state.rb +135 -0
  83. data/oj-3.17.3/lib/oj/version.rb +4 -0
  84. data/oj-3.17.3/lib/oj.rb +15 -0
  85. data/oj-3.17.3/pages/Advanced.md +22 -0
  86. data/oj-3.17.3/pages/Compatibility.md +25 -0
  87. data/oj-3.17.3/pages/Custom.md +23 -0
  88. data/oj-3.17.3/pages/Encoding.md +65 -0
  89. data/oj-3.17.3/pages/InstallOptions.md +20 -0
  90. data/oj-3.17.3/pages/JsonGem.md +94 -0
  91. data/oj-3.17.3/pages/Modes.md +161 -0
  92. data/oj-3.17.3/pages/Options.md +337 -0
  93. data/oj-3.17.3/pages/Parser.md +309 -0
  94. data/oj-3.17.3/pages/Rails.md +167 -0
  95. data/oj-3.17.3/pages/Security.md +20 -0
  96. data/oj-3.17.3/pages/WAB.md +13 -0
  97. metadata +136 -0
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oj
4
+
5
+ # A generic class that is used only for storing attributes. It is the base
6
+ # Class for auto-generated classes in the storage system. Instance variables
7
+ # are added using the instance_variable_set() method. All instance variables
8
+ # can be accessed using the variable name (without the @ prefix). No setters
9
+ # are provided as the Class is intended for reading only.
10
+ class Bag
11
+
12
+ # The initializer can take multiple arguments in the form of key values
13
+ # where the key is the variable name and the value is the variable
14
+ # value. This is intended for testing purposes only.
15
+ # @example Oj::Bag.new(:@x => 42, :@y => 57)
16
+ # @param [Hash] args instance variable symbols and their values
17
+ def initialize(args = {})
18
+ args.each do |k, v|
19
+ self.instance_variable_set(k, v)
20
+ end
21
+ end
22
+
23
+ # Replaces the Object.respond_to?() method.
24
+ # @param [Symbol] m method symbol
25
+ # @return [Boolean] true for any method that matches an instance
26
+ # variable reader, otherwise false.
27
+ def respond_to?(m)
28
+ return true if super
29
+
30
+ instance_variables.include?(:"@#{m}")
31
+ end
32
+
33
+ # Handles requests for variable values. Others cause an Exception to be
34
+ # raised.
35
+ # @param [Symbol] m method symbol
36
+ # @return [Boolean] the value of the specified instance variable.
37
+ # @raise [ArgumentError] if an argument is given. Zero arguments expected.
38
+ # @raise [NoMethodError] if the instance variable is not defined.
39
+ def method_missing(m, *args, &block)
40
+ raise ArgumentError.new("wrong number of arguments (#{args.size} for 0) to method #{m}") unless args.nil? or args.empty?
41
+
42
+ at_m = :"@#{m}"
43
+ raise NoMethodError.new("undefined method #{m}", m) unless instance_variable_defined?(at_m)
44
+
45
+ instance_variable_get(at_m)
46
+ end
47
+
48
+ # Replaces eql?() with something more reasonable for this Class.
49
+ # @param [Object] other Object to compare self to
50
+ # @return [Boolean] true if each variable and value are the same, otherwise false.
51
+ def eql?(other)
52
+ return false if (other.nil? or self.class != other.class)
53
+
54
+ ova = other.instance_variables
55
+ iv = instance_variables
56
+ return false if ova.size != iv.size
57
+
58
+ iv.all? { |vid| instance_variable_get(vid) != other.instance_variable_get(vid) }
59
+ end
60
+ alias == eql?
61
+
62
+ # Define a new class based on the Oj::Bag class. This is used internally in
63
+ # the Oj module and is available to service wrappers that receive XML
64
+ # requests that include Objects of Classes not defined in the storage
65
+ # process.
66
+ # @param [String] classname Class name or symbol that includes Module names.
67
+ # @return [Object] an instance of the specified Class.
68
+ # @raise [NameError] if the classname is invalid.
69
+ def self.define_class(classname)
70
+ classname = classname.to_s unless classname.is_a?(String)
71
+ tokens = classname.split('::').map(&:to_sym)
72
+ raise NameError.new("Invalid classname '#{classname}") if tokens.empty?
73
+
74
+ m = Object
75
+ tokens[0..-2].each do |sym|
76
+ if m.const_defined?(sym)
77
+ m = m.const_get(sym)
78
+ else
79
+ c = Module.new
80
+ m.const_set(sym, c)
81
+ m = c
82
+ end
83
+ end
84
+ sym = tokens[-1]
85
+ if m.const_defined?(sym)
86
+ c = m.const_get(sym)
87
+ else
88
+ c = Class.new(Oj::Bag)
89
+ m.const_set(sym, c)
90
+ end
91
+ c
92
+ end
93
+
94
+ end # Bag
95
+ end # Oj
@@ -0,0 +1,52 @@
1
+ module Oj
2
+
3
+ # A Hash subclass that normalizes the hash keys to allow lookup by the
4
+ # key.to_s or key.to_sym. It also supports looking up hash values by methods
5
+ # that match the keys.
6
+ class EasyHash < Hash
7
+
8
+ # Replaces the Object.respond_to?() method.
9
+ # @param [Symbol] m method symbol
10
+ # @param [Boolean] include_all whether to include private and protected methods in the search
11
+ # @return [Boolean] true for any method that matches an instance
12
+ # variable reader, otherwise false.
13
+ def respond_to?(m, include_all = false)
14
+ return true if super
15
+ return true if has_key?(m)
16
+ return true if has_key?(m.to_s)
17
+
18
+ has_key?(m.to_sym)
19
+ end
20
+
21
+ def [](key)
22
+ return fetch(key, nil) if has_key?(key)
23
+ return fetch(key.to_s, nil) if has_key?(key.to_s)
24
+
25
+ fetch(key.to_sym, nil)
26
+ end
27
+
28
+ # Handles requests for Hash values. Others cause an Exception to be raised.
29
+ # @param [Symbol|String] m method symbol
30
+ # @return [Boolean] the value of the specified instance variable.
31
+ # @raise [ArgumentError] if an argument is given. Zero arguments expected.
32
+ # @raise [NoMethodError] if the instance variable is not defined.
33
+ def method_missing(m, *args, &block)
34
+ if m.to_s.end_with?('=')
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
+
37
+ m = m[0..-2]
38
+ return store(m.to_s, args[0]) if has_key?(m.to_s)
39
+ return store(m.to_sym, args[0]) if has_key?(m.to_sym)
40
+
41
+ return store(m, args[0])
42
+ else
43
+ raise ArgumentError.new("wrong number of arguments (#{args.size} for 0 with #{m}) to method #{m}") unless args.nil? or args.empty?
44
+ return fetch(m, nil) if has_key?(m)
45
+ return fetch(m.to_s, nil) if has_key?(m.to_s)
46
+ return fetch(m.to_sym, nil) if has_key?(m.to_sym)
47
+ end
48
+ raise NoMethodError.new("undefined method #{m}", m)
49
+ end
50
+
51
+ end # EasyHash
52
+ end # Oj
@@ -0,0 +1,21 @@
1
+ module Oj
2
+
3
+ # Inherit Error class from StandardError.
4
+ Error = Class.new(StandardError)
5
+
6
+ # Following classes inherit from the Error class.
7
+ # -----------------------------------------------
8
+
9
+ # An Exception that is raised as a result of a parse error while parsing a JSON document.
10
+ ParseError = Class.new(Error)
11
+
12
+ # An Exception that is raised as a result of a path being too deep.
13
+ DepthError = Class.new(Error)
14
+
15
+ # An Exception that is raised if a file fails to load.
16
+ LoadError = Class.new(Error)
17
+
18
+ # An Exception that is raised if there is a conflict with mimicking JSON
19
+ MimicError = Class.new(Error)
20
+
21
+ end # Oj
@@ -0,0 +1,188 @@
1
+ require 'ostruct'
2
+ require 'oj/state'
3
+
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
57
+ end
58
+
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
65
+
66
+ def self.parser=(p)
67
+ @@parser = p
68
+ end
69
+
70
+ def self.parser()
71
+ @@parser
72
+ end
73
+
74
+ def self.generator=(g)
75
+ @@generator = g
76
+ end
77
+
78
+ def self.generator()
79
+ @@generator
80
+ end
81
+
82
+ module Ext
83
+ class Parser
84
+ def initialize(src)
85
+ raise TypeError.new("already initialized") unless @source.nil?
86
+
87
+ @source = src
88
+ end
89
+
90
+ def source()
91
+ raise TypeError.new("already initialized") if @source.nil?
92
+
93
+ @source
94
+ end
95
+
96
+ def parse()
97
+ raise TypeError.new("already initialized") if @source.nil?
98
+
99
+ JSON.parse(@source)
100
+ end
101
+
102
+ end # Parser
103
+ end # Ext
104
+
105
+ State = ::JSON::Ext::Generator::State unless defined?(::JSON::State)
106
+
107
+ begin
108
+ send(:remove_const, :Parser)
109
+ rescue
110
+ # ignore and move on
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
125
+
126
+ attr_writer :json_creatable
127
+
128
+ def json_create(data)
129
+ data = data.dup
130
+ data.delete JSON.create_id
131
+ self[data]
132
+ end
133
+
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
148
+
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
153
+
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
185
+ end
186
+
187
+ end # JSON
188
+ end
@@ -0,0 +1,301 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'bigdecimal'
4
+ require 'ostruct'
5
+
6
+ module Oj
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
+
54
+ # A bit hack-ish but does the trick. The JSON.dump_default_options is a Hash
55
+ # but in mimic we use a C struct to store defaults. This class creates a view
56
+ # onto that struct.
57
+ class MimicDumpOption < Hash
58
+ def initialize()
59
+ oo = Oj.default_options
60
+ self.store(:max_nesting, false)
61
+ self.store(:allow_nan, true)
62
+ self.store(:quirks_mode, oo[:quirks_mode])
63
+ self.store(:ascii_only, (:ascii == oo[:escape_mode]))
64
+
65
+ super
66
+ end
67
+
68
+ def []=(key, value)
69
+ case key
70
+ when :quirks_mode
71
+ Oj.default_options = {:quirks_mode => value}
72
+ when :ascii_only
73
+ Oj.default_options = {:ascii_only => value}
74
+ end
75
+ end
76
+ end
77
+
78
+ # Loads mimic-ed JSON paths. Used by Oj.mimic_JSON().
79
+ # @param mimic_paths [Array] additional paths to add to the Ruby loaded features.
80
+ def self.mimic_loaded(mimic_paths=[])
81
+ $LOAD_PATH.each do |d|
82
+ next unless File.exist?(d)
83
+
84
+ jfile = File.join(d, 'json.rb')
85
+ $LOADED_FEATURES << jfile unless $LOADED_FEATURES.include?(jfile) if File.exist?(jfile)
86
+
87
+ Dir.glob(File.join(d, 'json', '**', '*.rb')).each do |file|
88
+ # allow json/add/xxx to be loaded. User can override with Oj.add_to_json(xxx).
89
+ $LOADED_FEATURES << file unless $LOADED_FEATURES.include?(file) unless file.include?('add')
90
+ end
91
+ end
92
+ mimic_paths.each { |p| $LOADED_FEATURES << p }
93
+ $LOADED_FEATURES << 'json' unless $LOADED_FEATURES.include?('json')
94
+
95
+ require 'oj/json'
96
+
97
+ if Object.const_defined?('OpenStruct')
98
+ OpenStruct.class_eval do
99
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
100
+ unless defined?(self.as_json)
101
+ def as_json(*)
102
+ name = self.class.name.to_s
103
+ raise JSON::JSONError, "Only named structs are supported!" if 0 == name.length
104
+
105
+ { JSON.create_id => name, 't' => table }
106
+ end
107
+ end
108
+ def self.json_create(h)
109
+ new(h['t'] || h[:t])
110
+ end
111
+ end
112
+ end
113
+
114
+ BigDecimal.class_eval do
115
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
116
+ unless defined?(self.as_json)
117
+ def as_json(*)
118
+ {JSON.create_id => 'BigDecimal', 'b' => _dump }
119
+ end
120
+ end
121
+ def self.json_create(h)
122
+ BigDecimal._load(h['b'])
123
+ end
124
+ end
125
+
126
+ Complex.class_eval do
127
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
128
+ unless defined?(self.as_json)
129
+ def as_json(*)
130
+ {JSON.create_id => 'Complex', 'r' => real, 'i' => imag }
131
+ end
132
+ end
133
+ def self.json_create(h)
134
+ Complex(h['r'], h['i'])
135
+ end
136
+ end
137
+
138
+ DateTime.class_eval do
139
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
140
+ unless defined?(self.as_json)
141
+ def as_json(*)
142
+ { JSON.create_id => 'DateTime',
143
+ 'y' => year,
144
+ 'm' => month,
145
+ 'd' => day,
146
+ 'H' => hour,
147
+ 'M' => min,
148
+ 'S' => sec,
149
+ 'of' => offset.to_s,
150
+ 'sg' => start }
151
+ end
152
+ end
153
+ def self.json_create(h)
154
+ # offset is a rational as a string
155
+ as, bs = h['of'].split('/')
156
+ a = as.to_i
157
+ b = bs.to_i
158
+ if 0 == b
159
+ off = a
160
+ else
161
+ off = Rational(a, b)
162
+ end
163
+ civil(h['y'], h['m'], h['d'], h['H'], h['M'], h['S'], off, h['sg'])
164
+ end
165
+ end
166
+
167
+ Date.class_eval do
168
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
169
+ unless defined?(self.as_json)
170
+ def as_json(*)
171
+ { JSON.create_id => 'Date', 'y' => year, 'm' => month, 'd' => day, 'sg' => start }
172
+ end
173
+ end
174
+ def self.json_create(h)
175
+ civil(h['y'], h['m'], h['d'], h['sg'])
176
+ end
177
+ end
178
+
179
+ Exception.class_eval do
180
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
181
+ unless defined?(self.as_json)
182
+ def as_json(*)
183
+ {JSON.create_id => self.class.name, 'm' => message, 'b' => backtrace }
184
+ end
185
+ end
186
+ def self.json_create(h)
187
+ e = new(h['m'])
188
+ e.set_backtrace(h['b'])
189
+ e
190
+ end
191
+ end
192
+
193
+ Range.class_eval do
194
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
195
+ unless defined?(self.as_json)
196
+ def as_json(*)
197
+ {JSON.create_id => 'Range', 'a' => [first, last, exclude_end?]}
198
+ end
199
+ end
200
+ def self.json_create(h)
201
+ new(*h['a'])
202
+ end
203
+ end
204
+
205
+ Rational.class_eval do
206
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
207
+ unless defined?(self.as_json)
208
+ def as_json(*)
209
+ {JSON.create_id => 'Rational', 'n' => numerator, 'd' => denominator }
210
+ end
211
+ end
212
+ def self.json_create(h)
213
+ Rational(h['n'], h['d'])
214
+ end
215
+ end
216
+
217
+ Regexp.class_eval do
218
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
219
+ unless defined?(self.as_json)
220
+ def as_json(*)
221
+ {JSON.create_id => 'Regexp', 'o' => options, 's' => source }
222
+ end
223
+ end
224
+ def self.json_create(h)
225
+ new(h['s'], h['o'])
226
+ end
227
+ end
228
+
229
+ Struct.class_eval do
230
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
231
+ unless defined?(self.as_json)
232
+ def as_json(*)
233
+ name = self.class.name.to_s
234
+ raise JSON::JSONError, "Only named structs are supported!" if 0 == name.length
235
+
236
+ { JSON.create_id => name, 'v' => values }
237
+ end
238
+ end
239
+ def self.json_create(h)
240
+ new(*h['v'])
241
+ end
242
+ end
243
+
244
+ Symbol.class_eval do
245
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
246
+ unless defined?(self.as_json)
247
+ def as_json(*)
248
+ {JSON.create_id => 'Symbol', 's' => to_s }
249
+ end
250
+ end
251
+ def self.json_create(h)
252
+ h['s'].to_sym
253
+ end
254
+ end
255
+
256
+ Time.class_eval do
257
+ # Both the JSON gem and Rails monkey patch as_json. Let them battle it out.
258
+ unless defined?(self.as_json)
259
+ def as_json(*)
260
+ nsecs = [ tv_usec * 1000 ]
261
+ nsecs << tv_nsec if respond_to?(:tv_nsec)
262
+ nsecs = nsecs.max
263
+ { JSON.create_id => 'Time', 's' => tv_sec, 'n' => nsecs }
264
+ end
265
+ end
266
+ def self.json_create(h)
267
+ if (usec = h.delete('u'))
268
+ h['n'] = usec * 1000
269
+ end
270
+ if instance_methods.include?(:tv_nsec)
271
+ at(h['s'], Rational(h['n'], 1000))
272
+ else
273
+ at(h['s'], h['n'] / 1000)
274
+ end
275
+ end
276
+ end
277
+ end # self.mimic_loaded
278
+
279
+ end # Oj
280
+
281
+ # More monkey patches.
282
+ class String
283
+ def to_json_raw_object
284
+ {
285
+ JSON.create_id => self.class.name,
286
+ 'raw' => self.bytes
287
+ }
288
+ end
289
+ def to_json_raw(*)
290
+ to_json_raw_object().to_json()
291
+ end
292
+ def self.json_create(obj)
293
+ s = ''
294
+ s.encode!(Encoding::ASCII_8BIT) if s.respond_to?(:encode!)
295
+ raw = obj['raw']
296
+ if raw.is_a? Array
297
+ raw.each { |v| s << v }
298
+ end
299
+ s
300
+ end
301
+ end