Bryan O'Sullivan avatar Bryan O'Sullivan committed 4fcfb59

Backed out changeset daedec26ae9d

Comments (0)

Files changed (1)

Data/Aeson/Parser.hs

     , value
     ) where
 
-import Blaze.ByteString.Builder
-import Blaze.ByteString.Builder.Char.Utf8
-import Data.Monoid (Monoid(..))
 import Control.Applicative as A
 import Data.Aeson.Types (Value(..))
 import Data.Attoparsec.Char8
 import Data.Bits (shiftL)
 import Data.ByteString as B
-import Data.ByteString.Unsafe as B
 import Data.Char (chr)
 import Data.Map as Map
 import Data.Text as T
-import Data.Text.Encoding (decodeUtf8)
+import Data.Text.Encoding (decodeUtf8, encodeUtf8)
 import Data.Vector as Vector hiding ((++))
 import Data.Word (Word8)
 import qualified Data.Attoparsec as A
                                         then Nothing
                                         else Just (c == backslash)
   _ <- A.word8 doubleQuote
-  decodeUtf8 <$> reparse unescape s
+  (decodeUtf8 . B.concat) <$> reparse unescape s
 
 reparse :: Parser a -> ByteString -> Parser a
 reparse p s = case (case parse p s of {Partial k -> k ""; r -> r}) of
                 Fail _ _ msg -> fail msg
                 _            -> fail "unexpected failure"
 
-unescape :: Parser ByteString
-unescape = toByteString <$> go mempty where
-  go bld = do
+unescape :: Parser [ByteString]
+unescape = Prelude.reverse <$> go [] where
+  go acc = do
     let backslash = 92
     h <- A.takeWhile (/=backslash)
     let rest = do
           w <- A.word8 backslash *> A.satisfy (`B.elem` "\"\\/ntbrfu")
           case B.findIndex (==w) "\"\\/ntbrf" of
-            Just i  -> go (bld `mappend` fromByteString h `mappend` fromWord8 (B.unsafeIndex "\"\\/\n\t\b\r\f" i))
+            Just i  -> go (B.singleton (B.index "\"\\/\n\t\b\r\f" i):h:acc)
             Nothing -> do
                  a <- reparse hexadecimal =<< A.take 4
                  if a < 0xd800 || a > 0xdfff
-                   then go (bld `mappend` fromByteString h `mappend` fromChar (chr a))
+                   then go (encodeUtf8 (T.singleton . chr $ a):h:acc)
                    else do
                      b <- string "\\u" *> (reparse hexadecimal =<< A.take 4)
                      if a <= 0xdbff && b >= 0xdc00 && b <= 0xdfff
                        then let c = ((a - 0xd800) `shiftL` 10) + (b - 0xdc00) +
                                     0x10000
-                            in go (bld `mappend` fromByteString h `mappend` fromChar (chr c))
+                            in go (encodeUtf8 (T.singleton . chr $ c):h:acc)
                        else fail "invalid UTF-16 surrogates"
-    rest <|> return (bld `mappend` fromByteString h)
+    rest <|> return (h:acc)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.