json_pure 2.7.2 → 2.7.4
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 +4 -4
- data/BSDL +22 -0
- data/CHANGES.md +44 -17
- data/LEGAL +60 -0
- data/README.md +13 -165
- data/json_pure.gemspec +9 -7
- data/lib/json/add/bigdecimal.rb +1 -1
- data/lib/json/add/complex.rb +1 -1
- data/lib/json/add/core.rb +1 -1
- data/lib/json/add/date.rb +1 -1
- data/lib/json/add/date_time.rb +1 -1
- data/lib/json/add/exception.rb +1 -1
- data/lib/json/add/ostruct.rb +1 -1
- data/lib/json/add/range.rb +1 -1
- data/lib/json/add/rational.rb +1 -1
- data/lib/json/add/regexp.rb +1 -1
- data/lib/json/add/struct.rb +1 -1
- data/lib/json/add/symbol.rb +1 -2
- data/lib/json/add/time.rb +3 -10
- data/lib/json/common.rb +74 -43
- data/lib/json/ext.rb +15 -5
- data/lib/json/generic_object.rb +1 -1
- data/lib/json/pure/generator.rb +89 -22
- data/lib/json/pure/parser.rb +27 -33
- data/lib/json/pure.rb +1 -0
- data/lib/json/version.rb +3 -7
- data/lib/json.rb +1 -1
- metadata +16 -11
- /data/{LICENSE → COPYING} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '088e992126b90dfedd6384a72ef625d2ba88fc512d53c456d6dace2e47113f74'
|
4
|
+
data.tar.gz: 56f1c68c346faea122ebfd5883ee23231d773a395ffa12a73992fe7e848ae4f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fd7d0ff4b86c5be76e3556b5568ec03eb4dd33f07349945b13ed91fd46766c24cb0251d9abc821519ae2a5e99659e90ce67cda3749564a09a53779acd2478c1
|
7
|
+
data.tar.gz: 814eb2de2b847e014cac1115b8c41c40267d13f377afedcaa28443aa08c3dbf3f8b965167e53c360d8061743fb6a95999a3f8b2aea87b5b0d041055c8e23bc99
|
data/BSDL
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions
|
5
|
+
are met:
|
6
|
+
1. Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
13
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
14
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
15
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
16
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
17
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
18
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
19
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
20
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
21
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
22
|
+
SUCH DAMAGE.
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Changes
|
2
2
|
|
3
|
+
### 2024-10-25 (2.7.4)
|
4
|
+
|
5
|
+
* Workaround a bug in 3.4.8 and older https://github.com/rubygems/rubygems/pull/6490.
|
6
|
+
This bug would cause some gems with native extension to fail during compilation.
|
7
|
+
* Workaround different versions of `json` and `json_pure` being loaded (not officially supported).
|
8
|
+
* Make `json_pure` Ractor compatible.
|
9
|
+
|
10
|
+
### 2024-10-24 (2.7.3)
|
11
|
+
|
12
|
+
* Numerous performance optimizations in `JSON.generate` and `JSON.dump` (up to 2 times faster).
|
13
|
+
* Limit the size of ParserError exception messages, only include up to 32 bytes of the unparseable source.
|
14
|
+
* Fix json-pure's `Object#to_json` to accept non state arguments
|
15
|
+
* Fix multiline comment support in `json-pure`.
|
16
|
+
* Fix `JSON.parse` to no longer mutate the argument encoding when passed an ASCII-8BIT string.
|
17
|
+
* Fix `String#to_json` to raise on invalid encoding in `json-pure`.
|
18
|
+
* Delete code that was based on CVTUTF.
|
19
|
+
* Use the pure-Ruby generator on TruffleRuby.
|
20
|
+
* Fix `strict` mode in `json-pure` to not break on Integer.
|
21
|
+
|
22
|
+
### 2024-04-04 (2.7.2)
|
23
|
+
|
24
|
+
* Use rb_sym2str instead of SYM2ID #561
|
25
|
+
* Fix memory leak when exception is raised during JSON generation #574
|
26
|
+
* Remove references to "19" methods in JRuby #576
|
27
|
+
* Make OpenStruct support as optional by @hsbt in #565
|
28
|
+
* Autoload JSON::GenericObject to avoid require ostruct warning in Ruby 3.4 #577
|
29
|
+
* Warn to install ostruct if json couldn't load it by @hsbt #578
|
30
|
+
|
3
31
|
### 2023-12-05 (2.7.1)
|
4
32
|
|
5
33
|
* JSON.dump: handle unenclosed hashes regression #554
|
@@ -168,7 +196,7 @@
|
|
168
196
|
* Remove Rubinius exception since transcoding should be working now.
|
169
197
|
|
170
198
|
## 2013-05-13 (1.8.0)
|
171
|
-
* Fix https://github.com/
|
199
|
+
* Fix https://github.com/ruby/json/issues/162 reported by Marc-Andre
|
172
200
|
Lafortune <github_rocks@marc-andre.ca>. Thanks!
|
173
201
|
* Applied patches by Yui NARUSE <naruse@airemix.jp> to suppress warning with
|
174
202
|
-Wchar-subscripts and better validate UTF-8 strings.
|
@@ -188,7 +216,7 @@
|
|
188
216
|
JSON::GenericObject.json_creatable = true
|
189
217
|
as well.
|
190
218
|
* Remove useless assert in fbuffer implementation.
|
191
|
-
* Apply patch attached to https://github.com/
|
219
|
+
* Apply patch attached to https://github.com/ruby/json/issues#issue/155
|
192
220
|
provided by John Shahid <jvshahid@gmail.com>, Thx!
|
193
221
|
* Add license information to rubygems spec data, reported by Jordi Massaguer Pla <jmassaguerpla@suse.de>.
|
194
222
|
* Improve documentation, thx to Zachary Scott <zachary@zacharyscott.net>.
|
@@ -202,7 +230,7 @@
|
|
202
230
|
* Fix compilation of extension on older rubies.
|
203
231
|
|
204
232
|
## 2012-07-26 (1.7.4)
|
205
|
-
* Fix compilation problem on AIX, see https://github.com/
|
233
|
+
* Fix compilation problem on AIX, see https://github.com/ruby/json/issues/142
|
206
234
|
|
207
235
|
## 2012-05-12 (1.7.3)
|
208
236
|
* Work around Rubinius encoding issues using iconv for conversion instead.
|
@@ -224,9 +252,9 @@
|
|
224
252
|
* Propagate src encoding to values made from it (fixes 1.9 mode converting
|
225
253
|
everything to ascii-8bit; harmless for 1.8 mode too) (Thomas E. Enebo
|
226
254
|
<tom.enebo@gmail.com>), should fix
|
227
|
-
https://github.com/
|
228
|
-
* Fix https://github.com/
|
229
|
-
* Fix https://github.com/
|
255
|
+
https://github.com/ruby/json/issues#issue/119.
|
256
|
+
* Fix https://github.com/ruby/json/issues#issue/124 Thx to Jason Hutchens.
|
257
|
+
* Fix https://github.com/ruby/json/issues#issue/117
|
230
258
|
|
231
259
|
## 2012-01-15 (1.6.5)
|
232
260
|
* Vit Ondruch <v.ondruch@tiscali.cz> reported a bug that shows up when using
|
@@ -253,7 +281,7 @@
|
|
253
281
|
patch go to Josh Partlow (jpartlow@github).
|
254
282
|
* Improve parsing speed for JSON numbers (integers and floats) in a similar way to
|
255
283
|
what Evan Phoenix <evan@phx.io> suggested in:
|
256
|
-
https://github.com/
|
284
|
+
https://github.com/ruby/json/pull/103
|
257
285
|
|
258
286
|
## 2011-09-18 (1.6.1)
|
259
287
|
* Using -target 1.5 to force Java bits to compile with 1.5.
|
@@ -266,15 +294,14 @@
|
|
266
294
|
* Fix memory leak when used from multiple JRuby. (Patch by
|
267
295
|
jfirebaugh@github).
|
268
296
|
* Apply patch by Eric Wong <nocode@yhbt.net> that fixes garbage collection problem
|
269
|
-
reported in https://github.com/
|
297
|
+
reported in https://github.com/ruby/json/issues/46.
|
270
298
|
* Add :quirks_mode option to parser and generator.
|
271
299
|
* Add support for Rational and Complex number additions via json/add/complex
|
272
300
|
and json/add/rational requires.
|
273
301
|
|
274
302
|
## 2011-06-20 (1.5.3)
|
275
303
|
* Alias State#configure method as State#merge to increase duck type synonymy with Hash.
|
276
|
-
|
277
|
-
the new way.
|
304
|
+
* Add `as_json` methods in json/add/core, so rails can create its json objects the new way.
|
278
305
|
|
279
306
|
## 2011-05-11 (1.5.2)
|
280
307
|
* Apply documentation patch by Cory Monty <cory.monty@gmail.com>.
|
@@ -285,7 +312,7 @@
|
|
285
312
|
|
286
313
|
## 2011-01-24 (1.5.1)
|
287
314
|
* Made rake-compiler build a fat binary gem. This should fix issue
|
288
|
-
https://github.com/
|
315
|
+
https://github.com/ruby/json/issues#issue/54.
|
289
316
|
|
290
317
|
## 2011-01-22 (1.5.0)
|
291
318
|
* Included Java source codes for the Jruby extension made by Daniel Luz
|
@@ -295,7 +322,7 @@
|
|
295
322
|
reported by Riley Goodside.
|
296
323
|
|
297
324
|
## 2010-08-09 (1.4.6)
|
298
|
-
* Fixed oversight reported in http://github.com/
|
325
|
+
* Fixed oversight reported in http://github.com/ruby/json/issues/closed#issue/23,
|
299
326
|
always create a new object from the state prototype.
|
300
327
|
* Made pure and ext api more similar again.
|
301
328
|
|
@@ -305,12 +332,12 @@
|
|
305
332
|
argument.
|
306
333
|
* Some fixes in the state objects and additional tests.
|
307
334
|
## 2010-08-06 (1.4.4)
|
308
|
-
* Fixes build problem for rubinius under OS X, http://github.com/
|
309
|
-
* Fixes crashes described in http://github.com/
|
310
|
-
http://github.com/
|
335
|
+
* Fixes build problem for rubinius under OS X, http://github.com/ruby/json/issues/closed#issue/25
|
336
|
+
* Fixes crashes described in http://github.com/ruby/json/issues/closed#issue/21 and
|
337
|
+
http://github.com/ruby/json/issues/closed#issue/23
|
311
338
|
## 2010-05-05 (1.4.3)
|
312
339
|
* Fixed some test assertions, from Ruby r27587 and r27590, patch by nobu.
|
313
|
-
* Fixed issue http://github.com/
|
340
|
+
* Fixed issue http://github.com/ruby/json/issues/#issue/20 reported by
|
314
341
|
electronicwhisper@github. Thx!
|
315
342
|
|
316
343
|
## 2010-04-26 (1.4.2)
|
@@ -332,7 +359,7 @@
|
|
332
359
|
* Extension should at least be compatible with MRI, YARV and Rubinius.
|
333
360
|
|
334
361
|
## 2010-04-07 (1.2.4)
|
335
|
-
*
|
362
|
+
* Trigger const_missing callback to make Rails' dynamic class loading work.
|
336
363
|
|
337
364
|
## 2010-03-11 (1.2.3)
|
338
365
|
* Added a `State#[]` method which returns an attribute's value in order to
|
data/LEGAL
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- rdoc -*-
|
2
|
+
|
3
|
+
= LEGAL NOTICE INFORMATION
|
4
|
+
--------------------------
|
5
|
+
|
6
|
+
All the files in this distribution are covered under either the Ruby's
|
7
|
+
license (see the file COPYING) or public-domain except some files
|
8
|
+
mentioned below.
|
9
|
+
|
10
|
+
== MIT License
|
11
|
+
>>>
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
13
|
+
a copy of this software and associated documentation files (the
|
14
|
+
"Software"), to deal in the Software without restriction, including
|
15
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
16
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
17
|
+
permit persons to whom the Software is furnished to do so, subject to
|
18
|
+
the following conditions:
|
19
|
+
|
20
|
+
The above copyright notice and this permission notice shall be
|
21
|
+
included in all copies or substantial portions of the Software.
|
22
|
+
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
24
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
25
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
26
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
27
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
28
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
29
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
30
|
+
|
31
|
+
== Old-style BSD license
|
32
|
+
>>>
|
33
|
+
Redistribution and use in source and binary forms, with or without
|
34
|
+
modification, are permitted provided that the following conditions
|
35
|
+
are met:
|
36
|
+
1. Redistributions of source code must retain the above copyright
|
37
|
+
notice, this list of conditions and the following disclaimer.
|
38
|
+
2. Redistributions in binary form must reproduce the above copyright
|
39
|
+
notice, this list of conditions and the following disclaimer in the
|
40
|
+
documentation and/or other materials provided with the distribution.
|
41
|
+
3. Neither the name of the University nor the names of its contributors
|
42
|
+
may be used to endorse or promote products derived from this software
|
43
|
+
without specific prior written permission.
|
44
|
+
|
45
|
+
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
46
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
47
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
48
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
49
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
50
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
51
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
52
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
53
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
54
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
55
|
+
SUCH DAMAGE.
|
56
|
+
|
57
|
+
IMPORTANT NOTE::
|
58
|
+
|
59
|
+
From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
60
|
+
paragraph 3 above is now null and void.
|
data/README.md
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
# JSON implementation for Ruby
|
2
2
|
|
3
|
-
[](https://github.com/ruby/json/actions/workflows/ci.yml)
|
4
4
|
|
5
5
|
## Description
|
6
6
|
|
7
|
-
This is
|
8
|
-
http://www.ietf.org/rfc/rfc7159.txt .
|
9
|
-
will be two variants available:
|
7
|
+
This is an implementation of the JSON specification according to RFC 7159
|
8
|
+
http://www.ietf.org/rfc/rfc7159.txt . There is two variants available:
|
10
9
|
|
11
|
-
* A pure ruby variant, that relies on the
|
12
|
-
|
10
|
+
* A pure ruby variant, that relies on the `strscan` extensions, which is
|
11
|
+
part of the ruby standard library.
|
13
12
|
* The quite a bit faster native extension variant, which is in parts
|
14
|
-
implemented in C or Java and comes with
|
15
|
-
|
13
|
+
implemented in C or Java and comes with a parser generated by the [Ragel]
|
14
|
+
state machine compiler.
|
16
15
|
|
17
16
|
Both variants of the JSON generator generate UTF-8 character sequences by
|
18
17
|
default. If an :ascii\_only option with a true value is given, they escape all
|
@@ -32,45 +31,19 @@ It's recommended to use the extension variant of JSON, because it's faster than
|
|
32
31
|
the pure ruby variant. If you cannot build it on your system, you can settle
|
33
32
|
for the latter.
|
34
33
|
|
35
|
-
|
34
|
+
Install the gem and add to the application's Gemfile by executing:
|
36
35
|
|
37
|
-
|
38
|
-
# rake install
|
39
|
-
```
|
40
|
-
|
41
|
-
The above command will build the extensions and install them on your system.
|
42
|
-
|
43
|
-
```
|
44
|
-
# rake install_pure
|
45
|
-
```
|
46
|
-
|
47
|
-
or
|
48
|
-
|
49
|
-
```
|
50
|
-
# ruby install.rb
|
51
|
-
```
|
36
|
+
$ bundle add json
|
52
37
|
|
53
|
-
|
38
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
54
39
|
|
55
|
-
|
40
|
+
$ gem install json
|
56
41
|
|
57
|
-
```
|
58
|
-
# gem install json
|
59
|
-
```
|
60
|
-
|
61
|
-
instead, to install the newest JSON version.
|
62
42
|
|
63
43
|
There is also a pure ruby json only variant of the gem, that can be installed
|
64
44
|
with:
|
65
45
|
|
66
|
-
|
67
|
-
# gem install json_pure
|
68
|
-
```
|
69
|
-
|
70
|
-
## Compiling the extensions yourself
|
71
|
-
|
72
|
-
If you want to create the `parser.c` file from its `parser.rl` file or draw nice
|
73
|
-
graphviz images of the state machines, you need [Ragel].
|
46
|
+
$ gem install json_pure
|
74
47
|
|
75
48
|
## Usage
|
76
49
|
|
@@ -254,136 +227,11 @@ There are also the methods `Kernel#j` for generate, and `Kernel#jj` for
|
|
254
227
|
`pretty_generate` output to the console, that work analogous to Core Ruby's `p` and
|
255
228
|
the `pp` library's `pp` methods.
|
256
229
|
|
257
|
-
The script `tools/server.rb` contains a small example if you want to test, how
|
258
|
-
receiving a JSON object from a webrick server in your browser with the
|
259
|
-
JavaScript prototype library http://www.prototypejs.org works.
|
260
|
-
|
261
|
-
## Speed Comparisons
|
262
|
-
|
263
|
-
I have created some benchmark results (see the benchmarks/data-p4-3Ghz
|
264
|
-
subdir of the package) for the JSON-parser to estimate the speed up in the C
|
265
|
-
extension:
|
266
|
-
|
267
|
-
```
|
268
|
-
Comparing times (call_time_mean):
|
269
|
-
1 ParserBenchmarkExt#parser 900 repeats:
|
270
|
-
553.922304770 ( real) -> 21.500x
|
271
|
-
0.001805307
|
272
|
-
2 ParserBenchmarkYAML#parser 1000 repeats:
|
273
|
-
224.513358139 ( real) -> 8.714x
|
274
|
-
0.004454078
|
275
|
-
3 ParserBenchmarkPure#parser 1000 repeats:
|
276
|
-
26.755020642 ( real) -> 1.038x
|
277
|
-
0.037376163
|
278
|
-
4 ParserBenchmarkRails#parser 1000 repeats:
|
279
|
-
25.763381731 ( real) -> 1.000x
|
280
|
-
0.038814780
|
281
|
-
calls/sec ( time) -> speed covers
|
282
|
-
secs/call
|
283
|
-
```
|
284
|
-
|
285
|
-
In the table above 1 is `JSON::Ext::Parser`, 2 is `YAML.load` with YAML
|
286
|
-
compatible JSON document, 3 is is `JSON::Pure::Parser`, and 4 is
|
287
|
-
`ActiveSupport::JSON.decode`. The ActiveSupport JSON-decoder converts the
|
288
|
-
input first to YAML and then uses the YAML-parser, the conversion seems to
|
289
|
-
slow it down so much that it is only as fast as the `JSON::Pure::Parser`!
|
290
|
-
|
291
|
-
If you look at the benchmark data you can see that this is mostly caused by
|
292
|
-
the frequent high outliers - the median of the Rails-parser runs is still
|
293
|
-
overall smaller than the median of the `JSON::Pure::Parser` runs:
|
294
|
-
|
295
|
-
```
|
296
|
-
Comparing times (call_time_median):
|
297
|
-
1 ParserBenchmarkExt#parser 900 repeats:
|
298
|
-
800.592479481 ( real) -> 26.936x
|
299
|
-
0.001249075
|
300
|
-
2 ParserBenchmarkYAML#parser 1000 repeats:
|
301
|
-
271.002390644 ( real) -> 9.118x
|
302
|
-
0.003690004
|
303
|
-
3 ParserBenchmarkRails#parser 1000 repeats:
|
304
|
-
30.227910865 ( real) -> 1.017x
|
305
|
-
0.033082008
|
306
|
-
4 ParserBenchmarkPure#parser 1000 repeats:
|
307
|
-
29.722384421 ( real) -> 1.000x
|
308
|
-
0.033644676
|
309
|
-
calls/sec ( time) -> speed covers
|
310
|
-
secs/call
|
311
|
-
```
|
312
|
-
|
313
|
-
I have benchmarked the `JSON-Generator` as well. This generated a few more
|
314
|
-
values, because there are different modes that also influence the achieved
|
315
|
-
speed:
|
316
|
-
|
317
|
-
```
|
318
|
-
Comparing times (call_time_mean):
|
319
|
-
1 GeneratorBenchmarkExt#generator_fast 1000 repeats:
|
320
|
-
547.354332608 ( real) -> 15.090x
|
321
|
-
0.001826970
|
322
|
-
2 GeneratorBenchmarkExt#generator_safe 1000 repeats:
|
323
|
-
443.968212317 ( real) -> 12.240x
|
324
|
-
0.002252414
|
325
|
-
3 GeneratorBenchmarkExt#generator_pretty 900 repeats:
|
326
|
-
375.104545883 ( real) -> 10.341x
|
327
|
-
0.002665923
|
328
|
-
4 GeneratorBenchmarkPure#generator_fast 1000 repeats:
|
329
|
-
49.978706968 ( real) -> 1.378x
|
330
|
-
0.020008521
|
331
|
-
5 GeneratorBenchmarkRails#generator 1000 repeats:
|
332
|
-
38.531868759 ( real) -> 1.062x
|
333
|
-
0.025952543
|
334
|
-
6 GeneratorBenchmarkPure#generator_safe 1000 repeats:
|
335
|
-
36.927649925 ( real) -> 1.018x 7 (>=3859)
|
336
|
-
0.027079979
|
337
|
-
7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
|
338
|
-
36.272134441 ( real) -> 1.000x 6 (>=3859)
|
339
|
-
0.027569373
|
340
|
-
calls/sec ( time) -> speed covers
|
341
|
-
secs/call
|
342
|
-
```
|
343
|
-
|
344
|
-
In the table above 1-3 are `JSON::Ext::Generator` methods. 4, 6, and 7 are
|
345
|
-
`JSON::Pure::Generator` methods and 5 is the Rails JSON generator. It is now a
|
346
|
-
bit faster than the `generator_safe` and `generator_pretty` methods of the pure
|
347
|
-
variant but slower than the others.
|
348
|
-
|
349
|
-
To achieve the fastest JSON document output, you can use the `fast_generate`
|
350
|
-
method. Beware, that this will disable the checking for circular Ruby data
|
351
|
-
structures, which may cause JSON to go into an infinite loop.
|
352
|
-
|
353
|
-
Here are the median comparisons for completeness' sake:
|
354
|
-
|
355
|
-
```
|
356
|
-
Comparing times (call_time_median):
|
357
|
-
1 GeneratorBenchmarkExt#generator_fast 1000 repeats:
|
358
|
-
708.258020939 ( real) -> 16.547x
|
359
|
-
0.001411915
|
360
|
-
2 GeneratorBenchmarkExt#generator_safe 1000 repeats:
|
361
|
-
569.105020353 ( real) -> 13.296x
|
362
|
-
0.001757145
|
363
|
-
3 GeneratorBenchmarkExt#generator_pretty 900 repeats:
|
364
|
-
482.825371244 ( real) -> 11.280x
|
365
|
-
0.002071142
|
366
|
-
4 GeneratorBenchmarkPure#generator_fast 1000 repeats:
|
367
|
-
62.717626652 ( real) -> 1.465x
|
368
|
-
0.015944481
|
369
|
-
5 GeneratorBenchmarkRails#generator 1000 repeats:
|
370
|
-
43.965681162 ( real) -> 1.027x
|
371
|
-
0.022745013
|
372
|
-
6 GeneratorBenchmarkPure#generator_safe 1000 repeats:
|
373
|
-
43.929073409 ( real) -> 1.026x 7 (>=3859)
|
374
|
-
0.022763968
|
375
|
-
7 GeneratorBenchmarkPure#generator_pretty 1000 repeats:
|
376
|
-
42.802514491 ( real) -> 1.000x 6 (>=3859)
|
377
|
-
0.023363113
|
378
|
-
calls/sec ( time) -> speed covers
|
379
|
-
secs/call
|
380
|
-
```
|
381
|
-
|
382
230
|
## Development
|
383
231
|
|
384
232
|
### Release
|
385
233
|
|
386
|
-
Update the json.
|
234
|
+
Update the `lib/json/version.rb` file.
|
387
235
|
|
388
236
|
```
|
389
237
|
rbenv shell 2.6.5
|
data/json_pure.gemspec
CHANGED
@@ -16,7 +16,9 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.rdoc_options = ["--title".freeze, "JSON implementation for ruby".freeze, "--main".freeze, "README.md".freeze]
|
17
17
|
s.files = [
|
18
18
|
"CHANGES.md".freeze,
|
19
|
-
"
|
19
|
+
"COPYING".freeze,
|
20
|
+
"BSDL".freeze,
|
21
|
+
"LEGAL".freeze,
|
20
22
|
"README.md".freeze,
|
21
23
|
"json_pure.gemspec".freeze,
|
22
24
|
"lib/json.rb".freeze,
|
@@ -42,14 +44,14 @@ Gem::Specification.new do |s|
|
|
42
44
|
"lib/json/pure/parser.rb".freeze,
|
43
45
|
"lib/json/version.rb".freeze,
|
44
46
|
]
|
45
|
-
s.homepage = "https://
|
47
|
+
s.homepage = "https://ruby.github.io/json".freeze
|
46
48
|
s.metadata = {
|
47
|
-
'bug_tracker_uri' => 'https://github.com/
|
48
|
-
'changelog_uri' => 'https://github.com/
|
49
|
-
'documentation_uri' => 'https://
|
49
|
+
'bug_tracker_uri' => 'https://github.com/ruby/json/issues',
|
50
|
+
'changelog_uri' => 'https://github.com/ruby/json/blob/master/CHANGES.md',
|
51
|
+
'documentation_uri' => 'https://ruby.github.io/json/doc/index.html',
|
50
52
|
'homepage_uri' => s.homepage,
|
51
|
-
'source_code_uri' => 'https://github.com/
|
52
|
-
'wiki_uri' => 'https://github.com/
|
53
|
+
'source_code_uri' => 'https://github.com/ruby/json',
|
54
|
+
'wiki_uri' => 'https://github.com/ruby/json/wiki'
|
53
55
|
}
|
54
56
|
|
55
57
|
s.required_ruby_version = Gem::Requirement.new(">= 2.3".freeze)
|
data/lib/json/add/bigdecimal.rb
CHANGED
data/lib/json/add/complex.rb
CHANGED
data/lib/json/add/core.rb
CHANGED
data/lib/json/add/date.rb
CHANGED
data/lib/json/add/date_time.rb
CHANGED
data/lib/json/add/exception.rb
CHANGED
data/lib/json/add/ostruct.rb
CHANGED
data/lib/json/add/range.rb
CHANGED
data/lib/json/add/rational.rb
CHANGED
data/lib/json/add/regexp.rb
CHANGED
data/lib/json/add/struct.rb
CHANGED
data/lib/json/add/symbol.rb
CHANGED
data/lib/json/add/time.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
2
|
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
3
3
|
require 'json'
|
4
4
|
end
|
@@ -10,11 +10,7 @@ class Time
|
|
10
10
|
if usec = object.delete('u') # used to be tv_usec -> tv_nsec
|
11
11
|
object['n'] = usec * 1000
|
12
12
|
end
|
13
|
-
|
14
|
-
at(object['s'], Rational(object['n'], 1000))
|
15
|
-
else
|
16
|
-
at(object['s'], object['n'] / 1000)
|
17
|
-
end
|
13
|
+
at(object['s'], Rational(object['n'], 1000))
|
18
14
|
end
|
19
15
|
|
20
16
|
# Methods <tt>Time#as_json</tt> and +Time.json_create+ may be used
|
@@ -34,13 +30,10 @@ class Time
|
|
34
30
|
# # => 2023-11-25 11:00:56.472846644 -0600
|
35
31
|
#
|
36
32
|
def as_json(*)
|
37
|
-
nanoseconds = [ tv_usec * 1000 ]
|
38
|
-
respond_to?(:tv_nsec) and nanoseconds << tv_nsec
|
39
|
-
nanoseconds = nanoseconds.max
|
40
33
|
{
|
41
34
|
JSON.create_id => self.class.name,
|
42
35
|
's' => tv_sec,
|
43
|
-
'n' =>
|
36
|
+
'n' => tv_nsec,
|
44
37
|
}
|
45
38
|
end
|
46
39
|
|
data/lib/json/common.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#frozen_string_literal:
|
1
|
+
#frozen_string_literal: true
|
2
2
|
require 'json/version'
|
3
3
|
|
4
4
|
module JSON
|
@@ -20,11 +20,16 @@ module JSON
|
|
20
20
|
# ruby = [0, 1, nil]
|
21
21
|
# JSON[ruby] # => '[0,1,null]'
|
22
22
|
def [](object, opts = {})
|
23
|
-
if object.
|
24
|
-
JSON.parse(object
|
25
|
-
|
26
|
-
|
23
|
+
if object.is_a?(String)
|
24
|
+
return JSON.parse(object, opts)
|
25
|
+
elsif object.respond_to?(:to_str)
|
26
|
+
str = object.to_str
|
27
|
+
if str.is_a?(String)
|
28
|
+
return JSON.parse(object.to_str, opts)
|
29
|
+
end
|
27
30
|
end
|
31
|
+
|
32
|
+
JSON.generate(object, opts)
|
28
33
|
end
|
29
34
|
|
30
35
|
# Returns the JSON parser class that is used by JSON. This is either
|
@@ -112,23 +117,17 @@ module JSON
|
|
112
117
|
attr_accessor :state
|
113
118
|
end
|
114
119
|
|
115
|
-
DEFAULT_CREATE_ID = 'json_class'.freeze
|
116
|
-
private_constant :DEFAULT_CREATE_ID
|
117
|
-
|
118
|
-
CREATE_ID_TLS_KEY = "JSON.create_id".freeze
|
119
|
-
private_constant :CREATE_ID_TLS_KEY
|
120
|
-
|
121
120
|
# Sets create identifier, which is used to decide if the _json_create_
|
122
121
|
# hook of a class should be called; initial value is +json_class+:
|
123
122
|
# JSON.create_id # => 'json_class'
|
124
123
|
def self.create_id=(new_value)
|
125
|
-
Thread.current[
|
124
|
+
Thread.current[:"JSON.create_id"] = new_value.dup.freeze
|
126
125
|
end
|
127
126
|
|
128
127
|
# Returns the current create identifier.
|
129
128
|
# See also JSON.create_id=.
|
130
129
|
def self.create_id
|
131
|
-
Thread.current[
|
130
|
+
Thread.current[:"JSON.create_id"] || 'json_class'
|
132
131
|
end
|
133
132
|
|
134
133
|
NaN = 0.0/0
|
@@ -216,8 +215,12 @@ module JSON
|
|
216
215
|
# # Raises JSON::ParserError (783: unexpected token at ''):
|
217
216
|
# JSON.parse('')
|
218
217
|
#
|
219
|
-
def parse(source, opts =
|
220
|
-
|
218
|
+
def parse(source, opts = nil)
|
219
|
+
if opts.nil?
|
220
|
+
Parser.new(source).parse
|
221
|
+
else
|
222
|
+
Parser.new(source, opts).parse
|
223
|
+
end
|
221
224
|
end
|
222
225
|
|
223
226
|
# :call-seq:
|
@@ -406,7 +409,7 @@ module JSON
|
|
406
409
|
self.load_default_options = {
|
407
410
|
:max_nesting => false,
|
408
411
|
:allow_nan => true,
|
409
|
-
:allow_blank
|
412
|
+
:allow_blank => true,
|
410
413
|
:create_additions => true,
|
411
414
|
}
|
412
415
|
|
@@ -538,15 +541,23 @@ module JSON
|
|
538
541
|
# #<Admin:0x00000000064c41f8
|
539
542
|
# @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
|
540
543
|
#
|
541
|
-
def load(source, proc = nil, options =
|
542
|
-
opts =
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
544
|
+
def load(source, proc = nil, options = nil)
|
545
|
+
opts = if options.nil?
|
546
|
+
load_default_options
|
547
|
+
else
|
548
|
+
load_default_options.merge(options)
|
549
|
+
end
|
550
|
+
|
551
|
+
unless source.is_a?(String)
|
552
|
+
if source.respond_to? :to_str
|
553
|
+
source = source.to_str
|
554
|
+
elsif source.respond_to? :to_io
|
555
|
+
source = source.to_io.read
|
556
|
+
elsif source.respond_to?(:read)
|
557
|
+
source = source.read
|
558
|
+
end
|
549
559
|
end
|
560
|
+
|
550
561
|
if opts[:allow_blank] && (source.nil? || source.empty?)
|
551
562
|
source = 'null'
|
552
563
|
end
|
@@ -576,13 +587,12 @@ module JSON
|
|
576
587
|
# Sets or returns the default options for the JSON.dump method.
|
577
588
|
# Initially:
|
578
589
|
# opts = JSON.dump_default_options
|
579
|
-
# opts # => {:max_nesting=>false, :allow_nan=>true
|
590
|
+
# opts # => {:max_nesting=>false, :allow_nan=>true}
|
580
591
|
attr_accessor :dump_default_options
|
581
592
|
end
|
582
593
|
self.dump_default_options = {
|
583
594
|
:max_nesting => false,
|
584
595
|
:allow_nan => true,
|
585
|
-
:script_safe => false,
|
586
596
|
}
|
587
597
|
|
588
598
|
# :call-seq:
|
@@ -613,26 +623,42 @@ module JSON
|
|
613
623
|
# Output:
|
614
624
|
# {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}
|
615
625
|
def dump(obj, anIO = nil, limit = nil, kwargs = nil)
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
626
|
+
if kwargs.nil?
|
627
|
+
if limit.nil?
|
628
|
+
if anIO.is_a?(Hash)
|
629
|
+
kwargs = anIO
|
630
|
+
anIO = nil
|
631
|
+
end
|
632
|
+
elsif limit.is_a?(Hash)
|
633
|
+
kwargs = limit
|
634
|
+
limit = nil
|
635
|
+
end
|
623
636
|
end
|
637
|
+
|
638
|
+
unless anIO.nil?
|
639
|
+
if anIO.respond_to?(:to_io)
|
640
|
+
anIO = anIO.to_io
|
641
|
+
elsif limit.nil? && !anIO.respond_to?(:write)
|
642
|
+
anIO, limit = nil, anIO
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
624
646
|
opts = JSON.dump_default_options
|
625
647
|
opts = opts.merge(:max_nesting => limit) if limit
|
626
648
|
opts = merge_dump_options(opts, **kwargs) if kwargs
|
627
|
-
|
628
|
-
|
649
|
+
|
650
|
+
result = begin
|
651
|
+
generate(obj, opts)
|
652
|
+
rescue JSON::NestingError
|
653
|
+
raise ArgumentError, "exceed depth limit"
|
654
|
+
end
|
655
|
+
|
656
|
+
if anIO.nil?
|
657
|
+
result
|
658
|
+
else
|
629
659
|
anIO.write result
|
630
660
|
anIO
|
631
|
-
else
|
632
|
-
result
|
633
661
|
end
|
634
|
-
rescue JSON::NestingError
|
635
|
-
raise ArgumentError, "exceed depth limit"
|
636
662
|
end
|
637
663
|
|
638
664
|
# Encodes string using String.encode.
|
@@ -678,11 +704,16 @@ module ::Kernel
|
|
678
704
|
# The _opts_ argument is passed through to generate/parse respectively. See
|
679
705
|
# generate and parse for their documentation.
|
680
706
|
def JSON(object, *args)
|
681
|
-
if object.
|
682
|
-
JSON.parse(object
|
683
|
-
|
684
|
-
|
707
|
+
if object.is_a?(String)
|
708
|
+
return JSON.parse(object, args.first)
|
709
|
+
elsif object.respond_to?(:to_str)
|
710
|
+
str = object.to_str
|
711
|
+
if str.is_a?(String)
|
712
|
+
return JSON.parse(object.to_str, args.first)
|
713
|
+
end
|
685
714
|
end
|
715
|
+
|
716
|
+
JSON.generate(object, args.first)
|
686
717
|
end
|
687
718
|
end
|
688
719
|
|
data/lib/json/ext.rb
CHANGED
@@ -1,14 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json/common'
|
2
4
|
|
3
5
|
module JSON
|
4
6
|
# This module holds all the modules/classes that implement JSON's
|
5
7
|
# functionality as C extensions.
|
6
8
|
module Ext
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
if RUBY_ENGINE == 'truffleruby'
|
10
|
+
require 'json/ext/parser'
|
11
|
+
require 'json/pure'
|
12
|
+
$DEBUG and warn "Using Ext extension for JSON parser and Pure library for JSON generator."
|
13
|
+
JSON.parser = Parser
|
14
|
+
JSON.generator = JSON::Pure::Generator
|
15
|
+
else
|
16
|
+
require 'json/ext/parser'
|
17
|
+
require 'json/ext/generator'
|
18
|
+
$DEBUG and warn "Using Ext extension for JSON."
|
19
|
+
JSON.parser = Parser
|
20
|
+
JSON.generator = Generator
|
21
|
+
end
|
12
22
|
end
|
13
23
|
|
14
24
|
JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
|
data/lib/json/generic_object.rb
CHANGED
data/lib/json/pure/generator.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module JSON
|
3
3
|
MAP = {
|
4
4
|
"\x0" => '\u0000',
|
@@ -35,7 +35,7 @@ module JSON
|
|
35
35
|
"\x1f" => '\u001f',
|
36
36
|
'"' => '\"',
|
37
37
|
'\\' => '\\\\',
|
38
|
-
} # :nodoc:
|
38
|
+
}.freeze # :nodoc:
|
39
39
|
|
40
40
|
ESCAPE_PATTERN = /[\/"\\\x0-\x1f]/n # :nodoc:
|
41
41
|
|
@@ -43,15 +43,14 @@ module JSON
|
|
43
43
|
'/' => '\\/',
|
44
44
|
"\u2028".b => '\u2028',
|
45
45
|
"\u2029".b => '\u2029',
|
46
|
-
)
|
46
|
+
).freeze
|
47
47
|
|
48
48
|
SCRIPT_SAFE_ESCAPE_PATTERN = Regexp.union(ESCAPE_PATTERN, "\u2028".b, "\u2029".b)
|
49
49
|
|
50
50
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
51
51
|
# UTF16 big endian characters as \u????, and return it.
|
52
52
|
def utf8_to_json(string, script_safe = false) # :nodoc:
|
53
|
-
string = string.
|
54
|
-
string.force_encoding(::Encoding::ASCII_8BIT)
|
53
|
+
string = string.b
|
55
54
|
if script_safe
|
56
55
|
string.gsub!(SCRIPT_SAFE_ESCAPE_PATTERN) { SCRIPT_SAFE_MAP[$&] || $& }
|
57
56
|
else
|
@@ -62,8 +61,7 @@ module JSON
|
|
62
61
|
end
|
63
62
|
|
64
63
|
def utf8_to_json_ascii(string, script_safe = false) # :nodoc:
|
65
|
-
string = string.
|
66
|
-
string.force_encoding(::Encoding::ASCII_8BIT)
|
64
|
+
string = string.b
|
67
65
|
map = script_safe ? SCRIPT_SAFE_MAP : MAP
|
68
66
|
string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
|
69
67
|
string.gsub!(/(
|
@@ -75,7 +73,7 @@ module JSON
|
|
75
73
|
[\x80-\xc1\xf5-\xff] # invalid
|
76
74
|
)/nx) { |c|
|
77
75
|
c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
|
78
|
-
s =
|
76
|
+
s = c.encode(::Encoding::UTF_16BE, ::Encoding::UTF_8).unpack('H*')[0]
|
79
77
|
s.force_encoding(::Encoding::ASCII_8BIT)
|
80
78
|
s.gsub!(/.{4}/n, '\\\\u\&')
|
81
79
|
s.force_encoding(::Encoding::UTF_8)
|
@@ -219,7 +217,9 @@ module JSON
|
|
219
217
|
@script_safe
|
220
218
|
end
|
221
219
|
|
222
|
-
# Returns true, if
|
220
|
+
# Returns true, if strict mode is enabled. Otherwise returns false.
|
221
|
+
# Strict mode only allow serializing JSON native types: Hash, Array,
|
222
|
+
# String, Integer, Float, true, false and nil.
|
223
223
|
def strict?
|
224
224
|
@strict
|
225
225
|
end
|
@@ -237,6 +237,8 @@ module JSON
|
|
237
237
|
opts.each do |key, value|
|
238
238
|
instance_variable_set "@#{key}", value
|
239
239
|
end
|
240
|
+
|
241
|
+
# NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json
|
240
242
|
@indent = opts[:indent] if opts.key?(:indent)
|
241
243
|
@space = opts[:space] if opts.key?(:space)
|
242
244
|
@space_before = opts[:space_before] if opts.key?(:space_before)
|
@@ -286,12 +288,71 @@ module JSON
|
|
286
288
|
# created this method raises a
|
287
289
|
# GeneratorError exception.
|
288
290
|
def generate(obj)
|
289
|
-
|
291
|
+
if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
|
292
|
+
!@ascii_only and !@script_safe and @max_nesting == 0 and !@strict
|
293
|
+
result = generate_json(obj, ''.dup)
|
294
|
+
else
|
295
|
+
result = obj.to_json(self)
|
296
|
+
end
|
290
297
|
JSON.valid_utf8?(result) or raise GeneratorError,
|
291
298
|
"source sequence #{result.inspect} is illegal/malformed utf-8"
|
292
299
|
result
|
293
300
|
end
|
294
301
|
|
302
|
+
# Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
|
303
|
+
private def generate_json(obj, buf)
|
304
|
+
case obj
|
305
|
+
when Hash
|
306
|
+
buf << '{'
|
307
|
+
first = true
|
308
|
+
obj.each_pair do |k,v|
|
309
|
+
buf << ',' unless first
|
310
|
+
fast_serialize_string(k.to_s, buf)
|
311
|
+
buf << ':'
|
312
|
+
generate_json(v, buf)
|
313
|
+
first = false
|
314
|
+
end
|
315
|
+
buf << '}'
|
316
|
+
when Array
|
317
|
+
buf << '['
|
318
|
+
first = true
|
319
|
+
obj.each do |e|
|
320
|
+
buf << ',' unless first
|
321
|
+
generate_json(e, buf)
|
322
|
+
first = false
|
323
|
+
end
|
324
|
+
buf << ']'
|
325
|
+
when String
|
326
|
+
fast_serialize_string(obj, buf)
|
327
|
+
when Integer
|
328
|
+
buf << obj.to_s
|
329
|
+
else
|
330
|
+
# Note: Float is handled this way since Float#to_s is slow anyway
|
331
|
+
buf << obj.to_json(self)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
# Assumes !@ascii_only, !@script_safe
|
336
|
+
if Regexp.method_defined?(:match?)
|
337
|
+
private def fast_serialize_string(string, buf) # :nodoc:
|
338
|
+
buf << '"'
|
339
|
+
string = string.encode(::Encoding::UTF_8) unless string.encoding == ::Encoding::UTF_8
|
340
|
+
raise GeneratorError, "source sequence is illegal/malformed utf-8" unless string.valid_encoding?
|
341
|
+
|
342
|
+
if /["\\\x0-\x1f]/n.match?(string)
|
343
|
+
buf << string.gsub(/["\\\x0-\x1f]/n, MAP)
|
344
|
+
else
|
345
|
+
buf << string
|
346
|
+
end
|
347
|
+
buf << '"'
|
348
|
+
end
|
349
|
+
else
|
350
|
+
# Ruby 2.3 compatibility
|
351
|
+
private def fast_serialize_string(string, buf) # :nodoc:
|
352
|
+
buf << string.to_json(self)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
295
356
|
# Return the value returned by method +name+.
|
296
357
|
def [](name)
|
297
358
|
if respond_to?(name)
|
@@ -316,8 +377,8 @@ module JSON
|
|
316
377
|
# Converts this object to a string (calling #to_s), converts
|
317
378
|
# it to a JSON string, and returns the result. This is a fallback, if no
|
318
379
|
# special method #to_json was defined for some object.
|
319
|
-
def to_json(
|
320
|
-
if
|
380
|
+
def to_json(state = nil, *)
|
381
|
+
if state && State.from_state(state).strict?
|
321
382
|
raise GeneratorError, "#{self.class} not allowed in JSON"
|
322
383
|
else
|
323
384
|
to_s.to_json
|
@@ -346,15 +407,15 @@ module JSON
|
|
346
407
|
|
347
408
|
def json_transform(state)
|
348
409
|
delim = ",#{state.object_nl}"
|
349
|
-
result = "{#{state.object_nl}"
|
410
|
+
result = +"{#{state.object_nl}"
|
350
411
|
depth = state.depth += 1
|
351
412
|
first = true
|
352
413
|
indent = !state.object_nl.empty?
|
353
414
|
each { |key, value|
|
354
415
|
result << delim unless first
|
355
416
|
result << state.indent * depth if indent
|
356
|
-
result = "#{result}#{key.to_s.to_json(state)}#{state.space_before}:#{state.space}"
|
357
|
-
if state.strict?
|
417
|
+
result = +"#{result}#{key.to_s.to_json(state)}#{state.space_before}:#{state.space}"
|
418
|
+
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
|
358
419
|
raise GeneratorError, "#{value.class} not allowed in JSON"
|
359
420
|
elsif value.respond_to?(:to_json)
|
360
421
|
result << value.to_json(state)
|
@@ -387,17 +448,20 @@ module JSON
|
|
387
448
|
private
|
388
449
|
|
389
450
|
def json_transform(state)
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
451
|
+
result = '['.dup
|
452
|
+
if state.array_nl.empty?
|
453
|
+
delim = ","
|
454
|
+
else
|
455
|
+
result << state.array_nl
|
456
|
+
delim = ",#{state.array_nl}"
|
457
|
+
end
|
394
458
|
depth = state.depth += 1
|
395
459
|
first = true
|
396
460
|
indent = !state.array_nl.empty?
|
397
461
|
each { |value|
|
398
462
|
result << delim unless first
|
399
463
|
result << state.indent * depth if indent
|
400
|
-
if state.strict?
|
464
|
+
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
|
401
465
|
raise GeneratorError, "#{value.class} not allowed in JSON"
|
402
466
|
elsif value.respond_to?(:to_json)
|
403
467
|
result << value.to_json(state)
|
@@ -448,14 +512,17 @@ module JSON
|
|
448
512
|
def to_json(state = nil, *args)
|
449
513
|
state = State.from_state(state)
|
450
514
|
if encoding == ::Encoding::UTF_8
|
515
|
+
unless valid_encoding?
|
516
|
+
raise GeneratorError, "source sequence is illegal/malformed utf-8"
|
517
|
+
end
|
451
518
|
string = self
|
452
519
|
else
|
453
520
|
string = encode(::Encoding::UTF_8)
|
454
521
|
end
|
455
522
|
if state.ascii_only?
|
456
|
-
|
523
|
+
%("#{JSON.utf8_to_json_ascii(string, state.script_safe)}")
|
457
524
|
else
|
458
|
-
|
525
|
+
%("#{JSON.utf8_to_json(string, state.script_safe)}")
|
459
526
|
end
|
460
527
|
end
|
461
528
|
|
data/lib/json/pure/parser.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#frozen_string_literal:
|
1
|
+
#frozen_string_literal: true
|
2
2
|
require 'strscan'
|
3
3
|
|
4
4
|
module JSON
|
@@ -39,11 +39,8 @@ module JSON
|
|
39
39
|
//[^\n\r]*[\n\r]| # line comments
|
40
40
|
/\* # c-style comments
|
41
41
|
(?:
|
42
|
-
[
|
43
|
-
|
44
|
-
\*[^/]| # asterisks that do not end this comment
|
45
|
-
/(?=\*/) # single slash before this comment's end
|
46
|
-
)*
|
42
|
+
[\s\S]*? # any char, repeated lazily
|
43
|
+
)
|
47
44
|
\*/ # the End of this comment
|
48
45
|
|[ \t\r\n]+ # whitespaces: space, horizontal tab, lf, cr
|
49
46
|
)+
|
@@ -70,12 +67,16 @@ module JSON
|
|
70
67
|
# * *create_additions*: If set to true, the Parser creates
|
71
68
|
# additions when a matching class and create_id are found. This
|
72
69
|
# option defaults to false.
|
73
|
-
# * *object_class*: Defaults to Hash
|
74
|
-
#
|
70
|
+
# * *object_class*: Defaults to Hash. If another type is provided, it will be used
|
71
|
+
# instead of Hash to represent JSON objects. The type must respond to
|
72
|
+
# +new+ without arguments, and return an object that respond to +[]=+.
|
73
|
+
# * *array_class*: Defaults to Array If another type is provided, it will be used
|
74
|
+
# instead of Hash to represent JSON arrays. The type must respond to
|
75
|
+
# +new+ without arguments, and return an object that respond to +<<+.
|
75
76
|
# * *decimal_class*: Specifies which class to use instead of the default
|
76
77
|
# (Float) when parsing decimal numbers. This class must accept a single
|
77
78
|
# string argument in its constructor.
|
78
|
-
def initialize(source, opts =
|
79
|
+
def initialize(source, opts = nil)
|
79
80
|
opts ||= {}
|
80
81
|
source = convert_encoding source
|
81
82
|
super source
|
@@ -147,44 +148,37 @@ module JSON
|
|
147
148
|
end
|
148
149
|
|
149
150
|
# Unescape characters in strings.
|
150
|
-
UNESCAPE_MAP =
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
})
|
162
|
-
|
163
|
-
EMPTY_8BIT_STRING = ''
|
164
|
-
if ::String.method_defined?(:encode)
|
165
|
-
EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
|
166
|
-
end
|
151
|
+
UNESCAPE_MAP = {
|
152
|
+
'"' => '"',
|
153
|
+
'\\' => '\\',
|
154
|
+
'/' => '/',
|
155
|
+
'b' => "\b",
|
156
|
+
'f' => "\f",
|
157
|
+
'n' => "\n",
|
158
|
+
'r' => "\r",
|
159
|
+
't' => "\t",
|
160
|
+
'u' => nil,
|
161
|
+
}.freeze
|
167
162
|
|
168
163
|
STR_UMINUS = ''.respond_to?(:-@)
|
169
164
|
def parse_string
|
170
165
|
if scan(STRING)
|
171
166
|
return '' if self[1].empty?
|
172
|
-
string = self[1].gsub(%r(
|
173
|
-
|
167
|
+
string = self[1].gsub(%r{(?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff])}n) do |c|
|
168
|
+
k = $&[1]
|
169
|
+
if u = UNESCAPE_MAP.fetch(k) { k.chr }
|
174
170
|
u
|
175
171
|
else # \uXXXX
|
176
|
-
bytes =
|
172
|
+
bytes = ''.b
|
177
173
|
i = 0
|
178
174
|
while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
|
179
175
|
bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
|
180
176
|
i += 1
|
181
177
|
end
|
182
|
-
|
178
|
+
bytes.encode(Encoding::UTF_8, Encoding::UTF_16BE).force_encoding(::Encoding::BINARY)
|
183
179
|
end
|
184
180
|
end
|
185
|
-
|
186
|
-
string.force_encoding(::Encoding::UTF_8)
|
187
|
-
end
|
181
|
+
string.force_encoding(::Encoding::UTF_8)
|
188
182
|
|
189
183
|
if @freeze
|
190
184
|
if STR_UMINUS
|
data/lib/json/pure.rb
CHANGED
data/lib/json/version.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
# frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module JSON
|
3
|
-
|
4
|
-
VERSION = '2.7.2'
|
5
|
-
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
|
6
|
-
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
|
7
|
-
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
|
8
|
-
VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
|
4
|
+
VERSION = '2.7.4'
|
9
5
|
end
|
data/lib/json.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_pure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.7.
|
4
|
+
version: 2.7.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
8
|
+
autorequire:
|
8
9
|
bindir: bin
|
9
10
|
cert_chain: []
|
10
|
-
date: 2024-
|
11
|
+
date: 2024-10-25 00:00:00.000000000 Z
|
11
12
|
dependencies: []
|
12
13
|
description: This is a JSON implementation in pure Ruby.
|
13
14
|
email: flori@ping.de
|
@@ -16,8 +17,10 @@ extensions: []
|
|
16
17
|
extra_rdoc_files:
|
17
18
|
- README.md
|
18
19
|
files:
|
20
|
+
- BSDL
|
19
21
|
- CHANGES.md
|
20
|
-
-
|
22
|
+
- COPYING
|
23
|
+
- LEGAL
|
21
24
|
- README.md
|
22
25
|
- json_pure.gemspec
|
23
26
|
- lib/json.rb
|
@@ -42,16 +45,17 @@ files:
|
|
42
45
|
- lib/json/pure/generator.rb
|
43
46
|
- lib/json/pure/parser.rb
|
44
47
|
- lib/json/version.rb
|
45
|
-
homepage: https://
|
48
|
+
homepage: https://ruby.github.io/json
|
46
49
|
licenses:
|
47
50
|
- Ruby
|
48
51
|
metadata:
|
49
|
-
bug_tracker_uri: https://github.com/
|
50
|
-
changelog_uri: https://github.com/
|
51
|
-
documentation_uri: https://
|
52
|
-
homepage_uri: https://
|
53
|
-
source_code_uri: https://github.com/
|
54
|
-
wiki_uri: https://github.com/
|
52
|
+
bug_tracker_uri: https://github.com/ruby/json/issues
|
53
|
+
changelog_uri: https://github.com/ruby/json/blob/master/CHANGES.md
|
54
|
+
documentation_uri: https://ruby.github.io/json/doc/index.html
|
55
|
+
homepage_uri: https://ruby.github.io/json
|
56
|
+
source_code_uri: https://github.com/ruby/json
|
57
|
+
wiki_uri: https://github.com/ruby/json/wiki
|
58
|
+
post_install_message:
|
55
59
|
rdoc_options:
|
56
60
|
- "--title"
|
57
61
|
- JSON implementation for ruby
|
@@ -70,7 +74,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
74
|
- !ruby/object:Gem::Version
|
71
75
|
version: '0'
|
72
76
|
requirements: []
|
73
|
-
rubygems_version: 3.
|
77
|
+
rubygems_version: 3.5.11
|
78
|
+
signing_key:
|
74
79
|
specification_version: 4
|
75
80
|
summary: JSON Implementation for Ruby
|
76
81
|
test_files: []
|
/data/{LICENSE → COPYING}
RENAMED
File without changes
|