json 2.7.3 → 2.9.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 +49 -0
- data/README.md +8 -77
- data/ext/json/ext/fbuffer/fbuffer.h +122 -54
- data/ext/json/ext/generator/generator.c +425 -235
- data/ext/json/ext/parser/extconf.rb +5 -27
- data/ext/json/ext/parser/parser.c +1597 -596
- data/ext/json/ext/parser/parser.rl +726 -258
- data/json.gemspec +4 -1
- data/lib/json/add/bigdecimal.rb +1 -1
- data/lib/json/common.rb +239 -72
- data/lib/json/ext/generator/state.rb +12 -31
- data/lib/json/ext.rb +2 -7
- data/lib/json/{pure → truffle_ruby}/generator.rb +180 -131
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +15 -20
- metadata +4 -8
- data/ext/json/ext/generator/generator.h +0 -129
- data/ext/json/ext/parser/parser.h +0 -60
- data/lib/json/pure/parser.rb +0 -331
- data/lib/json/pure.rb +0 -16
data/json.gemspec
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
version = File.foreach(File.join(__dir__, "lib/json/version.rb")) do |line|
|
|
2
4
|
/^\s*VERSION\s*=\s*'(.*)'/ =~ line and break $1
|
|
3
5
|
end rescue nil
|
|
@@ -19,7 +21,7 @@ spec = Gem::Specification.new do |s|
|
|
|
19
21
|
'wiki_uri' => 'https://github.com/ruby/json/wiki'
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
s.required_ruby_version = Gem::Requirement.new(">= 2.
|
|
24
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.7")
|
|
23
25
|
|
|
24
26
|
if java_ext
|
|
25
27
|
s.description = "A JSON implementation as a JRuby extension."
|
|
@@ -48,6 +50,7 @@ spec = Gem::Specification.new do |s|
|
|
|
48
50
|
|
|
49
51
|
if java_ext
|
|
50
52
|
s.platform = 'java'
|
|
53
|
+
s.files += Dir["lib/json/ext/**/*.jar"]
|
|
51
54
|
else
|
|
52
55
|
s.extensions = Dir["ext/json/**/extconf.rb"]
|
|
53
56
|
s.files += Dir["ext/json/**/*.{c,h,rl}"]
|
data/lib/json/add/bigdecimal.rb
CHANGED
data/lib/json/common.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#frozen_string_literal: true
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'json/version'
|
|
3
4
|
|
|
4
5
|
module JSON
|
|
@@ -25,16 +26,14 @@ module JSON
|
|
|
25
26
|
elsif object.respond_to?(:to_str)
|
|
26
27
|
str = object.to_str
|
|
27
28
|
if str.is_a?(String)
|
|
28
|
-
return JSON.parse(
|
|
29
|
+
return JSON.parse(str, opts)
|
|
29
30
|
end
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
JSON.generate(object, opts)
|
|
33
34
|
end
|
|
34
35
|
|
|
35
|
-
# Returns the JSON parser class that is used by JSON.
|
|
36
|
-
# JSON::Ext::Parser or JSON::Pure::Parser:
|
|
37
|
-
# JSON.parser # => JSON::Ext::Parser
|
|
36
|
+
# Returns the JSON parser class that is used by JSON.
|
|
38
37
|
attr_reader :parser
|
|
39
38
|
|
|
40
39
|
# Set the JSON parser class _parser_ to be used by JSON.
|
|
@@ -49,18 +48,9 @@ module JSON
|
|
|
49
48
|
# level (absolute namespace path?). If there doesn't exist a constant at
|
|
50
49
|
# the given path, an ArgumentError is raised.
|
|
51
50
|
def deep_const_get(path) # :nodoc:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
when p.const_defined?(c, true) then p.const_get(c)
|
|
56
|
-
else
|
|
57
|
-
begin
|
|
58
|
-
p.const_missing(c)
|
|
59
|
-
rescue NameError => e
|
|
60
|
-
raise ArgumentError, "can't get const #{path}: #{e}"
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
51
|
+
Object.const_get(path)
|
|
52
|
+
rescue NameError => e
|
|
53
|
+
raise ArgumentError, "can't get const #{path}: #{e}"
|
|
64
54
|
end
|
|
65
55
|
|
|
66
56
|
# Set the module _generator_ to be used by JSON.
|
|
@@ -69,7 +59,7 @@ module JSON
|
|
|
69
59
|
@generator = generator
|
|
70
60
|
generator_methods = generator::GeneratorMethods
|
|
71
61
|
for const in generator_methods.constants
|
|
72
|
-
klass =
|
|
62
|
+
klass = const_get(const)
|
|
73
63
|
modul = generator_methods.const_get(const)
|
|
74
64
|
klass.class_eval do
|
|
75
65
|
instance_methods(false).each do |m|
|
|
@@ -106,14 +96,10 @@ module JSON
|
|
|
106
96
|
)
|
|
107
97
|
end
|
|
108
98
|
|
|
109
|
-
# Returns the JSON generator module that is used by JSON.
|
|
110
|
-
# either JSON::Ext::Generator or JSON::Pure::Generator:
|
|
111
|
-
# JSON.generator # => JSON::Ext::Generator
|
|
99
|
+
# Returns the JSON generator module that is used by JSON.
|
|
112
100
|
attr_reader :generator
|
|
113
101
|
|
|
114
|
-
# Sets or Returns the JSON generator state class that is used by JSON.
|
|
115
|
-
# either JSON::Ext::Generator::State or JSON::Pure::Generator::State:
|
|
116
|
-
# JSON.state # => JSON::Ext::Generator::State
|
|
102
|
+
# Sets or Returns the JSON generator state class that is used by JSON.
|
|
117
103
|
attr_accessor :state
|
|
118
104
|
end
|
|
119
105
|
|
|
@@ -157,7 +143,23 @@ module JSON
|
|
|
157
143
|
# :startdoc:
|
|
158
144
|
|
|
159
145
|
# This exception is raised if a generator or unparser error occurs.
|
|
160
|
-
class GeneratorError < JSONError
|
|
146
|
+
class GeneratorError < JSONError
|
|
147
|
+
attr_reader :invalid_object
|
|
148
|
+
|
|
149
|
+
def initialize(message, invalid_object = nil)
|
|
150
|
+
super(message)
|
|
151
|
+
@invalid_object = invalid_object
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def detailed_message(...)
|
|
155
|
+
if @invalid_object.nil?
|
|
156
|
+
super
|
|
157
|
+
else
|
|
158
|
+
"#{super}\nInvalid object: #{@invalid_object.inspect}"
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
161
163
|
# For backwards compatibility
|
|
162
164
|
UnparserError = GeneratorError # :nodoc:
|
|
163
165
|
|
|
@@ -195,17 +197,17 @@ module JSON
|
|
|
195
197
|
# {Parsing \JSON}[#module-JSON-label-Parsing+JSON].
|
|
196
198
|
#
|
|
197
199
|
# Parses nested JSON objects:
|
|
198
|
-
# source =
|
|
199
|
-
#
|
|
200
|
-
#
|
|
201
|
-
#
|
|
202
|
-
#
|
|
203
|
-
#
|
|
204
|
-
#
|
|
205
|
-
#
|
|
206
|
-
#
|
|
207
|
-
#
|
|
208
|
-
#
|
|
200
|
+
# source = <<~JSON
|
|
201
|
+
# {
|
|
202
|
+
# "name": "Dave",
|
|
203
|
+
# "age" :40,
|
|
204
|
+
# "hats": [
|
|
205
|
+
# "Cattleman's",
|
|
206
|
+
# "Panama",
|
|
207
|
+
# "Tophat"
|
|
208
|
+
# ]
|
|
209
|
+
# }
|
|
210
|
+
# JSON
|
|
209
211
|
# ruby = JSON.parse(source)
|
|
210
212
|
# ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
|
|
211
213
|
#
|
|
@@ -216,11 +218,7 @@ module JSON
|
|
|
216
218
|
# JSON.parse('')
|
|
217
219
|
#
|
|
218
220
|
def parse(source, opts = nil)
|
|
219
|
-
|
|
220
|
-
Parser.new(source).parse
|
|
221
|
-
else
|
|
222
|
-
Parser.new(source, opts).parse
|
|
223
|
-
end
|
|
221
|
+
Parser.parse(source, opts)
|
|
224
222
|
end
|
|
225
223
|
|
|
226
224
|
# :call-seq:
|
|
@@ -249,8 +247,8 @@ module JSON
|
|
|
249
247
|
# parse(File.read(path), opts)
|
|
250
248
|
#
|
|
251
249
|
# See method #parse.
|
|
252
|
-
def load_file(filespec, opts =
|
|
253
|
-
parse(File.read(filespec), opts)
|
|
250
|
+
def load_file(filespec, opts = nil)
|
|
251
|
+
parse(File.read(filespec, encoding: Encoding::UTF_8), opts)
|
|
254
252
|
end
|
|
255
253
|
|
|
256
254
|
# :call-seq:
|
|
@@ -261,7 +259,7 @@ module JSON
|
|
|
261
259
|
#
|
|
262
260
|
# See method #parse!
|
|
263
261
|
def load_file!(filespec, opts = {})
|
|
264
|
-
parse!(File.read(filespec), opts)
|
|
262
|
+
parse!(File.read(filespec, encoding: Encoding::UTF_8), opts)
|
|
265
263
|
end
|
|
266
264
|
|
|
267
265
|
# :call-seq:
|
|
@@ -302,11 +300,10 @@ module JSON
|
|
|
302
300
|
#
|
|
303
301
|
def generate(obj, opts = nil)
|
|
304
302
|
if State === opts
|
|
305
|
-
|
|
303
|
+
opts.generate(obj)
|
|
306
304
|
else
|
|
307
|
-
|
|
305
|
+
State.generate(obj, opts, nil)
|
|
308
306
|
end
|
|
309
|
-
state.generate(obj)
|
|
310
307
|
end
|
|
311
308
|
|
|
312
309
|
# :stopdoc:
|
|
@@ -399,6 +396,20 @@ module JSON
|
|
|
399
396
|
module_function :pretty_unparse
|
|
400
397
|
# :startdoc:
|
|
401
398
|
|
|
399
|
+
class << self
|
|
400
|
+
# Sets or returns default options for the JSON.unsafe_load method.
|
|
401
|
+
# Initially:
|
|
402
|
+
# opts = JSON.load_default_options
|
|
403
|
+
# opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
|
|
404
|
+
attr_accessor :unsafe_load_default_options
|
|
405
|
+
end
|
|
406
|
+
self.unsafe_load_default_options = {
|
|
407
|
+
:max_nesting => false,
|
|
408
|
+
:allow_nan => true,
|
|
409
|
+
:allow_blank => true,
|
|
410
|
+
:create_additions => true,
|
|
411
|
+
}
|
|
412
|
+
|
|
402
413
|
class << self
|
|
403
414
|
# Sets or returns default options for the JSON.load method.
|
|
404
415
|
# Initially:
|
|
@@ -407,17 +418,179 @@ module JSON
|
|
|
407
418
|
attr_accessor :load_default_options
|
|
408
419
|
end
|
|
409
420
|
self.load_default_options = {
|
|
410
|
-
:max_nesting => false,
|
|
411
421
|
:allow_nan => true,
|
|
412
422
|
:allow_blank => true,
|
|
413
|
-
:create_additions =>
|
|
423
|
+
:create_additions => nil,
|
|
414
424
|
}
|
|
425
|
+
# :call-seq:
|
|
426
|
+
# JSON.unsafe_load(source, proc = nil, options = {}) -> object
|
|
427
|
+
#
|
|
428
|
+
# Returns the Ruby objects created by parsing the given +source+.
|
|
429
|
+
#
|
|
430
|
+
# BEWARE: This method is meant to serialise data from trusted user input,
|
|
431
|
+
# like from your own database server or clients under your control, it could
|
|
432
|
+
# be dangerous to allow untrusted users to pass JSON sources into it.
|
|
433
|
+
#
|
|
434
|
+
# - Argument +source+ must be, or be convertible to, a \String:
|
|
435
|
+
# - If +source+ responds to instance method +to_str+,
|
|
436
|
+
# <tt>source.to_str</tt> becomes the source.
|
|
437
|
+
# - If +source+ responds to instance method +to_io+,
|
|
438
|
+
# <tt>source.to_io.read</tt> becomes the source.
|
|
439
|
+
# - If +source+ responds to instance method +read+,
|
|
440
|
+
# <tt>source.read</tt> becomes the source.
|
|
441
|
+
# - If both of the following are true, source becomes the \String <tt>'null'</tt>:
|
|
442
|
+
# - Option +allow_blank+ specifies a truthy value.
|
|
443
|
+
# - The source, as defined above, is +nil+ or the empty \String <tt>''</tt>.
|
|
444
|
+
# - Otherwise, +source+ remains the source.
|
|
445
|
+
# - Argument +proc+, if given, must be a \Proc that accepts one argument.
|
|
446
|
+
# It will be called recursively with each result (depth-first order).
|
|
447
|
+
# See details below.
|
|
448
|
+
# - Argument +opts+, if given, contains a \Hash of options for the parsing.
|
|
449
|
+
# See {Parsing Options}[#module-JSON-label-Parsing+Options].
|
|
450
|
+
# The default options can be changed via method JSON.unsafe_load_default_options=.
|
|
451
|
+
#
|
|
452
|
+
# ---
|
|
453
|
+
#
|
|
454
|
+
# When no +proc+ is given, modifies +source+ as above and returns the result of
|
|
455
|
+
# <tt>parse(source, opts)</tt>; see #parse.
|
|
456
|
+
#
|
|
457
|
+
# Source for following examples:
|
|
458
|
+
# source = <<~JSON
|
|
459
|
+
# {
|
|
460
|
+
# "name": "Dave",
|
|
461
|
+
# "age" :40,
|
|
462
|
+
# "hats": [
|
|
463
|
+
# "Cattleman's",
|
|
464
|
+
# "Panama",
|
|
465
|
+
# "Tophat"
|
|
466
|
+
# ]
|
|
467
|
+
# }
|
|
468
|
+
# JSON
|
|
469
|
+
#
|
|
470
|
+
# Load a \String:
|
|
471
|
+
# ruby = JSON.unsafe_load(source)
|
|
472
|
+
# ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
|
|
473
|
+
#
|
|
474
|
+
# Load an \IO object:
|
|
475
|
+
# require 'stringio'
|
|
476
|
+
# object = JSON.unsafe_load(StringIO.new(source))
|
|
477
|
+
# object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
|
|
478
|
+
#
|
|
479
|
+
# Load a \File object:
|
|
480
|
+
# path = 't.json'
|
|
481
|
+
# File.write(path, source)
|
|
482
|
+
# File.open(path) do |file|
|
|
483
|
+
# JSON.unsafe_load(file)
|
|
484
|
+
# end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
|
|
485
|
+
#
|
|
486
|
+
# ---
|
|
487
|
+
#
|
|
488
|
+
# When +proc+ is given:
|
|
489
|
+
# - Modifies +source+ as above.
|
|
490
|
+
# - Gets the +result+ from calling <tt>parse(source, opts)</tt>.
|
|
491
|
+
# - Recursively calls <tt>proc(result)</tt>.
|
|
492
|
+
# - Returns the final result.
|
|
493
|
+
#
|
|
494
|
+
# Example:
|
|
495
|
+
# require 'json'
|
|
496
|
+
#
|
|
497
|
+
# # Some classes for the example.
|
|
498
|
+
# class Base
|
|
499
|
+
# def initialize(attributes)
|
|
500
|
+
# @attributes = attributes
|
|
501
|
+
# end
|
|
502
|
+
# end
|
|
503
|
+
# class User < Base; end
|
|
504
|
+
# class Account < Base; end
|
|
505
|
+
# class Admin < Base; end
|
|
506
|
+
# # The JSON source.
|
|
507
|
+
# json = <<-EOF
|
|
508
|
+
# {
|
|
509
|
+
# "users": [
|
|
510
|
+
# {"type": "User", "username": "jane", "email": "jane@example.com"},
|
|
511
|
+
# {"type": "User", "username": "john", "email": "john@example.com"}
|
|
512
|
+
# ],
|
|
513
|
+
# "accounts": [
|
|
514
|
+
# {"account": {"type": "Account", "paid": true, "account_id": "1234"}},
|
|
515
|
+
# {"account": {"type": "Account", "paid": false, "account_id": "1235"}}
|
|
516
|
+
# ],
|
|
517
|
+
# "admins": {"type": "Admin", "password": "0wn3d"}
|
|
518
|
+
# }
|
|
519
|
+
# EOF
|
|
520
|
+
# # Deserializer method.
|
|
521
|
+
# def deserialize_obj(obj, safe_types = %w(User Account Admin))
|
|
522
|
+
# type = obj.is_a?(Hash) && obj["type"]
|
|
523
|
+
# safe_types.include?(type) ? Object.const_get(type).new(obj) : obj
|
|
524
|
+
# end
|
|
525
|
+
# # Call to JSON.unsafe_load
|
|
526
|
+
# ruby = JSON.unsafe_load(json, proc {|obj|
|
|
527
|
+
# case obj
|
|
528
|
+
# when Hash
|
|
529
|
+
# obj.each {|k, v| obj[k] = deserialize_obj v }
|
|
530
|
+
# when Array
|
|
531
|
+
# obj.map! {|v| deserialize_obj v }
|
|
532
|
+
# end
|
|
533
|
+
# })
|
|
534
|
+
# pp ruby
|
|
535
|
+
# Output:
|
|
536
|
+
# {"users"=>
|
|
537
|
+
# [#<User:0x00000000064c4c98
|
|
538
|
+
# @attributes=
|
|
539
|
+
# {"type"=>"User", "username"=>"jane", "email"=>"jane@example.com"}>,
|
|
540
|
+
# #<User:0x00000000064c4bd0
|
|
541
|
+
# @attributes=
|
|
542
|
+
# {"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>],
|
|
543
|
+
# "accounts"=>
|
|
544
|
+
# [{"account"=>
|
|
545
|
+
# #<Account:0x00000000064c4928
|
|
546
|
+
# @attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
|
|
547
|
+
# {"account"=>
|
|
548
|
+
# #<Account:0x00000000064c4680
|
|
549
|
+
# @attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
|
|
550
|
+
# "admins"=>
|
|
551
|
+
# #<Admin:0x00000000064c41f8
|
|
552
|
+
# @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
|
|
553
|
+
#
|
|
554
|
+
def unsafe_load(source, proc = nil, options = nil)
|
|
555
|
+
opts = if options.nil?
|
|
556
|
+
unsafe_load_default_options
|
|
557
|
+
else
|
|
558
|
+
unsafe_load_default_options.merge(options)
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
unless source.is_a?(String)
|
|
562
|
+
if source.respond_to? :to_str
|
|
563
|
+
source = source.to_str
|
|
564
|
+
elsif source.respond_to? :to_io
|
|
565
|
+
source = source.to_io.read
|
|
566
|
+
elsif source.respond_to?(:read)
|
|
567
|
+
source = source.read
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
if opts[:allow_blank] && (source.nil? || source.empty?)
|
|
572
|
+
source = 'null'
|
|
573
|
+
end
|
|
574
|
+
result = parse(source, opts)
|
|
575
|
+
recurse_proc(result, &proc) if proc
|
|
576
|
+
result
|
|
577
|
+
end
|
|
415
578
|
|
|
416
579
|
# :call-seq:
|
|
417
580
|
# JSON.load(source, proc = nil, options = {}) -> object
|
|
418
581
|
#
|
|
419
582
|
# Returns the Ruby objects created by parsing the given +source+.
|
|
420
583
|
#
|
|
584
|
+
# BEWARE: This method is meant to serialise data from trusted user input,
|
|
585
|
+
# like from your own database server or clients under your control, it could
|
|
586
|
+
# be dangerous to allow untrusted users to pass JSON sources into it.
|
|
587
|
+
# If you must use it, use JSON.unsafe_load instead to make it clear.
|
|
588
|
+
#
|
|
589
|
+
# Since JSON version 2.8.0, `load` emits a deprecation warning when a
|
|
590
|
+
# non native type is deserialized, without `create_additions` being explicitly
|
|
591
|
+
# enabled, and in JSON version 3.0, `load` will have `create_additions` disabled
|
|
592
|
+
# by default.
|
|
593
|
+
#
|
|
421
594
|
# - Argument +source+ must be, or be convertible to, a \String:
|
|
422
595
|
# - If +source+ responds to instance method +to_str+,
|
|
423
596
|
# <tt>source.to_str</tt> becomes the source.
|
|
@@ -432,9 +605,6 @@ module JSON
|
|
|
432
605
|
# - Argument +proc+, if given, must be a \Proc that accepts one argument.
|
|
433
606
|
# It will be called recursively with each result (depth-first order).
|
|
434
607
|
# See details below.
|
|
435
|
-
# BEWARE: This method is meant to serialise data from trusted user input,
|
|
436
|
-
# like from your own database server or clients under your control, it could
|
|
437
|
-
# be dangerous to allow untrusted users to pass JSON sources into it.
|
|
438
608
|
# - Argument +opts+, if given, contains a \Hash of options for the parsing.
|
|
439
609
|
# See {Parsing Options}[#module-JSON-label-Parsing+Options].
|
|
440
610
|
# The default options can be changed via method JSON.load_default_options=.
|
|
@@ -445,17 +615,17 @@ module JSON
|
|
|
445
615
|
# <tt>parse(source, opts)</tt>; see #parse.
|
|
446
616
|
#
|
|
447
617
|
# Source for following examples:
|
|
448
|
-
# source =
|
|
449
|
-
#
|
|
450
|
-
#
|
|
451
|
-
#
|
|
452
|
-
#
|
|
453
|
-
#
|
|
454
|
-
#
|
|
455
|
-
#
|
|
456
|
-
#
|
|
457
|
-
#
|
|
458
|
-
#
|
|
618
|
+
# source = <<~JSON
|
|
619
|
+
# {
|
|
620
|
+
# "name": "Dave",
|
|
621
|
+
# "age" :40,
|
|
622
|
+
# "hats": [
|
|
623
|
+
# "Cattleman's",
|
|
624
|
+
# "Panama",
|
|
625
|
+
# "Tophat"
|
|
626
|
+
# ]
|
|
627
|
+
# }
|
|
628
|
+
# JSON
|
|
459
629
|
#
|
|
460
630
|
# Load a \String:
|
|
461
631
|
# ruby = JSON.load(source)
|
|
@@ -647,18 +817,15 @@ module JSON
|
|
|
647
817
|
opts = opts.merge(:max_nesting => limit) if limit
|
|
648
818
|
opts = merge_dump_options(opts, **kwargs) if kwargs
|
|
649
819
|
|
|
650
|
-
|
|
651
|
-
|
|
820
|
+
begin
|
|
821
|
+
if State === opts
|
|
822
|
+
opts.generate(obj, anIO)
|
|
823
|
+
else
|
|
824
|
+
State.generate(obj, opts, anIO)
|
|
825
|
+
end
|
|
652
826
|
rescue JSON::NestingError
|
|
653
827
|
raise ArgumentError, "exceed depth limit"
|
|
654
828
|
end
|
|
655
|
-
|
|
656
|
-
if anIO.nil?
|
|
657
|
-
result
|
|
658
|
-
else
|
|
659
|
-
anIO.write result
|
|
660
|
-
anIO
|
|
661
|
-
end
|
|
662
829
|
end
|
|
663
830
|
|
|
664
831
|
# Encodes string using String.encode.
|
|
@@ -42,41 +42,22 @@ module JSON
|
|
|
42
42
|
raise TypeError, "can't convert #{opts.class} into Hash"
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
|
-
|
|
46
|
-
opts.each do |key, value|
|
|
47
|
-
case key
|
|
48
|
-
when :indent
|
|
49
|
-
self.indent = value
|
|
50
|
-
when :space
|
|
51
|
-
self.space = value
|
|
52
|
-
when :space_before
|
|
53
|
-
self.space_before = value
|
|
54
|
-
when :array_nl
|
|
55
|
-
self.array_nl = value
|
|
56
|
-
when :object_nl
|
|
57
|
-
self.object_nl = value
|
|
58
|
-
when :max_nesting
|
|
59
|
-
self.max_nesting = value || 0
|
|
60
|
-
when :depth
|
|
61
|
-
self.depth = value
|
|
62
|
-
when :buffer_initial_length
|
|
63
|
-
self.buffer_initial_length = value
|
|
64
|
-
when :allow_nan
|
|
65
|
-
self.allow_nan = value
|
|
66
|
-
when :ascii_only
|
|
67
|
-
self.ascii_only = value
|
|
68
|
-
when :script_safe, :escape_slash
|
|
69
|
-
self.script_safe = value
|
|
70
|
-
when :strict
|
|
71
|
-
self.strict = value
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
self
|
|
45
|
+
_configure(opts)
|
|
76
46
|
end
|
|
77
47
|
|
|
78
48
|
alias_method :merge, :configure
|
|
79
49
|
|
|
50
|
+
# call-seq:
|
|
51
|
+
# generate(obj) -> String
|
|
52
|
+
# generate(obj, anIO) -> anIO
|
|
53
|
+
#
|
|
54
|
+
# Generates a valid JSON document from object +obj+ and returns the
|
|
55
|
+
# result. If no valid JSON document can be created this method raises a
|
|
56
|
+
# GeneratorError exception.
|
|
57
|
+
def generate(obj, io = nil)
|
|
58
|
+
_generate(obj, io)
|
|
59
|
+
end
|
|
60
|
+
|
|
80
61
|
# call-seq: to_h
|
|
81
62
|
#
|
|
82
63
|
# Returns the configuration instance variables as a hash, that can be
|
data/lib/json/ext.rb
CHANGED
|
@@ -8,17 +8,12 @@ module JSON
|
|
|
8
8
|
module Ext
|
|
9
9
|
if RUBY_ENGINE == 'truffleruby'
|
|
10
10
|
require 'json/ext/parser'
|
|
11
|
-
require 'json/
|
|
12
|
-
$DEBUG and warn "Using Ext extension for JSON parser and Pure library for JSON generator."
|
|
11
|
+
require 'json/truffle_ruby/generator'
|
|
13
12
|
JSON.parser = Parser
|
|
14
|
-
JSON.generator = JSON::
|
|
13
|
+
JSON.generator = ::JSON::TruffleRuby::Generator
|
|
15
14
|
else
|
|
16
15
|
require 'json/ext/parser'
|
|
17
16
|
require 'json/ext/generator'
|
|
18
|
-
unless RUBY_ENGINE == 'jruby'
|
|
19
|
-
require 'json/ext/generator/state'
|
|
20
|
-
end
|
|
21
|
-
$DEBUG and warn "Using Ext extension for JSON."
|
|
22
17
|
JSON.parser = Parser
|
|
23
18
|
JSON.generator = Generator
|
|
24
19
|
end
|