json 1.8.2 → 2.3.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.
Files changed (82) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.travis.yml +11 -9
  4. data/{CHANGES → CHANGES.md} +220 -89
  5. data/Gemfile +10 -6
  6. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  7. data/{README.rdoc → README.md} +204 -137
  8. data/Rakefile +35 -113
  9. data/VERSION +1 -1
  10. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  11. data/ext/json/ext/generator/generator.c +215 -110
  12. data/ext/json/ext/generator/generator.h +18 -5
  13. data/ext/json/ext/parser/extconf.rb +3 -0
  14. data/ext/json/ext/parser/parser.c +422 -508
  15. data/ext/json/ext/parser/parser.h +15 -8
  16. data/ext/json/ext/parser/parser.rl +151 -200
  17. data/ext/json/extconf.rb +0 -1
  18. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  19. data/java/src/json/ext/Generator.java +44 -22
  20. data/java/src/json/ext/GeneratorMethods.java +1 -2
  21. data/java/src/json/ext/GeneratorService.java +1 -2
  22. data/java/src/json/ext/GeneratorState.java +3 -56
  23. data/java/src/json/ext/OptionsReader.java +2 -3
  24. data/java/src/json/ext/Parser.java +132 -415
  25. data/java/src/json/ext/Parser.rl +48 -124
  26. data/java/src/json/ext/ParserService.java +1 -2
  27. data/java/src/json/ext/RuntimeInfo.java +1 -6
  28. data/java/src/json/ext/StringDecoder.java +1 -2
  29. data/java/src/json/ext/StringEncoder.java +5 -0
  30. data/java/src/json/ext/Utils.java +1 -2
  31. data/json-java.gemspec +16 -2
  32. data/json.gemspec +0 -0
  33. data/json_pure.gemspec +22 -29
  34. data/lib/json.rb +379 -29
  35. data/lib/json/add/bigdecimal.rb +3 -2
  36. data/lib/json/add/complex.rb +4 -3
  37. data/lib/json/add/core.rb +1 -0
  38. data/lib/json/add/date.rb +1 -1
  39. data/lib/json/add/date_time.rb +1 -1
  40. data/lib/json/add/exception.rb +1 -1
  41. data/lib/json/add/ostruct.rb +3 -3
  42. data/lib/json/add/range.rb +1 -1
  43. data/lib/json/add/rational.rb +3 -2
  44. data/lib/json/add/regexp.rb +3 -3
  45. data/lib/json/add/set.rb +29 -0
  46. data/lib/json/add/struct.rb +1 -1
  47. data/lib/json/add/symbol.rb +1 -1
  48. data/lib/json/add/time.rb +1 -1
  49. data/lib/json/common.rb +335 -128
  50. data/lib/json/ext.rb +0 -6
  51. data/lib/json/generic_object.rb +5 -4
  52. data/lib/json/pure.rb +2 -8
  53. data/lib/json/pure/generator.rb +64 -127
  54. data/lib/json/pure/parser.rb +42 -82
  55. data/lib/json/version.rb +2 -1
  56. data/references/rfc7159.txt +899 -0
  57. data/tests/fixtures/obsolete_fail1.json +1 -0
  58. data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
  59. data/tests/json_common_interface_test.rb +126 -0
  60. data/tests/json_encoding_test.rb +107 -0
  61. data/tests/json_ext_parser_test.rb +15 -0
  62. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +10 -8
  63. data/tests/{test_json_generate.rb → json_generator_test.rb} +123 -39
  64. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  65. data/tests/json_parser_test.rb +472 -0
  66. data/tests/json_string_matching_test.rb +38 -0
  67. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  68. data/tools/diff.sh +18 -0
  69. data/tools/fuzz.rb +1 -9
  70. metadata +46 -53
  71. data/COPYING +0 -58
  72. data/COPYING-json-jruby +0 -57
  73. data/GPL +0 -340
  74. data/TODO +0 -1
  75. data/data/example.json +0 -1
  76. data/data/index.html +0 -38
  77. data/data/prototype.js +0 -4184
  78. data/tests/fixtures/fail1.json +0 -1
  79. data/tests/test_json.rb +0 -553
  80. data/tests/test_json_encoding.rb +0 -65
  81. data/tests/test_json_string_matching.rb +0 -39
  82. data/tests/test_json_unicode.rb +0 -72
@@ -1,3 +1,4 @@
1
+ #frozen_string_literal: false
1
2
  # This file requires the implementations of ruby core's custom objects for
2
3
  # serialisation/deserialisation.
3
4
 
@@ -1,9 +1,9 @@
1
+ #frozen_string_literal: false
1
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
3
  require 'json'
3
4
  end
4
5
  require 'date'
5
6
 
6
- # Date serialization/deserialization
7
7
  class Date
8
8
 
9
9
  # Deserializes JSON string by converting Julian year <tt>y</tt>, month
@@ -1,9 +1,9 @@
1
+ #frozen_string_literal: false
1
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
3
  require 'json'
3
4
  end
4
5
  require 'date'
5
6
 
6
- # DateTime serialization/deserialization
7
7
  class DateTime
8
8
 
9
9
  # Deserializes JSON string by converting year <tt>y</tt>, month <tt>m</tt>,
@@ -1,8 +1,8 @@
1
+ #frozen_string_literal: false
1
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
3
  require 'json'
3
4
  end
4
5
 
5
- # Exception serialization/deserialization
6
6
  class Exception
7
7
 
8
8
  # Deserializes JSON string by constructing new Exception object with message
@@ -1,13 +1,13 @@
1
+ #frozen_string_literal: false
1
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
3
  require 'json'
3
4
  end
4
5
  require 'ostruct'
5
6
 
6
- # OpenStruct serialization/deserialization
7
7
  class OpenStruct
8
8
 
9
9
  # Deserializes JSON string by constructing new Struct object with values
10
- # <tt>v</tt> serialized by <tt>to_json</tt>.
10
+ # <tt>t</tt> serialized by <tt>to_json</tt>.
11
11
  def self.json_create(object)
12
12
  new(object['t'] || object[:t])
13
13
  end
@@ -23,7 +23,7 @@ class OpenStruct
23
23
  }
24
24
  end
25
25
 
26
- # Stores class name (OpenStruct) with this struct's values <tt>v</tt> as a
26
+ # Stores class name (OpenStruct) with this struct's values <tt>t</tt> as a
27
27
  # JSON string.
28
28
  def to_json(*args)
29
29
  as_json.to_json(*args)
@@ -1,8 +1,8 @@
1
+ #frozen_string_literal: false
1
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
3
  require 'json'
3
4
  end
4
5
 
5
- # Range serialization/deserialization
6
6
  class Range
7
7
 
8
8
  # Deserializes JSON string by constructing new Range object with arguments
@@ -1,3 +1,4 @@
1
+ #frozen_string_literal: false
1
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
3
  require 'json'
3
4
  end
@@ -21,7 +22,7 @@ class Rational
21
22
  end
22
23
 
23
24
  # Stores class name (Rational) along with numerator value <tt>n</tt> and denominator value <tt>d</tt> as JSON string
24
- def to_json(*)
25
- as_json.to_json
25
+ def to_json(*args)
26
+ as_json.to_json(*args)
26
27
  end
27
28
  end
@@ -1,8 +1,8 @@
1
+ #frozen_string_literal: false
1
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
3
  require 'json'
3
4
  end
4
5
 
5
- # Regexp serialization/deserialization
6
6
  class Regexp
7
7
 
8
8
  # Deserializes JSON string by constructing new Regexp object with source
@@ -24,7 +24,7 @@ class Regexp
24
24
 
25
25
  # Stores class name (Regexp) with options <tt>o</tt> and source <tt>s</tt>
26
26
  # (Regexp or String) as JSON string
27
- def to_json(*)
28
- as_json.to_json
27
+ def to_json(*args)
28
+ as_json.to_json(*args)
29
29
  end
30
30
  end
@@ -0,0 +1,29 @@
1
+ unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
+ require 'json'
3
+ end
4
+ defined?(::Set) or require 'set'
5
+
6
+ class Set
7
+ # Import a JSON Marshalled object.
8
+ #
9
+ # method used for JSON marshalling support.
10
+ def self.json_create(object)
11
+ new object['a']
12
+ end
13
+
14
+ # Marshal the object to JSON.
15
+ #
16
+ # method used for JSON marshalling support.
17
+ def as_json(*)
18
+ {
19
+ JSON.create_id => self.class.name,
20
+ 'a' => to_a,
21
+ }
22
+ end
23
+
24
+ # return the JSON value
25
+ def to_json(*args)
26
+ as_json.to_json(*args)
27
+ end
28
+ end
29
+
@@ -1,8 +1,8 @@
1
+ #frozen_string_literal: false
1
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
3
  require 'json'
3
4
  end
4
5
 
5
- # Struct serialization/deserialization
6
6
  class Struct
7
7
 
8
8
  # Deserializes JSON string by constructing new Struct object with values
@@ -1,8 +1,8 @@
1
+ #frozen_string_literal: false
1
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
3
  require 'json'
3
4
  end
4
5
 
5
- # Symbol serialization/deserialization
6
6
  class Symbol
7
7
  # Returns a hash, that will be turned into a JSON object and represent this
8
8
  # object.
@@ -1,8 +1,8 @@
1
+ #frozen_string_literal: false
1
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
2
3
  require 'json'
3
4
  end
4
5
 
5
- # Time serialization/deserialization
6
6
  class Time
7
7
 
8
8
  # Deserializes JSON string by converting time since epoch to Time
@@ -1,14 +1,18 @@
1
+ #frozen_string_literal: false
1
2
  require 'json/version'
2
3
  require 'json/generic_object'
3
4
 
4
5
  module JSON
5
6
  class << self
6
- # If _object_ is string-like, parse the string and return the parsed result
7
- # as a Ruby data structure. Otherwise generate a JSON text from the Ruby
8
- # data structure object and return it.
7
+ # If +object+ is a
8
+ # {String-convertible object}[doc/implicit_conversion_rdoc.html#label-String-Convertible+Objects]
9
+ # (implementing +to_str+), calls JSON.parse with +object+ and +opts+:
10
+ # json = '[0, 1, null]'
11
+ # JSON[json]# => [0, 1, nil]
9
12
  #
10
- # The _opts_ argument is passed through to generate/parse respectively. See
11
- # generate and parse for their documentation.
13
+ # Otherwise, calls JSON.generate with +object+ and +opts+:
14
+ # ruby = [0, 1, nil]
15
+ # JSON[ruby] # => '[0,1,null]'
12
16
  def [](object, opts = {})
13
17
  if object.respond_to? :to_str
14
18
  JSON.parse(object.to_str, opts)
@@ -18,13 +22,14 @@ module JSON
18
22
  end
19
23
 
20
24
  # Returns the JSON parser class that is used by JSON. This is either
21
- # JSON::Ext::Parser or JSON::Pure::Parser.
25
+ # JSON::Ext::Parser or JSON::Pure::Parser:
26
+ # JSON.parser # => JSON::Ext::Parser
22
27
  attr_reader :parser
23
28
 
24
29
  # Set the JSON parser class _parser_ to be used by JSON.
25
30
  def parser=(parser) # :nodoc:
26
31
  @parser = parser
27
- remove_const :Parser if JSON.const_defined_in?(self, :Parser)
32
+ remove_const :Parser if const_defined?(:Parser, false)
28
33
  const_set :Parser, parser
29
34
  end
30
35
 
@@ -35,8 +40,8 @@ module JSON
35
40
  def deep_const_get(path) # :nodoc:
36
41
  path.to_s.split(/::/).inject(Object) do |p, c|
37
42
  case
38
- when c.empty? then p
39
- when JSON.const_defined_in?(p, c) then p.const_get(c)
43
+ when c.empty? then p
44
+ when p.const_defined?(c, true) then p.const_get(c)
40
45
  else
41
46
  begin
42
47
  p.const_missing(c)
@@ -83,15 +88,18 @@ module JSON
83
88
  end
84
89
 
85
90
  # Returns the JSON generator module that is used by JSON. This is
86
- # either JSON::Ext::Generator or JSON::Pure::Generator.
91
+ # either JSON::Ext::Generator or JSON::Pure::Generator:
92
+ # JSON.generator # => JSON::Ext::Generator
87
93
  attr_reader :generator
88
94
 
89
- # Returns the JSON generator state class that is used by JSON. This is
90
- # either JSON::Ext::Generator::State or JSON::Pure::Generator::State.
95
+ # Sets or Returns the JSON generator state class that is used by JSON. This is
96
+ # either JSON::Ext::Generator::State or JSON::Pure::Generator::State:
97
+ # JSON.state # => JSON::Ext::Generator::State
91
98
  attr_accessor :state
92
99
 
93
- # This is create identifier, which is used to decide if the _json_create_
94
- # hook of a class should be called. It defaults to 'json_class'.
100
+ # Sets or returns create identifier, which is used to decide if the _json_create_
101
+ # hook of a class should be called; initial value is +json_class+:
102
+ # JSON.create_id # => 'json_class'
95
103
  attr_accessor :create_id
96
104
  end
97
105
  self.create_id = 'json_class'
@@ -125,7 +133,7 @@ module JSON
125
133
  # This exception is raised if a generator or unparser error occurs.
126
134
  class GeneratorError < JSONError; end
127
135
  # For backwards compatibility
128
- UnparserError = GeneratorError
136
+ UnparserError = GeneratorError # :nodoc:
129
137
 
130
138
  # This exception is raised if the required unicode support is missing on the
131
139
  # system. Usually this means that the iconv library is not installed.
@@ -133,77 +141,276 @@ module JSON
133
141
 
134
142
  module_function
135
143
 
136
- # Parse the JSON document _source_ into a Ruby data structure and return it.
137
- #
138
- # _opts_ can have the following
139
- # keys:
140
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
141
- # structures. Disable depth checking with :max_nesting => false. It defaults
142
- # to 100.
143
- # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
144
- # defiance of RFC 4627 to be parsed by the Parser. This option defaults
145
- # to false.
146
- # * *symbolize_names*: If set to true, returns symbols for the names
147
- # (keys) in a JSON object. Otherwise strings are returned. Strings are
148
- # the default.
149
- # * *create_additions*: If set to false, the Parser doesn't create
150
- # additions even if a matching class and create_id was found. This option
151
- # defaults to false.
152
- # * *object_class*: Defaults to Hash
153
- # * *array_class*: Defaults to Array
144
+ # :call-seq:
145
+ # JSON.parse(source, opts) -> object
146
+ #
147
+ # Argument +source+ contains the \String to be parsed. It must be a
148
+ # {String-convertible object}[doc/implicit_conversion_rdoc.html#label-String-Convertible+Objects]
149
+ # (implementing +to_str+), and must contain valid \JSON data.
150
+ #
151
+ # Argument +opts+, if given, contains options for the parsing, and must be a
152
+ # {Hash-convertible object}[doc/implicit_conversion_rdoc.html#label-Hash-Convertible+Objects]
153
+ # (implementing +to_hash+).
154
+ #
155
+ # Returns the Ruby objects created by parsing the given +source+.
156
+ #
157
+ # ---
158
+ #
159
+ # When +source+ is a \JSON array, returns a Ruby \Array:
160
+ # source = '["foo", 1.0, true, false, null]'
161
+ # ruby = JSON.parse(source)
162
+ # ruby # => ["foo", 1.0, true, false, nil]
163
+ # ruby.class # => Array
164
+ #
165
+ # When +source+ is a \JSON object, returns a Ruby \Hash:
166
+ # source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
167
+ # ruby = JSON.parse(source)
168
+ # ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
169
+ # ruby.class # => Hash
170
+ #
171
+ # For examples of parsing for all \JSON data types, see
172
+ # {Parsing \JSON}[#module-JSON-label-Parsing+JSON].
173
+ #
174
+ # ====== Input Options
175
+ #
176
+ # Option +max_nesting+ (\Integer) specifies the maximum nesting depth allowed;
177
+ # defaults to +100+; specify +false+ to disable depth checking.
178
+ #
179
+ # With the default, +false+:
180
+ # source = '[0, [1, [2, [3]]]]'
181
+ # ruby = JSON.parse(source)
182
+ # ruby # => [0, [1, [2, [3]]]]
183
+ # Too deep:
184
+ # # Raises JSON::NestingError (nesting of 2 is too deep):
185
+ # JSON.parse(source, {max_nesting: 1})
186
+ # Bad value:
187
+ # # Raises TypeError (wrong argument type Symbol (expected Fixnum)):
188
+ # JSON.parse(source, {max_nesting: :foo})
189
+ #
190
+ # ---
191
+ #
192
+ # Option +allow_nan+ (boolean) specifies whether to allow
193
+ # NaN, Infinity, and MinusInfinity in +source+;
194
+ # defaults to +false+.
195
+ #
196
+ # With the default, +false+:
197
+ # # Raises JSON::ParserError (225: unexpected token at '[NaN]'):
198
+ # JSON.parse('[NaN]')
199
+ # # Raises JSON::ParserError (232: unexpected token at '[Infinity]'):
200
+ # JSON.parse('[Infinity]')
201
+ # # Raises JSON::ParserError (248: unexpected token at '[-Infinity]'):
202
+ # JSON.parse('[-Infinity]')
203
+ # Allow:
204
+ # source = '[NaN, Infinity, -Infinity]'
205
+ # ruby = JSON.parse(source, {allow_nan: true})
206
+ # ruby # => [NaN, Infinity, -Infinity]
207
+ #
208
+ # ====== Output Options
209
+ #
210
+ # Option +symbolize_names+ (boolean) specifies whether returned \Hash keys
211
+ # should be Symbols;
212
+ # defaults to +false+ (use Strings).
213
+ #
214
+ # With the default, +false+:
215
+ # source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
216
+ # ruby = JSON.parse(source)
217
+ # ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
218
+ # Use Symbols:
219
+ # ruby = JSON.parse(source, {symbolize_names: true})
220
+ # ruby # => {:a=>"foo", :b=>1.0, :c=>true, :d=>false, :e=>nil}
221
+ #
222
+ # ---
223
+ #
224
+ # Option +object_class+ (\Class) specifies the Ruby class to be used
225
+ # for each \JSON object;
226
+ # defaults to \Hash.
227
+ #
228
+ # With the default, \Hash:
229
+ # source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
230
+ # ruby = JSON.parse(source)
231
+ # ruby.class # => Hash
232
+ # Use class \OpenStruct:
233
+ # ruby = JSON.parse(source, {object_class: OpenStruct})
234
+ # ruby # => #<OpenStruct a="foo", b=1.0, c=true, d=false, e=nil>
235
+ #
236
+ # ---
237
+ #
238
+ # Option +array_class+ (\Class) specifies the Ruby class to be used
239
+ # for each \JSON array;
240
+ # defaults to \Array.
241
+ #
242
+ # With the default, \Array:
243
+ # source = '["foo", 1.0, true, false, null]'
244
+ # ruby = JSON.parse(source)
245
+ # ruby.class # => Array
246
+ # Use class \Set:
247
+ # ruby = JSON.parse(source, {array_class: Set})
248
+ # ruby # => #<Set: {"foo", 1.0, true, false, nil}>
249
+ #
250
+ # ---
251
+ #
252
+ # Option +create_additions+ (boolean) specifies whether to use \JSON additions in parsing.
253
+ # See {\JSON Additions}[#module-JSON-label-JSON+Additions].
254
+ #
255
+ # ====== Exceptions
256
+ #
257
+ # Raises an exception if +source+ is not valid JSON:
258
+ #
259
+ # # Raises JSON::ParserError (783: unexpected token at ''):
260
+ # JSON.parse('')
261
+ #
154
262
  def parse(source, opts = {})
155
- Parser.new(source, opts).parse
263
+ Parser.new(source, **(opts||{})).parse
156
264
  end
157
265
 
158
- # Parse the JSON document _source_ into a Ruby data structure and return it.
159
- # The bang version of the parse method defaults to the more dangerous values
160
- # for the _opts_ hash, so be sure only to parse trusted _source_ documents.
161
- #
162
- # _opts_ can have the following keys:
163
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
164
- # structures. Enable depth checking with :max_nesting => anInteger. The parse!
165
- # methods defaults to not doing max depth checking: This can be dangerous
166
- # if someone wants to fill up your stack.
167
- # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in
168
- # defiance of RFC 4627 to be parsed by the Parser. This option defaults
169
- # to true.
170
- # * *create_additions*: If set to false, the Parser doesn't create
171
- # additions even if a matching class and create_id was found. This option
172
- # defaults to false.
266
+ # :call-seq:
267
+ # JSON.parse!(source, opts) -> object
268
+ #
269
+ # Calls
270
+ # parse(source, opts)
271
+ # with +source+ and possibly modified +opts+.
272
+ #
273
+ # Differences from JSON.parse:
274
+ # - Option +max_nesting+, if not provided, defaults to +false+,
275
+ # which disables checking for nesting depth.
276
+ # - Option +allow_nan+, if not provided, defaults to +true+.
173
277
  def parse!(source, opts = {})
174
278
  opts = {
175
279
  :max_nesting => false,
176
280
  :allow_nan => true
177
- }.update(opts)
178
- Parser.new(source, opts).parse
281
+ }.merge(opts)
282
+ Parser.new(source, **(opts||{})).parse
179
283
  end
180
284
 
181
- # Generate a JSON document from the Ruby data structure _obj_ and return
182
- # it. _state_ is * a JSON::State object,
183
- # * or a Hash like object (responding to to_hash),
184
- # * an object convertible into a hash by a to_h method,
185
- # that is used as or to configure a State object.
186
- #
187
- # It defaults to a state object, that creates the shortest possible JSON text
188
- # in one line, checks for circular data structures and doesn't allow NaN,
189
- # Infinity, and -Infinity.
190
- #
191
- # A _state_ hash can have the following keys:
192
- # * *indent*: a string used to indent levels (default: ''),
193
- # * *space*: a string that is put after, a : or , delimiter (default: ''),
194
- # * *space_before*: a string that is put before a : pair delimiter (default: ''),
195
- # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
196
- # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
197
- # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
198
- # generated, otherwise an exception is thrown if these values are
199
- # encountered. This options defaults to false.
200
- # * *max_nesting*: The maximum depth of nesting allowed in the data
201
- # structures from which JSON is to be generated. Disable depth checking
202
- # with :max_nesting => false, it defaults to 100.
203
- #
204
- # See also the fast_generate for the fastest creation method with the least
205
- # amount of sanity checks, and the pretty_generate method for some
206
- # defaults for pretty output.
285
+ # :call-seq:
286
+ # JSON.generate(obj, opts = nil) -> new_string
287
+ #
288
+ # Argument +obj+ is the Ruby object to be converted to \JSON.
289
+ #
290
+ # Argument +opts+, if given, contains options for the generation, and must be a
291
+ # {Hash-convertible object}[doc/implicit_conversion_rdoc.html#label-Hash-Convertible+Objects]
292
+ # (implementing +to_hash+).
293
+ #
294
+ # Returns a \String containing the generated \JSON data.
295
+ #
296
+ # See also JSON.fast_generate, JSON.pretty_generate.
297
+ #
298
+ # ---
299
+ #
300
+ # When +obj+ is an
301
+ # {Array-convertible object}[doc/implicit_conversion_rdoc.html#label-Array-Convertible+Objects]
302
+ # (implementing +to_ary+), returns a \String containing a \JSON array:
303
+ # obj = ["foo", 1.0, true, false, nil]
304
+ # json = JSON.generate(obj)
305
+ # json # => '["foo",1.0,true,false,null]'
306
+ #
307
+ # When +obj+ is a
308
+ # {Hash-convertible object}[doc/implicit_conversion_rdoc.html#label-Hash-Convertible+Objects],
309
+ # return a \String containing a \JSON object:
310
+ # obj = {foo: 0, bar: 's', baz: :bat}
311
+ # json = JSON.generate(obj)
312
+ # json # => '{"foo":0,"bar":"s","baz":"bat"}'
313
+ #
314
+ # For examples of generating from other Ruby objects, see
315
+ # {Generating \JSON from Other Objects}[#module-JSON-label-Generating+JSON+from+Other+Objects].
316
+ #
317
+ # ====== Input Options
318
+ #
319
+ # Option +allow_nan+ (boolean) specifies whether
320
+ # +NaN+, +Infinity+, and <tt>-Infinity</tt> may be generated;
321
+ # defaults to +false+.
322
+ #
323
+ # With the default, +false+:
324
+ # # Raises JSON::GeneratorError (920: NaN not allowed in JSON):
325
+ # JSON.generate(JSON::NaN)
326
+ # # Raises JSON::GeneratorError (917: Infinity not allowed in JSON):
327
+ # JSON.generate(JSON::Infinity)
328
+ # # Raises JSON::GeneratorError (917: -Infinity not allowed in JSON):
329
+ # JSON.generate(JSON::MinusInfinity)
330
+ #
331
+ # Allow:
332
+ # ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity]
333
+ # JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
334
+ #
335
+ # ---
336
+ #
337
+ # Option +max_nesting+ (\Integer) specifies the maximum nesting depth
338
+ # in +obj+; defaults to +100+.
339
+ #
340
+ # With the default, +100+:
341
+ # obj = [[[[[[0]]]]]]
342
+ # JSON.generate(obj) # => '[[[[[[0]]]]]]'
343
+ #
344
+ # Too deep:
345
+ # # Raises JSON::NestingError (nesting of 2 is too deep):
346
+ # JSON.generate(obj, max_nesting: 2)
347
+ #
348
+ # ====== Output Options
349
+ #
350
+ # The default formatting options generate the most compact
351
+ # \JSON data, all on one line and with no whitespace.
352
+ #
353
+ # You can use these formatting options to generate
354
+ # \JSON data in a more open format, using whitespace.
355
+ # See also JSON.pretty_generate.
356
+ #
357
+ # - Option +array_nl+ (\String) specifies a string (usually a newline)
358
+ # to be inserted after each \JSON array; defaults to the empty \String, <tt>''</tt>.
359
+ # - Option +object_nl+ (\String) specifies a string (usually a newline)
360
+ # to be inserted after each \JSON object; defaults to the empty \String, <tt>''</tt>.
361
+ # - Option +indent+ (\String) specifies the string (usually spaces) to be
362
+ # used for indentation; defaults to the empty \String, <tt>''</tt>;
363
+ # defaults to the empty \String, <tt>''</tt>;
364
+ # has no effect unless options +array_nl+ or +object_nl+ specify newlines.
365
+ # - Option +space+ (\String) specifies a string (usually a space) to be
366
+ # inserted after the colon in each \JSON object's pair;
367
+ # defaults to the empty \String, <tt>''</tt>.
368
+ # - Option +space_before+ (\String) specifies a string (usually a space) to be
369
+ # inserted before the colon in each \JSON object's pair;
370
+ # defaults to the empty \String, <tt>''</tt>.
371
+ #
372
+ # In this example, +obj+ is used first to generate the shortest
373
+ # \JSON data (no whitespace), then again with all formatting options
374
+ # specified:
375
+ #
376
+ # obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
377
+ # json = JSON.generate(obj)
378
+ # puts 'Compact:', json
379
+ # opts = {
380
+ # array_nl: "\n",
381
+ # object_nl: "\n",
382
+ # indent+: ' ',
383
+ # space_before: ' ',
384
+ # space: ' '
385
+ # }
386
+ # puts 'Open:', JSON.generate(obj, opts)
387
+ #
388
+ # Output:
389
+ # Compact:
390
+ # {"foo":["bar","baz"],"bat":{"bam":0,"bad":1}}
391
+ # Open:
392
+ # {
393
+ # "foo" : [
394
+ # "bar",
395
+ # "baz"
396
+ # ],
397
+ # "bat" : {
398
+ # "bam" : 0,
399
+ # "bad" : 1
400
+ # }
401
+ # }
402
+ #
403
+ # ---
404
+ #
405
+ # Raises an exception if any formatting option is not a \String.
406
+ #
407
+ # ====== Exceptions
408
+ #
409
+ # Raises an exception if +obj+ contains circular references:
410
+ # a = []; b = []; a.push(b); b.push(a)
411
+ # # Raises JSON::NestingError (nesting of 100 is too deep):
412
+ # JSON.generate(a)
413
+ #
207
414
  def generate(obj, opts = nil)
208
415
  if State === opts
209
416
  state, opts = opts, nil
@@ -230,11 +437,16 @@ module JSON
230
437
  module_function :unparse
231
438
  # :startdoc:
232
439
 
233
- # Generate a JSON document from the Ruby data structure _obj_ and return it.
234
- # This method disables the checks for circles in Ruby objects.
440
+ # Arguments +obj+ and +opts+ here are the same as
441
+ # arguments +obj+ and +opts+ in JSON.generate.
442
+ #
443
+ # By default, generates \JSON data without checking
444
+ # for circular references in +obj+ (option +max_nesting+ set to +false+, disabled).
235
445
  #
236
- # *WARNING*: Be careful not to pass any Ruby data structures with circles as
237
- # _obj_ argument because this will cause JSON to go into an infinite loop.
446
+ # Raises an exception if +obj+ contains circular references:
447
+ # a = []; b = []; a.push(b); b.push(a)
448
+ # # Raises SystemStackError (stack level too deep):
449
+ # JSON.fast_generate(a)
238
450
  def fast_generate(obj, opts = nil)
239
451
  if State === opts
240
452
  state, opts = opts, nil
@@ -260,12 +472,36 @@ module JSON
260
472
  module_function :fast_unparse
261
473
  # :startdoc:
262
474
 
263
- # Generate a JSON document from the Ruby data structure _obj_ and return it.
264
- # The returned document is a prettier form of the document returned by
265
- # #unparse.
475
+ # :call-seq:
476
+ # JSON.pretty_generate(obj, opts = nil) -> new_string
477
+ #
478
+ # Arguments +obj+ and +opts+ here are the same as
479
+ # arguments +obj+ and +opts+ in JSON.generate.
480
+ #
481
+ # Default options are:
482
+ # {
483
+ # indent: ' ', # Two spaces
484
+ # space: ' ', # One space
485
+ # array_nl: "\n", # Newline
486
+ # object_nl: "\n" # Newline
487
+ # }
488
+ #
489
+ # Example:
490
+ # obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
491
+ # json = JSON.pretty_generate(obj)
492
+ # puts json
493
+ # Output:
494
+ # {
495
+ # "foo": [
496
+ # "bar",
497
+ # "baz"
498
+ # ],
499
+ # "bat": {
500
+ # "bam": 0,
501
+ # "bad": 1
502
+ # }
503
+ # }
266
504
  #
267
- # The _opts_ argument can be used to configure the generator. See the
268
- # generate method for a more detailed explanation.
269
505
  def pretty_generate(obj, opts = nil)
270
506
  if State === opts
271
507
  state, opts = opts, nil
@@ -292,16 +528,16 @@ module JSON
292
528
  # :startdoc:
293
529
 
294
530
  class << self
295
- # The global default options for the JSON.load method:
296
- # :max_nesting: false
297
- # :allow_nan: true
298
- # :quirks_mode: true
531
+ # Sets or returns default options for the JSON.load method.
532
+ # Initially:
533
+ # opts = JSON.load_default_options
534
+ # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
299
535
  attr_accessor :load_default_options
300
536
  end
301
537
  self.load_default_options = {
302
538
  :max_nesting => false,
303
539
  :allow_nan => true,
304
- :quirks_mode => true,
540
+ :allow_blank => true,
305
541
  :create_additions => true,
306
542
  }
307
543
 
@@ -328,7 +564,7 @@ module JSON
328
564
  elsif source.respond_to?(:read)
329
565
  source = source.read
330
566
  end
331
- if opts[:quirks_mode] && (source.nil? || source.empty?)
567
+ if opts[:allow_blank] && (source.nil? || source.empty?)
332
568
  source = 'null'
333
569
  end
334
570
  result = parse(source, opts)
@@ -354,16 +590,15 @@ module JSON
354
590
  module_function :restore
355
591
 
356
592
  class << self
357
- # The global default options for the JSON.dump method:
358
- # :max_nesting: false
359
- # :allow_nan: true
360
- # :quirks_mode: true
593
+ # Sets or returns the default options for the JSON.dump method.
594
+ # Initially:
595
+ # opts = JSON.dump_default_options
596
+ # opts # => {:max_nesting=>false, :allow_nan=>true}
361
597
  attr_accessor :dump_default_options
362
598
  end
363
599
  self.dump_default_options = {
364
600
  :max_nesting => false,
365
601
  :allow_nan => true,
366
- :quirks_mode => true,
367
602
  }
368
603
 
369
604
  # Dumps _obj_ as a JSON string, i.e. calls generate on the object and returns
@@ -402,37 +637,9 @@ module JSON
402
637
  raise ArgumentError, "exceed depth limit"
403
638
  end
404
639
 
405
- # Swap consecutive bytes of _string_ in place.
406
- def self.swap!(string) # :nodoc:
407
- 0.upto(string.size / 2) do |i|
408
- break unless string[2 * i + 1]
409
- string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
410
- end
411
- string
412
- end
413
-
414
- # Shortcut for iconv.
415
- if ::String.method_defined?(:encode)
416
- # Encodes string using Ruby's _String.encode_
417
- def self.iconv(to, from, string)
418
- string.encode(to, from)
419
- end
420
- else
421
- require 'iconv'
422
- # Encodes string using _iconv_ library
423
- def self.iconv(to, from, string)
424
- Iconv.conv(to, from, string)
425
- end
426
- end
427
-
428
- if ::Object.method(:const_defined?).arity == 1
429
- def self.const_defined_in?(modul, constant)
430
- modul.const_defined?(constant)
431
- end
432
- else
433
- def self.const_defined_in?(modul, constant)
434
- modul.const_defined?(constant, false)
435
- end
640
+ # Encodes string using String.encode.
641
+ def self.iconv(to, from, string)
642
+ string.encode(to, from)
436
643
  end
437
644
  end
438
645