json 2.7.6-java → 2.8.0-java
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 +11 -0
- data/README.md +8 -77
- data/json.gemspec +3 -1
- data/lib/json/add/bigdecimal.rb +1 -1
- data/lib/json/common.rb +200 -59
- data/lib/json/ext/generator/state.rb +1 -31
- data/lib/json/ext.rb +2 -4
- data/lib/json/{pure → truffle_ruby}/generator.rb +150 -128
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +15 -20
- metadata +4 -6
- data/lib/json/pure/parser.rb +0 -331
- data/lib/json/pure.rb +0 -16
@@ -1,101 +1,105 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module JSON
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
3
|
+
module TruffleRuby
|
4
|
+
module Generator
|
5
|
+
MAP = {
|
6
|
+
"\x0" => '\u0000',
|
7
|
+
"\x1" => '\u0001',
|
8
|
+
"\x2" => '\u0002',
|
9
|
+
"\x3" => '\u0003',
|
10
|
+
"\x4" => '\u0004',
|
11
|
+
"\x5" => '\u0005',
|
12
|
+
"\x6" => '\u0006',
|
13
|
+
"\x7" => '\u0007',
|
14
|
+
"\b" => '\b',
|
15
|
+
"\t" => '\t',
|
16
|
+
"\n" => '\n',
|
17
|
+
"\xb" => '\u000b',
|
18
|
+
"\f" => '\f',
|
19
|
+
"\r" => '\r',
|
20
|
+
"\xe" => '\u000e',
|
21
|
+
"\xf" => '\u000f',
|
22
|
+
"\x10" => '\u0010',
|
23
|
+
"\x11" => '\u0011',
|
24
|
+
"\x12" => '\u0012',
|
25
|
+
"\x13" => '\u0013',
|
26
|
+
"\x14" => '\u0014',
|
27
|
+
"\x15" => '\u0015',
|
28
|
+
"\x16" => '\u0016',
|
29
|
+
"\x17" => '\u0017',
|
30
|
+
"\x18" => '\u0018',
|
31
|
+
"\x19" => '\u0019',
|
32
|
+
"\x1a" => '\u001a',
|
33
|
+
"\x1b" => '\u001b',
|
34
|
+
"\x1c" => '\u001c',
|
35
|
+
"\x1d" => '\u001d',
|
36
|
+
"\x1e" => '\u001e',
|
37
|
+
"\x1f" => '\u001f',
|
38
|
+
'"' => '\"',
|
39
|
+
'\\' => '\\\\',
|
40
|
+
}.freeze # :nodoc:
|
41
|
+
|
42
|
+
ESCAPE_PATTERN = /[\/"\\\x0-\x1f]/n # :nodoc:
|
43
|
+
|
44
|
+
SCRIPT_SAFE_MAP = MAP.merge(
|
45
|
+
'/' => '\\/',
|
46
|
+
"\u2028".b => '\u2028',
|
47
|
+
"\u2029".b => '\u2029',
|
48
|
+
).freeze
|
49
|
+
|
50
|
+
SCRIPT_SAFE_ESCAPE_PATTERN = Regexp.union(ESCAPE_PATTERN, "\u2028".b, "\u2029".b)
|
51
|
+
|
52
|
+
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
53
|
+
# UTF16 big endian characters as \u????, and return it.
|
54
|
+
def utf8_to_json(string, script_safe = false) # :nodoc:
|
55
|
+
string = string.b
|
56
|
+
if script_safe
|
57
|
+
string.gsub!(SCRIPT_SAFE_ESCAPE_PATTERN) { SCRIPT_SAFE_MAP[$&] || $& }
|
58
|
+
else
|
59
|
+
string.gsub!(ESCAPE_PATTERN) { MAP[$&] || $& }
|
60
|
+
end
|
61
|
+
string.force_encoding(::Encoding::UTF_8)
|
62
|
+
string
|
63
|
+
end
|
62
64
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
65
|
+
def utf8_to_json_ascii(string, script_safe = false) # :nodoc:
|
66
|
+
string = string.b
|
67
|
+
map = script_safe ? SCRIPT_SAFE_MAP : MAP
|
68
|
+
string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
|
69
|
+
string.gsub!(/(
|
70
|
+
(?:
|
71
|
+
[\xc2-\xdf][\x80-\xbf] |
|
72
|
+
[\xe0-\xef][\x80-\xbf]{2} |
|
73
|
+
[\xf0-\xf4][\x80-\xbf]{3}
|
74
|
+
)+ |
|
75
|
+
[\x80-\xc1\xf5-\xff] # invalid
|
76
|
+
)/nx) { |c|
|
77
|
+
c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
|
78
|
+
s = c.encode(::Encoding::UTF_16BE, ::Encoding::UTF_8).unpack('H*')[0]
|
79
|
+
s.force_encoding(::Encoding::BINARY)
|
80
|
+
s.gsub!(/.{4}/n, '\\\\u\&')
|
81
|
+
s.force_encoding(::Encoding::UTF_8)
|
82
|
+
}
|
83
|
+
string.force_encoding(::Encoding::UTF_8)
|
84
|
+
string
|
85
|
+
rescue => e
|
86
|
+
raise GeneratorError.wrap(e)
|
87
|
+
end
|
86
88
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
89
|
+
def valid_utf8?(string)
|
90
|
+
encoding = string.encoding
|
91
|
+
(encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
|
92
|
+
string.valid_encoding?
|
93
|
+
end
|
94
|
+
module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8?
|
93
95
|
|
94
|
-
module Pure
|
95
|
-
module Generator
|
96
96
|
# This class is used to create State instances, that are use to hold data
|
97
97
|
# while generating a JSON text from a Ruby data structure.
|
98
98
|
class State
|
99
|
+
def self.generate(obj, opts = nil)
|
100
|
+
new(opts).generate(obj)
|
101
|
+
end
|
102
|
+
|
99
103
|
# Creates a State object from _opts_, which ought to be Hash to create
|
100
104
|
# a new State instance configured by _opts_, something else to create
|
101
105
|
# an unconfigured instance. If _opts_ is a State object, it is just
|
@@ -130,7 +134,7 @@ module JSON
|
|
130
134
|
# * *allow_nan*: true if NaN, Infinity, and -Infinity should be
|
131
135
|
# generated, otherwise an exception is thrown, if these values are
|
132
136
|
# encountered. This options defaults to false.
|
133
|
-
def initialize(opts =
|
137
|
+
def initialize(opts = nil)
|
134
138
|
@indent = ''
|
135
139
|
@space = ''
|
136
140
|
@space_before = ''
|
@@ -138,10 +142,12 @@ module JSON
|
|
138
142
|
@array_nl = ''
|
139
143
|
@allow_nan = false
|
140
144
|
@ascii_only = false
|
141
|
-
@
|
142
|
-
@strict = false
|
145
|
+
@depth = 0
|
143
146
|
@buffer_initial_length = 1024
|
144
|
-
|
147
|
+
@script_safe = false
|
148
|
+
@strict = false
|
149
|
+
@max_nesting = 100
|
150
|
+
configure(opts) if opts
|
145
151
|
end
|
146
152
|
|
147
153
|
# This string is used to indent levels in the JSON text.
|
@@ -294,27 +300,25 @@ module JSON
|
|
294
300
|
else
|
295
301
|
result = obj.to_json(self)
|
296
302
|
end
|
297
|
-
JSON.valid_utf8?(result) or raise GeneratorError,
|
303
|
+
JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError,
|
298
304
|
"source sequence #{result.inspect} is illegal/malformed utf-8"
|
299
305
|
result
|
300
306
|
end
|
301
307
|
|
302
308
|
# Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
|
303
309
|
private def generate_json(obj, buf)
|
304
|
-
|
305
|
-
|
310
|
+
case obj
|
311
|
+
when Hash
|
306
312
|
buf << '{'
|
307
313
|
first = true
|
308
314
|
obj.each_pair do |k,v|
|
309
315
|
buf << ',' unless first
|
310
316
|
|
311
317
|
key_str = k.to_s
|
312
|
-
if key_str.
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
generate_json(key_str, buf)
|
317
|
-
end
|
318
|
+
if key_str.class == String
|
319
|
+
fast_serialize_string(key_str, buf)
|
320
|
+
elsif key_str.is_a?(String)
|
321
|
+
generate_json(key_str, buf)
|
318
322
|
else
|
319
323
|
raise TypeError, "#{k.class}#to_s returns an instance of #{key_str.class}, expected a String"
|
320
324
|
end
|
@@ -324,7 +328,7 @@ module JSON
|
|
324
328
|
first = false
|
325
329
|
end
|
326
330
|
buf << '}'
|
327
|
-
|
331
|
+
when Array
|
328
332
|
buf << '['
|
329
333
|
first = true
|
330
334
|
obj.each do |e|
|
@@ -333,9 +337,13 @@ module JSON
|
|
333
337
|
first = false
|
334
338
|
end
|
335
339
|
buf << ']'
|
336
|
-
|
337
|
-
|
338
|
-
|
340
|
+
when String
|
341
|
+
if obj.class == String
|
342
|
+
fast_serialize_string(obj, buf)
|
343
|
+
else
|
344
|
+
buf << obj.to_json(self)
|
345
|
+
end
|
346
|
+
when Integer
|
339
347
|
buf << obj.to_s
|
340
348
|
else
|
341
349
|
# Note: Float is handled this way since Float#to_s is slow anyway
|
@@ -344,24 +352,23 @@ module JSON
|
|
344
352
|
end
|
345
353
|
|
346
354
|
# Assumes !@ascii_only, !@script_safe
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
buf << string.gsub(/["\\\x0-\x1f]/n, MAP)
|
355
|
-
else
|
356
|
-
buf << string
|
355
|
+
private def fast_serialize_string(string, buf) # :nodoc:
|
356
|
+
buf << '"'
|
357
|
+
unless string.encoding == ::Encoding::UTF_8
|
358
|
+
begin
|
359
|
+
string = string.encode(::Encoding::UTF_8)
|
360
|
+
rescue Encoding::UndefinedConversionError => error
|
361
|
+
raise GeneratorError, error.message
|
357
362
|
end
|
358
|
-
buf << '"'
|
359
363
|
end
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
buf << string.
|
364
|
+
raise GeneratorError, "source sequence is illegal/malformed utf-8" unless string.valid_encoding?
|
365
|
+
|
366
|
+
if /["\\\x0-\x1f]/n.match?(string)
|
367
|
+
buf << string.gsub(/["\\\x0-\x1f]/n, MAP)
|
368
|
+
else
|
369
|
+
buf << string
|
364
370
|
end
|
371
|
+
buf << '"'
|
365
372
|
end
|
366
373
|
|
367
374
|
# Return the value returned by method +name+.
|
@@ -417,9 +424,15 @@ module JSON
|
|
417
424
|
end
|
418
425
|
|
419
426
|
def json_transform(state)
|
427
|
+
depth = state.depth += 1
|
428
|
+
|
429
|
+
if empty?
|
430
|
+
state.depth -= 1
|
431
|
+
return '{}'
|
432
|
+
end
|
433
|
+
|
420
434
|
delim = ",#{state.object_nl}"
|
421
435
|
result = +"{#{state.object_nl}"
|
422
|
-
depth = state.depth += 1
|
423
436
|
first = true
|
424
437
|
indent = !state.object_nl.empty?
|
425
438
|
each { |key, value|
|
@@ -427,8 +440,8 @@ module JSON
|
|
427
440
|
result << state.indent * depth if indent
|
428
441
|
|
429
442
|
key_str = key.to_s
|
430
|
-
|
431
|
-
|
443
|
+
if key_str.is_a?(String)
|
444
|
+
key_json = key_str.to_json(state)
|
432
445
|
else
|
433
446
|
raise TypeError, "#{key.class}#to_s returns an instance of #{key_str.class}, expected a String"
|
434
447
|
end
|
@@ -467,6 +480,13 @@ module JSON
|
|
467
480
|
private
|
468
481
|
|
469
482
|
def json_transform(state)
|
483
|
+
depth = state.depth += 1
|
484
|
+
|
485
|
+
if empty?
|
486
|
+
state.depth -= 1
|
487
|
+
return '[]'
|
488
|
+
end
|
489
|
+
|
470
490
|
result = '['.dup
|
471
491
|
if state.array_nl.empty?
|
472
492
|
delim = ","
|
@@ -474,7 +494,7 @@ module JSON
|
|
474
494
|
result << state.array_nl
|
475
495
|
delim = ",#{state.array_nl}"
|
476
496
|
end
|
477
|
-
|
497
|
+
|
478
498
|
first = true
|
479
499
|
indent = !state.array_nl.empty?
|
480
500
|
each { |value|
|
@@ -539,10 +559,12 @@ module JSON
|
|
539
559
|
string = encode(::Encoding::UTF_8)
|
540
560
|
end
|
541
561
|
if state.ascii_only?
|
542
|
-
%("#{JSON.utf8_to_json_ascii(string, state.script_safe)}")
|
562
|
+
%("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}")
|
543
563
|
else
|
544
|
-
%("#{JSON.utf8_to_json(string, state.script_safe)}")
|
564
|
+
%("#{JSON::TruffleRuby::Generator.utf8_to_json(string, state.script_safe)}")
|
545
565
|
end
|
566
|
+
rescue Encoding::UndefinedConversionError => error
|
567
|
+
raise ::JSON::GeneratorError, error.message
|
546
568
|
end
|
547
569
|
|
548
570
|
# Module that holds the extending methods if, the String module is
|
data/lib/json/version.rb
CHANGED
data/lib/json.rb
CHANGED
@@ -378,13 +378,13 @@ require 'json/common'
|
|
378
378
|
# json1 = JSON.generate(ruby)
|
379
379
|
# ruby1 = JSON.parse(json1, create_additions: true)
|
380
380
|
# # Make a nice display.
|
381
|
-
# display =
|
382
|
-
#
|
383
|
-
#
|
384
|
-
#
|
385
|
-
#
|
386
|
-
#
|
387
|
-
#
|
381
|
+
# display = <<~EOT
|
382
|
+
# Generated JSON:
|
383
|
+
# Without addition: #{json0} (#{json0.class})
|
384
|
+
# With addition: #{json1} (#{json1.class})
|
385
|
+
# Parsed JSON:
|
386
|
+
# Without addition: #{ruby0.inspect} (#{ruby0.class})
|
387
|
+
# With addition: #{ruby1.inspect} (#{ruby1.class})
|
388
388
|
# EOT
|
389
389
|
# puts display
|
390
390
|
#
|
@@ -562,13 +562,13 @@ require 'json/common'
|
|
562
562
|
# json1 = JSON.generate(foo1)
|
563
563
|
# obj1 = JSON.parse(json1, create_additions: true)
|
564
564
|
# # Make a nice display.
|
565
|
-
# display =
|
566
|
-
#
|
567
|
-
#
|
568
|
-
#
|
569
|
-
#
|
570
|
-
#
|
571
|
-
#
|
565
|
+
# display = <<~EOT
|
566
|
+
# Generated JSON:
|
567
|
+
# Without custom addition: #{json0} (#{json0.class})
|
568
|
+
# With custom addition: #{json1} (#{json1.class})
|
569
|
+
# Parsed JSON:
|
570
|
+
# Without custom addition: #{obj0.inspect} (#{obj0.class})
|
571
|
+
# With custom addition: #{obj1.inspect} (#{obj1.class})
|
572
572
|
# EOT
|
573
573
|
# puts display
|
574
574
|
#
|
@@ -583,10 +583,5 @@ require 'json/common'
|
|
583
583
|
#
|
584
584
|
module JSON
|
585
585
|
require 'json/version'
|
586
|
-
|
587
|
-
begin
|
588
|
-
require 'json/ext'
|
589
|
-
rescue LoadError
|
590
|
-
require 'json/pure'
|
591
|
-
end
|
586
|
+
require 'json/ext'
|
592
587
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Daniel Luz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A JSON implementation as a JRuby extension.
|
14
14
|
email: dev+ruby@mernen.com
|
@@ -42,9 +42,7 @@ files:
|
|
42
42
|
- lib/json/ext.rb
|
43
43
|
- lib/json/ext/generator/state.rb
|
44
44
|
- lib/json/generic_object.rb
|
45
|
-
- lib/json/
|
46
|
-
- lib/json/pure/generator.rb
|
47
|
-
- lib/json/pure/parser.rb
|
45
|
+
- lib/json/truffle_ruby/generator.rb
|
48
46
|
- lib/json/version.rb
|
49
47
|
homepage: https://ruby.github.io/json
|
50
48
|
licenses:
|
@@ -68,7 +66,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
66
|
requirements:
|
69
67
|
- - ">="
|
70
68
|
- !ruby/object:Gem::Version
|
71
|
-
version: '2.
|
69
|
+
version: '2.7'
|
72
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
71
|
requirements:
|
74
72
|
- - ">="
|