MonadCatchIO-transformers-foreign (empty) → 0.1
raw patch · 4 files changed
+139/−0 lines, 4 filesdep +MonadCatchIO-transformersdep +basedep +primitivesetup-changed
Dependencies added: MonadCatchIO-transformers, base, primitive, transformers
Files
- LICENSE +30/−0
- MonadCatchIO-transformers-foreign.cabal +29/−0
- Setup.hs +2/−0
- src/Control/Monad/CatchIO/Foreign.hs +78/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2010, Antoine Latter++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Antoine Latter nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ MonadCatchIO-transformers-foreign.cabal view
@@ -0,0 +1,29 @@+-- MonadCatchIO-mtl-foreign.cabal auto-generated by cabal init. For+-- additional options, see+-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.+Name: MonadCatchIO-transformers-foreign+Version: 0.1+Synopsis: Polymorphic combinators for working with foreign functions+Description: Functions like 'alloca' are provided, except not restricted+ to 'IO'.+License: BSD3+License-file: LICENSE+Author: Antoine Latter+Maintainer: aslatter@gmail.com+-- Copyright: +Category: Control+Build-type: Simple+-- Extra-source-files: +Cabal-version: >=1.6++Library+ Exposed-modules: Control.Monad.CatchIO.Foreign+ Build-depends: base == 4.*, MonadCatchIO-transformers == 0.2.*,+ transformers == 0.2.*++ if impl(ghc)+ Build-depends: primitive == 0.3.*++ Hs-Source-Dirs: src/+ -- Other-modules: + -- Build-tools:
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Control/Monad/CatchIO/Foreign.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE CPP, MagicHash, UnboxedTuples #-}+{-|+ This module assumes that you are familiar with the funcitons+ of the same name in Foreign.Marshall.Alloc, Foreign.Marshal.AllocArray+ and in Foreign.ForeignPtr.++ The functions are generalized to work in any monad which is an+ instance of MonadCatchIO.+ -}+module Control.Monad.CatchIO.Foreign+ ( alloca+ , allocaBytes+ , allocaArray+ , allocaArray0+ , withForeignPtr+ )+ where++-- this is a bit dodgy - we use the MIN_VERSION macro to+-- see if we're compiled against transformers or mtl+#ifdef MIN_VERSION_transformers+import Control.Monad.IO.Class(liftIO)+#else+import Control.Monad.Trans (liftIO)+#endif++import Control.Monad.CatchIO++import qualified Foreign as F+import Foreign (Ptr,ForeignPtr, sizeOf, alignment, Storable)++#ifdef __GLASGOW_HASKELL__+import qualified Data.Primitive as P+import GHC.Exts+import GHC.IOBase hiding (liftIO)+#endif++alloca :: (F.Storable a, MonadCatchIO m) => (Ptr a -> m b) -> m b+alloca = doAlloca undefined+ where+ doAlloca :: (MonadCatchIO m', Storable a') => a' -> (Ptr a' -> m' b') -> m' b'+ doAlloca dummy = allocaBytesAligned (F.sizeOf dummy) (F.alignment dummy)++allocaBytes :: (MonadCatchIO m) => Int -> (Ptr a -> m b) -> m b+allocaBytes size = bracket (liftIO $ F.mallocBytes size) (liftIO . F.free)++allocaBytesAligned :: (MonadCatchIO m) => Int -> Int -> (Ptr a -> m b) -> m b+#ifdef __GLASGOW_HASKELL__+allocaBytesAligned size alignment k+ = do+ ba <- liftIO $ P.newAlignedPinnedByteArray size alignment >>= P.unsafeFreezeByteArray+ r <- k $ case P.byteArrayContents ba of+ P.Addr addr# -> Ptr addr#+ liftIO $ touch ba+ return r++touch :: a -> IO ()+touch a = IO $ \s -> case touch# a s of+ s' -> (# s', () #)++#else+allocaBytesAligned size _ = allocaBytes size -- wrong, but the FFI doesn't offer anything else+#endif++allocaArray :: (F.Storable a, MonadCatchIO m) => Int -> (Ptr a -> m b) -> m b+allocaArray = doAlloca undefined+ where+ doAlloca :: (Storable a', MonadCatchIO m') => a' -> Int -> (Ptr a' -> m' b') -> m' b'+ doAlloca dummy size = allocaBytesAligned (size * sizeOf dummy) (alignment dummy)++allocaArray0 :: (F.Storable a, MonadCatchIO m) => Int -> (Ptr a -> m b) -> m b+allocaArray0 size = allocaArray (size + 1)++withForeignPtr :: (MonadCatchIO m) => ForeignPtr a -> (Ptr a -> m b) -> m b+withForeignPtr fo io+ = do r <- io (F.unsafeForeignPtrToPtr fo)+ liftIO $ F.touchForeignPtr fo+ return r