diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/json/common.rb | 55 | ||||
-rw-r--r-- | lib/json/ext.rb | 6 | ||||
-rw-r--r-- | lib/json/pure.rb | 10 | ||||
-rw-r--r-- | lib/json/pure/generator.rb | 161 | ||||
-rw-r--r-- | lib/json/pure/parser.rb | 14 |
5 files changed, 65 insertions, 181 deletions
diff --git a/lib/json/common.rb b/lib/json/common.rb index 1215d41..55908f8 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -24,7 +24,7 @@ module JSON # Set the JSON parser class _parser_ to be used by JSON. def parser=(parser) # :nodoc: @parser = parser - remove_const :Parser if JSON.const_defined_in?(self, :Parser) + remove_const :Parser if const_defined?(:Parser, true) const_set :Parser, parser end @@ -35,8 +35,8 @@ module JSON def deep_const_get(path) # :nodoc: path.to_s.split(/::/).inject(Object) do |p, c| case - when c.empty? then p - when JSON.const_defined_in?(p, c) then p.const_get(c) + when c.empty? then p + when p.const_defined?(c, true) then p.const_get(c) else begin p.const_missing(c) @@ -141,7 +141,7 @@ module JSON # structures. Disable depth checking with :max_nesting => false. It # defaults to 100. # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in - # defiance of RFC 4627 to be parsed by the Parser. This option defaults + # defiance of RFC 7159 to be parsed by the Parser. This option defaults # to false. # * *symbolize_names*: If set to true, returns symbols for the names # (keys) in a JSON object. Otherwise strings are returned. Strings are @@ -165,7 +165,7 @@ module JSON # parse! methods defaults to not doing max depth checking: This can be # dangerous if someone wants to fill up your stack. # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in - # defiance of RFC 4627 to be parsed by the Parser. This option defaults + # defiance of RFC 7159 to be parsed by the Parser. This option defaults # to true. # * *create_additions*: If set to false, the Parser doesn't create # additions even if a matching class and create_id was found. This option @@ -174,7 +174,7 @@ module JSON opts = { :max_nesting => false, :allow_nan => true - }.update(opts) + }.merge(opts) Parser.new(source, opts).parse end @@ -295,13 +295,13 @@ module JSON # The global default options for the JSON.load method: # :max_nesting: false # :allow_nan: true - # :quirks_mode: true + # :allow_blank: true attr_accessor :load_default_options end self.load_default_options = { :max_nesting => false, :allow_nan => true, - :quirks_mode => true, + :allow_blank => true, :create_additions => true, } @@ -328,7 +328,7 @@ module JSON elsif source.respond_to?(:read) source = source.read end - if opts[:quirks_mode] && (source.nil? || source.empty?) + if opts[:allow_blank] && (source.nil? || source.empty?) source = 'null' end result = parse(source, opts) @@ -357,13 +357,12 @@ module JSON # The global default options for the JSON.dump method: # :max_nesting: false # :allow_nan: true - # :quirks_mode: true + # :allow_blank: true attr_accessor :dump_default_options end self.dump_default_options = { :max_nesting => false, :allow_nan => true, - :quirks_mode => true, } # Dumps _obj_ as a JSON string, i.e. calls generate on the object and returns @@ -402,37 +401,9 @@ module JSON raise ArgumentError, "exceed depth limit" end - # Swap consecutive bytes of _string_ in place. - def self.swap!(string) # :nodoc: - 0.upto(string.size / 2) do |i| - break unless string[2 * i + 1] - string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i] - end - string - end - - # Shortcut for iconv. - if ::String.method_defined?(:encode) - # Encodes string using Ruby's _String.encode_ - def self.iconv(to, from, string) - string.encode(to, from) - end - else - require 'iconv' - # Encodes string using _iconv_ library - def self.iconv(to, from, string) - Iconv.conv(to, from, string) - end - end - - if ::Object.method(:const_defined?).arity == 1 - def self.const_defined_in?(modul, constant) - modul.const_defined?(constant) - end - else - def self.const_defined_in?(modul, constant) - modul.const_defined?(constant, false) - end + # Encodes string using Ruby's _String.encode_ + def self.iconv(to, from, string) + string.encode(to, from) end end diff --git a/lib/json/ext.rb b/lib/json/ext.rb index c5f8131..7264a85 100644 --- a/lib/json/ext.rb +++ b/lib/json/ext.rb @@ -1,9 +1,3 @@ -if ENV['SIMPLECOV_COVERAGE'].to_i == 1 - require 'simplecov' - SimpleCov.start do - add_filter "/tests/" - end -end require 'json/common' module JSON diff --git a/lib/json/pure.rb b/lib/json/pure.rb index b68668b..53178b3 100644 --- a/lib/json/pure.rb +++ b/lib/json/pure.rb @@ -1,17 +1,11 @@ -if ENV['SIMPLECOV_COVERAGE'].to_i == 1 - require 'simplecov' - SimpleCov.start do - add_filter "/tests/" - end -end require 'json/common' -require 'json/pure/parser' -require 'json/pure/generator' module JSON # This module holds all the modules/classes that implement JSON's # functionality in pure ruby. module Pure + require 'json/pure/parser' + require 'json/pure/generator' $DEBUG and warn "Using Pure library for JSON." JSON.parser = Parser JSON.generator = Generator diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index cc8b0fd..98bc369 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -38,85 +38,45 @@ module JSON # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with # UTF16 big endian characters as \u????, and return it. - if defined?(::Encoding) - def utf8_to_json(string) # :nodoc: - string = string.dup - string.force_encoding(::Encoding::ASCII_8BIT) - string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] } - string.force_encoding(::Encoding::UTF_8) - string - end - - def utf8_to_json_ascii(string) # :nodoc: - string = string.dup - string.force_encoding(::Encoding::ASCII_8BIT) - string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] } - string.gsub!(/( - (?: - [\xc2-\xdf][\x80-\xbf] | - [\xe0-\xef][\x80-\xbf]{2} | - [\xf0-\xf4][\x80-\xbf]{3} - )+ | - [\x80-\xc1\xf5-\xff] # invalid - )/nx) { |c| - c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'" - s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0] - s.force_encoding(::Encoding::ASCII_8BIT) - s.gsub!(/.{4}/n, '\\\\u\&') - s.force_encoding(::Encoding::UTF_8) - } - string.force_encoding(::Encoding::UTF_8) - string - rescue => e - raise GeneratorError.wrap(e) - end - - def valid_utf8?(string) - encoding = string.encoding - (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) && - string.valid_encoding? - end - module_function :valid_utf8? - else - def utf8_to_json(string) # :nodoc: - string.gsub(/["\\\x0-\x1f]/n) { MAP[$&] } - end + def utf8_to_json(string) # :nodoc: + string = string.dup + string.force_encoding(::Encoding::ASCII_8BIT) + string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] } + string.force_encoding(::Encoding::UTF_8) + string + end - def utf8_to_json_ascii(string) # :nodoc: - string = string.gsub(/["\\\x0-\x1f]/) { MAP[$&] } - string.gsub!(/( - (?: - [\xc2-\xdf][\x80-\xbf] | - [\xe0-\xef][\x80-\xbf]{2} | - [\xf0-\xf4][\x80-\xbf]{3} - )+ | - [\x80-\xc1\xf5-\xff] # invalid - )/nx) { |c| - c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'" - s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0] - s.gsub!(/.{4}/n, '\\\\u\&') - } - string - rescue => e - raise GeneratorError.wrap(e) - end + def utf8_to_json_ascii(string) # :nodoc: + string = string.dup + string.force_encoding(::Encoding::ASCII_8BIT) + string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] } + string.gsub!(/( + (?: + [\xc2-\xdf][\x80-\xbf] | + [\xe0-\xef][\x80-\xbf]{2} | + [\xf0-\xf4][\x80-\xbf]{3} + )+ | + [\x80-\xc1\xf5-\xff] # invalid + )/nx) { |c| + c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'" + s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0] + s.force_encoding(::Encoding::ASCII_8BIT) + s.gsub!(/.{4}/n, '\\\\u\&') + s.force_encoding(::Encoding::UTF_8) + } + string.force_encoding(::Encoding::UTF_8) + string + rescue => e + raise GeneratorError.wrap(e) + end - def valid_utf8?(string) - string =~ - /\A( [\x09\x0a\x0d\x20-\x7e] # ASCII - | [\xc2-\xdf][\x80-\xbf] # non-overlong 2-byte - | \xe0[\xa0-\xbf][\x80-\xbf] # excluding overlongs - | [\xe1-\xec\xee\xef][\x80-\xbf]{2} # straight 3-byte - | \xed[\x80-\x9f][\x80-\xbf] # excluding surrogates - | \xf0[\x90-\xbf][\x80-\xbf]{2} # planes 1-3 - | [\xf1-\xf3][\x80-\xbf]{3} # planes 4-15 - | \xf4[\x80-\x8f][\x80-\xbf]{2} # plane 16 - )*\z/nx - end + def valid_utf8?(string) + encoding = string.encoding + (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) && + string.valid_encoding? end module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8? - module Pure module Generator # This class is used to create State instances, that are use to hold data @@ -154,8 +114,6 @@ module JSON # * *allow_nan*: true if NaN, Infinity, and -Infinity should be # generated, otherwise an exception is thrown, if these values are # encountered. This options defaults to false. - # * *quirks_mode*: Enables quirks_mode for parser, that is for example - # generating single JSON values instead of documents is possible. def initialize(opts = {}) @indent = '' @space = '' @@ -164,7 +122,6 @@ module JSON @array_nl = '' @allow_nan = false @ascii_only = false - @quirks_mode = false @buffer_initial_length = 1024 configure opts end @@ -190,10 +147,6 @@ module JSON # the generated JSON, max_nesting = 0 if no maximum is checked. attr_accessor :max_nesting - # If this attribute is set to true, quirks mode is enabled, otherwise - # it's disabled. - attr_accessor :quirks_mode - # :stopdoc: attr_reader :buffer_initial_length @@ -233,11 +186,6 @@ module JSON @ascii_only end - # Returns true, if quirks mode is enabled. Otherwise returns false. - def quirks_mode? - @quirks_mode - end - # Configure this State instance with the Hash _opts_, and return # itself. def configure(opts) @@ -259,7 +207,6 @@ module JSON @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan) @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only) @depth = opts[:depth] || 0 - @quirks_mode = opts[:quirks_mode] if opts.key?(:quirks_mode) @buffer_initial_length ||= opts[:buffer_initial_length] if !opts.key?(:max_nesting) # defaults to 100 @@ -439,34 +386,20 @@ module JSON end module String - if defined?(::Encoding) - # This string should be encoded with UTF-8 A call to this method - # returns a JSON string encoded with UTF16 big endian characters as - # \u????. - def to_json(state = nil, *args) - state = State.from_state(state) - if encoding == ::Encoding::UTF_8 - string = self - else - string = encode(::Encoding::UTF_8) - end - if state.ascii_only? - '"' << JSON.utf8_to_json_ascii(string) << '"' - else - '"' << JSON.utf8_to_json(string) << '"' - end + # This string should be encoded with UTF-8 A call to this method + # returns a JSON string encoded with UTF16 big endian characters as + # \u????. + def to_json(state = nil, *args) + state = State.from_state(state) + if encoding == ::Encoding::UTF_8 + string = self + else + string = encode(::Encoding::UTF_8) end - else - # This string should be encoded with UTF-8 A call to this method - # returns a JSON string encoded with UTF16 big endian characters as - # \u????. - def to_json(state = nil, *args) - state = State.from_state(state) - if state.ascii_only? - '"' << JSON.utf8_to_json_ascii(self) << '"' - else - '"' << JSON.utf8_to_json(self) << '"' - end + if state.ascii_only? + '"' << JSON.utf8_to_json_ascii(string) << '"' + else + '"' << JSON.utf8_to_json(string) << '"' end end diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index c5d1501..f02f408 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -58,7 +58,7 @@ module JSON # structures. Disable depth checking with :max_nesting => false|nil|0, # it defaults to 100. # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in - # defiance of RFC 4627 to be parsed by the Parser. This option defaults + # defiance of RFC 7159 to be parsed by the Parser. This option defaults # to false. # * *symbolize_names*: If set to true, returns symbols for the names # (keys) in a JSON object. Otherwise strings are returned, which is @@ -69,13 +69,9 @@ module JSON # option defaults to false. # * *object_class*: Defaults to Hash # * *array_class*: Defaults to Array - # * *quirks_mode*: Enables quirks_mode for parser, that is for example - # parsing single JSON values instead of documents is possible. def initialize(source, opts = {}) opts ||= {} - unless @quirks_mode = opts[:quirks_mode] - source = convert_encoding source - end + source = convert_encoding source super source if !opts.key?(:max_nesting) # defaults to 100 @max_nesting = 100 @@ -102,10 +98,6 @@ module JSON alias source string - def quirks_mode? - !!@quirks_mode - end - def reset super @current_nesting = 0 @@ -138,7 +130,7 @@ module JSON raise TypeError, "#{source.inspect} is not like a string" end - if defined?(::Encoding) + if source.encoding != ::Encoding::ASCII_8BIT source = source.encode(::Encoding::UTF_8) source.force_encoding(::Encoding::ASCII_8BIT) end |