json 2.12.2 → 2.18.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 +90 -8
- data/LEGAL +12 -0
- data/README.md +19 -1
- data/ext/json/ext/fbuffer/fbuffer.h +31 -54
- data/ext/json/ext/generator/extconf.rb +2 -26
- data/ext/json/ext/generator/generator.c +349 -335
- data/ext/json/ext/json.h +97 -0
- data/ext/json/ext/parser/extconf.rb +7 -2
- data/ext/json/ext/parser/parser.c +664 -401
- data/ext/json/ext/simd/conf.rb +24 -0
- data/ext/json/ext/simd/simd.h +191 -0
- data/ext/json/ext/vendor/fpconv.c +12 -11
- data/ext/json/ext/vendor/ryu.h +819 -0
- 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 +78 -40
- data/lib/json/ext/generator/state.rb +11 -14
- data/lib/json/generic_object.rb +0 -8
- data/lib/json/truffle_ruby/generator.rb +113 -63
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +55 -0
- metadata +8 -4
- data/ext/json/ext/generator/simd.h +0 -112
|
@@ -47,6 +47,19 @@ 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
|
+
|
|
58
|
+
def self.valid_encoding?(string) # :nodoc:
|
|
59
|
+
return false unless string.encoding == ::Encoding::UTF_8 || string.encoding == ::Encoding::US_ASCII
|
|
60
|
+
string.is_a?(Symbol) || string.valid_encoding?
|
|
61
|
+
end
|
|
62
|
+
|
|
50
63
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
|
51
64
|
# UTF16 big endian characters as \u????, and return it.
|
|
52
65
|
def self.utf8_to_json(string, script_safe = false) # :nodoc:
|
|
@@ -204,7 +217,7 @@ module JSON
|
|
|
204
217
|
return if @max_nesting.zero?
|
|
205
218
|
current_nesting = depth + 1
|
|
206
219
|
current_nesting > @max_nesting and
|
|
207
|
-
raise NestingError, "nesting of #{current_nesting} is too deep"
|
|
220
|
+
raise NestingError, "nesting of #{current_nesting} is too deep. Did you try to serialize objects with circular references?"
|
|
208
221
|
end
|
|
209
222
|
|
|
210
223
|
# Returns true, if circular data structures are checked,
|
|
@@ -271,6 +284,12 @@ module JSON
|
|
|
271
284
|
false
|
|
272
285
|
end
|
|
273
286
|
|
|
287
|
+
if opts.key?(:allow_duplicate_key)
|
|
288
|
+
@allow_duplicate_key = !!opts[:allow_duplicate_key]
|
|
289
|
+
else
|
|
290
|
+
@allow_duplicate_key = nil # nil is deprecation
|
|
291
|
+
end
|
|
292
|
+
|
|
274
293
|
@strict = !!opts[:strict] if opts.key?(:strict)
|
|
275
294
|
|
|
276
295
|
if !opts.key?(:max_nesting) # defaults to 100
|
|
@@ -284,14 +303,23 @@ module JSON
|
|
|
284
303
|
end
|
|
285
304
|
alias merge configure
|
|
286
305
|
|
|
306
|
+
def allow_duplicate_key? # :nodoc:
|
|
307
|
+
@allow_duplicate_key
|
|
308
|
+
end
|
|
309
|
+
|
|
287
310
|
# Returns the configuration instance variables as a hash, that can be
|
|
288
311
|
# passed to the configure method.
|
|
289
312
|
def to_h
|
|
290
313
|
result = {}
|
|
291
314
|
instance_variables.each do |iv|
|
|
292
|
-
|
|
293
|
-
result[
|
|
315
|
+
key = iv.to_s[1..-1]
|
|
316
|
+
result[key.to_sym] = instance_variable_get(iv)
|
|
294
317
|
end
|
|
318
|
+
|
|
319
|
+
if result[:allow_duplicate_key].nil?
|
|
320
|
+
result.delete(:allow_duplicate_key)
|
|
321
|
+
end
|
|
322
|
+
|
|
295
323
|
result
|
|
296
324
|
end
|
|
297
325
|
|
|
@@ -302,6 +330,9 @@ module JSON
|
|
|
302
330
|
# created this method raises a
|
|
303
331
|
# GeneratorError exception.
|
|
304
332
|
def generate(obj, anIO = nil)
|
|
333
|
+
return dup.generate(obj, anIO) if frozen?
|
|
334
|
+
|
|
335
|
+
depth = @depth
|
|
305
336
|
if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
|
|
306
337
|
!@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
|
|
307
338
|
result = generate_json(obj, ''.dup)
|
|
@@ -318,10 +349,8 @@ module JSON
|
|
|
318
349
|
else
|
|
319
350
|
result
|
|
320
351
|
end
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
def generate_new(obj, anIO = nil) # :nodoc:
|
|
324
|
-
dup.generate(obj, anIO)
|
|
352
|
+
ensure
|
|
353
|
+
@depth = depth unless frozen?
|
|
325
354
|
end
|
|
326
355
|
|
|
327
356
|
# Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
|
|
@@ -330,8 +359,17 @@ module JSON
|
|
|
330
359
|
when Hash
|
|
331
360
|
buf << '{'
|
|
332
361
|
first = true
|
|
362
|
+
key_type = nil
|
|
333
363
|
obj.each_pair do |k,v|
|
|
334
|
-
|
|
364
|
+
if first
|
|
365
|
+
key_type = k.class
|
|
366
|
+
else
|
|
367
|
+
if key_type && !@allow_duplicate_key && key_type != k.class
|
|
368
|
+
key_type = nil # stop checking
|
|
369
|
+
JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
|
|
370
|
+
end
|
|
371
|
+
buf << ','
|
|
372
|
+
end
|
|
335
373
|
|
|
336
374
|
key_str = k.to_s
|
|
337
375
|
if key_str.class == String
|
|
@@ -398,6 +436,8 @@ module JSON
|
|
|
398
436
|
|
|
399
437
|
# Return the value returned by method +name+.
|
|
400
438
|
def [](name)
|
|
439
|
+
::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
|
|
440
|
+
|
|
401
441
|
if respond_to?(name)
|
|
402
442
|
__send__(name)
|
|
403
443
|
else
|
|
@@ -407,6 +447,8 @@ module JSON
|
|
|
407
447
|
end
|
|
408
448
|
|
|
409
449
|
def []=(name, value)
|
|
450
|
+
::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
|
|
451
|
+
|
|
410
452
|
if respond_to?(name_writer = "#{name}=")
|
|
411
453
|
__send__ name_writer, value
|
|
412
454
|
else
|
|
@@ -424,10 +466,10 @@ module JSON
|
|
|
424
466
|
state = State.from_state(state) if state
|
|
425
467
|
if state&.strict?
|
|
426
468
|
value = self
|
|
427
|
-
if state.strict? && !(
|
|
469
|
+
if state.strict? && !Generator.native_type?(value)
|
|
428
470
|
if state.as_json
|
|
429
|
-
value = state.as_json.call(value)
|
|
430
|
-
unless
|
|
471
|
+
value = state.as_json.call(value, false)
|
|
472
|
+
unless Generator.native_type?(value)
|
|
431
473
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
432
474
|
end
|
|
433
475
|
value.to_json(state)
|
|
@@ -449,17 +491,15 @@ module JSON
|
|
|
449
491
|
# _depth_ is used to find out nesting depth, to indent accordingly.
|
|
450
492
|
def to_json(state = nil, *)
|
|
451
493
|
state = State.from_state(state)
|
|
494
|
+
depth = state.depth
|
|
452
495
|
state.check_max_nesting
|
|
453
496
|
json_transform(state)
|
|
497
|
+
ensure
|
|
498
|
+
state.depth = depth
|
|
454
499
|
end
|
|
455
500
|
|
|
456
501
|
private
|
|
457
502
|
|
|
458
|
-
def json_shift(state)
|
|
459
|
-
state.object_nl.empty? or return ''
|
|
460
|
-
state.indent * state.depth
|
|
461
|
-
end
|
|
462
|
-
|
|
463
503
|
def json_transform(state)
|
|
464
504
|
depth = state.depth += 1
|
|
465
505
|
|
|
@@ -471,11 +511,34 @@ module JSON
|
|
|
471
511
|
delim = ",#{state.object_nl}"
|
|
472
512
|
result = +"{#{state.object_nl}"
|
|
473
513
|
first = true
|
|
514
|
+
key_type = nil
|
|
474
515
|
indent = !state.object_nl.empty?
|
|
475
516
|
each { |key, value|
|
|
476
|
-
|
|
517
|
+
if first
|
|
518
|
+
key_type = key.class
|
|
519
|
+
else
|
|
520
|
+
if key_type && !state.allow_duplicate_key? && key_type != key.class
|
|
521
|
+
key_type = nil # stop checking
|
|
522
|
+
JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false)
|
|
523
|
+
end
|
|
524
|
+
result << delim
|
|
525
|
+
end
|
|
477
526
|
result << state.indent * depth if indent
|
|
478
527
|
|
|
528
|
+
if state.strict?
|
|
529
|
+
if state.as_json && (!Generator.native_key?(key) || !Generator.valid_encoding?(key))
|
|
530
|
+
key = state.as_json.call(key, true)
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
unless Generator.native_key?(key)
|
|
534
|
+
raise GeneratorError.new("#{key.class} not allowed as object key in JSON", key)
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
unless Generator.valid_encoding?(key)
|
|
538
|
+
raise GeneratorError.new("source sequence is illegal/malformed utf-8", key)
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
|
|
479
542
|
key_str = key.to_s
|
|
480
543
|
if key_str.is_a?(String)
|
|
481
544
|
key_json = key_str.to_json(state)
|
|
@@ -484,24 +547,26 @@ module JSON
|
|
|
484
547
|
end
|
|
485
548
|
|
|
486
549
|
result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
|
|
487
|
-
if state.strict? && !(
|
|
550
|
+
if state.strict? && !Generator.native_type?(value)
|
|
488
551
|
if state.as_json
|
|
489
|
-
value = state.as_json.call(value)
|
|
490
|
-
unless
|
|
552
|
+
value = state.as_json.call(value, false)
|
|
553
|
+
unless Generator.native_type?(value)
|
|
491
554
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
492
555
|
end
|
|
493
556
|
result << value.to_json(state)
|
|
557
|
+
state.depth = depth
|
|
494
558
|
else
|
|
495
559
|
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
|
496
560
|
end
|
|
497
561
|
elsif value.respond_to?(:to_json)
|
|
498
562
|
result << value.to_json(state)
|
|
563
|
+
state.depth = depth
|
|
499
564
|
else
|
|
500
565
|
result << %{"#{String(value)}"}
|
|
501
566
|
end
|
|
502
567
|
first = false
|
|
503
568
|
}
|
|
504
|
-
depth
|
|
569
|
+
depth -= 1
|
|
505
570
|
unless first
|
|
506
571
|
result << state.object_nl
|
|
507
572
|
result << state.indent * depth if indent
|
|
@@ -518,8 +583,11 @@ module JSON
|
|
|
518
583
|
# produced JSON string output further.
|
|
519
584
|
def to_json(state = nil, *)
|
|
520
585
|
state = State.from_state(state)
|
|
586
|
+
depth = state.depth
|
|
521
587
|
state.check_max_nesting
|
|
522
588
|
json_transform(state)
|
|
589
|
+
ensure
|
|
590
|
+
state.depth = depth
|
|
523
591
|
end
|
|
524
592
|
|
|
525
593
|
private
|
|
@@ -545,10 +613,10 @@ module JSON
|
|
|
545
613
|
each { |value|
|
|
546
614
|
result << delim unless first
|
|
547
615
|
result << state.indent * depth if indent
|
|
548
|
-
if state.strict? && !(
|
|
616
|
+
if state.strict? && !Generator.native_type?(value)
|
|
549
617
|
if state.as_json
|
|
550
|
-
value = state.as_json.call(value)
|
|
551
|
-
unless
|
|
618
|
+
value = state.as_json.call(value, false)
|
|
619
|
+
unless Generator.native_type?(value)
|
|
552
620
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
553
621
|
end
|
|
554
622
|
result << value.to_json(state)
|
|
@@ -557,12 +625,13 @@ module JSON
|
|
|
557
625
|
end
|
|
558
626
|
elsif value.respond_to?(:to_json)
|
|
559
627
|
result << value.to_json(state)
|
|
628
|
+
state.depth = depth
|
|
560
629
|
else
|
|
561
630
|
result << %{"#{String(value)}"}
|
|
562
631
|
end
|
|
563
632
|
first = false
|
|
564
633
|
}
|
|
565
|
-
depth
|
|
634
|
+
depth -= 1
|
|
566
635
|
result << state.array_nl
|
|
567
636
|
result << state.indent * depth if indent
|
|
568
637
|
result << ']'
|
|
@@ -582,11 +651,14 @@ module JSON
|
|
|
582
651
|
if state.allow_nan?
|
|
583
652
|
to_s
|
|
584
653
|
elsif state.strict? && state.as_json
|
|
585
|
-
casted_value = state.as_json.call(self)
|
|
654
|
+
casted_value = state.as_json.call(self, false)
|
|
586
655
|
|
|
587
656
|
if casted_value.equal?(self)
|
|
588
657
|
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
|
589
658
|
end
|
|
659
|
+
unless Generator.native_type?(casted_value)
|
|
660
|
+
raise GeneratorError.new("#{casted_value.class} returned by #{state.as_json} not allowed in JSON", casted_value)
|
|
661
|
+
end
|
|
590
662
|
|
|
591
663
|
state.check_max_nesting
|
|
592
664
|
state.depth += 1
|
|
@@ -619,14 +691,25 @@ module JSON
|
|
|
619
691
|
# \u????.
|
|
620
692
|
def to_json(state = nil, *args)
|
|
621
693
|
state = State.from_state(state)
|
|
622
|
-
|
|
623
|
-
|
|
694
|
+
string = self
|
|
695
|
+
|
|
696
|
+
if state.strict? && state.as_json
|
|
697
|
+
unless Generator.valid_encoding?(string)
|
|
698
|
+
string = state.as_json.call(string, false)
|
|
699
|
+
unless string.is_a?(::String)
|
|
700
|
+
return string.to_json(state, *args)
|
|
701
|
+
end
|
|
702
|
+
end
|
|
703
|
+
end
|
|
704
|
+
|
|
705
|
+
if string.encoding == ::Encoding::UTF_8
|
|
706
|
+
unless string.valid_encoding?
|
|
624
707
|
raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
|
|
625
708
|
end
|
|
626
|
-
string = self
|
|
627
709
|
else
|
|
628
|
-
string = encode(::Encoding::UTF_8)
|
|
710
|
+
string = string.encode(::Encoding::UTF_8)
|
|
629
711
|
end
|
|
712
|
+
|
|
630
713
|
if state.ascii_only?
|
|
631
714
|
%("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}")
|
|
632
715
|
else
|
|
@@ -635,39 +718,6 @@ module JSON
|
|
|
635
718
|
rescue Encoding::UndefinedConversionError => error
|
|
636
719
|
raise ::JSON::GeneratorError.new(error.message, self)
|
|
637
720
|
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
721
|
end
|
|
672
722
|
|
|
673
723
|
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.18.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,11 +26,14 @@ 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/
|
|
29
|
+
- ext/json/ext/json.h
|
|
30
30
|
- ext/json/ext/parser/extconf.rb
|
|
31
31
|
- ext/json/ext/parser/parser.c
|
|
32
|
+
- ext/json/ext/simd/conf.rb
|
|
33
|
+
- ext/json/ext/simd/simd.h
|
|
32
34
|
- ext/json/ext/vendor/fpconv.c
|
|
33
35
|
- ext/json/ext/vendor/jeaiii-ltoa.h
|
|
36
|
+
- ext/json/ext/vendor/ryu.h
|
|
34
37
|
- json.gemspec
|
|
35
38
|
- lib/json.rb
|
|
36
39
|
- lib/json/add/bigdecimal.rb
|
|
@@ -44,6 +47,7 @@ files:
|
|
|
44
47
|
- lib/json/add/rational.rb
|
|
45
48
|
- lib/json/add/regexp.rb
|
|
46
49
|
- lib/json/add/set.rb
|
|
50
|
+
- lib/json/add/string.rb
|
|
47
51
|
- lib/json/add/struct.rb
|
|
48
52
|
- lib/json/add/symbol.rb
|
|
49
53
|
- lib/json/add/time.rb
|
|
@@ -80,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
80
84
|
- !ruby/object:Gem::Version
|
|
81
85
|
version: '0'
|
|
82
86
|
requirements: []
|
|
83
|
-
rubygems_version: 3.6.
|
|
87
|
+
rubygems_version: 3.6.9
|
|
84
88
|
specification_version: 4
|
|
85
89
|
summary: JSON Implementation for Ruby
|
|
86
90
|
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
|