{-# LANGUAGE ScopedTypeVariables , UnicodeSyntax #-} module Text.HyperEstraier.Utils ( withUTF8CString , withUTF8CString' , packMallocUTF8CString , peekUTF8CString , marshalOpts , withArrayOfPtrs ) where import Data.Bits import qualified Data.ByteString as B import qualified Data.ByteString.Unsafe as B import qualified Data.Text as T import Data.Text.Encoding import Foreign.C.String import Foreign.Marshal.Array import Foreign.Ptr import Prelude.Unicode withUTF8CString ∷ T.Text → (CString → IO a) → IO a {-# INLINE withUTF8CString #-} withUTF8CString = B.useAsCString ∘ encodeUtf8 withUTF8CString' ∷ Maybe T.Text → (CString → IO a) → IO a {-# INLINE withUTF8CString' #-} withUTF8CString' (Just str) f = B.useAsCString (encodeUtf8 str) f withUTF8CString' Nothing f = f nullPtr packMallocUTF8CString ∷ CString → IO T.Text {-# INLINE packMallocUTF8CString #-} packMallocUTF8CString = fmap decodeUtf8 ∘ B.unsafePackMallocCString peekUTF8CString ∷ CString → IO T.Text {-# INLINE peekUTF8CString #-} peekUTF8CString = fmap decodeUtf8 ∘ B.packCString marshalOpts ∷ Bits b => (a → b) → [a] → b {-# INLINE marshalOpts #-} marshalOpts = (foldl (.|.) 0 .) ∘ map withArrayOfPtrs ∷ ∀a b c. (a → (Ptr b → IO c) → IO c) → [a] → (Ptr (Ptr b) → IO c) → IO c {-# INLINEABLE withArrayOfPtrs #-} withArrayOfPtrs withXPtr xs f = withXPtrList xs [] $ flip withArray f where withXPtrList ∷ [a] → [Ptr b] → ([Ptr b] → IO c) → IO c withXPtrList [] acc g = g (reverse acc) withXPtrList (y:ys) acc g = withXPtr y $ \xPtr → withXPtrList ys (xPtr:acc) g