on master help sign in
Move ffi/pure implementations into separate folders.
commitf16a7f517edc7e8e9af688b7cd05da9d8ba867f8 authorJames Parker <dev@jamesparker.me> dateWed 15 Feb 2017, 23:57 (10 years ago) parenta0a3e63
3 files changed+55−57
aeson.cabal+4−1 ffi/Data/Aeson/Parser/Unescape.hs+51 Data/Aeson/Parser/Unescape.hs → pure/Data/Aeson/Parser/Unescape.hs−56
aeson.cabal+4−1
@@ -155,9 +155,12 @@ library
155155 ghc-options: -O2
156156
157157 include-dirs: include
158− if flag(cffi)
158+ if impl(ghcjs) || !flag(cffi)
159+ hs-source-dirs: . pure
160+ else
159161 c-sources: cbits/unescape_string.c
160162 cpp-options: -DCFFI
163+ hs-source-dirs: . ffi
161164
162165test-suite tests
163166 default-language: Haskell2010
ffi/Data/Aeson/Parser/Unescape.hsnew file+51
@@ -0,0 +1,51 @@
1+{-# LANGUAGE ForeignFunctionInterface #-}
2+{-# LANGUAGE MagicHash #-}
3+{-# LANGUAGE UnliftedFFITypes #-}
4+
5+module Data.Aeson.Parser.Unescape (
6+ unescapeText
7+) where
8+
9+import Control.Exception (evaluate, throw, try)
10+import Control.Monad.ST.Unsafe (unsafeIOToST, unsafeSTToIO)
11+import Data.ByteString as B
12+import Data.ByteString.Internal as B hiding (c2w)
13+import qualified Data.Text.Array as A
14+import Data.Text.Encoding.Error (UnicodeException (..))
15+import Data.Text.Internal (Text (..))
16+import Data.Text.Internal.Private (runText)
17+import Data.Text.Unsafe (unsafeDupablePerformIO)
18+import Data.Word (Word8)
19+import Foreign.C.Types (CInt (..), CSize (..))
20+import Foreign.ForeignPtr (withForeignPtr)
21+import Foreign.Marshal.Utils (with)
22+import Foreign.Ptr (Ptr, plusPtr)
23+import Foreign.Storable (peek)
24+import GHC.Base (MutableByteArray#)
25+
26+foreign import ccall unsafe "_js_decode_string" c_js_decode
27+ :: MutableByteArray# s -> Ptr CSize
28+ -> Ptr Word8 -> Ptr Word8 -> IO CInt
29+
30+unescapeText' :: ByteString -> Text
31+unescapeText' (PS fp off len) = runText $ \done -> do
32+ let go dest = withForeignPtr fp $ \ptr ->
33+ with (0::CSize) $ \destOffPtr -> do
34+ let end = ptr `plusPtr` (off + len)
35+ loop curPtr = do
36+ res <- c_js_decode (A.maBA dest) destOffPtr curPtr end
37+ case res of
38+ 0 -> do
39+ n <- peek destOffPtr
40+ unsafeSTToIO (done dest (fromIntegral n))
41+ _ ->
42+ throw (DecodeError desc Nothing)
43+ loop (ptr `plusPtr` off)
44+ (unsafeIOToST . go) =<< A.new len
45+ where
46+ desc = "Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream"
47+{-# INLINE unescapeText' #-}
48+
49+unescapeText :: ByteString -> Either UnicodeException Text
50+unescapeText = unsafeDupablePerformIO . try . evaluate . unescapeText'
51+{-# INLINE unescapeText #-}
Data/Aeson/Parser/Unescape.hs → pure/Data/Aeson/Parser/Unescape.hsrenamed−56
@@ -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 #-}