json 2.19.3 → 2.21.1
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/CHANGES.md +61 -1
- data/LEGAL +3 -3
- data/README.md +16 -7
- data/ext/json/ext/fbuffer/fbuffer.h +32 -24
- data/ext/json/ext/generator/extconf.rb +3 -0
- data/ext/json/ext/generator/generator.c +116 -35
- data/ext/json/ext/json.h +78 -0
- data/ext/json/ext/parser/extconf.rb +21 -0
- data/ext/json/ext/parser/parser.c +1580 -360
- data/ext/json/ext/vendor/fast_float_parser.h +814 -0
- data/lib/json/common.rb +9 -0
- data/lib/json/ext/generator/state.rb +1 -0
- data/lib/json/ext.rb +26 -0
- data/lib/json/truffle_ruby/generator.rb +47 -9
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +23 -5
- metadata +3 -3
- data/ext/json/ext/vendor/ryu.h +0 -819
data/lib/json/common.rb
CHANGED
|
@@ -155,6 +155,15 @@ module JSON
|
|
|
155
155
|
# Set the module _generator_ to be used by JSON.
|
|
156
156
|
def generator=(generator) # :nodoc:
|
|
157
157
|
old, $VERBOSE = $VERBOSE, nil
|
|
158
|
+
|
|
159
|
+
# The default proc used when the +sort_keys+ generation option is +true+.
|
|
160
|
+
# It returns a new hash with the entries sorted by their keys.
|
|
161
|
+
sort_keys_proc = ->(hash) { hash.sort.to_h }
|
|
162
|
+
if defined?(::Ractor) && Ractor.respond_to?(:shareable_lambda)
|
|
163
|
+
sort_keys_proc = Ractor.shareable_lambda(&sort_keys_proc)
|
|
164
|
+
end
|
|
165
|
+
generator::State.default_sort_keys_proc = sort_keys_proc
|
|
166
|
+
|
|
158
167
|
@generator = generator
|
|
159
168
|
if generator.const_defined?(:GeneratorMethods)
|
|
160
169
|
generator_methods = generator::GeneratorMethods
|
data/lib/json/ext.rb
CHANGED
|
@@ -41,5 +41,31 @@ module JSON
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
if defined?(ResumableParser) # Not yet available on JRuby
|
|
45
|
+
class ResumableParser
|
|
46
|
+
# Returns whether the parser is entirely done: no unconsumed bytes in
|
|
47
|
+
# the buffer, no document under construction and no parsed value
|
|
48
|
+
# awaiting retrieval.
|
|
49
|
+
#
|
|
50
|
+
# The main use case is detecting a truncated stream once the input is
|
|
51
|
+
# exhausted:
|
|
52
|
+
#
|
|
53
|
+
# loop do
|
|
54
|
+
# begin
|
|
55
|
+
# parser << socket.readpartial(4096)
|
|
56
|
+
# rescue EOFError
|
|
57
|
+
# break
|
|
58
|
+
# end
|
|
59
|
+
# while parser.parse
|
|
60
|
+
# process(parser.value)
|
|
61
|
+
# end
|
|
62
|
+
# end
|
|
63
|
+
# warn "stream was truncated" unless parser.empty?
|
|
64
|
+
def empty?
|
|
65
|
+
eos? && !partial_value? && !value?
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
44
70
|
JSON_LOADED = true unless defined?(JSON::JSON_LOADED)
|
|
45
71
|
end
|
|
@@ -48,7 +48,7 @@ module JSON
|
|
|
48
48
|
SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/
|
|
49
49
|
|
|
50
50
|
def self.native_type?(value) # :nodoc:
|
|
51
|
-
(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
|
|
51
|
+
(false == value || true == value || nil == value || String === value || Symbol === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def self.native_key?(key) # :nodoc:
|
|
@@ -111,6 +111,8 @@ module JSON
|
|
|
111
111
|
# This class is used to create State instances, that are use to hold data
|
|
112
112
|
# while generating a JSON text from a Ruby data structure.
|
|
113
113
|
class State
|
|
114
|
+
singleton_class.attr_accessor :default_sort_keys_proc # :nodoc:
|
|
115
|
+
|
|
114
116
|
def self.generate(obj, opts = nil, io = nil)
|
|
115
117
|
new(opts).generate(obj, io)
|
|
116
118
|
end
|
|
@@ -164,6 +166,7 @@ module JSON
|
|
|
164
166
|
@script_safe = false
|
|
165
167
|
@strict = false
|
|
166
168
|
@max_nesting = 100
|
|
169
|
+
@sort_keys = false
|
|
167
170
|
configure(opts) if opts
|
|
168
171
|
end
|
|
169
172
|
|
|
@@ -199,6 +202,33 @@ module JSON
|
|
|
199
202
|
# supported by the JSON spec will raise a JSON::GeneratorError
|
|
200
203
|
attr_accessor :strict
|
|
201
204
|
|
|
205
|
+
# Controls key sorting in the generated JSON. If set to +true+, object
|
|
206
|
+
# keys are sorted by key lexicographically. If set to a Proc, it
|
|
207
|
+
# receives the entire Hash and must return a Hash with its pairs in the
|
|
208
|
+
# desired order.
|
|
209
|
+
attr_reader :sort_keys
|
|
210
|
+
|
|
211
|
+
def sort_keys=(value) # :nodoc:
|
|
212
|
+
type_error = false
|
|
213
|
+
@sort_keys = case value
|
|
214
|
+
when Proc
|
|
215
|
+
value
|
|
216
|
+
when true
|
|
217
|
+
State.default_sort_keys_proc
|
|
218
|
+
when nil, false
|
|
219
|
+
false
|
|
220
|
+
else
|
|
221
|
+
type_error = true
|
|
222
|
+
false
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
if type_error
|
|
226
|
+
raise TypeError, "The `sort_keys` argument must be a boolean or a Proc"
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
@sort_keys
|
|
230
|
+
end
|
|
231
|
+
|
|
202
232
|
# :stopdoc:
|
|
203
233
|
attr_reader :buffer_initial_length
|
|
204
234
|
|
|
@@ -285,6 +315,7 @@ module JSON
|
|
|
285
315
|
@allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
|
|
286
316
|
@as_json = opts[:as_json].to_proc if opts[:as_json]
|
|
287
317
|
@ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
|
|
318
|
+
self.sort_keys = opts[:sort_keys] if opts.key?(:sort_keys)
|
|
288
319
|
@depth = opts[:depth] || 0
|
|
289
320
|
@buffer_initial_length ||= opts[:buffer_initial_length]
|
|
290
321
|
|
|
@@ -307,6 +338,9 @@ module JSON
|
|
|
307
338
|
if !opts.key?(:max_nesting) # defaults to 100
|
|
308
339
|
@max_nesting = 100
|
|
309
340
|
elsif opts[:max_nesting]
|
|
341
|
+
unless opts[:max_nesting].is_a?(Integer)
|
|
342
|
+
raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
|
|
343
|
+
end
|
|
310
344
|
@max_nesting = opts[:max_nesting]
|
|
311
345
|
else
|
|
312
346
|
@max_nesting = 0
|
|
@@ -346,9 +380,13 @@ module JSON
|
|
|
346
380
|
|
|
347
381
|
depth = @depth
|
|
348
382
|
if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
|
|
349
|
-
!@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
|
|
383
|
+
!@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj) and !@sort_keys
|
|
350
384
|
result = generate_json(obj, ''.dup)
|
|
351
385
|
else
|
|
386
|
+
if @sort_keys
|
|
387
|
+
obj = @sort_keys.call(obj)
|
|
388
|
+
end
|
|
389
|
+
|
|
352
390
|
result = obj.to_json(self)
|
|
353
391
|
end
|
|
354
392
|
JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError.new(
|
|
@@ -517,11 +555,11 @@ module JSON
|
|
|
517
555
|
|
|
518
556
|
if empty?
|
|
519
557
|
state.depth -= 1
|
|
520
|
-
return '{}'
|
|
558
|
+
return +'{}'
|
|
521
559
|
end
|
|
522
560
|
|
|
523
561
|
delim = ",#{state.object_nl}"
|
|
524
|
-
result =
|
|
562
|
+
result = "{#{state.object_nl}"
|
|
525
563
|
first = true
|
|
526
564
|
key_type = nil
|
|
527
565
|
indent = !state.object_nl.empty?
|
|
@@ -558,7 +596,7 @@ module JSON
|
|
|
558
596
|
raise TypeError, "#{key.class}#to_s returns an instance of #{key_str.class}, expected a String"
|
|
559
597
|
end
|
|
560
598
|
|
|
561
|
-
result =
|
|
599
|
+
result = "#{result}#{key_json}#{state.space_before}:#{state.space}"
|
|
562
600
|
if state.strict? && !Generator.native_type?(value)
|
|
563
601
|
if state.as_json
|
|
564
602
|
value = state.as_json.call(value, false)
|
|
@@ -609,7 +647,7 @@ module JSON
|
|
|
609
647
|
|
|
610
648
|
if empty?
|
|
611
649
|
state.depth -= 1
|
|
612
|
-
return '[]'
|
|
650
|
+
return +'[]'
|
|
613
651
|
end
|
|
614
652
|
|
|
615
653
|
result = '['.dup
|
|
@@ -734,17 +772,17 @@ module JSON
|
|
|
734
772
|
|
|
735
773
|
module TrueClass
|
|
736
774
|
# Returns a JSON string for true: 'true'.
|
|
737
|
-
def to_json(*) 'true' end
|
|
775
|
+
def to_json(*) +'true' end
|
|
738
776
|
end
|
|
739
777
|
|
|
740
778
|
module FalseClass
|
|
741
779
|
# Returns a JSON string for false: 'false'.
|
|
742
|
-
def to_json(*) 'false' end
|
|
780
|
+
def to_json(*) +'false' end
|
|
743
781
|
end
|
|
744
782
|
|
|
745
783
|
module NilClass
|
|
746
784
|
# Returns a JSON string for nil: 'null'.
|
|
747
|
-
def to_json(*) 'null' end
|
|
785
|
+
def to_json(*) +'null' end
|
|
748
786
|
end
|
|
749
787
|
end
|
|
750
788
|
end
|
data/lib/json/version.rb
CHANGED
data/lib/json.rb
CHANGED
|
@@ -145,11 +145,11 @@ require 'json/common'
|
|
|
145
145
|
# # warning: detected duplicate keys in JSON object.
|
|
146
146
|
# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
|
|
147
147
|
#
|
|
148
|
-
# When set to
|
|
148
|
+
# When set to +true+:
|
|
149
149
|
# # The last value is used.
|
|
150
150
|
# JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
|
|
151
151
|
#
|
|
152
|
-
# When set to
|
|
152
|
+
# When set to +false+, the future default:
|
|
153
153
|
# JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
|
|
154
154
|
#
|
|
155
155
|
# ---
|
|
@@ -184,6 +184,20 @@ require 'json/common'
|
|
|
184
184
|
#
|
|
185
185
|
# ---
|
|
186
186
|
#
|
|
187
|
+
# Option +allow_comments+ (boolean) specifies whether to allow
|
|
188
|
+
# JavaScript style comments (either <tt>// comment</tt> or <tt>/* comment */</tt>);
|
|
189
|
+
# defaults to +false+.
|
|
190
|
+
#
|
|
191
|
+
# When not specified, a deprecation warning is emitted if a comment is encountered.
|
|
192
|
+
#
|
|
193
|
+
# When set to +true+, comments are ignored:
|
|
194
|
+
# JSON.parse('/* comment */ {"a": 1, "a":2}') # => {"a" => 2}
|
|
195
|
+
#
|
|
196
|
+
# When set to +false+, the future default:
|
|
197
|
+
# JSON.parse('/* comment */ {"a": 1, "a":2}') # unexpected character: '/' at line 1 column 1 (JSON::ParserError)
|
|
198
|
+
#
|
|
199
|
+
# ---
|
|
200
|
+
#
|
|
187
201
|
# Option +allow_control_characters+ (boolean) specifies whether to allow
|
|
188
202
|
# unescaped ASCII control characters, such as newlines, in strings;
|
|
189
203
|
# defaults to +false+.
|
|
@@ -335,8 +349,8 @@ require 'json/common'
|
|
|
335
349
|
# JSON.generate(JSON::MinusInfinity)
|
|
336
350
|
#
|
|
337
351
|
# Allow:
|
|
338
|
-
# ruby = [Float::
|
|
339
|
-
# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
|
|
352
|
+
# ruby = [Float::NAN, Float::INFINITY, JSON::NaN, JSON::Infinity, JSON::MinusInfinity]
|
|
353
|
+
# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,NaN,Infinity,-Infinity]'
|
|
340
354
|
#
|
|
341
355
|
# ---
|
|
342
356
|
#
|
|
@@ -394,7 +408,6 @@ require 'json/common'
|
|
|
394
408
|
# to be inserted after each \JSON object; defaults to the empty \String, <tt>''</tt>.
|
|
395
409
|
# - Option +indent+ (\String) specifies the string (usually spaces) to be
|
|
396
410
|
# used for indentation; defaults to the empty \String, <tt>''</tt>;
|
|
397
|
-
# defaults to the empty \String, <tt>''</tt>;
|
|
398
411
|
# has no effect unless options +array_nl+ or +object_nl+ specify newlines.
|
|
399
412
|
# - Option +space+ (\String) specifies a string (usually a space) to be
|
|
400
413
|
# inserted after the colon in each \JSON object's pair;
|
|
@@ -402,6 +415,11 @@ require 'json/common'
|
|
|
402
415
|
# - Option +space_before+ (\String) specifies a string (usually a space) to be
|
|
403
416
|
# inserted before the colon in each \JSON object's pair;
|
|
404
417
|
# defaults to the empty \String, <tt>''</tt>.
|
|
418
|
+
# - Option +sort_keys+ (boolean or \Proc) controls whether and how the keys of a
|
|
419
|
+
# hash are sorted when generating the output; defaults to <tt>false</tt>.
|
|
420
|
+
# When +true+, keys are sorted lexicographically. When a \Proc, it receives
|
|
421
|
+
# the entire \Hash and must return a \Hash with its pairs in the desired
|
|
422
|
+
# order, allowing for arbitrary sort orders.
|
|
405
423
|
#
|
|
406
424
|
# In this example, +obj+ is used first to generate the shortest
|
|
407
425
|
# \JSON data (no whitespace), then again with all formatting options
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.21.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -31,9 +31,9 @@ files:
|
|
|
31
31
|
- ext/json/ext/parser/parser.c
|
|
32
32
|
- ext/json/ext/simd/conf.rb
|
|
33
33
|
- ext/json/ext/simd/simd.h
|
|
34
|
+
- ext/json/ext/vendor/fast_float_parser.h
|
|
34
35
|
- ext/json/ext/vendor/fpconv.c
|
|
35
36
|
- ext/json/ext/vendor/jeaiii-ltoa.h
|
|
36
|
-
- ext/json/ext/vendor/ryu.h
|
|
37
37
|
- json.gemspec
|
|
38
38
|
- lib/json.rb
|
|
39
39
|
- lib/json/add/bigdecimal.rb
|
|
@@ -84,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
84
84
|
- !ruby/object:Gem::Version
|
|
85
85
|
version: '0'
|
|
86
86
|
requirements: []
|
|
87
|
-
rubygems_version: 4.0.
|
|
87
|
+
rubygems_version: 4.0.12
|
|
88
88
|
specification_version: 4
|
|
89
89
|
summary: JSON Implementation for Ruby
|
|
90
90
|
test_files: []
|