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,9 +1,3 @@
1
- if ENV['SIMPLECOV_COVERAGE'].to_i == 1
2
- require 'simplecov'
3
- SimpleCov.start do
4
- add_filter "/tests/"
5
- end
6
- end
7
1
  require 'json/common'
8
2
 
9
3
  module JSON
@@ -1,3 +1,4 @@
1
+ #frozen_string_literal: false
1
2
  require 'ostruct'
2
3
 
3
4
  module JSON
@@ -48,12 +49,12 @@ module JSON
48
49
  end
49
50
 
50
51
  def [](name)
51
- table[name.to_sym]
52
- end
52
+ __send__(name)
53
+ end unless method_defined?(:[])
53
54
 
54
55
  def []=(name, value)
55
- __send__ "#{name}=", value
56
- end
56
+ __send__("#{name}=", value)
57
+ end unless method_defined?(:[]=)
57
58
 
58
59
  def |(other)
59
60
  self.class[other.to_hash.merge(to_hash)]
@@ -1,17 +1,11 @@
1
- if ENV['SIMPLECOV_COVERAGE'].to_i == 1
2
- require 'simplecov'
3
- SimpleCov.start do
4
- add_filter "/tests/"
5
- end
6
- end
7
1
  require 'json/common'
8
- require 'json/pure/parser'
9
- require 'json/pure/generator'
10
2
 
11
3
  module JSON
12
4
  # This module holds all the modules/classes that implement JSON's
13
5
  # functionality in pure ruby.
14
6
  module Pure
7
+ require 'json/pure/parser'
8
+ require 'json/pure/generator'
15
9
  $DEBUG and warn "Using Pure library for JSON."
16
10
  JSON.parser = Parser
17
11
  JSON.generator = Generator
@@ -1,3 +1,4 @@
1
+ #frozen_string_literal: false
1
2
  module JSON
2
3
  MAP = {
3
4
  "\x0" => '\u0000',
@@ -38,85 +39,45 @@ module JSON
38
39
 
39
40
  # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
40
41
  # UTF16 big endian characters as \u????, and return it.
41
- if defined?(::Encoding)
42
- def utf8_to_json(string) # :nodoc:
43
- string = string.dup
44
- string.force_encoding(::Encoding::ASCII_8BIT)
45
- string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
46
- string.force_encoding(::Encoding::UTF_8)
47
- string
48
- end
49
-
50
- def utf8_to_json_ascii(string) # :nodoc:
51
- string = string.dup
52
- string.force_encoding(::Encoding::ASCII_8BIT)
53
- string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] }
54
- string.gsub!(/(
55
- (?:
56
- [\xc2-\xdf][\x80-\xbf] |
57
- [\xe0-\xef][\x80-\xbf]{2} |
58
- [\xf0-\xf4][\x80-\xbf]{3}
59
- )+ |
60
- [\x80-\xc1\xf5-\xff] # invalid
61
- )/nx) { |c|
62
- c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
63
- s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
64
- s.force_encoding(::Encoding::ASCII_8BIT)
65
- s.gsub!(/.{4}/n, '\\\\u\&')
66
- s.force_encoding(::Encoding::UTF_8)
67
- }
68
- string.force_encoding(::Encoding::UTF_8)
69
- string
70
- rescue => e
71
- raise GeneratorError.wrap(e)
72
- end
73
-
74
- def valid_utf8?(string)
75
- encoding = string.encoding
76
- (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
77
- string.valid_encoding?
78
- end
79
- module_function :valid_utf8?
80
- else
81
- def utf8_to_json(string) # :nodoc:
82
- string.gsub(/["\\\x0-\x1f]/n) { MAP[$&] }
83
- end
42
+ def utf8_to_json(string) # :nodoc:
43
+ string = string.dup
44
+ string.force_encoding(::Encoding::ASCII_8BIT)
45
+ string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
46
+ string.force_encoding(::Encoding::UTF_8)
47
+ string
48
+ end
84
49
 
85
- def utf8_to_json_ascii(string) # :nodoc:
86
- string = string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
87
- string.gsub!(/(
88
- (?:
89
- [\xc2-\xdf][\x80-\xbf] |
90
- [\xe0-\xef][\x80-\xbf]{2} |
91
- [\xf0-\xf4][\x80-\xbf]{3}
92
- )+ |
93
- [\x80-\xc1\xf5-\xff] # invalid
94
- )/nx) { |c|
95
- c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
96
- s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
97
- s.gsub!(/.{4}/n, '\\\\u\&')
98
- }
99
- string
100
- rescue => e
101
- raise GeneratorError.wrap(e)
102
- end
50
+ def utf8_to_json_ascii(string) # :nodoc:
51
+ string = string.dup
52
+ string.force_encoding(::Encoding::ASCII_8BIT)
53
+ string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] }
54
+ string.gsub!(/(
55
+ (?:
56
+ [\xc2-\xdf][\x80-\xbf] |
57
+ [\xe0-\xef][\x80-\xbf]{2} |
58
+ [\xf0-\xf4][\x80-\xbf]{3}
59
+ )+ |
60
+ [\x80-\xc1\xf5-\xff] # invalid
61
+ )/nx) { |c|
62
+ c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
63
+ s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
64
+ s.force_encoding(::Encoding::ASCII_8BIT)
65
+ s.gsub!(/.{4}/n, '\\\\u\&')
66
+ s.force_encoding(::Encoding::UTF_8)
67
+ }
68
+ string.force_encoding(::Encoding::UTF_8)
69
+ string
70
+ rescue => e
71
+ raise GeneratorError.wrap(e)
72
+ end
103
73
 
104
- def valid_utf8?(string)
105
- string =~
106
- /\A( [\x09\x0a\x0d\x20-\x7e] # ASCII
107
- | [\xc2-\xdf][\x80-\xbf] # non-overlong 2-byte
108
- | \xe0[\xa0-\xbf][\x80-\xbf] # excluding overlongs
109
- | [\xe1-\xec\xee\xef][\x80-\xbf]{2} # straight 3-byte
110
- | \xed[\x80-\x9f][\x80-\xbf] # excluding surrogates
111
- | \xf0[\x90-\xbf][\x80-\xbf]{2} # planes 1-3
112
- | [\xf1-\xf3][\x80-\xbf]{3} # planes 4-15
113
- | \xf4[\x80-\x8f][\x80-\xbf]{2} # plane 16
114
- )*\z/nx
115
- end
74
+ def valid_utf8?(string)
75
+ encoding = string.encoding
76
+ (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
77
+ string.valid_encoding?
116
78
  end
117
79
  module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8?
118
80
 
119
-
120
81
  module Pure
121
82
  module Generator
122
83
  # This class is used to create State instances, that are use to hold data
@@ -154,8 +115,6 @@ module JSON
154
115
  # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
155
116
  # generated, otherwise an exception is thrown, if these values are
156
117
  # encountered. This options defaults to false.
157
- # * *quirks_mode*: Enables quirks_mode for parser, that is for example
158
- # generating single JSON values instead of documents is possible.
159
118
  def initialize(opts = {})
160
119
  @indent = ''
161
120
  @space = ''
@@ -164,7 +123,6 @@ module JSON
164
123
  @array_nl = ''
165
124
  @allow_nan = false
166
125
  @ascii_only = false
167
- @quirks_mode = false
168
126
  @buffer_initial_length = 1024
169
127
  configure opts
170
128
  end
@@ -190,10 +148,6 @@ module JSON
190
148
  # the generated JSON, max_nesting = 0 if no maximum is checked.
191
149
  attr_accessor :max_nesting
192
150
 
193
- # If this attribute is set to true, quirks mode is enabled, otherwise
194
- # it's disabled.
195
- attr_accessor :quirks_mode
196
-
197
151
  # :stopdoc:
198
152
  attr_reader :buffer_initial_length
199
153
 
@@ -233,11 +187,6 @@ module JSON
233
187
  @ascii_only
234
188
  end
235
189
 
236
- # Returns true, if quirks mode is enabled. Otherwise returns false.
237
- def quirks_mode?
238
- @quirks_mode
239
- end
240
-
241
190
  # Configure this State instance with the Hash _opts_, and return
242
191
  # itself.
243
192
  def configure(opts)
@@ -259,7 +208,6 @@ module JSON
259
208
  @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
260
209
  @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
261
210
  @depth = opts[:depth] || 0
262
- @quirks_mode = opts[:quirks_mode] if opts.key?(:quirks_mode)
263
211
  @buffer_initial_length ||= opts[:buffer_initial_length]
264
212
 
265
213
  if !opts.key?(:max_nesting) # defaults to 100
@@ -286,20 +234,14 @@ module JSON
286
234
 
287
235
  alias to_hash to_h
288
236
 
289
- # Generates a valid JSON document from object +obj+ and returns the
290
- # result. If no valid JSON document can be created this method raises a
237
+ # Generates a valid JSON document from object +obj+ and
238
+ # returns the result. If no valid JSON document can be
239
+ # created this method raises a
291
240
  # GeneratorError exception.
292
241
  def generate(obj)
293
242
  result = obj.to_json(self)
294
243
  JSON.valid_utf8?(result) or raise GeneratorError,
295
244
  "source sequence #{result.inspect} is illegal/malformed utf-8"
296
- unless @quirks_mode
297
- unless result =~ /\A\s*\[/ && result =~ /\]\s*\Z/ ||
298
- result =~ /\A\s*\{/ && result =~ /\}\s*\Z/
299
- then
300
- raise GeneratorError, "only generation of JSON objects or arrays allowed"
301
- end
302
- end
303
245
  result
304
246
  end
305
247
 
@@ -308,7 +250,8 @@ module JSON
308
250
  if respond_to?(name)
309
251
  __send__(name)
310
252
  else
311
- instance_variable_get("@#{name}")
253
+ instance_variable_get("@#{name}") if
254
+ instance_variables.include?("@#{name}".to_sym) # avoid warning
312
255
  end
313
256
  end
314
257
 
@@ -363,7 +306,11 @@ module JSON
363
306
  result << state.space_before
364
307
  result << ':'
365
308
  result << state.space
366
- result << value.to_json(state)
309
+ if value.respond_to?(:to_json)
310
+ result << value.to_json(state)
311
+ else
312
+ result << %{"#{String(value)}"}
313
+ end
367
314
  first = false
368
315
  }
369
316
  depth = state.depth -= 1
@@ -398,7 +345,11 @@ module JSON
398
345
  each { |value|
399
346
  result << delim unless first
400
347
  result << state.indent * depth if indent
401
- result << value.to_json(state)
348
+ if value.respond_to?(:to_json)
349
+ result << value.to_json(state)
350
+ else
351
+ result << %{"#{String(value)}"}
352
+ end
402
353
  first = false
403
354
  }
404
355
  depth = state.depth -= 1
@@ -437,38 +388,24 @@ module JSON
437
388
  end
438
389
 
439
390
  module String
440
- if defined?(::Encoding)
441
- # This string should be encoded with UTF-8 A call to this method
442
- # returns a JSON string encoded with UTF16 big endian characters as
443
- # \u????.
444
- def to_json(state = nil, *args)
445
- state = State.from_state(state)
446
- if encoding == ::Encoding::UTF_8
447
- string = self
448
- else
449
- string = encode(::Encoding::UTF_8)
450
- end
451
- if state.ascii_only?
452
- '"' << JSON.utf8_to_json_ascii(string) << '"'
453
- else
454
- '"' << JSON.utf8_to_json(string) << '"'
455
- end
391
+ # This string should be encoded with UTF-8 A call to this method
392
+ # returns a JSON string encoded with UTF16 big endian characters as
393
+ # \u????.
394
+ def to_json(state = nil, *args)
395
+ state = State.from_state(state)
396
+ if encoding == ::Encoding::UTF_8
397
+ string = self
398
+ else
399
+ string = encode(::Encoding::UTF_8)
456
400
  end
457
- else
458
- # This string should be encoded with UTF-8 A call to this method
459
- # returns a JSON string encoded with UTF16 big endian characters as
460
- # \u????.
461
- def to_json(state = nil, *args)
462
- state = State.from_state(state)
463
- if state.ascii_only?
464
- '"' << JSON.utf8_to_json_ascii(self) << '"'
465
- else
466
- '"' << JSON.utf8_to_json(self) << '"'
467
- end
401
+ if state.ascii_only?
402
+ '"' << JSON.utf8_to_json_ascii(string) << '"'
403
+ else
404
+ '"' << JSON.utf8_to_json(string) << '"'
468
405
  end
469
406
  end
470
407
 
471
- # Module that holds the extinding methods if, the String module is
408
+ # Module that holds the extending methods if, the String module is
472
409
  # included.
473
410
  module Extend
474
411
  # Raw Strings are JSON Objects (the raw bytes are stored in an
@@ -1,3 +1,4 @@
1
+ #frozen_string_literal: false
1
2
  require 'strscan'
2
3
 
3
4
  module JSON
@@ -48,7 +49,7 @@ module JSON
48
49
  )+
49
50
  )mx
50
51
 
51
- UNPARSED = Object.new
52
+ UNPARSED = Object.new.freeze
52
53
 
53
54
  # Creates a new JSON::Pure::Parser instance for the string _source_.
54
55
  #
@@ -58,23 +59,23 @@ module JSON
58
59
  # structures. Disable depth checking with :max_nesting => false|nil|0,
59
60
  # it defaults to 100.
60
61
  # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
61
- # defiance of RFC 4627 to be parsed by the Parser. This option defaults
62
+ # defiance of RFC 7159 to be parsed by the Parser. This option defaults
62
63
  # to false.
63
64
  # * *symbolize_names*: If set to true, returns symbols for the names
64
- # (keys) in a JSON object. Otherwise strings are returned, which is also
65
- # the default.
65
+ # (keys) in a JSON object. Otherwise strings are returned, which is
66
+ # also the default. It's not possible to use this option in
67
+ # conjunction with the *create_additions* option.
66
68
  # * *create_additions*: If set to true, the Parser creates
67
- # additions when if a matching class and create_id was found. This
69
+ # additions when a matching class and create_id are found. This
68
70
  # option defaults to false.
69
71
  # * *object_class*: Defaults to Hash
70
72
  # * *array_class*: Defaults to Array
71
- # * *quirks_mode*: Enables quirks_mode for parser, that is for example
72
- # parsing single JSON values instead of documents is possible.
73
+ # * *decimal_class*: Specifies which class to use instead of the default
74
+ # (Float) when parsing decimal numbers. This class must accept a single
75
+ # string argument in its constructor.
73
76
  def initialize(source, opts = {})
74
77
  opts ||= {}
75
- unless @quirks_mode = opts[:quirks_mode]
76
- source = convert_encoding source
77
- end
78
+ source = convert_encoding source
78
79
  super source
79
80
  if !opts.key?(:max_nesting) # defaults to 100
80
81
  @max_nesting = 100
@@ -90,56 +91,38 @@ module JSON
90
91
  else
91
92
  @create_additions = false
92
93
  end
94
+ @symbolize_names && @create_additions and raise ArgumentError,
95
+ 'options :symbolize_names and :create_additions cannot be used '\
96
+ 'in conjunction'
93
97
  @create_id = @create_additions ? JSON.create_id : nil
94
98
  @object_class = opts[:object_class] || Hash
95
99
  @array_class = opts[:array_class] || Array
100
+ @decimal_class = opts[:decimal_class]
96
101
  @match_string = opts[:match_string]
97
102
  end
98
103
 
99
104
  alias source string
100
105
 
101
- def quirks_mode?
102
- !!@quirks_mode
103
- end
104
-
105
106
  def reset
106
107
  super
107
108
  @current_nesting = 0
108
109
  end
109
110
 
110
- # Parses the current JSON string _source_ and returns the complete data
111
- # structure as a result.
111
+ # Parses the current JSON string _source_ and returns the
112
+ # complete data structure as a result.
112
113
  def parse
113
114
  reset
114
115
  obj = nil
115
- if @quirks_mode
116
- while !eos? && skip(IGNORE)
117
- end
118
- if eos?
119
- raise ParserError, "source did not contain any JSON!"
120
- else
121
- obj = parse_value
122
- obj == UNPARSED and raise ParserError, "source did not contain any JSON!"
123
- end
116
+ while !eos? && skip(IGNORE) do end
117
+ if eos?
118
+ raise ParserError, "source is not valid JSON!"
124
119
  else
125
- until eos?
126
- case
127
- when scan(OBJECT_OPEN)
128
- obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
129
- @current_nesting = 1
130
- obj = parse_object
131
- when scan(ARRAY_OPEN)
132
- obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
133
- @current_nesting = 1
134
- obj = parse_array
135
- when skip(IGNORE)
136
- ;
137
- else
138
- raise ParserError, "source '#{peek(20)}' not in JSON!"
139
- end
140
- end
141
- obj or raise ParserError, "source did not contain any JSON!"
120
+ obj = parse_value
121
+ UNPARSED.equal?(obj) and raise ParserError,
122
+ "source is not valid JSON!"
142
123
  end
124
+ while !eos? && skip(IGNORE) do end
125
+ eos? or raise ParserError, "source is not valid JSON!"
143
126
  obj
144
127
  end
145
128
 
@@ -149,43 +132,12 @@ module JSON
149
132
  if source.respond_to?(:to_str)
150
133
  source = source.to_str
151
134
  else
152
- raise TypeError, "#{source.inspect} is not like a string"
135
+ raise TypeError,
136
+ "#{source.inspect} is not like a string"
153
137
  end
154
- if defined?(::Encoding)
155
- if source.encoding == ::Encoding::ASCII_8BIT
156
- b = source[0, 4].bytes.to_a
157
- source =
158
- case
159
- when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
160
- source.dup.force_encoding(::Encoding::UTF_32BE).encode!(::Encoding::UTF_8)
161
- when b.size >= 4 && b[0] == 0 && b[2] == 0
162
- source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8)
163
- when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
164
- source.dup.force_encoding(::Encoding::UTF_32LE).encode!(::Encoding::UTF_8)
165
- when b.size >= 4 && b[1] == 0 && b[3] == 0
166
- source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8)
167
- else
168
- source.dup
169
- end
170
- else
171
- source = source.encode(::Encoding::UTF_8)
172
- end
138
+ if source.encoding != ::Encoding::ASCII_8BIT
139
+ source = source.encode(::Encoding::UTF_8)
173
140
  source.force_encoding(::Encoding::ASCII_8BIT)
174
- else
175
- b = source
176
- source =
177
- case
178
- when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
179
- JSON.iconv('utf-8', 'utf-32be', b)
180
- when b.size >= 4 && b[0] == 0 && b[2] == 0
181
- JSON.iconv('utf-8', 'utf-16be', b)
182
- when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
183
- JSON.iconv('utf-8', 'utf-32le', b)
184
- when b.size >= 4 && b[1] == 0 && b[3] == 0
185
- JSON.iconv('utf-8', 'utf-16le', b)
186
- else
187
- b
188
- end
189
141
  end
190
142
  source
191
143
  end
@@ -245,7 +197,15 @@ module JSON
245
197
  def parse_value
246
198
  case
247
199
  when scan(FLOAT)
248
- Float(self[1])
200
+ if @decimal_class then
201
+ if @decimal_class == BigDecimal then
202
+ BigDecimal(self[1])
203
+ else
204
+ @decimal_class.new(self[1]) || Float(self[1])
205
+ end
206
+ else
207
+ Float(self[1])
208
+ end
249
209
  when scan(INTEGER)
250
210
  Integer(self[1])
251
211
  when scan(TRUE)
@@ -254,7 +214,7 @@ module JSON
254
214
  false
255
215
  when scan(NULL)
256
216
  nil
257
- when (string = parse_string) != UNPARSED
217
+ when !UNPARSED.equal?(string = parse_string)
258
218
  string
259
219
  when scan(ARRAY_OPEN)
260
220
  @current_nesting += 1
@@ -284,7 +244,7 @@ module JSON
284
244
  delim = false
285
245
  until eos?
286
246
  case
287
- when (value = parse_value) != UNPARSED
247
+ when !UNPARSED.equal?(value = parse_value)
288
248
  delim = false
289
249
  result << value
290
250
  skip(IGNORE)
@@ -316,13 +276,13 @@ module JSON
316
276
  delim = false
317
277
  until eos?
318
278
  case
319
- when (string = parse_string) != UNPARSED
279
+ when !UNPARSED.equal?(string = parse_string)
320
280
  skip(IGNORE)
321
281
  unless scan(PAIR_DELIMITER)
322
282
  raise ParserError, "expected ':' in object at '#{peek(20)}'!"
323
283
  end
324
284
  skip(IGNORE)
325
- unless (value = parse_value).equal? UNPARSED
285
+ unless UNPARSED.equal?(value = parse_value)
326
286
  result[@symbolize_names ? string.to_sym : string] = value
327
287
  delim = false
328
288
  skip(IGNORE)