diff options
author | Florian Frank <flori@ping.de> | 2009-10-15 21:02:49 +0200 |
---|---|---|
committer | Florian Frank <flori@ping.de> | 2009-10-16 21:51:09 +0200 |
commit | 03b157516fa22ac135496a3831963f8305f7a0bb (patch) | |
tree | cd16481453ac694256e8177caf0f7b9047670aa0 /lib | |
parent | d9f9557594840b0381007d2dad769d473adc59f3 (diff) | |
download | json-03b157516fa22ac135496a3831963f8305f7a0bb.tar.gz |
implemented utf sniffing, transcoding in parser
improved documentation
added to changes
Diffstat (limited to 'lib')
-rw-r--r-- | lib/json/common.rb | 6 | ||||
-rw-r--r-- | lib/json/pure/parser.rb | 36 |
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] |