summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFlorian Frank <flori@ping.de>2009-10-15 21:02:49 +0200
committerFlorian Frank <flori@ping.de>2009-10-16 21:51:09 +0200
commit03b157516fa22ac135496a3831963f8305f7a0bb (patch)
treecd16481453ac694256e8177caf0f7b9047670aa0 /lib
parentd9f9557594840b0381007d2dad769d473adc59f3 (diff)
downloadjson-03b157516fa22ac135496a3831963f8305f7a0bb.tar.gz
implemented utf sniffing, transcoding in parser
improved documentation added to changes
Diffstat (limited to 'lib')
-rw-r--r--lib/json/common.rb6
-rw-r--r--lib/json/pure/parser.rb36
2 files changed, 41 insertions, 1 deletions
diff --git a/lib/json/common.rb b/lib/json/common.rb
index c7808fb..39f6336 100644
--- a/lib/json/common.rb
+++ b/lib/json/common.rb
@@ -1,4 +1,5 @@
require 'json/version'
+require 'iconv'
module JSON
class << self
@@ -316,6 +317,11 @@ module JSON
rescue JSON::NestingError
raise ArgumentError, "exceed depth limit"
end
+
+ # Shortuct for iconv.
+ def self.iconv(to, from, string)
+ Iconv.iconv(to, from, string).first
+ end
end
module ::Kernel
diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb
index 7e8fe08..7a09f2f 100644
--- a/lib/json/pure/parser.rb
+++ b/lib/json/pure/parser.rb
@@ -66,7 +66,41 @@ module JSON
# * *object_class*: Defaults to Hash
# * *array_class*: Defaults to Array
def initialize(source, opts = {})
- super
+ if defined?(::Encoding)
+ if source.encoding == Encoding::ASCII_8BIT
+ b = source[0, 4].bytes.to_a
+ source = case
+ when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
+ source.dup.force_encoding(Encoding::UTF_32BE).encode!(Encoding::UTF_8)
+ when b.size >= 4 && b[0] == 0 && b[2] == 0
+ source.dup.force_encoding(Encoding::UTF_16BE).encode!(Encoding::UTF_8)
+ when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
+ source.dup.force_encoding(Encoding::UTF_32LE).encode!(Encoding::UTF_8)
+ when b.size >= 4 && b[1] == 0 && b[3] == 0
+ source.dup.force_encoding(Encoding::UTF_16LE).encode!(Encoding::UTF_8)
+ else
+ source.dup
+ end
+ else
+ source = source.encode(Encoding::UTF_8)
+ end
+ source.force_encoding(Encoding::ASCII_8BIT)
+ else
+ b = source
+ source = case
+ when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
+ JSON.iconv('utf-8', 'utf-32be', b)
+ when b.size >= 4 && b[0] == 0 && b[2] == 0
+ JSON.iconv('utf-8', 'utf-16be', b)
+ when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
+ JSON.iconv('utf-8', 'utf-32le', b)
+ when b.size >= 4 && b[1] == 0 && b[3] == 0
+ JSON.iconv('utf-8', 'utf-16le', b)
+ else
+ b
+ end
+ end
+ super source
if !opts.key?(:max_nesting) # defaults to 19
@max_nesting = 19
elsif opts[:max_nesting]