on master help sign in
Backed out changeset daedec26ae9d
3fbe8daBryan O'Sullivan
Data/Aeson/Parser.hs+9−13
@@ -6,19 +6,15 @@ module Data.Aeson.Parser
6 , value
6 , value
7 ) where
7 ) where
8
8
9−import Blaze.ByteString.Builder
10−import Blaze.ByteString.Builder.Char.Utf8
11−import Data.Monoid (Monoid(..))
12import Control.Applicative as A
9import Control.Applicative as A
13import Data.Aeson.Types (Value(..))
10import Data.Aeson.Types (Value(..))
14import Data.Attoparsec.Char8
11import Data.Attoparsec.Char8
15import Data.Bits (shiftL)
12import Data.Bits (shiftL)
16import Data.ByteString as B
13import Data.ByteString as B
17−import Data.ByteString.Unsafe as B
18import Data.Char (chr)
14import Data.Char (chr)
19import Data.Map as Map
15import Data.Map as Map
20import Data.Text as T
16import Data.Text as T
21−import Data.Text.Encoding (decodeUtf8)
17+import Data.Text.Encoding (decodeUtf8, encodeUtf8)
22import Data.Vector as Vector hiding ((++))
18import Data.Vector as Vector hiding ((++))
23import Data.Word (Word8)
19import Data.Word (Word8)
24import qualified Data.Attoparsec as A
20import qualified Data.Attoparsec as A
@@ -71,7 +67,7 @@ jstring_ = do
71 then Nothing
67 then Nothing
72 else Just (c == backslash)
68 else Just (c == backslash)
73 _ <- A.word8 doubleQuote
69 _ <- A.word8 doubleQuote
74− decodeUtf8 <$> reparse unescape s
70+ (decodeUtf8 . B.concat) <$> reparse unescape s
75
71
76reparse :: Parser a -> ByteString -> Parser a
72reparse :: Parser a -> ByteString -> Parser a
77reparse p s = case (case parse p s of {Partial k -> k ""; r -> r}) of
73reparse p s = case (case parse p s of {Partial k -> k ""; r -> r}) of
@@ -79,24 +75,24 @@ reparse p s = case (case parse p s of {Partial k -> k ""; r -> r}) of
79 Fail _ _ msg -> fail msg
75 Fail _ _ msg -> fail msg
80 _ -> fail "unexpected failure"
76 _ -> fail "unexpected failure"
81
77
82−unescape :: Parser ByteString
78+unescape :: Parser [ByteString]
83−unescape = toByteString <$> go mempty where
79+unescape = Prelude.reverse <$> go [] where
84− go bld = do
80+ go acc = do
85 let backslash = 92
81 let backslash = 92
86 h <- A.takeWhile (/=backslash)
82 h <- A.takeWhile (/=backslash)
87 let rest = do
83 let rest = do
88 w <- A.word8 backslash *> A.satisfy (`B.elem` "\"\\/ntbrfu")
84 w <- A.word8 backslash *> A.satisfy (`B.elem` "\"\\/ntbrfu")
89 case B.findIndex (==w) "\"\\/ntbrf" of
85 case B.findIndex (==w) "\"\\/ntbrf" of
90− Just i -> go (bld `mappend` fromByteString h `mappend` fromWord8 (B.unsafeIndex "\"\\/\n\t\b\r\f" i))
86+ Just i -> go (B.singleton (B.index "\"\\/\n\t\b\r\f" i):h:acc)
91 Nothing -> do
87 Nothing -> do
92 a <- reparse hexadecimal =<< A.take 4
88 a <- reparse hexadecimal =<< A.take 4
93 if a < 0xd800 || a > 0xdfff
89 if a < 0xd800 || a > 0xdfff
94− then go (bld `mappend` fromByteString h `mappend` fromChar (chr a))
90+ then go (encodeUtf8 (T.singleton . chr $ a):h:acc)
95 else do
91 else do
96 b <- string "\\u" *> (reparse hexadecimal =<< A.take 4)
92 b <- string "\\u" *> (reparse hexadecimal =<< A.take 4)
97 if a <= 0xdbff && b >= 0xdc00 && b <= 0xdfff
93 if a <= 0xdbff && b >= 0xdc00 && b <= 0xdfff
98 then let c = ((a - 0xd800) `shiftL` 10) + (b - 0xdc00) +
94 then let c = ((a - 0xd800) `shiftL` 10) + (b - 0xdc00) +
99 0x10000
95 0x10000
100− in go (bld `mappend` fromByteString h `mappend` fromChar (chr c))
96+ in go (encodeUtf8 (T.singleton . chr $ c):h:acc)
101 else fail "invalid UTF-16 surrogates"
97 else fail "invalid UTF-16 surrogates"
102− rest <|> return (bld `mappend` fromByteString h)
98+ rest <|> return (h:acc)