json 1.4.6 → 1.5.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.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- data/CHANGES +6 -0
- data/COPYING-json-jruby +57 -0
- data/README-json-jruby.markdown +33 -0
- data/Rakefile +224 -119
- data/VERSION +1 -1
- data/benchmarks/generator2_benchmark.rb +1 -1
- data/benchmarks/generator_benchmark.rb +1 -1
- data/ext/json/ext/generator/generator.c +20 -20
- data/ext/json/ext/generator/generator.h +7 -7
- data/ext/json/ext/parser/extconf.rb +1 -0
- data/ext/json/ext/parser/parser.c +122 -88
- data/ext/json/ext/parser/parser.h +7 -0
- data/ext/json/ext/parser/parser.rl +54 -20
- data/java/lib/bytelist-1.0.6.jar +0 -0
- data/java/lib/jcodings.jar +0 -0
- data/java/src/json/ext/ByteListTranscoder.java +167 -0
- data/java/src/json/ext/Generator.java +441 -0
- data/java/src/json/ext/GeneratorMethods.java +231 -0
- data/java/src/json/ext/GeneratorService.java +42 -0
- data/java/src/json/ext/GeneratorState.java +473 -0
- data/java/src/json/ext/OptionsReader.java +119 -0
- data/java/src/json/ext/Parser.java +2295 -0
- data/java/src/json/ext/Parser.rl +825 -0
- data/java/src/json/ext/ParserService.java +34 -0
- data/java/src/json/ext/RuntimeInfo.java +119 -0
- data/java/src/json/ext/StringDecoder.java +166 -0
- data/java/src/json/ext/StringEncoder.java +106 -0
- data/java/src/json/ext/Utils.java +89 -0
- data/json-java.gemspec +20 -0
- data/lib/json/add/core.rb +1 -2
- data/lib/json/add/rails.rb +4 -54
- data/lib/json/common.rb +36 -8
- data/lib/json/editor.rb +1 -3
- data/lib/json/ext.rb +2 -2
- data/lib/json/pure.rb +2 -64
- data/lib/json/pure/generator.rb +10 -8
- data/lib/json/pure/parser.rb +23 -12
- data/lib/json/version.rb +1 -1
- data/tests/setup_variant.rb +11 -0
- data/tests/test_json.rb +1 -5
- data/tests/test_json_addition.rb +14 -9
- data/tests/test_json_encoding.rb +9 -12
- data/tests/test_json_fixtures.rb +9 -8
- data/tests/test_json_generate.rb +3 -5
- data/tests/test_json_string_matching.rb +40 -0
- data/tests/test_json_unicode.rb +1 -5
- metadata +51 -13
- data/tests/test_json_rails.rb +0 -144
    
        data/json-java.gemspec
    ADDED
    
    | @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            #! /usr/bin/env jruby
         | 
| 2 | 
            +
            require "rubygems"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            spec = Gem::Specification.new do |s|
         | 
| 5 | 
            +
              s.name = "json"
         | 
| 6 | 
            +
              s.version = File.read("VERSION").chomp
         | 
| 7 | 
            +
              s.summary = "JSON implementation for JRuby"
         | 
| 8 | 
            +
              s.description = "A JSON implementation as a JRuby extension."
         | 
| 9 | 
            +
              s.author = "Daniel Luz"
         | 
| 10 | 
            +
              s.email = "dev+ruby@mernen.com"
         | 
| 11 | 
            +
              s.homepage = "http://json-jruby.rubyforge.org/"
         | 
| 12 | 
            +
              s.platform = 'java'
         | 
| 13 | 
            +
              s.rubyforge_project = "json-jruby"
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              s.files = Dir["{docs,lib,tests}/**/*"]
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            if $0 == __FILE__
         | 
| 19 | 
            +
              Gem::Builder.new(spec).build
         | 
| 20 | 
            +
            end
         | 
    
        data/lib/json/add/core.rb
    CHANGED
    
    | @@ -1,8 +1,7 @@ | |
| 1 1 | 
             
            # This file contains implementations of ruby core's custom objects for
         | 
| 2 2 | 
             
            # serialisation/deserialisation.
         | 
| 3 3 |  | 
| 4 | 
            -
            unless  | 
| 5 | 
            -
              ::JSON::JSON_LOADED
         | 
| 4 | 
            +
            unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
         | 
| 6 5 | 
             
              require 'json'
         | 
| 7 6 | 
             
            end
         | 
| 8 7 | 
             
            require 'date'
         | 
    
        data/lib/json/add/rails.rb
    CHANGED
    
    | @@ -1,58 +1,8 @@ | |
| 1 | 
            -
            # This file  | 
| 2 | 
            -
            # serialisation/deserialisation.
         | 
| 1 | 
            +
            # This file used to implementations of rails custom objects for
         | 
| 2 | 
            +
            # serialisation/deserialisation and is obsoleted now.
         | 
| 3 3 |  | 
| 4 | 
            -
            unless  | 
| 5 | 
            -
              ::JSON::JSON_LOADED
         | 
| 4 | 
            +
            unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
         | 
| 6 5 | 
             
              require 'json'
         | 
| 7 6 | 
             
            end
         | 
| 8 7 |  | 
| 9 | 
            -
             | 
| 10 | 
            -
              def self.json_create(object)
         | 
| 11 | 
            -
                obj = new
         | 
| 12 | 
            -
                for key, value in object
         | 
| 13 | 
            -
                  next if key == JSON.create_id
         | 
| 14 | 
            -
                  instance_variable_set "@#{key}", value
         | 
| 15 | 
            -
                end
         | 
| 16 | 
            -
                obj
         | 
| 17 | 
            -
              end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
              def to_json(*a)
         | 
| 20 | 
            -
                result = {
         | 
| 21 | 
            -
                  JSON.create_id => self.class.name
         | 
| 22 | 
            -
                }
         | 
| 23 | 
            -
                instance_variables.inject(result) do |r, name|
         | 
| 24 | 
            -
                  r[name[1..-1]] = instance_variable_get name
         | 
| 25 | 
            -
                  r
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
                result.to_json(*a)
         | 
| 28 | 
            -
              end
         | 
| 29 | 
            -
            end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
            class Symbol
         | 
| 32 | 
            -
              def to_json(*a)
         | 
| 33 | 
            -
                to_s.to_json(*a)
         | 
| 34 | 
            -
              end
         | 
| 35 | 
            -
            end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
            module Enumerable
         | 
| 38 | 
            -
              def to_json(*a)
         | 
| 39 | 
            -
                to_a.to_json(*a)
         | 
| 40 | 
            -
              end
         | 
| 41 | 
            -
            end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
            # class Regexp
         | 
| 44 | 
            -
            #   def to_json(*)
         | 
| 45 | 
            -
            #     inspect
         | 
| 46 | 
            -
            #   end
         | 
| 47 | 
            -
            # end
         | 
| 48 | 
            -
            #
         | 
| 49 | 
            -
            # The above rails definition has some problems:
         | 
| 50 | 
            -
            #
         | 
| 51 | 
            -
            # 1. { 'foo' => /bar/ }.to_json # => "{foo: /bar/}"
         | 
| 52 | 
            -
            #    This isn't valid JSON, because the regular expression syntax is not
         | 
| 53 | 
            -
            #    defined in RFC 4627. (And unquoted strings are disallowed there, too.)
         | 
| 54 | 
            -
            #    Though it is valid Javascript.
         | 
| 55 | 
            -
            #
         | 
| 56 | 
            -
            # 2. { 'foo' => /bar/mix }.to_json # => "{foo: /bar/mix}"
         | 
| 57 | 
            -
            #    This isn't even valid Javascript.
         | 
| 58 | 
            -
             | 
| 8 | 
            +
            $DEBUG and warn "required json/add/rails which is obsolete now!"
         | 
    
        data/lib/json/common.rb
    CHANGED
    
    | @@ -1,5 +1,4 @@ | |
| 1 1 | 
             
            require 'json/version'
         | 
| 2 | 
            -
            require 'iconv'
         | 
| 3 2 |  | 
| 4 3 | 
             
            module JSON
         | 
| 5 4 | 
             
              class << self
         | 
| @@ -24,7 +23,7 @@ module JSON | |
| 24 23 | 
             
                # Set the JSON parser class _parser_ to be used by JSON.
         | 
| 25 24 | 
             
                def parser=(parser) # :nodoc:
         | 
| 26 25 | 
             
                  @parser = parser
         | 
| 27 | 
            -
                  remove_const :Parser if  | 
| 26 | 
            +
                  remove_const :Parser if JSON.const_defined_in?(self, :Parser)
         | 
| 28 27 | 
             
                  const_set :Parser, parser
         | 
| 29 28 | 
             
                end
         | 
| 30 29 |  | 
| @@ -35,13 +34,13 @@ module JSON | |
| 35 34 | 
             
                def deep_const_get(path) # :nodoc:
         | 
| 36 35 | 
             
                  path.to_s.split(/::/).inject(Object) do |p, c|
         | 
| 37 36 | 
             
                    case
         | 
| 38 | 
            -
                    when c.empty? | 
| 39 | 
            -
                    when  | 
| 37 | 
            +
                    when c.empty?                     then p
         | 
| 38 | 
            +
                    when JSON.const_defined_in?(p, c) then p.const_get(c)
         | 
| 40 39 | 
             
                    else
         | 
| 41 40 | 
             
                      begin
         | 
| 42 41 | 
             
                        p.const_missing(c)
         | 
| 43 | 
            -
                      rescue NameError
         | 
| 44 | 
            -
                        raise ArgumentError, "can't  | 
| 42 | 
            +
                      rescue NameError => e
         | 
| 43 | 
            +
                        raise ArgumentError, "can't get const #{path}: #{e}"
         | 
| 45 44 | 
             
                      end
         | 
| 46 45 | 
             
                    end
         | 
| 47 46 | 
             
                  end
         | 
| @@ -49,6 +48,7 @@ module JSON | |
| 49 48 |  | 
| 50 49 | 
             
                # Set the module _generator_ to be used by JSON.
         | 
| 51 50 | 
             
                def generator=(generator) # :nodoc:
         | 
| 51 | 
            +
                  old, $VERBOSE = $VERBOSE, nil
         | 
| 52 52 | 
             
                  @generator = generator
         | 
| 53 53 | 
             
                  generator_methods = generator::GeneratorMethods
         | 
| 54 54 | 
             
                  for const in generator_methods.constants
         | 
| @@ -77,6 +77,8 @@ module JSON | |
| 77 77 | 
             
                    :object_nl      => "\n",
         | 
| 78 78 | 
             
                    :array_nl       => "\n"
         | 
| 79 79 | 
             
                  )
         | 
| 80 | 
            +
                ensure
         | 
| 81 | 
            +
                  $VERBOSE = old
         | 
| 80 82 | 
             
                end
         | 
| 81 83 |  | 
| 82 84 | 
             
                # Returns the JSON generator modul, that is used by JSON. This might be
         | 
| @@ -338,9 +340,35 @@ module JSON | |
| 338 340 | 
             
                raise ArgumentError, "exceed depth limit"
         | 
| 339 341 | 
             
              end
         | 
| 340 342 |  | 
| 343 | 
            +
              # Swap consecutive bytes of _string_ in place.
         | 
| 344 | 
            +
              def self.swap!(string) # :nodoc:
         | 
| 345 | 
            +
                0.upto(string.size / 2) do |i|
         | 
| 346 | 
            +
                  break unless string[2 * i + 1]
         | 
| 347 | 
            +
                  string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
         | 
| 348 | 
            +
                end
         | 
| 349 | 
            +
                string
         | 
| 350 | 
            +
              end
         | 
| 351 | 
            +
             | 
| 341 352 | 
             
              # Shortuct for iconv.
         | 
| 342 | 
            -
               | 
| 343 | 
            -
                 | 
| 353 | 
            +
              if ::String.method_defined?(:encode)
         | 
| 354 | 
            +
                def self.iconv(to, from, string)
         | 
| 355 | 
            +
                  string.encode(to, from)
         | 
| 356 | 
            +
                end
         | 
| 357 | 
            +
              else
         | 
| 358 | 
            +
                require 'iconv'
         | 
| 359 | 
            +
                def self.iconv(to, from, string)
         | 
| 360 | 
            +
                  Iconv.iconv(to, from, string).first
         | 
| 361 | 
            +
                end
         | 
| 362 | 
            +
              end
         | 
| 363 | 
            +
             | 
| 364 | 
            +
              if ::Object.method(:const_defined?).arity == 1
         | 
| 365 | 
            +
                def self.const_defined_in?(modul, constant)
         | 
| 366 | 
            +
                  modul.const_defined?(constant)
         | 
| 367 | 
            +
                end
         | 
| 368 | 
            +
              else
         | 
| 369 | 
            +
                def self.const_defined_in?(modul, constant)
         | 
| 370 | 
            +
                  modul.const_defined?(constant, false)
         | 
| 371 | 
            +
                end
         | 
| 344 372 | 
             
              end
         | 
| 345 373 | 
             
            end
         | 
| 346 374 |  | 
    
        data/lib/json/editor.rb
    CHANGED
    
    | @@ -2,7 +2,6 @@ | |
| 2 2 | 
             
            # requires ruby-gtk to be installed.
         | 
| 3 3 |  | 
| 4 4 | 
             
            require 'gtk2'
         | 
| 5 | 
            -
            require 'iconv'
         | 
| 6 5 | 
             
            require 'json'
         | 
| 7 6 | 
             
            require 'rbconfig'
         | 
| 8 7 | 
             
            require 'open-uri'
         | 
| @@ -1272,8 +1271,7 @@ module JSON | |
| 1272 1271 | 
             
                  def parse_json(json)
         | 
| 1273 1272 | 
             
                    check_pretty_printed(json)
         | 
| 1274 1273 | 
             
                    if @encoding && !/^utf8$/i.match(@encoding)
         | 
| 1275 | 
            -
                       | 
| 1276 | 
            -
                      json = iconverter.iconv(json)
         | 
| 1274 | 
            +
                      json = JSON.iconv 'utf-8', @encoding, json
         | 
| 1277 1275 | 
             
                    end
         | 
| 1278 1276 | 
             
                    JSON::parse(json, :max_nesting => false, :create_additions => false)
         | 
| 1279 1277 | 
             
                  end
         | 
    
        data/lib/json/ext.rb
    CHANGED
    
    | @@ -6,10 +6,10 @@ module JSON | |
| 6 6 | 
             
              module Ext
         | 
| 7 7 | 
             
                require 'json/ext/parser'
         | 
| 8 8 | 
             
                require 'json/ext/generator'
         | 
| 9 | 
            -
                $DEBUG and warn "Using  | 
| 9 | 
            +
                $DEBUG and warn "Using Ext extension for JSON."
         | 
| 10 10 | 
             
                JSON.parser = Parser
         | 
| 11 11 | 
             
                JSON.generator = Generator
         | 
| 12 12 | 
             
              end
         | 
| 13 13 |  | 
| 14 | 
            -
              JSON_LOADED = true
         | 
| 14 | 
            +
              JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
         | 
| 15 15 | 
             
            end
         | 
    
        data/lib/json/pure.rb
    CHANGED
    
    | @@ -3,75 +3,13 @@ require 'json/pure/parser' | |
| 3 3 | 
             
            require 'json/pure/generator'
         | 
| 4 4 |  | 
| 5 5 | 
             
            module JSON
         | 
| 6 | 
            -
              begin
         | 
| 7 | 
            -
                require 'iconv'
         | 
| 8 | 
            -
                # An iconv instance to convert from UTF8 to UTF16 Big Endian.
         | 
| 9 | 
            -
                UTF16toUTF8 = Iconv.new('utf-8', 'utf-16be') # :nodoc:
         | 
| 10 | 
            -
                # An iconv instance to convert from UTF16 Big Endian to UTF8.
         | 
| 11 | 
            -
                UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
         | 
| 12 | 
            -
                UTF8toUTF16.iconv('no bom')
         | 
| 13 | 
            -
              rescue LoadError
         | 
| 14 | 
            -
                raise MissingUnicodeSupport,
         | 
| 15 | 
            -
                  "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
         | 
| 16 | 
            -
              rescue Errno::EINVAL, Iconv::InvalidEncoding
         | 
| 17 | 
            -
                # Iconv doesn't support big endian utf-16. Let's try to hack this manually
         | 
| 18 | 
            -
                # into the converters.
         | 
| 19 | 
            -
                begin
         | 
| 20 | 
            -
                  old_verbose, $VERBSOSE = $VERBOSE, nil
         | 
| 21 | 
            -
                  # An iconv instance to convert from UTF8 to UTF16 Big Endian.
         | 
| 22 | 
            -
                  UTF16toUTF8 = Iconv.new('utf-8', 'utf-16') # :nodoc:
         | 
| 23 | 
            -
                  # An iconv instance to convert from UTF16 Big Endian to UTF8.
         | 
| 24 | 
            -
                  UTF8toUTF16 = Iconv.new('utf-16', 'utf-8') # :nodoc:
         | 
| 25 | 
            -
                  UTF8toUTF16.iconv('no bom')
         | 
| 26 | 
            -
                  if UTF8toUTF16.iconv("\xe2\x82\xac") == "\xac\x20"
         | 
| 27 | 
            -
                    swapper = Class.new do
         | 
| 28 | 
            -
                      def initialize(iconv) # :nodoc:
         | 
| 29 | 
            -
                        @iconv = iconv
         | 
| 30 | 
            -
                      end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                      def iconv(string) # :nodoc:
         | 
| 33 | 
            -
                        result = @iconv.iconv(string)
         | 
| 34 | 
            -
                        JSON.swap!(result)
         | 
| 35 | 
            -
                      end
         | 
| 36 | 
            -
                    end
         | 
| 37 | 
            -
                    UTF8toUTF16 = swapper.new(UTF8toUTF16) # :nodoc:
         | 
| 38 | 
            -
                  end
         | 
| 39 | 
            -
                  if UTF16toUTF8.iconv("\xac\x20") == "\xe2\x82\xac"
         | 
| 40 | 
            -
                    swapper = Class.new do
         | 
| 41 | 
            -
                      def initialize(iconv) # :nodoc:
         | 
| 42 | 
            -
                        @iconv = iconv
         | 
| 43 | 
            -
                      end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                      def iconv(string) # :nodoc:
         | 
| 46 | 
            -
                        string = JSON.swap!(string.dup)
         | 
| 47 | 
            -
                        @iconv.iconv(string)
         | 
| 48 | 
            -
                      end
         | 
| 49 | 
            -
                    end
         | 
| 50 | 
            -
                    UTF16toUTF8 = swapper.new(UTF16toUTF8) # :nodoc:
         | 
| 51 | 
            -
                  end
         | 
| 52 | 
            -
                rescue Errno::EINVAL, Iconv::InvalidEncoding
         | 
| 53 | 
            -
                  raise MissingUnicodeSupport, "iconv doesn't seem to support UTF-8/UTF-16 conversions"
         | 
| 54 | 
            -
                ensure
         | 
| 55 | 
            -
                  $VERBOSE = old_verbose
         | 
| 56 | 
            -
                end
         | 
| 57 | 
            -
              end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
              # Swap consecutive bytes of _string_ in place.
         | 
| 60 | 
            -
              def self.swap!(string) # :nodoc:
         | 
| 61 | 
            -
                0.upto(string.size / 2) do |i|
         | 
| 62 | 
            -
                  break unless string[2 * i + 1]
         | 
| 63 | 
            -
                  string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
         | 
| 64 | 
            -
                end
         | 
| 65 | 
            -
                string
         | 
| 66 | 
            -
              end
         | 
| 67 | 
            -
             | 
| 68 6 | 
             
              # This module holds all the modules/classes that implement JSON's
         | 
| 69 7 | 
             
              # functionality in pure ruby.
         | 
| 70 8 | 
             
              module Pure
         | 
| 71 | 
            -
                $DEBUG and warn "Using  | 
| 9 | 
            +
                $DEBUG and warn "Using Pure library for JSON."
         | 
| 72 10 | 
             
                JSON.parser = Parser
         | 
| 73 11 | 
             
                JSON.generator = Generator
         | 
| 74 12 | 
             
              end
         | 
| 75 13 |  | 
| 76 | 
            -
              JSON_LOADED = true
         | 
| 14 | 
            +
              JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
         | 
| 77 15 | 
             
            end
         | 
    
        data/lib/json/pure/generator.rb
    CHANGED
    
    | @@ -62,12 +62,12 @@ module JSON | |
| 62 62 | 
             
                                  [\x80-\xc1\xf5-\xff]       # invalid
         | 
| 63 63 | 
             
                                )/nx) { |c|
         | 
| 64 64 | 
             
                                  c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
         | 
| 65 | 
            -
                                  s = JSON | 
| 65 | 
            +
                                  s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
         | 
| 66 66 | 
             
                                  s.gsub!(/.{4}/n, '\\\\u\&')
         | 
| 67 67 | 
             
                                }
         | 
| 68 68 | 
             
                  string.force_encoding(::Encoding::UTF_8)
         | 
| 69 69 | 
             
                  string
         | 
| 70 | 
            -
                rescue  | 
| 70 | 
            +
                rescue => e
         | 
| 71 71 | 
             
                  raise GeneratorError, "Caught #{e.class}: #{e}"
         | 
| 72 72 | 
             
                end
         | 
| 73 73 | 
             
              else
         | 
| @@ -86,11 +86,11 @@ module JSON | |
| 86 86 | 
             
                                  [\x80-\xc1\xf5-\xff]       # invalid
         | 
| 87 87 | 
             
                                )/nx) { |c|
         | 
| 88 88 | 
             
                    c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
         | 
| 89 | 
            -
                    s = JSON | 
| 89 | 
            +
                    s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
         | 
| 90 90 | 
             
                    s.gsub!(/.{4}/n, '\\\\u\&')
         | 
| 91 91 | 
             
                  }
         | 
| 92 92 | 
             
                  string
         | 
| 93 | 
            -
                rescue  | 
| 93 | 
            +
                rescue => e
         | 
| 94 94 | 
             
                  raise GeneratorError, "Caught #{e.class}: #{e}"
         | 
| 95 95 | 
             
                end
         | 
| 96 96 | 
             
              end
         | 
| @@ -106,11 +106,13 @@ module JSON | |
| 106 106 | 
             
                    # an unconfigured instance. If _opts_ is a State object, it is just
         | 
| 107 107 | 
             
                    # returned.
         | 
| 108 108 | 
             
                    def self.from_state(opts)
         | 
| 109 | 
            -
                      case | 
| 110 | 
            -
                      when self
         | 
| 109 | 
            +
                      case
         | 
| 110 | 
            +
                      when self === opts
         | 
| 111 111 | 
             
                        opts
         | 
| 112 | 
            -
                      when  | 
| 113 | 
            -
                        new(opts)
         | 
| 112 | 
            +
                      when opts.respond_to?(:to_hash)
         | 
| 113 | 
            +
                        new(opts.to_hash)
         | 
| 114 | 
            +
                      when opts.respond_to?(:to_h)
         | 
| 115 | 
            +
                        new(opts.to_h)
         | 
| 114 116 | 
             
                      else
         | 
| 115 117 | 
             
                        SAFE_STATE_PROTOTYPE.dup
         | 
| 116 118 | 
             
                      end
         | 
    
        data/lib/json/pure/parser.rb
    CHANGED
    
    | @@ -113,13 +113,13 @@ module JSON | |
| 113 113 | 
             
                    else
         | 
| 114 114 | 
             
                      @max_nesting = 0
         | 
| 115 115 | 
             
                    end
         | 
| 116 | 
            -
                    @allow_nan | 
| 117 | 
            -
                    @symbolize_names | 
| 118 | 
            -
                     | 
| 119 | 
            -
                     | 
| 120 | 
            -
                    @ | 
| 121 | 
            -
                    @ | 
| 122 | 
            -
                    @ | 
| 116 | 
            +
                    @allow_nan        = !!opts[:allow_nan]
         | 
| 117 | 
            +
                    @symbolize_names  = !!opts[:symbolize_names]
         | 
| 118 | 
            +
                    @create_additions = opts.key?(:create_additions) ? !!opts[:create_additions] : true
         | 
| 119 | 
            +
                    @create_id        = opts[:create_id] || JSON.create_id
         | 
| 120 | 
            +
                    @object_class     = opts[:object_class] || Hash
         | 
| 121 | 
            +
                    @array_class      = opts[:array_class] || Array
         | 
| 122 | 
            +
                    @match_string     = opts[:match_string]
         | 
| 123 123 | 
             
                  end
         | 
| 124 124 |  | 
| 125 125 | 
             
                  alias source string
         | 
| @@ -165,6 +165,11 @@ module JSON | |
| 165 165 | 
             
                    ?u  => nil, 
         | 
| 166 166 | 
             
                  })
         | 
| 167 167 |  | 
| 168 | 
            +
                  EMPTY_8BIT_STRING = ''
         | 
| 169 | 
            +
                  if ::String.method_defined?(:encode)
         | 
| 170 | 
            +
                    EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT 
         | 
| 171 | 
            +
                  end
         | 
| 172 | 
            +
             | 
| 168 173 | 
             
                  def parse_string
         | 
| 169 174 | 
             
                    if scan(STRING)
         | 
| 170 175 | 
             
                      return '' if self[1].empty?
         | 
| @@ -172,24 +177,30 @@ module JSON | |
| 172 177 | 
             
                        if u = UNESCAPE_MAP[$&[1]]
         | 
| 173 178 | 
             
                          u
         | 
| 174 179 | 
             
                        else # \uXXXX
         | 
| 175 | 
            -
                          bytes =  | 
| 180 | 
            +
                          bytes = EMPTY_8BIT_STRING.dup
         | 
| 176 181 | 
             
                          i = 0
         | 
| 177 182 | 
             
                          while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
         | 
| 178 183 | 
             
                            bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
         | 
| 179 184 | 
             
                            i += 1
         | 
| 180 185 | 
             
                          end
         | 
| 181 | 
            -
                          JSON | 
| 186 | 
            +
                          JSON.iconv('utf-8', 'utf-16be', bytes)
         | 
| 182 187 | 
             
                        end
         | 
| 183 188 | 
             
                      end
         | 
| 184 189 | 
             
                      if string.respond_to?(:force_encoding)
         | 
| 185 190 | 
             
                        string.force_encoding(::Encoding::UTF_8)
         | 
| 186 191 | 
             
                      end
         | 
| 192 | 
            +
                      if @create_additions and @match_string
         | 
| 193 | 
            +
                        for (regexp, klass) in @match_string
         | 
| 194 | 
            +
                          klass.json_creatable? or next
         | 
| 195 | 
            +
                          string =~ regexp and return klass.json_create(string)
         | 
| 196 | 
            +
                        end
         | 
| 197 | 
            +
                      end
         | 
| 187 198 | 
             
                      string
         | 
| 188 199 | 
             
                    else
         | 
| 189 200 | 
             
                      UNPARSED
         | 
| 190 201 | 
             
                    end
         | 
| 191 | 
            -
                  rescue  | 
| 192 | 
            -
                    raise  | 
| 202 | 
            +
                  rescue => e
         | 
| 203 | 
            +
                    raise ParserError, "Caught #{e.class} at '#{peek(20)}': #{e}"
         | 
| 193 204 | 
             
                  end
         | 
| 194 205 |  | 
| 195 206 | 
             
                  def parse_value
         | 
| @@ -290,7 +301,7 @@ module JSON | |
| 290 301 | 
             
                        if delim
         | 
| 291 302 | 
             
                          raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
         | 
| 292 303 | 
             
                        end
         | 
| 293 | 
            -
                        if @ | 
| 304 | 
            +
                        if @create_additions and klassname = result[@create_id]
         | 
| 294 305 | 
             
                          klass = JSON.deep_const_get klassname
         | 
| 295 306 | 
             
                          break unless klass and klass.json_creatable?
         | 
| 296 307 | 
             
                          result = klass.json_create(result)
         | 
    
        data/lib/json/version.rb
    CHANGED
    
    
    
        data/tests/test_json.rb
    CHANGED
    
    | @@ -2,11 +2,7 @@ | |
| 2 2 | 
             
            # -*- coding: utf-8 -*-
         | 
| 3 3 |  | 
| 4 4 | 
             
            require 'test/unit'
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            when 'pure' then require 'json/pure'
         | 
| 7 | 
            -
            when 'ext'  then require 'json/ext'
         | 
| 8 | 
            -
            else             require 'json'
         | 
| 9 | 
            -
            end
         | 
| 5 | 
            +
            require File.join(File.dirname(__FILE__), 'setup_variant')
         | 
| 10 6 | 
             
            require 'stringio'
         | 
| 11 7 |  | 
| 12 8 | 
             
            unless Array.method_defined?(:permutation)
         |