packages feed

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 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