json 2.12.2 → 2.15.0
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 +51 -8
- data/README.md +3 -1
- data/ext/json/ext/fbuffer/fbuffer.h +31 -5
- data/ext/json/ext/generator/extconf.rb +1 -25
- data/ext/json/ext/generator/generator.c +171 -190
- data/ext/json/ext/parser/extconf.rb +5 -1
- data/ext/json/ext/parser/parser.c +177 -36
- data/ext/json/ext/simd/conf.rb +24 -0
- data/ext/json/ext/simd/simd.h +188 -0
- data/ext/json/ext/vendor/fpconv.c +12 -11
- data/json.gemspec +2 -3
- data/lib/json/add/core.rb +1 -0
- data/lib/json/add/string.rb +35 -0
- data/lib/json/common.rb +50 -24
- data/lib/json/ext/generator/state.rb +7 -14
- data/lib/json/generic_object.rb +0 -8
- data/lib/json/truffle_ruby/generator.rb +63 -45
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +55 -0
- metadata +6 -4
- data/ext/json/ext/generator/simd.h +0 -112
data/lib/json/common.rb
CHANGED
@@ -48,7 +48,7 @@ module JSON
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
# TODO:
|
51
|
+
# TODO: extract :create_additions support to another gem for version 3.0
|
52
52
|
def create_additions_proc(opts)
|
53
53
|
if opts[:symbolize_names]
|
54
54
|
raise ArgumentError, "options :symbolize_names and :create_additions cannot be used in conjunction"
|
@@ -73,7 +73,7 @@ module JSON
|
|
73
73
|
if opts[:create_additions] != false
|
74
74
|
if class_name = object[JSON.create_id]
|
75
75
|
klass = JSON.deep_const_get(class_name)
|
76
|
-
if
|
76
|
+
if klass.respond_to?(:json_creatable?) ? klass.json_creatable? : klass.respond_to?(:json_create)
|
77
77
|
create_additions_warning if create_additions.nil?
|
78
78
|
object = klass.json_create(object)
|
79
79
|
end
|
@@ -87,31 +87,32 @@ module JSON
|
|
87
87
|
opts
|
88
88
|
end
|
89
89
|
|
90
|
-
GEM_ROOT = File.expand_path("../../../", __FILE__) + "/"
|
91
90
|
def create_additions_warning
|
92
|
-
|
91
|
+
JSON.deprecation_warning "JSON.load implicit support for `create_additions: true` is deprecated " \
|
93
92
|
"and will be removed in 3.0, use JSON.unsafe_load or explicitly " \
|
94
93
|
"pass `create_additions: true`"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
95
97
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
if RUBY_VERSION >= "3.0"
|
106
|
-
warn(message, uplevel: uplevel - 1, category: :deprecated)
|
98
|
+
class << self
|
99
|
+
def deprecation_warning(message, uplevel = 3) # :nodoc:
|
100
|
+
gem_root = File.expand_path("..", __dir__) + "/"
|
101
|
+
caller_locations(uplevel, 10).each do |frame|
|
102
|
+
if frame.path.nil? || frame.path.start_with?(gem_root) || frame.path.end_with?("/truffle/cext_ruby.rb", ".c")
|
103
|
+
uplevel += 1
|
107
104
|
else
|
108
|
-
|
105
|
+
break
|
109
106
|
end
|
110
107
|
end
|
108
|
+
|
109
|
+
if RUBY_VERSION >= "3.0"
|
110
|
+
warn(message, uplevel: uplevel, category: :deprecated)
|
111
|
+
else
|
112
|
+
warn(message, uplevel: uplevel)
|
113
|
+
end
|
111
114
|
end
|
112
|
-
end
|
113
115
|
|
114
|
-
class << self
|
115
116
|
# :call-seq:
|
116
117
|
# JSON[object] -> new_array or new_string
|
117
118
|
#
|
@@ -185,6 +186,25 @@ module JSON
|
|
185
186
|
|
186
187
|
private
|
187
188
|
|
189
|
+
# Called from the extension when a hash has both string and symbol keys
|
190
|
+
def on_mixed_keys_hash(hash, do_raise)
|
191
|
+
set = {}
|
192
|
+
hash.each_key do |key|
|
193
|
+
key_str = key.to_s
|
194
|
+
|
195
|
+
if set[key_str]
|
196
|
+
message = "detected duplicate key #{key_str.inspect} in #{hash.inspect}"
|
197
|
+
if do_raise
|
198
|
+
raise GeneratorError, message
|
199
|
+
else
|
200
|
+
deprecation_warning("#{message}.\nThis will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`")
|
201
|
+
end
|
202
|
+
else
|
203
|
+
set[key_str] = true
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
188
208
|
def deprecated_singleton_attr_accessor(*attrs)
|
189
209
|
args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : ""
|
190
210
|
attrs.each do |attr|
|
@@ -268,7 +288,7 @@ module JSON
|
|
268
288
|
# to string interpolation.
|
269
289
|
#
|
270
290
|
# Note: no validation is performed on the provided string. It is the
|
271
|
-
#
|
291
|
+
# responsibility of the caller to ensure the string contains valid JSON.
|
272
292
|
Fragment = Struct.new(:json) do
|
273
293
|
def initialize(json)
|
274
294
|
unless string = String.try_convert(json)
|
@@ -390,7 +410,7 @@ module JSON
|
|
390
410
|
#
|
391
411
|
# Returns a \String containing the generated \JSON data.
|
392
412
|
#
|
393
|
-
# See also JSON.
|
413
|
+
# See also JSON.pretty_generate.
|
394
414
|
#
|
395
415
|
# Argument +obj+ is the Ruby object to be converted to \JSON.
|
396
416
|
#
|
@@ -642,6 +662,7 @@ module JSON
|
|
642
662
|
# when Array
|
643
663
|
# obj.map! {|v| deserialize_obj v }
|
644
664
|
# end
|
665
|
+
# obj
|
645
666
|
# })
|
646
667
|
# pp ruby
|
647
668
|
# Output:
|
@@ -683,9 +704,13 @@ module JSON
|
|
683
704
|
if opts[:allow_blank] && (source.nil? || source.empty?)
|
684
705
|
source = 'null'
|
685
706
|
end
|
686
|
-
|
687
|
-
|
688
|
-
|
707
|
+
|
708
|
+
if proc
|
709
|
+
opts = opts.dup
|
710
|
+
opts[:on_load] = proc.to_proc
|
711
|
+
end
|
712
|
+
|
713
|
+
parse(source, opts)
|
689
714
|
end
|
690
715
|
|
691
716
|
# :call-seq:
|
@@ -802,6 +827,7 @@ module JSON
|
|
802
827
|
# when Array
|
803
828
|
# obj.map! {|v| deserialize_obj v }
|
804
829
|
# end
|
830
|
+
# obj
|
805
831
|
# })
|
806
832
|
# pp ruby
|
807
833
|
# Output:
|
@@ -1001,7 +1027,7 @@ module JSON
|
|
1001
1027
|
# See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options].
|
1002
1028
|
#
|
1003
1029
|
# For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is
|
1004
|
-
#
|
1030
|
+
# encountered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
|
1005
1031
|
# \JSON counterpart:
|
1006
1032
|
#
|
1007
1033
|
# module MyApp
|
@@ -8,20 +8,8 @@ module JSON
|
|
8
8
|
#
|
9
9
|
# Instantiates a new State object, configured by _opts_.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# * *indent*: a string used to indent levels (default: ''),
|
14
|
-
# * *space*: a string that is put after, a : or , delimiter (default: ''),
|
15
|
-
# * *space_before*: a string that is put before a : pair delimiter (default: ''),
|
16
|
-
# * *object_nl*: a string that is put at the end of a JSON object (default: ''),
|
17
|
-
# * *array_nl*: a string that is put at the end of a JSON array (default: ''),
|
18
|
-
# * *allow_nan*: true if NaN, Infinity, and -Infinity should be
|
19
|
-
# generated, otherwise an exception is thrown, if these values are
|
20
|
-
# encountered. This options defaults to false.
|
21
|
-
# * *ascii_only*: true if only ASCII characters should be generated. This
|
22
|
-
# option defaults to false.
|
23
|
-
# * *buffer_initial_length*: sets the initial length of the generator's
|
24
|
-
# internal buffer.
|
11
|
+
# Argument +opts+, if given, contains a \Hash of options for the generation.
|
12
|
+
# See {Generating Options}[#module-JSON-label-Generating+Options].
|
25
13
|
def initialize(opts = nil)
|
26
14
|
if opts && !opts.empty?
|
27
15
|
configure(opts)
|
@@ -68,6 +56,11 @@ module JSON
|
|
68
56
|
buffer_initial_length: buffer_initial_length,
|
69
57
|
}
|
70
58
|
|
59
|
+
allow_duplicate_key = allow_duplicate_key?
|
60
|
+
unless allow_duplicate_key.nil?
|
61
|
+
result[:allow_duplicate_key] = allow_duplicate_key
|
62
|
+
end
|
63
|
+
|
71
64
|
instance_variables.each do |iv|
|
72
65
|
iv = iv.to_s[1..-1]
|
73
66
|
result[iv.to_sym] = self[iv]
|
data/lib/json/generic_object.rb
CHANGED
@@ -52,14 +52,6 @@ module JSON
|
|
52
52
|
table
|
53
53
|
end
|
54
54
|
|
55
|
-
def [](name)
|
56
|
-
__send__(name)
|
57
|
-
end unless method_defined?(:[])
|
58
|
-
|
59
|
-
def []=(name, value)
|
60
|
-
__send__("#{name}=", value)
|
61
|
-
end unless method_defined?(:[]=)
|
62
|
-
|
63
55
|
def |(other)
|
64
56
|
self.class[other.to_hash.merge(to_hash)]
|
65
57
|
end
|
@@ -47,6 +47,14 @@ module JSON
|
|
47
47
|
|
48
48
|
SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/
|
49
49
|
|
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)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.native_key?(key) # :nodoc:
|
55
|
+
(Symbol === key || String === key)
|
56
|
+
end
|
57
|
+
|
50
58
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
51
59
|
# UTF16 big endian characters as \u????, and return it.
|
52
60
|
def self.utf8_to_json(string, script_safe = false) # :nodoc:
|
@@ -271,6 +279,12 @@ module JSON
|
|
271
279
|
false
|
272
280
|
end
|
273
281
|
|
282
|
+
if opts.key?(:allow_duplicate_key)
|
283
|
+
@allow_duplicate_key = !!opts[:allow_duplicate_key]
|
284
|
+
else
|
285
|
+
@allow_duplicate_key = nil # nil is deprecation
|
286
|
+
end
|
287
|
+
|
274
288
|
@strict = !!opts[:strict] if opts.key?(:strict)
|
275
289
|
|
276
290
|
if !opts.key?(:max_nesting) # defaults to 100
|
@@ -284,6 +298,10 @@ module JSON
|
|
284
298
|
end
|
285
299
|
alias merge configure
|
286
300
|
|
301
|
+
def allow_duplicate_key? # :nodoc:
|
302
|
+
@allow_duplicate_key
|
303
|
+
end
|
304
|
+
|
287
305
|
# Returns the configuration instance variables as a hash, that can be
|
288
306
|
# passed to the configure method.
|
289
307
|
def to_h
|
@@ -292,6 +310,11 @@ module JSON
|
|
292
310
|
iv = iv.to_s[1..-1]
|
293
311
|
result[iv.to_sym] = self[iv]
|
294
312
|
end
|
313
|
+
|
314
|
+
if result[:allow_duplicate_key].nil?
|
315
|
+
result.delete(:allow_duplicate_key)
|
316
|
+
end
|
317
|
+
|
295
318
|
result
|
296
319
|
end
|
297
320
|
|
@@ -330,8 +353,17 @@ module JSON
|
|
330
353
|
when Hash
|
331
354
|
buf << '{'
|
332
355
|
first = true
|
356
|
+
key_type = nil
|
333
357
|
obj.each_pair do |k,v|
|
334
|
-
|
358
|
+
if first
|
359
|
+
key_type = k.class
|
360
|
+
else
|
361
|
+
if key_type && !@allow_duplicate_key && key_type != k.class
|
362
|
+
key_type = nil # stop checking
|
363
|
+
JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
|
364
|
+
end
|
365
|
+
buf << ','
|
366
|
+
end
|
335
367
|
|
336
368
|
key_str = k.to_s
|
337
369
|
if key_str.class == String
|
@@ -424,10 +456,10 @@ module JSON
|
|
424
456
|
state = State.from_state(state) if state
|
425
457
|
if state&.strict?
|
426
458
|
value = self
|
427
|
-
if state.strict? && !(
|
459
|
+
if state.strict? && !Generator.native_type?(value)
|
428
460
|
if state.as_json
|
429
|
-
value = state.as_json.call(value)
|
430
|
-
unless
|
461
|
+
value = state.as_json.call(value, false)
|
462
|
+
unless Generator.native_type?(value)
|
431
463
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
432
464
|
end
|
433
465
|
value.to_json(state)
|
@@ -471,11 +503,30 @@ module JSON
|
|
471
503
|
delim = ",#{state.object_nl}"
|
472
504
|
result = +"{#{state.object_nl}"
|
473
505
|
first = true
|
506
|
+
key_type = nil
|
474
507
|
indent = !state.object_nl.empty?
|
475
508
|
each { |key, value|
|
476
|
-
|
509
|
+
if first
|
510
|
+
key_type = key.class
|
511
|
+
else
|
512
|
+
if key_type && !state.allow_duplicate_key? && key_type != key.class
|
513
|
+
key_type = nil # stop checking
|
514
|
+
JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false)
|
515
|
+
end
|
516
|
+
result << delim
|
517
|
+
end
|
477
518
|
result << state.indent * depth if indent
|
478
519
|
|
520
|
+
if state.strict? && !Generator.native_key?(key)
|
521
|
+
if state.as_json
|
522
|
+
key = state.as_json.call(key, true)
|
523
|
+
end
|
524
|
+
|
525
|
+
unless Generator.native_key?(key)
|
526
|
+
raise GeneratorError.new("#{key.class} not allowed as object key in JSON", value)
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
479
530
|
key_str = key.to_s
|
480
531
|
if key_str.is_a?(String)
|
481
532
|
key_json = key_str.to_json(state)
|
@@ -484,10 +535,10 @@ module JSON
|
|
484
535
|
end
|
485
536
|
|
486
537
|
result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
|
487
|
-
if state.strict? && !(
|
538
|
+
if state.strict? && !Generator.native_type?(value)
|
488
539
|
if state.as_json
|
489
|
-
value = state.as_json.call(value)
|
490
|
-
unless
|
540
|
+
value = state.as_json.call(value, false)
|
541
|
+
unless Generator.native_type?(value)
|
491
542
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
492
543
|
end
|
493
544
|
result << value.to_json(state)
|
@@ -545,10 +596,10 @@ module JSON
|
|
545
596
|
each { |value|
|
546
597
|
result << delim unless first
|
547
598
|
result << state.indent * depth if indent
|
548
|
-
if state.strict? && !(
|
599
|
+
if state.strict? && !Generator.native_type?(value)
|
549
600
|
if state.as_json
|
550
|
-
value = state.as_json.call(value)
|
551
|
-
unless
|
601
|
+
value = state.as_json.call(value, false)
|
602
|
+
unless Generator.native_type?(value)
|
552
603
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
553
604
|
end
|
554
605
|
result << value.to_json(state)
|
@@ -582,7 +633,7 @@ module JSON
|
|
582
633
|
if state.allow_nan?
|
583
634
|
to_s
|
584
635
|
elsif state.strict? && state.as_json
|
585
|
-
casted_value = state.as_json.call(self)
|
636
|
+
casted_value = state.as_json.call(self, false)
|
586
637
|
|
587
638
|
if casted_value.equal?(self)
|
588
639
|
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
@@ -635,39 +686,6 @@ module JSON
|
|
635
686
|
rescue Encoding::UndefinedConversionError => error
|
636
687
|
raise ::JSON::GeneratorError.new(error.message, self)
|
637
688
|
end
|
638
|
-
|
639
|
-
# Module that holds the extending methods if, the String module is
|
640
|
-
# included.
|
641
|
-
module Extend
|
642
|
-
# Raw Strings are JSON Objects (the raw bytes are stored in an
|
643
|
-
# array for the key "raw"). The Ruby String can be created by this
|
644
|
-
# module method.
|
645
|
-
def json_create(o)
|
646
|
-
o['raw'].pack('C*')
|
647
|
-
end
|
648
|
-
end
|
649
|
-
|
650
|
-
# Extends _modul_ with the String::Extend module.
|
651
|
-
def self.included(modul)
|
652
|
-
modul.extend Extend
|
653
|
-
end
|
654
|
-
|
655
|
-
# This method creates a raw object hash, that can be nested into
|
656
|
-
# other data structures and will be unparsed as a raw string. This
|
657
|
-
# method should be used, if you want to convert raw strings to JSON
|
658
|
-
# instead of UTF-8 strings, e. g. binary data.
|
659
|
-
def to_json_raw_object
|
660
|
-
{
|
661
|
-
JSON.create_id => self.class.name,
|
662
|
-
'raw' => self.unpack('C*'),
|
663
|
-
}
|
664
|
-
end
|
665
|
-
|
666
|
-
# This method creates a JSON text from the result of
|
667
|
-
# a call to to_json_raw_object of this String.
|
668
|
-
def to_json_raw(*args)
|
669
|
-
to_json_raw_object.to_json(*args)
|
670
|
-
end
|
671
689
|
end
|
672
690
|
|
673
691
|
module TrueClass
|
data/lib/json/version.rb
CHANGED
data/lib/json.rb
CHANGED
@@ -127,6 +127,24 @@ require 'json/common'
|
|
127
127
|
#
|
128
128
|
# ---
|
129
129
|
#
|
130
|
+
# Option +allow_duplicate_key+ specifies whether duplicate keys in objects
|
131
|
+
# should be ignored or cause an error to be raised:
|
132
|
+
#
|
133
|
+
# When not specified:
|
134
|
+
# # The last value is used and a deprecation warning emitted.
|
135
|
+
# JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
|
136
|
+
# # warning: detected duplicate keys in JSON object.
|
137
|
+
# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
|
138
|
+
#
|
139
|
+
# When set to `+true+`
|
140
|
+
# # The last value is used.
|
141
|
+
# JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
|
142
|
+
#
|
143
|
+
# When set to `+false+`, the future default:
|
144
|
+
# JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
|
145
|
+
#
|
146
|
+
# ---
|
147
|
+
#
|
130
148
|
# Option +allow_nan+ (boolean) specifies whether to allow
|
131
149
|
# NaN, Infinity, and MinusInfinity in +source+;
|
132
150
|
# defaults to +false+.
|
@@ -143,8 +161,23 @@ require 'json/common'
|
|
143
161
|
# ruby = JSON.parse(source, {allow_nan: true})
|
144
162
|
# ruby # => [NaN, Infinity, -Infinity]
|
145
163
|
#
|
164
|
+
# ---
|
165
|
+
#
|
166
|
+
# Option +allow_trailing_comma+ (boolean) specifies whether to allow
|
167
|
+
# trailing commas in objects and arrays;
|
168
|
+
# defaults to +false+.
|
169
|
+
#
|
170
|
+
# With the default, +false+:
|
171
|
+
# JSON.parse('[1,]') # unexpected character: ']' at line 1 column 4 (JSON::ParserError)
|
172
|
+
#
|
173
|
+
# When enabled:
|
174
|
+
# JSON.parse('[1,]', allow_trailing_comma: true) # => [1]
|
175
|
+
#
|
146
176
|
# ====== Output Options
|
147
177
|
#
|
178
|
+
# Option +freeze+ (boolean) specifies whether the returned objects will be frozen;
|
179
|
+
# defaults to +false+.
|
180
|
+
#
|
148
181
|
# Option +symbolize_names+ (boolean) specifies whether returned \Hash keys
|
149
182
|
# should be Symbols;
|
150
183
|
# defaults to +false+ (use Strings).
|
@@ -274,6 +307,25 @@ require 'json/common'
|
|
274
307
|
#
|
275
308
|
# ---
|
276
309
|
#
|
310
|
+
# Option +allow_duplicate_key+ (boolean) specifies whether
|
311
|
+
# hashes with duplicate keys should be allowed or produce an error.
|
312
|
+
# defaults to emit a deprecation warning.
|
313
|
+
#
|
314
|
+
# With the default, (not set):
|
315
|
+
# Warning[:deprecated] = true
|
316
|
+
# JSON.generate({ foo: 1, "foo" => 2 })
|
317
|
+
# # warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}.
|
318
|
+
# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
|
319
|
+
# # => '{"foo":1,"foo":2}'
|
320
|
+
#
|
321
|
+
# With <tt>false</tt>
|
322
|
+
# JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false)
|
323
|
+
# # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
|
324
|
+
#
|
325
|
+
# In version 3.0, <tt>false</tt> will become the default.
|
326
|
+
#
|
327
|
+
# ---
|
328
|
+
#
|
277
329
|
# Option +max_nesting+ (\Integer) specifies the maximum nesting depth
|
278
330
|
# in +obj+; defaults to +100+.
|
279
331
|
#
|
@@ -351,6 +403,9 @@ require 'json/common'
|
|
351
403
|
#
|
352
404
|
# == \JSON Additions
|
353
405
|
#
|
406
|
+
# Note that JSON Additions must only be used with trusted data, and is
|
407
|
+
# deprecated.
|
408
|
+
#
|
354
409
|
# When you "round trip" a non-\String object from Ruby to \JSON and back,
|
355
410
|
# you have a new \String, instead of the object you began with:
|
356
411
|
# ruby0 = Range.new(0, 2)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies: []
|
12
12
|
description: This is a JSON implementation as a Ruby extension in C.
|
13
13
|
email: flori@ping.de
|
@@ -26,9 +26,10 @@ files:
|
|
26
26
|
- ext/json/ext/fbuffer/fbuffer.h
|
27
27
|
- ext/json/ext/generator/extconf.rb
|
28
28
|
- ext/json/ext/generator/generator.c
|
29
|
-
- ext/json/ext/generator/simd.h
|
30
29
|
- ext/json/ext/parser/extconf.rb
|
31
30
|
- ext/json/ext/parser/parser.c
|
31
|
+
- ext/json/ext/simd/conf.rb
|
32
|
+
- ext/json/ext/simd/simd.h
|
32
33
|
- ext/json/ext/vendor/fpconv.c
|
33
34
|
- ext/json/ext/vendor/jeaiii-ltoa.h
|
34
35
|
- json.gemspec
|
@@ -44,6 +45,7 @@ files:
|
|
44
45
|
- lib/json/add/rational.rb
|
45
46
|
- lib/json/add/regexp.rb
|
46
47
|
- lib/json/add/set.rb
|
48
|
+
- lib/json/add/string.rb
|
47
49
|
- lib/json/add/struct.rb
|
48
50
|
- lib/json/add/symbol.rb
|
49
51
|
- lib/json/add/time.rb
|
@@ -80,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
82
|
- !ruby/object:Gem::Version
|
81
83
|
version: '0'
|
82
84
|
requirements: []
|
83
|
-
rubygems_version: 3.6.
|
85
|
+
rubygems_version: 3.6.9
|
84
86
|
specification_version: 4
|
85
87
|
summary: JSON Implementation for Ruby
|
86
88
|
test_files: []
|
@@ -1,112 +0,0 @@
|
|
1
|
-
typedef enum {
|
2
|
-
SIMD_NONE,
|
3
|
-
SIMD_NEON,
|
4
|
-
SIMD_SSE2
|
5
|
-
} SIMD_Implementation;
|
6
|
-
|
7
|
-
#ifdef JSON_ENABLE_SIMD
|
8
|
-
|
9
|
-
#ifdef __clang__
|
10
|
-
#if __has_builtin(__builtin_ctzll)
|
11
|
-
#define HAVE_BUILTIN_CTZLL 1
|
12
|
-
#else
|
13
|
-
#define HAVE_BUILTIN_CTZLL 0
|
14
|
-
#endif
|
15
|
-
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
16
|
-
#define HAVE_BUILTIN_CTZLL 1
|
17
|
-
#else
|
18
|
-
#define HAVE_BUILTIN_CTZLL 0
|
19
|
-
#endif
|
20
|
-
|
21
|
-
static inline uint32_t trailing_zeros64(uint64_t input) {
|
22
|
-
#if HAVE_BUILTIN_CTZLL
|
23
|
-
return __builtin_ctzll(input);
|
24
|
-
#else
|
25
|
-
uint32_t trailing_zeros = 0;
|
26
|
-
uint64_t temp = input;
|
27
|
-
while ((temp & 1) == 0 && temp > 0) {
|
28
|
-
trailing_zeros++;
|
29
|
-
temp >>= 1;
|
30
|
-
}
|
31
|
-
return trailing_zeros;
|
32
|
-
#endif
|
33
|
-
}
|
34
|
-
|
35
|
-
static inline int trailing_zeros(int input) {
|
36
|
-
#if HAVE_BUILTIN_CTZLL
|
37
|
-
return __builtin_ctz(input);
|
38
|
-
#else
|
39
|
-
int trailing_zeros = 0;
|
40
|
-
int temp = input;
|
41
|
-
while ((temp & 1) == 0 && temp > 0) {
|
42
|
-
trailing_zeros++;
|
43
|
-
temp >>= 1;
|
44
|
-
}
|
45
|
-
return trailing_zeros;
|
46
|
-
#endif
|
47
|
-
}
|
48
|
-
|
49
|
-
#define SIMD_MINIMUM_THRESHOLD 6
|
50
|
-
|
51
|
-
#if defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(__aarch64__) || defined(_M_ARM64)
|
52
|
-
#include <arm_neon.h>
|
53
|
-
|
54
|
-
#define FIND_SIMD_IMPLEMENTATION_DEFINED 1
|
55
|
-
static SIMD_Implementation find_simd_implementation(void) {
|
56
|
-
return SIMD_NEON;
|
57
|
-
}
|
58
|
-
|
59
|
-
#define HAVE_SIMD 1
|
60
|
-
#define HAVE_SIMD_NEON 1
|
61
|
-
|
62
|
-
uint8x16x4_t load_uint8x16_4(const unsigned char *table) {
|
63
|
-
uint8x16x4_t tab;
|
64
|
-
tab.val[0] = vld1q_u8(table);
|
65
|
-
tab.val[1] = vld1q_u8(table+16);
|
66
|
-
tab.val[2] = vld1q_u8(table+32);
|
67
|
-
tab.val[3] = vld1q_u8(table+48);
|
68
|
-
return tab;
|
69
|
-
}
|
70
|
-
|
71
|
-
#endif /* ARM Neon Support.*/
|
72
|
-
|
73
|
-
#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
|
74
|
-
|
75
|
-
#ifdef HAVE_X86INTRIN_H
|
76
|
-
#include <x86intrin.h>
|
77
|
-
|
78
|
-
#define HAVE_SIMD 1
|
79
|
-
#define HAVE_SIMD_SSE2 1
|
80
|
-
|
81
|
-
#ifdef HAVE_CPUID_H
|
82
|
-
#define FIND_SIMD_IMPLEMENTATION_DEFINED 1
|
83
|
-
|
84
|
-
#include <cpuid.h>
|
85
|
-
#endif /* HAVE_CPUID_H */
|
86
|
-
|
87
|
-
static SIMD_Implementation find_simd_implementation(void) {
|
88
|
-
|
89
|
-
#if defined(__GNUC__ ) || defined(__clang__)
|
90
|
-
#ifdef __GNUC__
|
91
|
-
__builtin_cpu_init();
|
92
|
-
#endif /* __GNUC__ */
|
93
|
-
|
94
|
-
// TODO Revisit. I think the SSE version now only uses SSE2 instructions.
|
95
|
-
if (__builtin_cpu_supports("sse2")) {
|
96
|
-
return SIMD_SSE2;
|
97
|
-
}
|
98
|
-
#endif /* __GNUC__ || __clang__*/
|
99
|
-
|
100
|
-
return SIMD_NONE;
|
101
|
-
}
|
102
|
-
|
103
|
-
#endif /* HAVE_X86INTRIN_H */
|
104
|
-
#endif /* X86_64 Support */
|
105
|
-
|
106
|
-
#endif /* JSON_ENABLE_SIMD */
|
107
|
-
|
108
|
-
#ifndef FIND_SIMD_IMPLEMENTATION_DEFINED
|
109
|
-
static SIMD_Implementation find_simd_implementation(void) {
|
110
|
-
return SIMD_NONE;
|
111
|
-
}
|
112
|
-
#endif
|