oj 2.18.5 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -226
  3. data/ext/oj/circarray.c +0 -25
  4. data/ext/oj/circarray.h +0 -25
  5. data/ext/oj/code.c +227 -0
  6. data/ext/oj/code.h +40 -0
  7. data/ext/oj/compat.c +126 -38
  8. data/ext/oj/custom.c +1097 -0
  9. data/ext/oj/dump.c +658 -2376
  10. data/ext/oj/dump.h +92 -0
  11. data/ext/oj/dump_compat.c +937 -0
  12. data/ext/oj/dump_leaf.c +254 -0
  13. data/ext/oj/dump_object.c +810 -0
  14. data/ext/oj/dump_rails.c +329 -0
  15. data/ext/oj/dump_strict.c +416 -0
  16. data/ext/oj/err.c +0 -25
  17. data/ext/oj/err.h +8 -2
  18. data/ext/oj/fast.c +24 -24
  19. data/ext/oj/mimic_json.c +817 -0
  20. data/ext/oj/mimic_rails.c +806 -0
  21. data/ext/oj/mimic_rails.h +17 -0
  22. data/ext/oj/object.c +18 -72
  23. data/ext/oj/odd.c +0 -25
  24. data/ext/oj/odd.h +2 -27
  25. data/ext/oj/oj.c +655 -1503
  26. data/ext/oj/oj.h +93 -40
  27. data/ext/oj/parse.c +99 -46
  28. data/ext/oj/parse.h +12 -26
  29. data/ext/oj/reader.c +1 -25
  30. data/ext/oj/reader.h +3 -25
  31. data/ext/oj/resolve.c +9 -11
  32. data/ext/oj/resolve.h +2 -2
  33. data/ext/oj/rxclass.c +133 -0
  34. data/ext/oj/rxclass.h +27 -0
  35. data/ext/oj/saj.c +4 -25
  36. data/ext/oj/scp.c +3 -25
  37. data/ext/oj/sparse.c +89 -13
  38. data/ext/oj/stream_writer.c +301 -0
  39. data/ext/oj/strict.c +4 -27
  40. data/ext/oj/string_writer.c +480 -0
  41. data/ext/oj/val_stack.h +6 -2
  42. data/lib/oj.rb +1 -23
  43. data/lib/oj/easy_hash.rb +12 -4
  44. data/lib/oj/json.rb +172 -0
  45. data/lib/oj/mimic.rb +123 -18
  46. data/lib/oj/state.rb +131 -0
  47. data/lib/oj/version.rb +1 -1
  48. data/pages/Advanced.md +22 -0
  49. data/pages/Compatibility.md +25 -0
  50. data/pages/Custom.md +23 -0
  51. data/pages/Encoding.md +65 -0
  52. data/pages/JsonGem.md +79 -0
  53. data/pages/Modes.md +140 -0
  54. data/pages/Options.md +250 -0
  55. data/pages/Rails.md +60 -0
  56. data/pages/Security.md +20 -0
  57. data/test/activesupport4/decoding_test.rb +105 -0
  58. data/test/activesupport4/encoding_test.rb +531 -0
  59. data/test/activesupport4/test_helper.rb +41 -0
  60. data/test/activesupport5/decoding_test.rb +125 -0
  61. data/test/activesupport5/encoding_test.rb +483 -0
  62. data/test/activesupport5/encoding_test_cases.rb +90 -0
  63. data/test/activesupport5/test_helper.rb +50 -0
  64. data/test/activesupport5/time_zone_test_helpers.rb +24 -0
  65. data/test/json_gem/json_addition_test.rb +216 -0
  66. data/test/json_gem/json_common_interface_test.rb +143 -0
  67. data/test/json_gem/json_encoding_test.rb +109 -0
  68. data/test/json_gem/json_ext_parser_test.rb +20 -0
  69. data/test/json_gem/json_fixtures_test.rb +35 -0
  70. data/test/json_gem/json_generator_test.rb +383 -0
  71. data/test/json_gem/json_generic_object_test.rb +90 -0
  72. data/test/json_gem/json_parser_test.rb +470 -0
  73. data/test/json_gem/json_string_matching_test.rb +42 -0
  74. data/test/json_gem/test_helper.rb +18 -0
  75. data/test/perf_compat.rb +30 -28
  76. data/test/perf_object.rb +1 -1
  77. data/test/perf_strict.rb +18 -1
  78. data/test/sample.rb +0 -1
  79. data/test/test_compat.rb +169 -93
  80. data/test/test_custom.rb +355 -0
  81. data/test/test_file.rb +0 -8
  82. data/test/test_null.rb +376 -0
  83. data/test/test_object.rb +268 -3
  84. data/test/test_scp.rb +22 -1
  85. data/test/test_strict.rb +160 -4
  86. data/test/test_various.rb +52 -620
  87. data/test/tests.rb +14 -0
  88. data/test/tests_mimic.rb +14 -0
  89. data/test/tests_mimic_addition.rb +7 -0
  90. metadata +89 -47
  91. data/test/activesupport_datetime_test.rb +0 -23
  92. data/test/bug.rb +0 -51
  93. data/test/bug2.rb +0 -10
  94. data/test/bug3.rb +0 -46
  95. data/test/bug_fast.rb +0 -32
  96. data/test/bug_load.rb +0 -24
  97. data/test/crash.rb +0 -111
  98. data/test/curl/curl_oj.rb +0 -46
  99. data/test/curl/get_oj.rb +0 -24
  100. data/test/curl/just_curl.rb +0 -31
  101. data/test/curl/just_oj.rb +0 -51
  102. data/test/example.rb +0 -11
  103. data/test/foo.rb +0 -24
  104. data/test/io.rb +0 -48
  105. data/test/isolated/test_mimic_rails_datetime.rb +0 -27
  106. data/test/mod.rb +0 -16
  107. data/test/rails.rb +0 -50
  108. data/test/russian.rb +0 -18
  109. data/test/struct.rb +0 -29
  110. data/test/test_serializer.rb +0 -59
  111. data/test/write_timebars.rb +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '0680538f0b702ac222fce52dacf832b743d99578'
4
- data.tar.gz: 13a74b36cf681763823e8ca0f93a53704feafc41
3
+ metadata.gz: 7b5e26434d67518ead10da0ffb7f97ca0d05a0de
4
+ data.tar.gz: cdd5a57251a116ba7e7f1d16136821a5baa04869
5
5
  SHA512:
6
- metadata.gz: a73409be107f9c6b262ad17cf6051401602910270c1d7a2929b4e9877b2b29651fb9e4f08c0436462f37d55f04d8d7c2f5fdb6cb43817ad121bdda8f3056cfdd
7
- data.tar.gz: 21b43f4f2ebe1af8d84ece21671ea42178bdfe9b8ac9125d3b326695e792c3882490f654f62bb0a77345e43bd5658fd6e2e9fdff9d8b2d5275f561a456aa4236
6
+ metadata.gz: 1a9ab31bbf01cd8794e88a25adcbb989dead17ac17c76ea792d0580211e516f67b9224aaa64e85af62b1ba5a1a230693c6e14415443f33e04f683e2e0cb632f0
7
+ data.tar.gz: 6656a40ec3b1aea8de039062f76f00124c0af96e4679df3975c97e495ced5aa5811f628304ec23c52baa17b18780eee6f2705cd9dedc23e75626e733e3777872
data/README.md CHANGED
@@ -1,7 +1,13 @@
1
- # Oj gem
1
+ # [![{}j](http://www.ohler.com/dev/images/oj_hel_fire_64.png)](http://www.ohler.com/oj) gem
2
+
2
3
  [![Build Status](https://img.shields.io/travis/ohler55/oj/master.svg)](http://travis-ci.org/ohler55/oj?branch=master) ![Gem](https://img.shields.io/gem/v/oj.svg) ![Gem](https://img.shields.io/gem/dt/oj.svg)
3
4
 
4
- A fast JSON parser and Object marshaller as a Ruby gem.
5
+ A *fast* JSON parser and Object marshaller as a Ruby gem.
6
+
7
+ Version 3.0 is out! 3.0 provides better json gem and Rails compatibility. It
8
+ also provides additional optimization options.
9
+
10
+ Please check out issue #364 and help pick or suggest a image to represent Oj.
5
11
 
6
12
  ## Using
7
13
 
@@ -25,11 +31,6 @@ puts "Same? #{h == h2}"
25
31
  # true
26
32
  ```
27
33
 
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
34
  ## Installation
34
35
  ```
35
36
  gem install oj
@@ -41,247 +42,53 @@ or in Bundler:
41
42
  gem 'oj'
42
43
  ```
43
44
 
44
- ## Advanced
45
-
46
- Optimized JSON (Oj), as the name implies, was written to provide speed optimized
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.
50
-
51
- Oj has several `dump` or serialization modes which control how Ruby `Object`s are
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.
55
-
56
- The fastest alternative parser API is the `Oj::Doc` API. The `Oj::Doc` API takes
57
- a completely different approach by opening a JSON document and providing calls
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.
60
-
61
- The `Oj::Saj` and `Oj::ScHandler` APIs are callback parsers that
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.
66
-
67
- ### Options
68
-
69
- To change default serialization mode use the following form. Attempting to
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:
72
-
73
- ```ruby
74
- Oj.default_options = {:mode => :compat }
75
- ```
76
-
77
- ### Common (for serializer and parser) options
78
-
79
- * `:mode` [Symbol] mode for dumping and loading JSON. **Important format details [here](http://www.ohler.com/dev/oj_misc/encoding_format.html)**
80
-
81
- - `:object` mode will dump any `Object` as a JSON `Object` with keys that
82
- match the Ruby `Object`'s variable names without the '@' prefix
83
- character. This mode has the best performance and is the default
84
-
85
- - `:strict` mode will only allow the 7 basic JSON types to be serialized. Any
86
- other `Object` will raise an `Exception`
87
-
88
- - `:null` mode replaces any `Object` that is not one of the JSON types with a JSON `null`
89
-
90
- - `:compat` mode attempts to be compatible with other systems. It will
91
- serialize any `Object`, but will check to see if the `Object` implements an
92
- `to_hash` or `to_json` method. If either exists, that method is used for
93
- serializing the `Object`. Since `as_json` is more flexible and produces
94
- more consistent output, it is preferred over the `to_json` method. If
95
- neither the `to_json` or `to_hash` methods exists, then the Oj internal
96
- `Object` variable encoding is used
97
-
98
- * `:time_format` [Symbol] time format when dumping in :compat and :object mode
99
-
100
- - `:unix` time is output as a decimal number in seconds since epoch including
101
- fractions of a second.
102
-
103
- - `:unix_zone` similar to the `:unix` format but with the timezone encoded in
104
- the exponent of the decimal number of seconds since epoch.
105
-
106
- - `:xmlschema` time is output as a string that follows the XML schema definition.
107
-
108
- - `:ruby` time is output as a string formatted using the Ruby `to_s` conversion.
109
-
110
- * `:second_precision` [Fixnum] number of digits after the decimal when dumping
111
- the seconds portion of time
112
-
113
- * `:bigdecimal_as_decimal` [Boolean] dump BigDecimal as a decimal number
114
- or as a String
115
-
116
- * `:create_id` [String] create id for json compatible object encoding,
117
- default is `json_create`.
118
-
119
- * `:allow_gc` [Boolean] allow or prohibit GC during parsing, default is
120
- true (allow).
121
-
122
- * `:quirks_mode` [Boolean] Allow single JSON values instead of
123
- documents, default is true (allow).
124
-
125
- * `:allow_invalid_unicode` [Boolean] Allow invalid unicode, default is
126
- false (don't allow)
127
-
128
- * `:omit_nil` [Boolean] If true, Hash and Object attributes with nil values
129
- are omitted
130
-
131
- ### Serializer options
132
-
133
- * `:indent` [Fixnum] number of spaces to indent each element in an JSON
134
- document, zero is no newline between JSON elements, negative indicates no
135
- newline between top level JSON elements in a stream
136
-
137
- * `:circular` [Boolean] support circular references while dumping
138
-
139
- * `:escape_mode` [Symbol] determines the characters to escape
140
-
141
- - `:newline` allows unescaped newlines in the output
142
-
143
- - `:json` follows the JSON specification. This is the default mode
45
+ ## Further Reading
144
46
 
145
- - `:xss_safe` escapes HTML and XML characters such as `&` and `<`
47
+ For more details on options, modes, advanced features, and more follow these
48
+ links.
146
49
 
147
- - `:ascii` escapes all non-ascii or characters with the hi-bit set
148
-
149
- * `:use_to_json` [Boolean] call `to_json()` methods on dump, default is
150
- false
151
-
152
- * `:use_as_json` [Boolean] call `as_json()` methods on dump, default is
153
- false
154
-
155
- * `:nan` [Symbol] How to dump Infinity, -Infinity, and
156
- NaN in :null, :strict, and :compat mode. Default is :auto
157
-
158
- - `:null` places a null
159
-
160
- - `:huge` places a huge number
161
-
162
- - `:word` places Infinity or NaN
163
-
164
- - `:raise` raises and exception
165
-
166
- - `:auto` uses default for each mode which are `:raise` for `:strict`, `:null` for `:null`, and `:word` for `:compat`
167
-
168
- ### Parser options
169
-
170
- * `:auto_define` [Boolean] automatically define classes if they do not
171
- exist
172
-
173
- * `:symbol_keys` [Boolean] use symbols instead of strings for hash keys
174
-
175
- * `:class_cache` [Boolean] cache classes for faster parsing (if
176
- dynamically modifying classes or reloading classes then don't use this)
177
-
178
- * `:bigdecimal_load` [Symbol] load decimals as BigDecimal instead of as a
179
- Float
180
-
181
- - `:bigdecimal` convert all decimal numbers to BigDecimal
182
-
183
- - `:float` convert all decimal numbers to Float
184
-
185
- - `:auto` the most precise for the number of digits is used
186
-
187
- * `:float_precision` [Fixnum] number of digits of precision when dumping
188
- floats, 0 indicates use Ruby
189
-
190
- * `:nilnil` [Boolean] if true a nil input to load will return nil and
191
- not raise an Exception
192
-
193
- * `:empty_string` [Boolean] if true an empty input will not raise an
194
- Exception, default is true (allow). When Oj.mimic_JSON is used,
195
- default is false (raise exception when empty string is encountered)
196
-
197
- * `:hash_class` [Class] Class to use instead of Hash on load
50
+ - [{file:Options.md}](pages/Options.md) for parse and dump options.
51
+ - [{file:Modes.md}](pages/Modes.md) for details on modes for strict JSON compliance, mimicing the JSON gem, and mimicing Rails and ActiveSupport behavior.
52
+ - [{file:JsonGem.md}](pages/JsonGem.md) includes more details on json gem compatibility and use.
53
+ - [{file:Rails.md}](pages/Rails.md) includes more details on Rails and ActiveSupport compatibility and use.
54
+ - [{file:Custom.md}](pages/Custom.md) includes more details on Custom mode.
55
+ - [{file:Encoding.md}](pages/Encoding.md) describes the :object encoding format.
56
+ - [{file:Compatibility.md}](pages/Compatibility.md) lists current compatibility with Rubys and Rails.
57
+ - [{file:Advanced.md}](pages/Advanced.md) for fast parser and marshalling features.
58
+ - [{file:Security.md}](pages/Security.md) for security considerations.
198
59
 
199
60
  ## Releases
200
61
 
201
- See [CHANGELOG.md](CHANGELOG.md)
202
-
203
- ## Compatibility
204
-
205
- **Ruby**
206
-
207
- Oj is compatible with Ruby 1.9.3, 2.0.0, 2.1, 2.2, 2.3, 2.4 and RBX.
208
- Support for JRuby has been removed as JRuby no longer supports C extensions and
209
- there are bugs in the older versions that are not being fixed.
210
-
211
- **Rails**
212
-
213
- 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.
214
- There is a
215
- [gem to patch this](https://github.com/GoodLife/rails-patch-json-encode) for
216
- Rails 3.2 and 4.0. As of the Oj 2.6.0 release the default behavior is to not use
217
- the `to_json()` method unless the `:use_to_json` option is set. This provides
218
- another work around to the rails older and newer behavior.
219
-
220
- The latest ActiveRecord is able to work with Oj by simply using the line:
221
-
222
- ```
223
- serialize :metadata, Oj
224
- ```
225
-
226
- In version Rails 4.1, multi_json has been removed, and this patch is unnecessary and will no longer work.
227
- 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:
228
-
229
- ```
230
- gem 'oj'
231
- gem 'oj_mimic_json'
232
- ```
233
-
234
- ## Security and Optimization
235
-
236
- Two settings in Oj are useful for parsing but do expose a vulnerability if used
237
- from an untrusted source. Symbolized keys can cause memory to be filled with
238
- previous versions of ruby. Ruby 2.1 and below does not garbage collect
239
- Symbols. The same is true for auto defining classes in all versions of ruby;
240
- memory will also be exhausted if too many classes are automatically
241
- defined. Auto defining is a useful feature during development and from trusted
242
- sources but it allows too many classes to be created in the object load mode and
243
- auto defined is used with an untrusted source. The `Oj.strict_load()` method
244
- sets and uses the most strict and safest options. It should be used by
245
- developers who find it difficult to understand the options available in Oj.
246
-
247
- The options in Oj are designed to provide flexibility to the developer. This
248
- flexibility allows Objects to be serialized and deserialized. No methods are
249
- ever called on these created Objects but that does not stop the developer from
250
- calling methods on them. As in any system, check your inputs before working with
251
- them. Taking an arbitrary `String` from a user and evaluating it is never a good
252
- idea from an unsecure source. The same is true for `Object` attributes as they
253
- are not more than `String`s. Always check inputs from untrusted sources.
62
+ See [{file:CHANGELOG.md}](CHANGELOG.md)
254
63
 
255
64
  ## Links
256
65
 
257
- *Documentation*: http://www.ohler.com/oj, http://rubydoc.info/gems/oj
66
+ - *Documentation*: http://www.ohler.com/oj, http://rubydoc.info/gems/oj
258
67
 
259
- *GitHub* *repo*: https://github.com/ohler55/oj
68
+ - *GitHub* *repo*: https://github.com/ohler55/oj
260
69
 
261
- *RubyGems* *repo*: https://rubygems.org/gems/oj
70
+ - *RubyGems* *repo*: https://rubygems.org/gems/oj
262
71
 
263
72
  Follow [@peterohler on Twitter](http://twitter.com/#!/peterohler) for announcements and news about the Oj gem.
264
73
 
265
74
  #### Performance Comparisons
266
75
 
267
- [Oj Strict Mode Performance](http://www.ohler.com/dev/oj_misc/performance_strict.html) compares Oj strict mode parser performance to other JSON parsers.
76
+ - [Oj Strict Mode Performance](http://www.ohler.com/dev/oj_misc/performance_strict.html) compares Oj strict mode parser performance to other JSON parsers.
268
77
 
269
- [Oj Compat Mode Performance](http://www.ohler.com/dev/oj_misc/performance_compat.html) compares Oj compat mode parser performance to other JSON parsers.
78
+ - [Oj Compat Mode Performance](http://www.ohler.com/dev/oj_misc/performance_compat.html) compares Oj compat mode parser performance to other JSON parsers.
270
79
 
271
- [Oj Object Mode Performance](http://www.ohler.com/dev/oj_misc/performance_object.html) compares Oj object mode parser performance to other marshallers.
80
+ - [Oj Object Mode Performance](http://www.ohler.com/dev/oj_misc/performance_object.html) compares Oj object mode parser performance to other marshallers.
272
81
 
273
- [Oj Callback Performance](http://www.ohler.com/dev/oj_misc/performance_callback.html) compares Oj callback parser performance to other JSON parsers.
82
+ - [Oj Callback Performance](http://www.ohler.com/dev/oj_misc/performance_callback.html) compares Oj callback parser performance to other JSON parsers.
274
83
 
275
84
  #### Links of Interest
276
85
 
277
- *Fast XML parser and marshaller on RubyGems*: https://rubygems.org/gems/ox
278
-
279
- *Fast XML parser and marshaller on GitHub*: https://github.com/ohler55/ox
86
+ - *Fast XML parser and marshaller on RubyGems*: https://rubygems.org/gems/ox
280
87
 
281
- [Oj Object Encoding Format](http://www.ohler.com/dev/oj_misc/encoding_format.html) describes the OJ Object JSON encoding format.
88
+ - *Fast XML parser and marshaller on GitHub*: https://github.com/ohler55/ox
282
89
 
283
- [Need for Speed](http://www.ohler.com/dev/need_for_speed/need_for_speed.html) for an overview of how Oj::Doc was designed.
90
+ - [Need for Speed](http://www.ohler.com/dev/need_for_speed/need_for_speed.html) for an overview of how Oj::Doc was designed.
284
91
 
285
- *OjC, a C JSON parser*: https://www.ohler.com/ojc also at https://github.com/ohler55/ojc
92
+ - *OjC, a C JSON parser*: https://www.ohler.com/ojc also at https://github.com/ohler55/ojc
286
93
 
287
- *Piper Push Cache, push JSON to browsers*: http://www.piperpushcache.com
94
+ - *Piper Push Cache, push JSON to browsers*: http://www.piperpushcache.com
@@ -1,31 +1,6 @@
1
1
  /* circarray.c
2
2
  * Copyright (c) 2012, Peter Ohler
3
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
4
  */
30
5
 
31
6
  #include "circarray.h"
@@ -1,31 +1,6 @@
1
1
  /* circarray.h
2
2
  * Copyright (c) 2012, Peter Ohler
3
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
4
  */
30
5
 
31
6
  #ifndef __OJ_CIRCARRAY_H__
@@ -0,0 +1,227 @@
1
+ /* code.c
2
+ * Copyright (c) 2017, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #include "code.h"
7
+ #include "dump.h"
8
+
9
+ inline static VALUE
10
+ resolve_classname(VALUE mod, const char *classname) {
11
+ VALUE clas = Qundef;
12
+ ID ci = rb_intern(classname);
13
+
14
+ if (rb_const_defined_at(mod, ci)) {
15
+ clas = rb_const_get_at(mod, ci);
16
+ }
17
+ return clas;
18
+ }
19
+
20
+ static VALUE
21
+ path2class(const char *name) {
22
+ char class_name[1024];
23
+ VALUE clas;
24
+ char *end = class_name + sizeof(class_name) - 1;
25
+ char *s;
26
+ const char *n = name;
27
+
28
+ clas = rb_cObject;
29
+ for (s = class_name; '\0' != *n; n++) {
30
+ if (':' == *n) {
31
+ *s = '\0';
32
+ n++;
33
+ if (':' != *n) {
34
+ return Qundef;
35
+ }
36
+ if (Qundef == (clas = resolve_classname(clas, class_name))) {
37
+ return Qundef;
38
+ }
39
+ s = class_name;
40
+ } else if (end <= s) {
41
+ return Qundef;
42
+ } else {
43
+ *s++ = *n;
44
+ }
45
+ }
46
+ *s = '\0';
47
+
48
+ return resolve_classname(clas, class_name);
49
+ }
50
+
51
+ bool
52
+ oj_code_dump(Code codes, VALUE obj, int depth, Out out) {
53
+ VALUE clas = rb_obj_class(obj);
54
+ Code c = codes;
55
+
56
+ for (; NULL != c->name; c++) {
57
+ if (Qundef == c->clas) { // indicates not defined
58
+ continue;
59
+ }
60
+ if (Qnil == c->clas) {
61
+ c->clas = path2class(c->name);
62
+ }
63
+ if (clas == c->clas && c->active) {
64
+ c->encode(obj, depth, out);
65
+ return true;
66
+ }
67
+ }
68
+ return false;
69
+ }
70
+
71
+ VALUE
72
+ oj_code_load(Code codes, VALUE clas, VALUE args) {
73
+ Code c = codes;
74
+
75
+ for (; NULL != c->name; c++) {
76
+ if (Qundef == c->clas) { // indicates not defined
77
+ continue;
78
+ }
79
+ if (Qnil == c->clas) {
80
+ c->clas = path2class(c->name);
81
+ }
82
+ if (clas == c->clas) {
83
+ if (NULL == c->decode) {
84
+ break;
85
+ }
86
+ return c->decode(clas, args);
87
+ }
88
+ }
89
+ return Qnil;
90
+ }
91
+
92
+ void
93
+ oj_code_set_active(Code codes, VALUE clas, bool active) {
94
+ Code c = codes;
95
+
96
+ for (; NULL != c->name; c++) {
97
+ if (Qundef == c->clas) { // indicates not defined
98
+ continue;
99
+ }
100
+ if (Qnil == c->clas) {
101
+ c->clas = path2class(c->name);
102
+ }
103
+ if (clas == c->clas || Qnil == clas) {
104
+ c->active = active;
105
+ if (Qnil != clas) {
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ bool
113
+ oj_code_has(Code codes, VALUE clas, bool encode) {
114
+ Code c = codes;
115
+
116
+ for (; NULL != c->name; c++) {
117
+ if (Qundef == c->clas) { // indicates not defined
118
+ continue;
119
+ }
120
+ if (Qnil == c->clas) {
121
+ c->clas = path2class(c->name);
122
+ }
123
+ if (clas == c->clas) {
124
+ if (encode) {
125
+ return c->active && NULL != c->encode;
126
+ } else {
127
+ return c->active && NULL != c->decode;
128
+ }
129
+ }
130
+ }
131
+ return false;
132
+ }
133
+
134
+ void
135
+ oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out) {
136
+ int d2 = depth + 1;
137
+ int d3 = d2 + 1;
138
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
139
+ const char *classname = rb_obj_classname(obj);
140
+ size_t len = strlen(classname);
141
+ size_t size = d2 * out->indent + 10 + len + out->opts->create_id_len + sep_len;
142
+
143
+ assure_size(out, size);
144
+ *out->cur++ = '{';
145
+ fill_indent(out, d2);
146
+ *out->cur++ = '"';
147
+ memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
148
+ out->cur += out->opts->create_id_len;
149
+ *out->cur++ = '"';
150
+ if (0 < out->opts->dump_opts.before_size) {
151
+ strcpy(out->cur, out->opts->dump_opts.before_sep);
152
+ out->cur += out->opts->dump_opts.before_size;
153
+ }
154
+ *out->cur++ = ':';
155
+ if (0 < out->opts->dump_opts.after_size) {
156
+ strcpy(out->cur, out->opts->dump_opts.after_sep);
157
+ out->cur += out->opts->dump_opts.after_size;
158
+ }
159
+ *out->cur++ = '"';
160
+ memcpy(out->cur, classname, len);
161
+ out->cur += len;
162
+ *out->cur++ = '"';
163
+
164
+ size = d3 * out->indent + 2;
165
+ for (; NULL != attrs->name; attrs++) {
166
+ assure_size(out, size + attrs->len + sep_len + 2);
167
+ *out->cur++ = ',';
168
+ fill_indent(out, d3);
169
+ *out->cur++ = '"';
170
+ memcpy(out->cur, attrs->name, attrs->len);
171
+ out->cur += attrs->len;
172
+ *out->cur++ = '"';
173
+ if (0 < out->opts->dump_opts.before_size) {
174
+ strcpy(out->cur, out->opts->dump_opts.before_sep);
175
+ out->cur += out->opts->dump_opts.before_size;
176
+ }
177
+ *out->cur++ = ':';
178
+ if (0 < out->opts->dump_opts.after_size) {
179
+ strcpy(out->cur, out->opts->dump_opts.after_sep);
180
+ out->cur += out->opts->dump_opts.after_size;
181
+ }
182
+ if (Qundef == attrs->value) {
183
+ if (Qundef != attrs->time) {
184
+ switch (out->opts->time_format) {
185
+ case RubyTime: oj_dump_ruby_time(attrs->time, out); break;
186
+ case XmlTime: oj_dump_xml_time(attrs->time, out); break;
187
+ case UnixZTime: oj_dump_time(attrs->time, out, true); break;
188
+ case UnixTime:
189
+ default: oj_dump_time(attrs->time, out, false); break;
190
+ }
191
+ } else {
192
+ char buf[32];
193
+ char *b = buf + sizeof(buf) - 1;
194
+ int neg = 0;
195
+ long num = attrs->num;
196
+
197
+ if (0 > num) {
198
+ neg = 1;
199
+ num = -num;
200
+ }
201
+ *b-- = '\0';
202
+ if (0 < num) {
203
+ for (; 0 < num; num /= 10, b--) {
204
+ *b = (num % 10) + '0';
205
+ }
206
+ if (neg) {
207
+ *b = '-';
208
+ } else {
209
+ b++;
210
+ }
211
+ } else {
212
+ *b = '0';
213
+ }
214
+ assure_size(out, (sizeof(buf) - (b - buf)));
215
+ for (; '\0' != *b; b++) {
216
+ *out->cur++ = *b;
217
+ }
218
+ }
219
+ } else {
220
+ oj_dump_compat_val(attrs->value, d3, out, true);
221
+ }
222
+ }
223
+ assure_size(out, depth * out->indent + 2);
224
+ fill_indent(out, depth);
225
+ *out->cur++ = '}';
226
+ *out->cur = '\0';
227
+ }