@@ -1,17 +1,7 @@
1−{-# LANGUAGE CPP #-}
2−
3−#ifdef CFFI
4−{-# LANGUAGE ForeignFunctionInterface #-}
5−{-# LANGUAGE MagicHash #-}
6−{-# LANGUAGE UnliftedFFITypes #-}
7−#endif
8−
91module Data.Aeson.Parser.Unescape (
102 unescapeText
113) where
124
13−#ifndef CFFI
14−
155import Control.Exception (evaluate, throw, try)
166import Control.Monad (when)
177import Data.ByteString as B
@@ -276,52 +266,6 @@ throwDecodeError =
276266 throw (DecodeError desc Nothing)
277267{-# INLINE throwDecodeError #-}
278268
279−
280−#else
281−-- FFI version.
282−
283−import Control.Exception (evaluate, throw, try)
284−import Control.Monad.ST.Unsafe (unsafeIOToST, unsafeSTToIO)
285−import Data.ByteString as B
286−import Data.ByteString.Internal as B hiding (c2w)
287−import qualified Data.Text.Array as A
288−import Data.Text.Encoding.Error (UnicodeException (..))
289−import Data.Text.Internal (Text (..))
290−import Data.Text.Internal.Private (runText)
291−import Data.Text.Unsafe (unsafeDupablePerformIO)
292−import Data.Word (Word8)
293−import Foreign.C.Types (CInt (..), CSize (..))
294−import Foreign.ForeignPtr (withForeignPtr)
295−import Foreign.Marshal.Utils (with)
296−import Foreign.Ptr (Ptr, plusPtr)
297−import Foreign.Storable (peek)
298−import GHC.Base (MutableByteArray#)
299−
300−foreign import ccall unsafe "_js_decode_string" c_js_decode
301− :: MutableByteArray# s -> Ptr CSize
302− -> Ptr Word8 -> Ptr Word8 -> IO CInt
303−
304−unescapeText' :: ByteString -> Text
305−unescapeText' (PS fp off len) = runText $ \done -> do
306− let go dest = withForeignPtr fp $ \ptr ->
307− with (0::CSize) $ \destOffPtr -> do
308− let end = ptr `plusPtr` (off + len)
309− loop curPtr = do
310− res <- c_js_decode (A.maBA dest) destOffPtr curPtr end
311− case res of
312− 0 -> do
313− n <- peek destOffPtr
314− unsafeSTToIO (done dest (fromIntegral n))
315− _ ->
316− throw (DecodeError desc Nothing)
317− loop (ptr `plusPtr` off)
318− (unsafeIOToST . go) =<< A.new len
319− where
320− desc = "Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream"
321−{-# INLINE unescapeText' #-}
322−
323−#endif
324−
325269unescapeText :: ByteString -> Either UnicodeException Text
326270unescapeText = unsafeDupablePerformIO . try . evaluate . unescapeText'
327271{-# INLINE unescapeText #-}