json_pure 2.7.2 → 2.7.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![CI](https://github.com/
|
3
|
+
[![CI](https://github.com/ruby/json/actions/workflows/ci.yml/badge.svg)](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
|