oj 3.7.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +96 -0
  4. data/ext/oj/buf.h +103 -0
  5. data/ext/oj/cache8.c +107 -0
  6. data/ext/oj/cache8.h +48 -0
  7. data/ext/oj/circarray.c +68 -0
  8. data/ext/oj/circarray.h +23 -0
  9. data/ext/oj/code.c +235 -0
  10. data/ext/oj/code.h +42 -0
  11. data/ext/oj/compat.c +299 -0
  12. data/ext/oj/custom.c +1188 -0
  13. data/ext/oj/dump.c +1232 -0
  14. data/ext/oj/dump.h +94 -0
  15. data/ext/oj/dump_compat.c +973 -0
  16. data/ext/oj/dump_leaf.c +252 -0
  17. data/ext/oj/dump_object.c +837 -0
  18. data/ext/oj/dump_strict.c +433 -0
  19. data/ext/oj/encode.h +45 -0
  20. data/ext/oj/err.c +57 -0
  21. data/ext/oj/err.h +70 -0
  22. data/ext/oj/extconf.rb +47 -0
  23. data/ext/oj/fast.c +1771 -0
  24. data/ext/oj/hash.c +163 -0
  25. data/ext/oj/hash.h +46 -0
  26. data/ext/oj/hash_test.c +512 -0
  27. data/ext/oj/mimic_json.c +873 -0
  28. data/ext/oj/object.c +771 -0
  29. data/ext/oj/odd.c +231 -0
  30. data/ext/oj/odd.h +44 -0
  31. data/ext/oj/oj.c +1694 -0
  32. data/ext/oj/oj.h +381 -0
  33. data/ext/oj/parse.c +1085 -0
  34. data/ext/oj/parse.h +111 -0
  35. data/ext/oj/rails.c +1485 -0
  36. data/ext/oj/rails.h +21 -0
  37. data/ext/oj/reader.c +231 -0
  38. data/ext/oj/reader.h +151 -0
  39. data/ext/oj/resolve.c +102 -0
  40. data/ext/oj/resolve.h +14 -0
  41. data/ext/oj/rxclass.c +147 -0
  42. data/ext/oj/rxclass.h +27 -0
  43. data/ext/oj/saj.c +714 -0
  44. data/ext/oj/scp.c +224 -0
  45. data/ext/oj/sparse.c +910 -0
  46. data/ext/oj/stream_writer.c +363 -0
  47. data/ext/oj/strict.c +212 -0
  48. data/ext/oj/string_writer.c +512 -0
  49. data/ext/oj/trace.c +79 -0
  50. data/ext/oj/trace.h +28 -0
  51. data/ext/oj/util.c +136 -0
  52. data/ext/oj/util.h +19 -0
  53. data/ext/oj/val_stack.c +118 -0
  54. data/ext/oj/val_stack.h +185 -0
  55. data/ext/oj/wab.c +631 -0
  56. data/lib/oj.rb +21 -0
  57. data/lib/oj/active_support_helper.rb +41 -0
  58. data/lib/oj/bag.rb +88 -0
  59. data/lib/oj/easy_hash.rb +52 -0
  60. data/lib/oj/error.rb +22 -0
  61. data/lib/oj/json.rb +176 -0
  62. data/lib/oj/mimic.rb +267 -0
  63. data/lib/oj/saj.rb +66 -0
  64. data/lib/oj/schandler.rb +142 -0
  65. data/lib/oj/state.rb +131 -0
  66. data/lib/oj/version.rb +5 -0
  67. data/pages/Advanced.md +22 -0
  68. data/pages/Compatibility.md +25 -0
  69. data/pages/Custom.md +23 -0
  70. data/pages/Encoding.md +65 -0
  71. data/pages/JsonGem.md +79 -0
  72. data/pages/Modes.md +154 -0
  73. data/pages/Options.md +266 -0
  74. data/pages/Rails.md +116 -0
  75. data/pages/Security.md +20 -0
  76. data/pages/WAB.md +13 -0
  77. data/test/_test_active.rb +76 -0
  78. data/test/_test_active_mimic.rb +96 -0
  79. data/test/_test_mimic_rails.rb +126 -0
  80. data/test/activerecord/result_test.rb +27 -0
  81. data/test/activesupport4/decoding_test.rb +108 -0
  82. data/test/activesupport4/encoding_test.rb +531 -0
  83. data/test/activesupport4/test_helper.rb +41 -0
  84. data/test/activesupport5/decoding_test.rb +125 -0
  85. data/test/activesupport5/encoding_test.rb +485 -0
  86. data/test/activesupport5/encoding_test_cases.rb +90 -0
  87. data/test/activesupport5/test_helper.rb +50 -0
  88. data/test/activesupport5/time_zone_test_helpers.rb +24 -0
  89. data/test/big.rb +15 -0
  90. data/test/files.rb +29 -0
  91. data/test/foo.rb +33 -0
  92. data/test/helper.rb +26 -0
  93. data/test/isolated/shared.rb +308 -0
  94. data/test/isolated/test_mimic_after.rb +13 -0
  95. data/test/isolated/test_mimic_alone.rb +12 -0
  96. data/test/isolated/test_mimic_as_json.rb +45 -0
  97. data/test/isolated/test_mimic_before.rb +13 -0
  98. data/test/isolated/test_mimic_define.rb +28 -0
  99. data/test/isolated/test_mimic_rails_after.rb +22 -0
  100. data/test/isolated/test_mimic_rails_before.rb +21 -0
  101. data/test/isolated/test_mimic_redefine.rb +15 -0
  102. data/test/json_gem/json_addition_test.rb +216 -0
  103. data/test/json_gem/json_common_interface_test.rb +148 -0
  104. data/test/json_gem/json_encoding_test.rb +107 -0
  105. data/test/json_gem/json_ext_parser_test.rb +20 -0
  106. data/test/json_gem/json_fixtures_test.rb +35 -0
  107. data/test/json_gem/json_generator_test.rb +383 -0
  108. data/test/json_gem/json_generic_object_test.rb +90 -0
  109. data/test/json_gem/json_parser_test.rb +470 -0
  110. data/test/json_gem/json_string_matching_test.rb +42 -0
  111. data/test/json_gem/test_helper.rb +18 -0
  112. data/test/mem.rb +35 -0
  113. data/test/perf.rb +107 -0
  114. data/test/perf_compat.rb +130 -0
  115. data/test/perf_fast.rb +164 -0
  116. data/test/perf_file.rb +64 -0
  117. data/test/perf_object.rb +138 -0
  118. data/test/perf_saj.rb +109 -0
  119. data/test/perf_scp.rb +151 -0
  120. data/test/perf_simple.rb +287 -0
  121. data/test/perf_strict.rb +145 -0
  122. data/test/perf_wab.rb +131 -0
  123. data/test/sample.rb +54 -0
  124. data/test/sample/change.rb +14 -0
  125. data/test/sample/dir.rb +19 -0
  126. data/test/sample/doc.rb +36 -0
  127. data/test/sample/file.rb +48 -0
  128. data/test/sample/group.rb +16 -0
  129. data/test/sample/hasprops.rb +16 -0
  130. data/test/sample/layer.rb +12 -0
  131. data/test/sample/line.rb +20 -0
  132. data/test/sample/oval.rb +10 -0
  133. data/test/sample/rect.rb +10 -0
  134. data/test/sample/shape.rb +35 -0
  135. data/test/sample/text.rb +20 -0
  136. data/test/sample_json.rb +37 -0
  137. data/test/test_compat.rb +509 -0
  138. data/test/test_custom.rb +406 -0
  139. data/test/test_debian.rb +53 -0
  140. data/test/test_fast.rb +470 -0
  141. data/test/test_file.rb +239 -0
  142. data/test/test_gc.rb +49 -0
  143. data/test/test_hash.rb +29 -0
  144. data/test/test_integer_range.rb +73 -0
  145. data/test/test_null.rb +376 -0
  146. data/test/test_object.rb +1018 -0
  147. data/test/test_saj.rb +186 -0
  148. data/test/test_scp.rb +433 -0
  149. data/test/test_strict.rb +410 -0
  150. data/test/test_various.rb +739 -0
  151. data/test/test_wab.rb +307 -0
  152. data/test/test_writer.rb +380 -0
  153. data/test/tests.rb +24 -0
  154. data/test/tests_mimic.rb +14 -0
  155. data/test/tests_mimic_addition.rb +7 -0
  156. metadata +359 -0
@@ -0,0 +1,66 @@
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.
6
+ #
7
+ # @example
8
+ #
9
+ # require 'oj'
10
+ #
11
+ # class MySaj < ::Oj::Saj
12
+ # def initialize()
13
+ # @hash_cnt = 0
14
+ # end
15
+ #
16
+ # def hash_start(key)
17
+ # @hash_cnt += 1
18
+ # end
19
+ # end
20
+ #
21
+ # cnt = MySaj.new()
22
+ # File.open('any.json', 'r') do |f|
23
+ # Oj.saj_parse(cnt, f)
24
+ # end
25
+ #
26
+ # To make the desired methods active while parsing the desired method should
27
+ # be made public in the subclasses. If the methods remain private they will
28
+ # not be called during parsing.
29
+ #
30
+ # def hash_start(key); end
31
+ # def hash_end(key); end
32
+ # def array_start(key); end
33
+ # def array_end(key); end
34
+ # def add_value(value, key); end
35
+ # def error(message, line, column); end
36
+ #
37
+ class Saj
38
+ # Create a new instance of the Saj handler class.
39
+ def initialize()
40
+ end
41
+
42
+ # To make the desired methods active while parsing the desired method should
43
+ # be made public in the subclasses. If the methods remain private they will
44
+ # not be called during parsing.
45
+ private
46
+
47
+ def hash_start(key)
48
+ end
49
+
50
+ def hash_end(key)
51
+ end
52
+
53
+ def array_start(key)
54
+ end
55
+
56
+ def array_end(key)
57
+ end
58
+
59
+ def add_value(value, key)
60
+ end
61
+
62
+ def error(message, line, column)
63
+ end
64
+
65
+ end # Saj
66
+ end # Oj
@@ -0,0 +1,142 @@
1
+ module Oj
2
+ # A Simple Callback Parser (SCP) for JSON. The Oj::ScHandler class should be
3
+ # subclassed and then used with the Oj.sc_parse() method. The Scp methods will
4
+ # then be called as the file is parsed. The handler does not have to be a
5
+ # subclass of the ScHandler class as long as it responds to the desired
6
+ # methods.
7
+ #
8
+ # @example
9
+ #
10
+ # require 'oj'
11
+ #
12
+ # class MyHandler < ::Oj::ScHandler
13
+ # def hash_start
14
+ # {}
15
+ # end
16
+ #
17
+ # def hash_set(h,k,v)
18
+ # h[k] = v
19
+ # end
20
+ #
21
+ # def array_start
22
+ # []
23
+ # end
24
+ #
25
+ # def array_append(a,v)
26
+ # a << v
27
+ # end
28
+ #
29
+ # def add_value(v)
30
+ # p v
31
+ # end
32
+ #
33
+ # def error(message, line, column)
34
+ # p "ERROR: #{message}"
35
+ # end
36
+ # end
37
+ #
38
+ # File.open('any.json', 'r') do |f|
39
+ # Oj.sc_parse(MyHandler.new, f)
40
+ # end
41
+ #
42
+ # To make the desired methods active while parsing the desired method should
43
+ # be made public in the subclasses. If the methods remain private they will
44
+ # not be called during parsing.
45
+ #
46
+ # def hash_start(); end
47
+ # def hash_end(); end
48
+ # def hash_key(key); end
49
+ # def hash_set(h, key, value); end
50
+ # def array_start(); end
51
+ # def array_end(); end
52
+ # def array_append(a, value); end
53
+ # def add_value(value); end
54
+ #
55
+ # As certain elements of a JSON document are reached during parsing the
56
+ # callbacks are called. The parser helps by keeping track of objects created
57
+ # by the callbacks but does not create those objects itself.
58
+ #
59
+ # hash_start
60
+ #
61
+ # When a JSON object element starts the hash_start() callback is called if
62
+ # public. It should return what ever Ruby Object is to be used as the element
63
+ # that will later be included in the hash_set() callback.
64
+ #
65
+ # hash_end
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.
70
+ #
71
+ # hash_key
72
+ #
73
+ # At the end of a JSON object element the hash_end() callback is called if public.
74
+ #
75
+ # hash_set
76
+ #
77
+ # When a key value pair is encountered during parsing the hash_set() callback
78
+ # is called if public. The first element will be the object returned from the
79
+ # enclosing hash_start() callback. The second argument is the key and the last
80
+ # is the value.
81
+ #
82
+ # array_start
83
+ #
84
+ # When a JSON array element is started the array_start() callback is called if
85
+ # public. It should return what ever Ruby Object is to be used as the element
86
+ # that will later be included in the array_append() callback.
87
+ #
88
+ # array_end
89
+ #
90
+ # At the end of a JSON array element the array_end() callback is called if public.
91
+ #
92
+ # array_append
93
+ #
94
+ # When a element is encountered that is an element of an array the
95
+ # array_append() callback is called if public. The first argument to the
96
+ # callback is the Ruby object returned from the enclosing array_start()
97
+ # callback.
98
+ #
99
+ # add_value
100
+ #
101
+ # The handler is expected to handle multiple JSON elements in one stream,
102
+ # file, or string. When a top level JSON has been read completely the
103
+ # add_value() callback is called. Even if only one element was ready this
104
+ # callback returns the Ruby object that was constructed during the parsing.
105
+ #
106
+ class ScHandler
107
+ # Create a new instance of the ScHandler class.
108
+ def initialize()
109
+ end
110
+
111
+ # To make the desired methods active while parsing the desired method should
112
+ # be made public in the subclasses. If the methods remain private they will
113
+ # not be called during parsing.
114
+ private
115
+
116
+ def hash_start()
117
+ end
118
+
119
+ def hash_end()
120
+ end
121
+
122
+ def hash_key(key)
123
+ key
124
+ end
125
+
126
+ def hash_set(h, key, value)
127
+ end
128
+
129
+ def array_start()
130
+ end
131
+
132
+ def array_end()
133
+ end
134
+
135
+ def add_value(value)
136
+ end
137
+
138
+ def array_append(a, value)
139
+ end
140
+
141
+ end # ScHandler
142
+ end # Oj
@@ -0,0 +1,131 @@
1
+
2
+ module JSON
3
+ module Ext
4
+ module Generator
5
+ unless defined?(::JSON::Ext::Generator::State)
6
+ # This class exists for json gem compatibility only. While it can be
7
+ # used as the options for other than compatibility a simple Hash is
8
+ # recommended as it is simpler and performs better. The only bit
9
+ # missing by not using a state object is the depth availability which
10
+ # may be the depth during dumping or maybe not since it can be set and
11
+ # the docs for depth= is the same as max_nesting. Note: Had to make
12
+ # this a subclass of Object instead of Hash like EashyHash due to
13
+ # conflicts with the json gem.
14
+ class State
15
+
16
+ def self.from_state(opts)
17
+ s = self.new()
18
+ s.clear()
19
+ s.merge(opts)
20
+ s
21
+ end
22
+
23
+ def initialize(opts = {})
24
+ @attrs = {}
25
+
26
+ # Populate with all vars then merge in opts. This class deviates from
27
+ # the json gem in that any of the options can be set with the opts
28
+ # argument. The json gem limits the opts use to 7 of the options.
29
+ @attrs[:indent] = ''
30
+ @attrs[:space] = ''
31
+ @attrs[:space_before] = ''
32
+ @attrs[:array_nl] = ''
33
+ @attrs[:object_nl] = ''
34
+ @attrs[:allow_nan] = false
35
+ @attrs[:buffer_initial_length] = 1024 # completely ignored by Oj
36
+ @attrs[:depth] = 0
37
+ @attrs[:max_nesting] = 100
38
+ @attrs[:check_circular?] = true
39
+ @attrs[:ascii_only] = false
40
+
41
+ @attrs.merge!(opts)
42
+ end
43
+
44
+ def to_h()
45
+ return @attrs.dup
46
+ end
47
+
48
+ def to_hash()
49
+ return @attrs.dup
50
+ end
51
+
52
+ def allow_nan?()
53
+ @attrs[:allow_nan]
54
+ end
55
+
56
+ def ascii_only?()
57
+ @attrs[:ascii_only]
58
+ end
59
+
60
+ def configure(opts)
61
+ raise TypeError.new('expected a Hash') unless opts.respond_to?(:to_h)
62
+ @attrs.merge!(opts.to_h)
63
+ end
64
+
65
+ def generate(obj)
66
+ JSON.generate(obj)
67
+ end
68
+
69
+ def merge(opts)
70
+ @attrs.merge!(opts)
71
+ end
72
+
73
+ # special rule for this.
74
+ def buffer_initial_length=(len)
75
+ len = 1024 if 0 >= len
76
+ @attrs[:buffer_initial_length] = len
77
+ end
78
+
79
+ # Replaces the Object.respond_to?() method.
80
+ # @param [Symbol] m method symbol
81
+ # @return [Boolean] true for any method that matches an instance
82
+ # variable reader, otherwise false.
83
+ def respond_to?(m)
84
+ return true if super
85
+ return true if has_key?(key)
86
+ return true if has_key?(key.to_s)
87
+ has_key?(key.to_sym)
88
+ end
89
+
90
+ def [](key)
91
+ key = key.to_sym
92
+ @attrs.fetch(key, nil)
93
+ end
94
+
95
+ def []=(key, value)
96
+ key = key.to_sym
97
+ @attrs[key] = value
98
+ end
99
+
100
+ def clear()
101
+ @attrs.clear()
102
+ end
103
+
104
+ def has_key?(k)
105
+ @attrs.has_key?(key.to_sym)
106
+ end
107
+
108
+ # Handles requests for Hash values. Others cause an Exception to be raised.
109
+ # @param [Symbol|String] m method symbol
110
+ # @return [Boolean] the value of the specified instance variable.
111
+ # @raise [ArgumentError] if an argument is given. Zero arguments expected.
112
+ # @raise [NoMethodError] if the instance variable is not defined.
113
+ def method_missing(m, *args, &block)
114
+ if m.to_s.end_with?('=')
115
+ raise ArgumentError.new("wrong number of arguments (#{args.size} for 1 with #{m}) to method #{m}") if args.nil? or 1 != args.length
116
+ m = m.to_s[0..-2]
117
+ m = m.to_sym
118
+ return @attrs.store(m, args[0])
119
+ else
120
+ raise ArgumentError.new("wrong number of arguments (#{args.size} for 0 with #{m}) to method #{m}") unless args.nil? or args.empty?
121
+ return @attrs[m.to_sym]
122
+ end
123
+ raise NoMethodError.new("undefined method #{m}", m)
124
+ end
125
+
126
+ end # State
127
+ end # defined check
128
+ end # Generator
129
+ end # Ext
130
+
131
+ end # JSON
@@ -0,0 +1,5 @@
1
+
2
+ module Oj
3
+ # Current version of the module.
4
+ VERSION = '3.7.12'
5
+ end
@@ -0,0 +1,22 @@
1
+ # Advanced Features
2
+
3
+ Optimized JSON (Oj), as the name implies, was written to provide speed optimized
4
+ JSON handling. It was designed as a faster alternative to Yajl and other
5
+ common Ruby JSON parsers. So far it has achieved that, and is about 2 times faster
6
+ than any other Ruby JSON parser, and 3 or more times faster at serializing JSON.
7
+
8
+ Oj has several `dump` or serialization modes which control how Ruby `Object`s are
9
+ converted to JSON. These modes are set with the `:mode` option in either the
10
+ default options or as one of the options to the `dump` method. In addition to
11
+ the various options there are also alternative APIs for parsing JSON.
12
+
13
+ The fastest alternative parser API is the `Oj::Doc` API. The `Oj::Doc` API takes
14
+ a completely different approach by opening a JSON document and providing calls
15
+ to navigate around the JSON while it is open. With this approach, JSON access
16
+ can be well over 20 times faster than conventional JSON parsing.
17
+
18
+ The `Oj::Saj` and `Oj::ScHandler` APIs are callback parsers that
19
+ walk the JSON document depth first and makes callbacks for each element.
20
+ Both callback parser are useful when only portions of the JSON are of
21
+ interest. Performance up to 20 times faster than conventional JSON is
22
+ possible if only a few elements of the JSON are of interest.
@@ -0,0 +1,25 @@
1
+ # Compatibility
2
+
3
+ **Ruby**
4
+
5
+ Oj is compatible with Ruby 2.0.0, 2.1, 2.2, 2.3, 2.4 and RBX.
6
+ Support for JRuby has been removed as JRuby no longer supports C extensions and
7
+ there are bugs in the older versions that are not being fixed.
8
+
9
+ **Rails**
10
+
11
+ Although up until 4.1 Rails uses [multi_json](https://github.com/intridea/multi_json), an [issue in Rails](https://github.com/rails/rails/issues/9212) causes ActiveSupport to fail to make use Oj for JSON handling.
12
+ There is a
13
+ [gem to patch this](https://github.com/GoodLife/rails-patch-json-encode) for
14
+ Rails 3.2 and 4.0. As of the Oj 2.6.0 release the default behavior is to not use
15
+ the `to_json()` method unless the `:use_to_json` option is set. This provides
16
+ another work around to the rails older and newer behavior.
17
+
18
+ The latest ActiveRecord is able to work with Oj by simply using the line:
19
+
20
+ ```
21
+ serialize :metadata, Oj
22
+ ```
23
+
24
+ In version Rails 4.1, multi_json has been removed, and this patch is unnecessary and will no longer work.
25
+ See {file:Rails.md}.
@@ -0,0 +1,23 @@
1
+ # Custom mode
2
+
3
+ The `:custom` mode is the most configurable mode and honors almost all
4
+ options. It provides the most flexibility although it can not be configured to
5
+ be exactly like any of the other modes. Each mode has some special aspect that
6
+ makes it unique. For example, the `:object` mode has it's own unique format
7
+ for object dumping and loading. The `:compat` mode mimic the json gem
8
+ including methods called for encoding and inconsistencies between
9
+ `JSON.dump()`, `JSON.generate()`, and `JSON()`.
10
+
11
+ The `:custom` mode is the default mode. It can be configured either by passing
12
+ options to the `Oj.dump()` and `Oj.load()` methods or by modifying the default
13
+ options.
14
+
15
+ The ability to create objects from JSON object elements is supported and
16
+ considers the `:create_additions` option. Special treatment is given to the
17
+ `:create_id` though. If the `:create_id` is set to `"^o"` then the Oj internal
18
+ encoding and decoding is used. These are more efficient than calling out to a
19
+ `to_json` method or `create_json` method on the classes. Those method do not
20
+ have to exist for the `"^o"` behavior to be utilized. Any other `:create_id`
21
+ value behaves similar to the json gem by calling `to_json` and `create_json`
22
+ as appropriate.
23
+
@@ -0,0 +1,65 @@
1
+ # Oj `:object` Mode Encoding
2
+
3
+ Object mode is for fast Ruby object serialization and deserialization. That
4
+ was the primary purpose of Oj when it was first developed. As such it is the
5
+ default mode unless changed in the Oj default options. In :object mode Oj
6
+ generates JSON that follows conventions which allow Class and other
7
+ information such as Object IDs for circular reference detection to be encoded
8
+ in a JSON document. The formatting follows these rules.
9
+
10
+ * JSON native types, true, false, nil, String, Hash, Array, and Number are
11
+ encoded normally.
12
+
13
+ * A Symbol is encoded as a JSON string with a preceding `':'` character.
14
+
15
+ * The `'^'` character denotes a special key value when in a JSON Object sequence.
16
+
17
+ * A Ruby String that starts with `':'`or the sequence `'^i'` or `'^r'` are
18
+ encoded by excaping the first character so that it appears as `'\u005e'` or
19
+ `'\u003a'` instead of `':'` or `'^'`.
20
+
21
+ * A `"^c"` JSON Object key indicates the value should be converted to a Ruby
22
+ class. The sequence `{"^c":"Oj::Bag"}` is read as the Oj::Bag class.
23
+
24
+ * A `"^t"` JSON Object key indicates the value should be converted to a Ruby
25
+ Time. The sequence `{"^t":1325775487.000000}` is read as Jan 5, 2012 at
26
+ 23:58:07.
27
+
28
+ * A `"^o"` JSON Object key indicates the value should be converted to a Ruby
29
+ Object. The first entry in the JSON Object must be a class with the `"^o"`
30
+ key. After that each entry is treated as a variable of the Object where the
31
+ key is the variable name without the preceding `'@'`. An example is
32
+ `{"^o":"Oj::Bag","x":58,"y":"marbles"}`. `"^O"`is the same except that it
33
+ is for built in or odd classes that don't obey the normal Ruby
34
+ rules. Examples are Rational, Date, and DateTime.
35
+
36
+ * A `"^u"` JSON Object key indicates the value should be converted to a Ruby
37
+ Struct. The first entry in the JSON Object must be a class with the
38
+ `"^u"` key. After that each entry is is given a numeric position in the
39
+ struct and that is used as the key in the JSON Object. An example is
40
+ `{"^u":["Range",1,7,false]}`.
41
+
42
+ * When encoding an Object, if the variable name does not begin with an
43
+ `'@'`character then the name preceded by a `'~'` character. This occurs in
44
+ the Exception class. An example is `{"^o":"StandardError","~mesg":"A
45
+ Message","~bt":[".\/tests.rb:345:in 'test_exception'"]}`.
46
+
47
+ * If a Hash entry has a key that is not a String or Symbol then the entry is
48
+ encoded with a key of the form `"^#n"` where n is a hex number. The value
49
+ is an Array where the first element is the key in the Hash and the second
50
+ is the value. An example is `{"^#3":[2,5]}`.
51
+
52
+ * A `"^i"` JSON entry in either an Object or Array is the ID of the Ruby
53
+ Object being encoded. It is used when the :circular flag is set. It can
54
+ appear in either a JSON Object or in a JSON Array. In an Object the
55
+ `"^i"` key has a corresponding reference Fixnum. In an array the sequence
56
+ will include an embedded reference number. An example is
57
+ `{"^o":"Oj::Bag","^i":1,"x":["^i2",true],"me":"^r1"}`.
58
+
59
+ * A `"^r"`JSON entry in an Object is a references to a Object or Array that
60
+ already appears in the JSON String. It must match up with a previous
61
+ `"^i"` ID. An example is `{"^o":"Oj::Bag","^i":1,"x":3,"me":"^r1"}`.
62
+
63
+ * If an Array element is a String and starts with `"^i"` then the first
64
+ character, the `'^'` is encoded as a hex character sequence. An example is
65
+ `["\u005ei37",3]`.