{-# OPTIONS_GHC -cpp -fglasgow-exts -fallow-undecidable-instances #-} ----------------------------------------------------------------------------- -- | -- Module : ForeignArray -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/base/LICENSE) -- -- Maintainer : libraries@haskell.org -- Stability : experimental -- Portability : non-portable (uses Data.Array.MArray) -- -- A storable array is an IO-mutable array which stores its -- contents in a contiguous memory block living in the C -- heap. Elements are stored according to the class 'Storable'. -- You can obtain the pointer to the array contents to manipulate -- elements from languages like C. -- -- It is similar to 'Data.Array.IO.IOUArray' but slower. -- Its advantage is that it's compatible with C. -- ----------------------------------------------------------------------------- module ForeignArray ( -- * Arrays of 'Storable' things. ForeignArray(..), -- data ForeignArray index element -- -- index type must be in class Ix -- -- element type must be in class Storable -- * Overloaded mutable array interface -- | Module "Data.Array.MArray" provides the interface of storable arrays. -- They are instances of class 'MArray' (with the 'IO' monad). module Data.Array.MArray, -- * Accessing the pointer to the array contents withForeignArray, -- :: ForeignArray i e -> (Ptr e -> IO a) -> IO a unsafePtrToForeignArray ) where import Prelude import Data.Array.Base import Data.Array.MArray import Foreign hiding (newArray) -- |The array type data ForeignArray i e = ForeignArray !i !i !(Ptr e) instance HasBounds ForeignArray where bounds (ForeignArray l u _) = (l,u) instance Storable e => MArray ForeignArray e IO where newArray (l,u) init = do a <- mallocArray size sequence_ [pokeElemOff a i init | i <- [0..size-1]] return (ForeignArray l u a) where size = rangeSize (l,u) newArray_ (l,u) = do a <- mallocArray (rangeSize (l,u)) return (ForeignArray l u a) unsafeRead (ForeignArray _ _ a) i = peekElemOff a i unsafeWrite (ForeignArray _ _ a) i e = pokeElemOff a i e -- |The pointer to the array contents is obtained by 'withForeignArray'. -- The idea is similar to 'ForeignPtr' (used internally here). -- The pointer should be used only during execution of the 'IO' action -- retured by the function passed as argument to 'withForeignArray'. withForeignArray :: ForeignArray i e -> (Ptr e -> IO a) -> IO a withForeignArray (ForeignArray _ _ a) f = f a -- |Construct a 'ForeignArray' from an arbitrary 'ForeignPtr'. It is -- the caller's responsibility to ensure that the 'ForeignPtr' points to -- an area of memory sufficient for the specified bounds. unsafePtrToForeignArray :: Ptr e -> (i,i) -> IO (ForeignArray i e) unsafePtrToForeignArray a (l,u) = return (ForeignArray l u a)