oj 2.18.3 → 3.13.14
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1324 -0
- data/README.md +51 -204
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +49 -72
- data/ext/oj/cache.c +326 -0
- data/ext/oj/cache.h +21 -0
- data/ext/oj/cache8.c +61 -64
- data/ext/oj/cache8.h +12 -39
- data/ext/oj/circarray.c +37 -68
- data/ext/oj/circarray.h +16 -42
- data/ext/oj/code.c +221 -0
- data/ext/oj/code.h +40 -0
- data/ext/oj/compat.c +231 -107
- data/ext/oj/custom.c +1125 -0
- data/ext/oj/debug.c +132 -0
- data/ext/oj/dump.c +935 -2513
- data/ext/oj/dump.h +108 -0
- data/ext/oj/dump_compat.c +936 -0
- data/ext/oj/dump_leaf.c +164 -0
- data/ext/oj/dump_object.c +761 -0
- data/ext/oj/dump_strict.c +410 -0
- data/ext/oj/encode.h +7 -42
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +40 -54
- data/ext/oj/err.h +52 -46
- data/ext/oj/extconf.rb +21 -30
- data/ext/oj/fast.c +1097 -1080
- data/ext/oj/intern.c +301 -0
- data/ext/oj/intern.h +26 -0
- data/ext/oj/mimic_json.c +893 -0
- data/ext/oj/object.c +549 -620
- data/ext/oj/odd.c +155 -167
- data/ext/oj/odd.h +37 -63
- data/ext/oj/oj.c +1661 -2063
- data/ext/oj/oj.h +341 -270
- data/ext/oj/parse.c +974 -737
- data/ext/oj/parse.h +105 -97
- data/ext/oj/parser.c +1526 -0
- data/ext/oj/parser.h +90 -0
- data/ext/oj/rails.c +1504 -0
- data/ext/oj/rails.h +18 -0
- data/ext/oj/reader.c +141 -163
- data/ext/oj/reader.h +75 -113
- data/ext/oj/resolve.c +45 -93
- data/ext/oj/resolve.h +7 -34
- data/ext/oj/rxclass.c +143 -0
- data/ext/oj/rxclass.h +26 -0
- data/ext/oj/saj.c +447 -511
- data/ext/oj/saj2.c +348 -0
- data/ext/oj/scp.c +91 -138
- data/ext/oj/sparse.c +793 -644
- data/ext/oj/stream_writer.c +331 -0
- data/ext/oj/strict.c +145 -109
- data/ext/oj/string_writer.c +493 -0
- data/ext/oj/trace.c +72 -0
- data/ext/oj/trace.h +28 -0
- data/ext/oj/usual.c +1254 -0
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +20 -0
- data/ext/oj/val_stack.c +62 -70
- data/ext/oj/val_stack.h +95 -129
- data/ext/oj/validate.c +51 -0
- data/ext/oj/wab.c +622 -0
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +17 -8
- data/lib/oj/error.rb +10 -11
- data/lib/oj/json.rb +176 -0
- data/lib/oj/mimic.rb +158 -19
- data/lib/oj/state.rb +132 -0
- data/lib/oj/version.rb +2 -2
- data/lib/oj.rb +1 -31
- data/pages/Advanced.md +22 -0
- data/pages/Compatibility.md +25 -0
- data/pages/Custom.md +23 -0
- data/pages/Encoding.md +65 -0
- data/pages/JsonGem.md +94 -0
- data/pages/Modes.md +161 -0
- data/pages/Options.md +327 -0
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +167 -0
- data/pages/Security.md +20 -0
- data/pages/WAB.md +13 -0
- data/test/activerecord/result_test.rb +32 -0
- data/test/activesupport4/decoding_test.rb +108 -0
- data/test/activesupport4/encoding_test.rb +531 -0
- data/test/activesupport4/test_helper.rb +41 -0
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +133 -0
- data/test/activesupport5/encoding_test.rb +500 -0
- data/test/activesupport5/encoding_test_cases.rb +98 -0
- data/test/activesupport5/test_helper.rb +72 -0
- data/test/activesupport5/time_zone_test_helpers.rb +39 -0
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +9 -0
- data/test/baz.rb +16 -0
- data/test/bug.rb +11 -46
- data/test/foo.rb +69 -16
- data/test/helper.rb +10 -1
- data/test/isolated/shared.rb +12 -8
- data/test/isolated/test_mimic_rails_after.rb +3 -3
- data/test/isolated/test_mimic_rails_before.rb +3 -3
- data/test/json_gem/json_addition_test.rb +216 -0
- data/test/json_gem/json_common_interface_test.rb +153 -0
- data/test/json_gem/json_encoding_test.rb +107 -0
- data/test/json_gem/json_ext_parser_test.rb +20 -0
- data/test/json_gem/json_fixtures_test.rb +35 -0
- data/test/json_gem/json_generator_test.rb +397 -0
- data/test/json_gem/json_generic_object_test.rb +90 -0
- data/test/json_gem/json_parser_test.rb +470 -0
- data/test/json_gem/json_string_matching_test.rb +42 -0
- data/test/json_gem/test_helper.rb +26 -0
- data/test/mem.rb +33 -0
- data/test/perf.rb +1 -1
- data/test/perf_compat.rb +30 -28
- data/test/perf_dump.rb +50 -0
- data/test/perf_object.rb +1 -1
- data/test/perf_once.rb +58 -0
- data/test/perf_parser.rb +189 -0
- data/test/perf_scp.rb +11 -10
- data/test/perf_strict.rb +30 -19
- data/test/perf_wab.rb +131 -0
- data/test/prec.rb +23 -0
- data/test/sample.rb +0 -1
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +219 -102
- data/test/test_custom.rb +533 -0
- data/test/test_fast.rb +107 -35
- data/test/test_file.rb +19 -25
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +11 -1
- data/test/test_integer_range.rb +72 -0
- data/test/test_null.rb +376 -0
- data/test/test_object.rb +357 -70
- data/test/test_parser.rb +27 -0
- data/test/test_parser_saj.rb +245 -0
- data/test/test_parser_usual.rb +217 -0
- data/test/test_rails.rb +35 -0
- data/test/test_saj.rb +1 -1
- data/test/test_scp.rb +39 -2
- data/test/test_strict.rb +186 -7
- data/test/test_various.rb +160 -774
- data/test/test_wab.rb +307 -0
- data/test/test_writer.rb +90 -2
- data/test/tests.rb +24 -0
- data/test/tests_mimic.rb +14 -0
- data/test/tests_mimic_addition.rb +7 -0
- data/test/zoo.rb +13 -0
- metadata +194 -56
- data/ext/oj/hash.c +0 -163
- data/ext/oj/hash.h +0 -46
- data/ext/oj/hash_test.c +0 -512
- data/test/activesupport_datetime_test.rb +0 -23
- data/test/bug2.rb +0 -10
- data/test/bug3.rb +0 -46
- data/test/bug_fast.rb +0 -32
- data/test/bug_load.rb +0 -24
- data/test/crash.rb +0 -111
- data/test/curl/curl_oj.rb +0 -46
- data/test/curl/get_oj.rb +0 -24
- data/test/curl/just_curl.rb +0 -31
- data/test/curl/just_oj.rb +0 -51
- data/test/example.rb +0 -11
- data/test/io.rb +0 -48
- data/test/isolated/test_mimic_rails_datetime.rb +0 -27
- data/test/mod.rb +0 -16
- data/test/rails.rb +0 -50
- data/test/russian.rb +0 -18
- data/test/struct.rb +0 -29
- data/test/test_serializer.rb +0 -59
- data/test/write_timebars.rb +0 -31
data/README.md
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
#
|
|
2
|
-
[](http://travis-ci.org/ohler55/oj)
|
|
1
|
+
# [](http://www.ohler.com/oj) gem
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
[](https://github.com/ohler55/oj/actions/workflows/CI.yml)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
[](https://dependabot.com/compatibility-score.html?dependency-name=oj&package-manager=bundler&version-scheme=semver)
|
|
7
|
+
[](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme)
|
|
8
|
+
|
|
9
|
+
A *fast* JSON parser and Object marshaller as a Ruby gem.
|
|
10
|
+
|
|
11
|
+
Version 3.13 is out with a much faster parser (`Oj::Parser`) and option isolation.
|
|
5
12
|
|
|
6
13
|
## Using
|
|
7
14
|
|
|
@@ -25,11 +32,6 @@ puts "Same? #{h == h2}"
|
|
|
25
32
|
# true
|
|
26
33
|
```
|
|
27
34
|
|
|
28
|
-
By default Oj uses the :object mode which is used to marshal and unmarshal Ruby
|
|
29
|
-
objects. Deserialize arbitrary JSON in object mode may lead to unexpected
|
|
30
|
-
results. :compat mode is a better choice for rails and :strict mode is a better
|
|
31
|
-
choice for general JSON parsing. See the options section below for details.
|
|
32
|
-
|
|
33
35
|
## Installation
|
|
34
36
|
```
|
|
35
37
|
gem install oj
|
|
@@ -41,230 +43,75 @@ or in Bundler:
|
|
|
41
43
|
gem 'oj'
|
|
42
44
|
```
|
|
43
45
|
|
|
44
|
-
##
|
|
46
|
+
## Rails and json quickstart
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
JSON handling. It was designed as a faster alternative to Yajl and other
|
|
48
|
-
common Ruby JSON parsers. So far it has achieved that, and is about 2 times faster
|
|
49
|
-
than any other Ruby JSON parser, and 3 or more times faster at serializing JSON.
|
|
48
|
+
See the Quickstart sections of the [Rails](pages/Rails.md) and [json](pages/JsonGem.md) docs.
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
converted to JSON. These modes are set with the `:mode` option in either the
|
|
53
|
-
default options or as one of the options to the `dump` method. In addition to
|
|
54
|
-
the various options there are also alternative APIs for parsing JSON.
|
|
50
|
+
## multi_json
|
|
55
51
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
to navigate around the JSON while it is open. With this approach, JSON access
|
|
59
|
-
can be well over 20 times faster than conventional JSON parsing.
|
|
52
|
+
Code which uses [multi_json](https://github.com/intridea/multi_json)
|
|
53
|
+
will automatically prefer Oj if it is installed.
|
|
60
54
|
|
|
61
|
-
|
|
62
|
-
walk the JSON document depth first and makes callbacks for each element.
|
|
63
|
-
Both callback parser are useful when only portions of the JSON are of
|
|
64
|
-
interest. Performance up to 20 times faster than conventional JSON is
|
|
65
|
-
possible if only a few elements of the JSON are of interest.
|
|
55
|
+
## Support
|
|
66
56
|
|
|
67
|
-
|
|
57
|
+
[Get supported Oj with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security).
|
|
68
58
|
|
|
69
|
-
|
|
70
|
-
modify the Oj.default_options Hash directly will not set the changes on the
|
|
71
|
-
actual default options but on a copy of the Hash:
|
|
59
|
+
## Further Reading
|
|
72
60
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
```
|
|
61
|
+
For more details on options, modes, advanced features, and more follow these
|
|
62
|
+
links.
|
|
76
63
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
- `:null` mode replaces any `Object` that is not one of the JSON types with a JSON `null`.
|
|
87
|
-
|
|
88
|
-
- `:compat` mode attempts to be compatible with other systems. It will
|
|
89
|
-
serialize any `Object`, but will check to see if the `Object` implements an
|
|
90
|
-
`to_hash` or `to_json` method. If either exists, that method is used for
|
|
91
|
-
serializing the `Object`. Since `as_json` is more flexible and produces
|
|
92
|
-
more consistent output, it is preferred over the `to_json` method. If
|
|
93
|
-
neither the `to_json` or `to_hash` methods exists, then the Oj internal
|
|
94
|
-
`Object` variable encoding is used.
|
|
95
|
-
|
|
96
|
-
* `:indent` [Fixnum] number of spaces to indent each element in an JSON
|
|
97
|
-
document, zero is no newline between JSON elements, negative indicates no
|
|
98
|
-
newline between top level JSON elements in a stream
|
|
99
|
-
|
|
100
|
-
* `:circular` [Boolean] support circular references while dumping.
|
|
101
|
-
|
|
102
|
-
* `:auto_define` [Boolean] automatically define classes if they do not
|
|
103
|
-
exist.
|
|
104
|
-
|
|
105
|
-
* `:symbol_keys` [Boolean] use symbols instead of strings for hash keys.
|
|
106
|
-
|
|
107
|
-
* `:escape_mode` [Symbol] determines the characters to escape.
|
|
108
|
-
|
|
109
|
-
- `:newline` allows unescaped newlines in the output.
|
|
110
|
-
|
|
111
|
-
- `:json` follows the JSON specification. This is the default mode.
|
|
112
|
-
|
|
113
|
-
- `:xss_safe` escapes HTML and XML characters such as `&` and `<`.
|
|
114
|
-
|
|
115
|
-
- `:ascii` escapes all non-ascii or characters with the hi-bit set.
|
|
116
|
-
|
|
117
|
-
* `:class_cache` [Boolean] cache classes for faster parsing (if
|
|
118
|
-
dynamically modifying classes or reloading classes then don't use this)
|
|
119
|
-
|
|
120
|
-
* `:time_format` [Symbol] time format when dumping in :compat and :object mode
|
|
121
|
-
|
|
122
|
-
- `:unix` time is output as a decimal number in seconds since epoch including
|
|
123
|
-
fractions of a second.
|
|
124
|
-
|
|
125
|
-
- `:unix_zone` similar to the `:unix` format but with the timezone encoded in
|
|
126
|
-
the exponent of the decimal number of seconds since epoch.
|
|
127
|
-
|
|
128
|
-
- `:xmlschema` time is output as a string that follows the XML schema definition.
|
|
129
|
-
|
|
130
|
-
- `:ruby` time is output as a string formatted using the Ruby `to_s` conversion.
|
|
131
|
-
|
|
132
|
-
* `:bigdecimal_as_decimal` [Boolean] dump BigDecimal as a decimal number
|
|
133
|
-
or as a String
|
|
134
|
-
|
|
135
|
-
* `:bigdecimal_load` [Symbol] load decimals as BigDecimal instead of as a
|
|
136
|
-
Float.
|
|
137
|
-
|
|
138
|
-
- `:bigdecimal` convert all decimal numbers to BigDecimal.
|
|
139
|
-
|
|
140
|
-
- `:float` convert all decimal numbers to Float.
|
|
141
|
-
|
|
142
|
-
- `:auto` the most precise for the number of digits is used.
|
|
143
|
-
|
|
144
|
-
* `:create_id` [String] create id for json compatible object encoding,
|
|
145
|
-
default is `json_create`.
|
|
146
|
-
|
|
147
|
-
* `:second_precision` [Fixnum] number of digits after the decimal when dumping
|
|
148
|
-
the seconds portion of time
|
|
149
|
-
|
|
150
|
-
* `:float_precision` [Fixnum] number of digits of precision when dumping
|
|
151
|
-
floats, 0 indicates use Ruby
|
|
152
|
-
|
|
153
|
-
* `:use_to_json` [Boolean] call to_json() methods on dump, default is
|
|
154
|
-
false
|
|
155
|
-
|
|
156
|
-
* `:use_as_json` [Boolean] call as_json() methods on dump, default is
|
|
157
|
-
false
|
|
158
|
-
|
|
159
|
-
* `:nilnil` [Boolean] if true a nil input to load will return nil and
|
|
160
|
-
not raise an Exception
|
|
161
|
-
|
|
162
|
-
* `:allow_gc` [Boolean] allow or prohibit GC during parsing, default is
|
|
163
|
-
true (allow).
|
|
164
|
-
|
|
165
|
-
* `:quirks_mode` [Boolean] Allow single JSON values instead of
|
|
166
|
-
documents, default is true (allow).
|
|
167
|
-
|
|
168
|
-
* `:nan` [:null|:huge|:word|:raise|:auto] How to dump Infinity, -Infinity, and
|
|
169
|
-
NaN in null, strict, and compat mode. :null places a null, :huge places a huge
|
|
170
|
-
number, :word places Infinity or NaN, :raise raises and exception, :auto uses
|
|
171
|
-
default for each mode which are :raise for :strict, :null for :null, and :word
|
|
172
|
-
for :compat. Default is :auto.
|
|
173
|
-
|
|
174
|
-
* `:allow_invalid_unicode` [Boolean] Allow invalid unicode, default is
|
|
175
|
-
false (don't allow)
|
|
176
|
-
|
|
177
|
-
* `:hash_class` [Class] Class to use instead of Hash on load
|
|
178
|
-
|
|
179
|
-
* `:omit_nil` [Boolean] If true, Hash and Object attributes with nil values
|
|
180
|
-
are omitted
|
|
64
|
+
- [{file:Options.md}](pages/Options.md) for parse and dump options.
|
|
65
|
+
- [{file:Modes.md}](pages/Modes.md) for details on modes for strict JSON compliance, mimicking the JSON gem, and mimicking Rails and ActiveSupport behavior.
|
|
66
|
+
- [{file:JsonGem.md}](pages/JsonGem.md) includes more details on json gem compatibility and use.
|
|
67
|
+
- [{file:Rails.md}](pages/Rails.md) includes more details on Rails and ActiveSupport compatibility and use.
|
|
68
|
+
- [{file:Custom.md}](pages/Custom.md) includes more details on Custom mode.
|
|
69
|
+
- [{file:Encoding.md}](pages/Encoding.md) describes the :object encoding format.
|
|
70
|
+
- [{file:Compatibility.md}](pages/Compatibility.md) lists current compatibility with Rubys and Rails.
|
|
71
|
+
- [{file:Advanced.md}](pages/Advanced.md) for fast parser and marshalling features.
|
|
72
|
+
- [{file:Security.md}](pages/Security.md) for security considerations.
|
|
181
73
|
|
|
182
74
|
## Releases
|
|
183
75
|
|
|
184
|
-
See [CHANGELOG.md](CHANGELOG.md)
|
|
185
|
-
|
|
186
|
-
## Compatibility
|
|
187
|
-
|
|
188
|
-
**Ruby**
|
|
189
|
-
|
|
190
|
-
Oj is compatible with Ruby 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1, 2.2, 2.3 and RBX.
|
|
191
|
-
Support for JRuby has been removed as JRuby no longer supports C extensions and
|
|
192
|
-
there are bugs in the older versions that are not being fixed.
|
|
193
|
-
|
|
194
|
-
**Rails**
|
|
195
|
-
|
|
196
|
-
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.
|
|
197
|
-
There is a
|
|
198
|
-
[gem to patch this](https://github.com/GoodLife/rails-patch-json-encode) for
|
|
199
|
-
Rails 3.2 and 4.0. As of the Oj 2.6.0 release the default behavior is to not use
|
|
200
|
-
the `to_json()` method unless the `:use_to_json` option is set. This provides
|
|
201
|
-
another work around to the rails older and newer behavior.
|
|
202
|
-
|
|
203
|
-
The latest ActiveRecord is able to work with Oj by simply using the line:
|
|
204
|
-
|
|
205
|
-
```
|
|
206
|
-
serialize :metadata, Oj
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
In version Rails 4.1, multi_json has been removed, and this patch is unnecessary and will no longer work.
|
|
210
|
-
Instead, use the `oj_mimic_json` [gem](https://github.com/ohler55/oj_mimic_json) along with `oj` in your `Gemfile` to have Oj mimic the JSON gem and be used in its place by `ActiveSupport` JSON handling:
|
|
211
|
-
|
|
212
|
-
```
|
|
213
|
-
gem 'oj'
|
|
214
|
-
gem 'oj_mimic_json'
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
## Security and Optimization
|
|
218
|
-
|
|
219
|
-
Two settings in Oj are useful for parsing but do expose a vulnerability if used
|
|
220
|
-
from an untrusted source. Symbolized keys can cause memory to be filled with
|
|
221
|
-
previous versions of ruby. Ruby 2.1 and below does not garbage collect
|
|
222
|
-
Symbols. The same is true for auto defining classes in all versions of ruby;
|
|
223
|
-
memory will also be exhausted if too many classes are automatically
|
|
224
|
-
defined. Auto defining is a useful feature during development and from trusted
|
|
225
|
-
sources but it allows too many classes to be created in the object load mode and
|
|
226
|
-
auto defined is used with an untrusted source. The `Oj.strict_load()` method
|
|
227
|
-
sets and uses the most strict and safest options. It should be used by
|
|
228
|
-
developers who find it difficult to understand the options available in Oj.
|
|
229
|
-
|
|
230
|
-
The options in Oj are designed to provide flexibility to the developer. This
|
|
231
|
-
flexibility allows Objects to be serialized and deserialized. No methods are
|
|
232
|
-
ever called on these created Objects but that does not stop the developer from
|
|
233
|
-
calling methods on them. As in any system, check your inputs before working with
|
|
234
|
-
them. Taking an arbitrary `String` from a user and evaluating it is never a good
|
|
235
|
-
idea from an unsecure source. The same is true for `Object` attributes as they
|
|
236
|
-
are not more than `String`s. Always check inputs from untrusted sources.
|
|
76
|
+
See [{file:CHANGELOG.md}](CHANGELOG.md) and [{file:RELEASE_NOTES.md}](RELEASE_NOTES.md)
|
|
237
77
|
|
|
238
78
|
## Links
|
|
239
79
|
|
|
240
|
-
*Documentation*: http://www.ohler.com/oj, http://rubydoc.info/gems/oj
|
|
80
|
+
- *Documentation*: http://www.ohler.com/oj/doc, http://rubydoc.info/gems/oj
|
|
241
81
|
|
|
242
|
-
*GitHub* *repo*: https://github.com/ohler55/oj
|
|
82
|
+
- *GitHub* *repo*: https://github.com/ohler55/oj
|
|
243
83
|
|
|
244
|
-
*RubyGems* *repo*: https://rubygems.org/gems/oj
|
|
84
|
+
- *RubyGems* *repo*: https://rubygems.org/gems/oj
|
|
245
85
|
|
|
246
|
-
Follow [@peterohler on Twitter](http://twitter.com
|
|
86
|
+
Follow [@peterohler on Twitter](http://twitter.com/peterohler) for announcements and news about the Oj gem.
|
|
247
87
|
|
|
248
88
|
#### Performance Comparisons
|
|
249
89
|
|
|
250
|
-
[Oj Strict Mode Performance](http://www.ohler.com/dev/oj_misc/performance_strict.html) compares Oj strict mode parser performance to other JSON parsers.
|
|
90
|
+
- [Oj Strict Mode Performance](http://www.ohler.com/dev/oj_misc/performance_strict.html) compares Oj strict mode parser performance to other JSON parsers.
|
|
251
91
|
|
|
252
|
-
[Oj Compat Mode Performance](http://www.ohler.com/dev/oj_misc/performance_compat.html) compares Oj compat mode parser performance to other JSON parsers.
|
|
92
|
+
- [Oj Compat Mode Performance](http://www.ohler.com/dev/oj_misc/performance_compat.html) compares Oj compat mode parser performance to other JSON parsers.
|
|
253
93
|
|
|
254
|
-
[Oj Object Mode Performance](http://www.ohler.com/dev/oj_misc/performance_object.html) compares Oj object mode parser performance to other marshallers.
|
|
94
|
+
- [Oj Object Mode Performance](http://www.ohler.com/dev/oj_misc/performance_object.html) compares Oj object mode parser performance to other marshallers.
|
|
255
95
|
|
|
256
|
-
[Oj Callback Performance](http://www.ohler.com/dev/oj_misc/performance_callback.html) compares Oj callback parser performance to other JSON parsers.
|
|
96
|
+
- [Oj Callback Performance](http://www.ohler.com/dev/oj_misc/performance_callback.html) compares Oj callback parser performance to other JSON parsers.
|
|
257
97
|
|
|
258
98
|
#### Links of Interest
|
|
259
99
|
|
|
260
|
-
*Fast XML parser and marshaller on RubyGems*: https://rubygems.org/gems/ox
|
|
100
|
+
- *Fast XML parser and marshaller on RubyGems*: https://rubygems.org/gems/ox
|
|
101
|
+
|
|
102
|
+
- *Fast XML parser and marshaller on GitHub*: https://github.com/ohler55/ox
|
|
103
|
+
|
|
104
|
+
- [Need for Speed](http://www.ohler.com/dev/need_for_speed/need_for_speed.html) for an overview of how Oj::Doc was designed.
|
|
261
105
|
|
|
262
|
-
|
|
106
|
+
- *OjC, a C JSON parser*: https://www.ohler.com/ojc also at https://github.com/ohler55/ojc
|
|
263
107
|
|
|
264
|
-
|
|
108
|
+
- *Agoo, a high performance Ruby web server supporting GraphQL on GitHub*: https://github.com/ohler55/agoo
|
|
265
109
|
|
|
266
|
-
|
|
110
|
+
- *Agoo-C, a high performance C web server supporting GraphQL on GitHub*: https://github.com/ohler55/agoo-c
|
|
267
111
|
|
|
268
|
-
|
|
112
|
+
#### Contributing
|
|
269
113
|
|
|
270
|
-
|
|
114
|
+
+ Provide a Pull Request off the `develop` branch.
|
|
115
|
+
+ Report a bug
|
|
116
|
+
+ Suggest an idea
|
|
117
|
+
+ Code is now formatted with the clang-format tool with the configuration file in the root of the repo.
|
data/RELEASE_NOTES.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# RELEASE NOTES
|
|
2
|
+
|
|
3
|
+
The release notes here are organized by release. For a list of changes
|
|
4
|
+
see the See [{file:CHANGELOG.md}](CHANGELOG.md) file. In this file are
|
|
5
|
+
the steps to take to aid in keeping things rolling after updating to
|
|
6
|
+
the latest version.
|
|
7
|
+
|
|
8
|
+
## 3.13.7
|
|
9
|
+
|
|
10
|
+
The default for JSON when mimicked by Oj is now to set
|
|
11
|
+
`:allow_invalid_unicode`. To change that behavior JSON.load, set that
|
|
12
|
+
option to false.
|
|
13
|
+
|
|
14
|
+
## 3.13.x
|
|
15
|
+
|
|
16
|
+
This release included a new cache that performs better than the
|
|
17
|
+
earlier cache and a new high performance parser.
|
|
18
|
+
|
|
19
|
+
### Cache
|
|
20
|
+
|
|
21
|
+
The new cache includes a least recently used expiration to reduce
|
|
22
|
+
memory use. The cache is also self adjusting and will expand as needed
|
|
23
|
+
for better performance. It also handles Hash keys and string values
|
|
24
|
+
with two options, `:cache_keys`, a boolean and `:cache_str` an
|
|
25
|
+
integer. The `:cache_str` if set to more than zero is the limit for
|
|
26
|
+
the length of string values to cache. The maximum value is 35 which
|
|
27
|
+
allows strings up to 34 bytes to be cached.
|
|
28
|
+
|
|
29
|
+
One interesting aspect of the cache is not so much the string caching
|
|
30
|
+
which performs similar to the Ruby intern functions but the caching of
|
|
31
|
+
symbols and object attribute names. There is a significant gain for
|
|
32
|
+
symbols and object attributes.
|
|
33
|
+
|
|
34
|
+
If the cache is not desired then setting the default options to turn
|
|
35
|
+
it off can be done with this line:
|
|
36
|
+
|
|
37
|
+
``` ruby
|
|
38
|
+
Oj.default_options = { cache_keys: false, cache_str: 0 }
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Oj::Parser
|
|
42
|
+
|
|
43
|
+
The new parser uses a different core that follows the approach taken
|
|
44
|
+
by [OjC](https://github.com/ohler55/ojc) and
|
|
45
|
+
[OjG](https://github.com/ohler55/ojg). It also takes advantage of the
|
|
46
|
+
bulk Array and Hash functions. Another issue the new parser addresses
|
|
47
|
+
is option management. Instead of a single global default_options each
|
|
48
|
+
parser instance maintains it's own options.
|
|
49
|
+
|
|
50
|
+
There is a price to be paid when using the Oj::Parser. The API is not
|
|
51
|
+
the same the older parser. A single parser can only be used in a
|
|
52
|
+
single thread. This allows reuse of internal buffers for additional
|
|
53
|
+
improvements in performance.
|
|
54
|
+
|
|
55
|
+
The performane advantage of the Oj::Parse is that it is more than 3
|
|
56
|
+
times faster than the Oj::compat_load call and 6 times faster than the
|
|
57
|
+
JSON gem.
|
|
58
|
+
|
|
59
|
+
### Dump Performance
|
|
60
|
+
|
|
61
|
+
Thanks to Watson1978 Oj.dump also received a speed boost.
|
data/ext/oj/buf.h
CHANGED
|
@@ -1,103 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
*
|
|
5
|
-
* Redistribution and use in source and binary forms, with or without
|
|
6
|
-
* modification, are permitted provided that the following conditions are met:
|
|
7
|
-
*
|
|
8
|
-
* - Redistributions of source code must retain the above copyright notice, this
|
|
9
|
-
* list of conditions and the following disclaimer.
|
|
10
|
-
*
|
|
11
|
-
* - Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
-
* this list of conditions and the following disclaimer in the documentation
|
|
13
|
-
* and/or other materials provided with the distribution.
|
|
14
|
-
*
|
|
15
|
-
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
|
16
|
-
* used to endorse or promote products derived from this software without
|
|
17
|
-
* specific prior written permission.
|
|
18
|
-
*
|
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
29
|
-
*/
|
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
|
30
3
|
|
|
31
|
-
#ifndef
|
|
32
|
-
#define
|
|
4
|
+
#ifndef OJ_BUF_H
|
|
5
|
+
#define OJ_BUF_H
|
|
33
6
|
|
|
34
7
|
#include "ruby.h"
|
|
35
8
|
|
|
36
|
-
typedef struct
|
|
37
|
-
char
|
|
38
|
-
char
|
|
39
|
-
char
|
|
40
|
-
char
|
|
41
|
-
} *Buf;
|
|
9
|
+
typedef struct _buf {
|
|
10
|
+
char *head;
|
|
11
|
+
char *end;
|
|
12
|
+
char *tail;
|
|
13
|
+
char base[1024];
|
|
14
|
+
} * Buf;
|
|
42
15
|
|
|
43
|
-
inline static void
|
|
44
|
-
buf_init(Buf buf) {
|
|
16
|
+
inline static void buf_init(Buf buf) {
|
|
45
17
|
buf->head = buf->base;
|
|
46
|
-
buf->end
|
|
18
|
+
buf->end = buf->base + sizeof(buf->base) - 1;
|
|
47
19
|
buf->tail = buf->head;
|
|
48
20
|
}
|
|
49
21
|
|
|
50
|
-
inline static void
|
|
51
|
-
|
|
22
|
+
inline static void buf_reset(Buf buf) {
|
|
23
|
+
buf->tail = buf->head;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
inline static void buf_cleanup(Buf buf) {
|
|
52
27
|
if (buf->base != buf->head) {
|
|
53
28
|
xfree(buf->head);
|
|
54
29
|
}
|
|
55
30
|
}
|
|
56
31
|
|
|
57
|
-
inline static size_t
|
|
58
|
-
buf_len(Buf buf) {
|
|
32
|
+
inline static size_t buf_len(Buf buf) {
|
|
59
33
|
return buf->tail - buf->head;
|
|
60
34
|
}
|
|
61
35
|
|
|
62
|
-
inline static
|
|
63
|
-
|
|
36
|
+
inline static const char *buf_str(Buf buf) {
|
|
37
|
+
*buf->tail = '\0';
|
|
38
|
+
return buf->head;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
inline static void buf_append_string(Buf buf, const char *s, size_t slen) {
|
|
64
42
|
if (buf->end <= buf->tail + slen) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
43
|
+
size_t len = buf->end - buf->head;
|
|
44
|
+
size_t toff = buf->tail - buf->head;
|
|
45
|
+
size_t new_len = len + slen + len / 2;
|
|
68
46
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
47
|
+
if (buf->base == buf->head) {
|
|
48
|
+
buf->head = ALLOC_N(char, new_len);
|
|
49
|
+
memcpy(buf->head, buf->base, len);
|
|
50
|
+
} else {
|
|
51
|
+
REALLOC_N(buf->head, char, new_len);
|
|
52
|
+
}
|
|
53
|
+
buf->tail = buf->head + toff;
|
|
54
|
+
buf->end = buf->head + new_len - 1;
|
|
77
55
|
}
|
|
78
56
|
memcpy(buf->tail, s, slen);
|
|
79
57
|
buf->tail += slen;
|
|
80
58
|
}
|
|
81
|
-
|
|
82
|
-
inline static void
|
|
83
|
-
buf_append(Buf buf, char c) {
|
|
59
|
+
|
|
60
|
+
inline static void buf_append(Buf buf, char c) {
|
|
84
61
|
if (buf->end <= buf->tail) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
62
|
+
size_t len = buf->end - buf->head;
|
|
63
|
+
size_t toff = buf->tail - buf->head;
|
|
64
|
+
size_t new_len = len + len / 2;
|
|
88
65
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
66
|
+
if (buf->base == buf->head) {
|
|
67
|
+
buf->head = ALLOC_N(char, new_len);
|
|
68
|
+
memcpy(buf->head, buf->base, len);
|
|
69
|
+
} else {
|
|
70
|
+
REALLOC_N(buf->head, char, new_len);
|
|
71
|
+
}
|
|
72
|
+
buf->tail = buf->head + toff;
|
|
73
|
+
buf->end = buf->head + new_len - 1;
|
|
97
74
|
}
|
|
98
75
|
*buf->tail = c;
|
|
99
76
|
buf->tail++;
|
|
100
77
|
//*buf->tail = '\0'; // for debugging
|
|
101
78
|
}
|
|
102
79
|
|
|
103
|
-
#endif /*
|
|
80
|
+
#endif /* OJ_BUF_H */
|