marshal-contt 0.1.1.0 → 0.1.2.0
raw patch · 3 files changed
+55/−33 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Foreign.Marshal.ContT: bracketContT :: (a -> IO b) -> (a -> IO c) -> ContT r IO a -> ContT r IO a
+ Foreign.Marshal.ContT: data Ptr a
+ Foreign.Marshal.ContT: nullPtr :: () => Ptr a
+ Foreign.Marshal.ContT: type CString = Ptr CChar
+ Foreign.Marshal.ContT: type CStringLen = (Ptr CChar, Int)
- Foreign.Marshal.ContT: calloc :: forall r a. Storable a => ContT r IO (Ptr a)
+ Foreign.Marshal.ContT: calloc :: forall a r. Storable a => ContT r IO (Ptr a)
- Foreign.Marshal.ContT: callocArray :: Storable a => Int -> ContT r IO (Ptr a)
+ Foreign.Marshal.ContT: callocArray :: forall a r. Storable a => Int -> ContT r IO (Ptr a)
- Foreign.Marshal.ContT: callocArray0 :: Storable a => Int -> ContT r IO (Ptr a)
+ Foreign.Marshal.ContT: callocArray0 :: forall a r. Storable a => Int -> ContT r IO (Ptr a)
Files
- CHANGELOG.md +7/−0
- marshal-contt.cabal +1/−2
- src/Foreign/Marshal/ContT.hs +47/−31
CHANGELOG.md view
@@ -1,5 +1,12 @@ # Revision history for marshal-contt +## 0.1.2.0 -- 2019-09-14++* Reimplement `calloc` and friends in terms of `alloca` to make them + exception-safe.+* Add `bracketContT` to add initialization and finalization hooks to an + existing `ContT`.+ ## 0.1.1.0 -- 2019-09-14 * Add combinators for using optics and projection functions to marshal more
marshal-contt.cabal view
@@ -1,5 +1,5 @@ name: marshal-contt-version: 0.1.1.0+version: 0.1.2.0 synopsis: A ContT-based wrapper for Haskell-to-C marshalling functions. description: See <https://github.com/typedrat/marshal-contt/blob/master/README.md>. homepage: https://github.com/typedrat/marshal-contt@@ -20,7 +20,6 @@ , mtl >= 2.2 && < 2.3 , bytestring >= 0.10.10.0 && < 0.11 , lens >= 4.16 && < 4.19- ghc-options: -Wall hs-source-dirs: src default-language: Haskell2010 default-extensions: FlexibleInstances
src/Foreign/Marshal/ContT.hs view
@@ -8,11 +8,11 @@ Portability : portable This library wraps the standard @base@ bracketed allocation primitives (along-with those from 'Data.ByteString') in a 'ContT'-based interface to ease the-chaining of complex marshalling operations.+with those from "Data.ByteString" and "Data.ByteString.Short") in a+'ContT'-based interface to ease the chaining of complex marshalling operations. -} module Foreign.Marshal.ContT - ( + ( -- * @alloca@ alloca, allocaWith, allocaBytes, allocaBytesAligned -- * @calloc@@@ -22,10 +22,14 @@ , allocaArray0, allocaArrayWith0, allocaArrayWith0Of -- * @callocArray@ , callocArray, callocArray0- -- * @withForeignPtr@+ -- * @withForeignPtr@ (and alternatives) , withForeignPtr+ , bracketContT -- * @ToCString@ , ToCString(..)+ -- * Reexports+ , CString, CStringLen+ , Ptr, nullPtr -- * Projected variants -- | These variants work in the same way as their corresponding functions -- without the terminal prime, but with a function argument that projects@@ -42,20 +46,22 @@ , iallocaArrayWith0', iallocaArrayWith0Of' ) where +import Control.Exception ( bracket ) import Control.Lens.Fold import Control.Lens.Getter import Control.Lens.Indexed--- import Control.Lens.Traversal import Control.Monad.Cont-import qualified Data.ByteString as BS -import qualified Data.ByteString.Short as SBS +import qualified Data.ByteString as BS+import qualified Data.ByteString.Short as SBS import Data.Foldable ( foldrM )+import Data.Functor ( ($>) ) import qualified Foreign.C.String as C import Foreign.C.String ( CString, CStringLen ) import qualified Foreign.ForeignPtr as C import Foreign.ForeignPtr ( ForeignPtr ) import qualified Foreign.Marshal.Alloc as C import qualified Foreign.Marshal.Array as C+import Foreign.Marshal.Utils ( fillBytes ) import Foreign.Ptr import Foreign.Storable @@ -87,27 +93,36 @@ allocaBytesAligned size align = ContT $ C.allocaBytesAligned size align {-# INLINE allocaBytesAligned #-} +-- | 'bracketContT' allows one to add initialization and finalization hooks to+-- an existing 'ContT' that will be executed even in cases where an exception+-- occurs. --+-- This provides an alternative to 'ForeignPtr's when the pointer will only+-- be used in code that is written with this library in mind.+bracketContT :: (a -> IO b) -> (a -> IO c) -> ContT r IO a -> ContT r IO a+bracketContT init' final = withContT $ \f a ->+ bracket (init' a $> a) final f +--+ -- | 'calloc' is a continuation that provides access to a pointer into a -- temporary block of zeroed memory sufficient to hold values of type @a@.-calloc :: forall r a. Storable a => ContT r IO (Ptr a)-calloc = ContT $ \f -> do- ptr <- C.calloc- out <- f ptr- C.free ptr- return out+calloc :: forall a r. Storable a => ContT r IO (Ptr a)+calloc = do+ ptr <- alloca+ let size = sizeOf (undefined :: a)+ liftIO $ fillBytes ptr 0 size+ return ptr {-# INLINE calloc #-} -- | 'callocBytes' @n@ is a continuation that provides access to a pointer into -- a temporary block of zeroed memory sufficient to hold @n@ bytes, with -- machine-standard alignment. callocBytes :: Int -> ContT r IO (Ptr a)-callocBytes size = ContT $ \f -> do- ptr <- C.callocBytes size- out <- f ptr- C.free ptr- return out+callocBytes size = do+ ptr <- allocaBytes size+ liftIO $ fillBytes ptr 0 size+ return ptr {-# INLINE callocBytes #-} --@@ -177,7 +192,8 @@ {-# INLINE iallocaArrayWith' #-} -- | A generic 'IndexedFold' or equivalent, taking an 'IndexedGetter',--- 'IndexedFold' (obviously), 'IndexedTraversal', or 'IndexedLens'.+-- 'IndexedFold' (obviously), 'Control.Lens.Type.IndexedTraversal', or+-- 'Control.Lens.Type.IndexedLens'. type AnIndexedFold i s a = forall m p. (Indexable i p) => p a (Const m a) -> s -> Const m s@@ -287,23 +303,23 @@ -- | 'callocArray0' @\@a@ @n@ is a continuation that provides access to a -- pointer into a temporary block of zeroed memory sufficient to hold @n@ -- values of type @a@.-callocArray :: Storable a => Int -> ContT r IO (Ptr a)-callocArray len = ContT $ \f -> do- ptr <- C.callocArray len- out <- f ptr- C.free ptr- return out+callocArray :: forall a r . Storable a => Int -> ContT r IO (Ptr a)+callocArray len = do+ ptr <- allocaArray len+ let size = sizeOf (undefined :: a)+ liftIO $ fillBytes ptr 0 (len * size)+ return ptr {-# INLINE callocArray #-} -- | 'callocArray0' @\@a@ @n@ is a continuation that provides access to a -- pointer into a temporary block of zeroed memory sufficient to hold @n@ -- values of type @a@, along with a final terminal element.-callocArray0 :: Storable a => Int -> ContT r IO (Ptr a)-callocArray0 len = ContT $ \f -> do- ptr <- C.callocArray0 len- out <- f ptr- C.free ptr- return out+callocArray0 :: forall a r . Storable a => Int -> ContT r IO (Ptr a)+callocArray0 len = do+ ptr <- allocaArray0 len+ let size = sizeOf (undefined :: a)+ liftIO $ fillBytes ptr 0 (len * size)+ return ptr {-# INLINE callocArray0 #-} --