summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Frank <flori@ping.de>2010-12-31 18:19:36 +0100
committerFlorian Frank <flori@ping.de>2011-01-02 21:13:44 +0100
commit51eb5f8cac8f1a44f503dbeaef027a907c4ac23a (patch)
treefd5e87ea38115db96bfdfcd4fd7ed3ba20a84fc6
parent632804116e13931ffbb41fe4b3916428c911b2c6 (diff)
downloadjson-51eb5f8cac8f1a44f503dbeaef027a907c4ac23a.tar.gz
use JSON.iconv abstraction
-rw-r--r--lib/json/common.rb9
-rw-r--r--lib/json/editor.rb4
-rw-r--r--lib/json/pure.rb62
-rw-r--r--lib/json/pure/generator.rb8
-rw-r--r--lib/json/pure/parser.rb6
-rwxr-xr-xtests/test_json_fixtures.rb11
6 files changed, 25 insertions, 75 deletions
diff --git a/lib/json/common.rb b/lib/json/common.rb
index 13debd1..1ca53cb 100644
--- a/lib/json/common.rb
+++ b/lib/json/common.rb
@@ -340,6 +340,15 @@ 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
+
# Shortuct for iconv.
if String.method_defined?(:encode)
def self.iconv(to, from, string)
diff --git a/lib/json/editor.rb b/lib/json/editor.rb
index 1e13f33..3450455 100644
--- a/lib/json/editor.rb
+++ b/lib/json/editor.rb
@@ -2,7 +2,6 @@
# requires ruby-gtk to be installed.
require 'gtk2'
-require 'iconv'
require 'json'
require 'rbconfig'
require 'open-uri'
@@ -1272,8 +1271,7 @@ module JSON
def parse_json(json)
check_pretty_printed(json)
if @encoding && !/^utf8$/i.match(@encoding)
- iconverter = Iconv.new('utf8', @encoding)
- json = iconverter.iconv(json)
+ json = JSON.iconv 'utf-8', @encoding, json
end
JSON::parse(json, :max_nesting => false, :create_additions => false)
end
diff --git a/lib/json/pure.rb b/lib/json/pure.rb
index 08efa83..f7ee3df 100644
--- a/lib/json/pure.rb
+++ b/lib/json/pure.rb
@@ -3,68 +3,6 @@ require 'json/pure/parser'
require 'json/pure/generator'
module JSON
- begin
- require 'iconv'
- # An iconv instance to convert from UTF8 to UTF16 Big Endian.
- UTF16toUTF8 = Iconv.new('utf-8', 'utf-16be') # :nodoc:
- # An iconv instance to convert from UTF16 Big Endian to UTF8.
- UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
- UTF8toUTF16.iconv('no bom')
- rescue LoadError
- raise MissingUnicodeSupport,
- "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
- rescue Errno::EINVAL, Iconv::InvalidEncoding
- # Iconv doesn't support big endian utf-16. Let's try to hack this manually
- # into the converters.
- begin
- old_verbose, $VERBSOSE = $VERBOSE, nil
- # An iconv instance to convert from UTF8 to UTF16 Big Endian.
- UTF16toUTF8 = Iconv.new('utf-8', 'utf-16') # :nodoc:
- # An iconv instance to convert from UTF16 Big Endian to UTF8.
- UTF8toUTF16 = Iconv.new('utf-16', 'utf-8') # :nodoc:
- UTF8toUTF16.iconv('no bom')
- if UTF8toUTF16.iconv("\xe2\x82\xac") == "\xac\x20"
- swapper = Class.new do
- def initialize(iconv) # :nodoc:
- @iconv = iconv
- end
-
- def iconv(string) # :nodoc:
- result = @iconv.iconv(string)
- JSON.swap!(result)
- end
- end
- UTF8toUTF16 = swapper.new(UTF8toUTF16) # :nodoc:
- end
- if UTF16toUTF8.iconv("\xac\x20") == "\xe2\x82\xac"
- swapper = Class.new do
- def initialize(iconv) # :nodoc:
- @iconv = iconv
- end
-
- def iconv(string) # :nodoc:
- string = JSON.swap!(string.dup)
- @iconv.iconv(string)
- end
- end
- UTF16toUTF8 = swapper.new(UTF16toUTF8) # :nodoc:
- end
- rescue Errno::EINVAL, Iconv::InvalidEncoding
- raise MissingUnicodeSupport, "iconv doesn't seem to support UTF-8/UTF-16 conversions"
- ensure
- $VERBOSE = old_verbose
- end
- 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
-
# This module holds all the modules/classes that implement JSON's
# functionality in pure ruby.
module Pure
diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb
index 94cb239..44cca60 100644
--- a/lib/json/pure/generator.rb
+++ b/lib/json/pure/generator.rb
@@ -62,12 +62,12 @@ module JSON
[\x80-\xc1\xf5-\xff] # invalid
)/nx) { |c|
c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
- s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
+ s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
s.gsub!(/.{4}/n, '\\\\u\&')
}
string.force_encoding(::Encoding::UTF_8)
string
- rescue Iconv::Failure => e
+ rescue => e
raise GeneratorError, "Caught #{e.class}: #{e}"
end
else
@@ -86,11 +86,11 @@ module JSON
[\x80-\xc1\xf5-\xff] # invalid
)/nx) { |c|
c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
- s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
+ s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
s.gsub!(/.{4}/n, '\\\\u\&')
}
string
- rescue Iconv::Failure => e
+ rescue => e
raise GeneratorError, "Caught #{e.class}: #{e}"
end
end
diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb
index 844931b..c166749 100644
--- a/lib/json/pure/parser.rb
+++ b/lib/json/pure/parser.rb
@@ -178,7 +178,7 @@ module JSON
bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
i += 1
end
- JSON::UTF16toUTF8.iconv(bytes)
+ JSON.iconv('utf-8', 'utf-16be', bytes)
end
end
if string.respond_to?(:force_encoding)
@@ -188,8 +188,8 @@ module JSON
else
UNPARSED
end
- rescue Iconv::Failure => e
- raise GeneratorError, "Caught #{e.class}: #{e}"
+ rescue => e
+ raise ParserError, "Caught #{e.class}: #{e}"
end
def parse_value
diff --git a/tests/test_json_fixtures.rb b/tests/test_json_fixtures.rb
index 95e57eb..378667f 100755
--- a/tests/test_json_fixtures.rb
+++ b/tests/test_json_fixtures.rb
@@ -18,15 +18,20 @@ class TC_JSONFixtures < Test::Unit::TestCase
def test_passing
for name, source in @passed
- assert JSON.parse(source),
- "Did not pass for fixture '#{name}'"
+ begin
+ assert JSON.parse(source),
+ "Did not pass for fixture '#{name}': #{source.inspect}"
+ rescue => e
+ warn "\nCaught #{e.class}(#{e}) for fixture '#{name}': #{source.inspect}\n#{e.backtrace * "\n"}"
+ raise e
+ end
end
end
def test_failing
for name, source in @failed
assert_raises(JSON::ParserError, JSON::NestingError,
- "Did not fail for fixture '#{name}'") do
+ "Did not fail for fixture '#{name}': #{source.inspect}") do
JSON.parse(source)
end
end