3ca37dcdac00b6d92d30f15256f49be7a4543cda
[ghc-hetmet.git] / ghc / lib / std / PrelMarshalUtils.lhs
1 % -----------------------------------------------------------------------------
2 % $Id: PrelMarshalUtils.lhs,v 1.1 2001/01/11 17:25:57 simonmar Exp $
3 %
4 % (c) The FFI task force, 2000
5 %
6
7 Utilities for primitive marshaling
8
9 \begin{code}
10 module PrelMarshalUtils (
11
12   -- combined allocation and marshalling
13   --
14   withObject,    -- :: Storable a => a -> (Ptr a -> IO b) -> IO b
15   {- FIXME: should be `with' -}
16   new,           -- :: Storable a => a -> IO (Ptr a)
17
18   -- marshalling of Boolean values (non-zero corresponds to `True')
19   --
20   fromBool,      -- :: Num a => Bool -> a
21   toBool,        -- :: Num a => a -> Bool
22
23   -- marshalling of Maybe values
24   --
25   maybeNew,      -- :: (      a -> IO (Ptr a))
26                  -- -> (Maybe a -> IO (Ptr a))
27   maybeWith,     -- :: (      a -> (Ptr b -> IO c) -> IO c) 
28                  -- -> (Maybe a -> (Ptr b -> IO c) -> IO c)
29   maybePeek,     -- :: (Ptr a -> IO        b ) 
30                  -- -> (Ptr a -> IO (Maybe b))
31
32   -- marshalling lists of storable objects
33   --
34   withMany,      -- :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
35
36   -- Haskellish interface to memcpy and memmove
37   -- (argument order: destination, source)
38   --
39   copyBytes,     -- :: Ptr a -> Ptr a -> Int -> IO ()
40   moveBytes      -- :: Ptr a -> Ptr a -> Int -> IO ()
41 ) where
42
43 import Monad            ( liftM )
44
45 import PrelPtr          ( Ptr, nullPtr )
46 import PrelStorable     ( Storable (poke) )
47 import PrelCTypesISO    ( CSize )
48 import PrelMarshalAlloc ( malloc, alloca )
49
50
51 -- combined allocation and marshalling
52 -- -----------------------------------
53
54 -- allocate storage for a value and marshal it into this storage
55 --
56 new     :: Storable a => a -> IO (Ptr a)
57 new val  = 
58   do 
59     ptr <- malloc
60     poke ptr val
61     return ptr
62
63 -- allocate temporary storage for a value and marshal it into this storage
64 --
65 -- * see the life time constraints imposed by `alloca'
66 --
67 {- FIXME: should be called `with' -}
68 withObject       :: Storable a => a -> (Ptr a -> IO b) -> IO b
69 withObject val f  = alloca $ \ptr -> do poke ptr val; f ptr
70
71
72 -- marshalling of Boolean values (non-zero corresponds to `True')
73 -- -----------------------------
74
75 -- convert a Haskell Boolean to its numeric representation
76 --
77 fromBool       :: Num a => Bool -> a
78 fromBool False  = 0
79 fromBool True   = 1
80
81 -- convert a Boolean in numeric representation to a Haskell value
82 --
83 toBool :: Num a => a -> Bool
84 toBool  = (/= 0)
85
86
87 -- marshalling of Maybe values
88 -- ---------------------------
89
90 -- allocate storage and marshall a storable value wrapped into a `Maybe'
91 --
92 -- * the `nullPtr' is used to represent `Nothing'
93 --
94 maybeNew :: (      a -> IO (Ptr a))
95          -> (Maybe a -> IO (Ptr a))
96 maybeNew  = maybe (return nullPtr)
97
98 -- converts a withXXX combinator into one marshalling a value wrapped into a
99 -- `Maybe'
100 --
101 maybeWith :: (      a -> (Ptr b -> IO c) -> IO c) 
102           -> (Maybe a -> (Ptr b -> IO c) -> IO c)
103 maybeWith  = maybe ($ nullPtr)
104
105 -- convert a peek combinator into a one returning `Nothing' if applied to a
106 -- `nullPtr' 
107 --
108 maybePeek                           :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
109 maybePeek peek ptr | ptr == nullPtr  = return Nothing
110                    | otherwise       = liftM Just $ peek ptr
111
112
113 -- marshalling lists of storable objects
114 -- -------------------------------------
115
116 -- replicates a withXXX combinator over a list of objects, yielding a list of
117 -- marshalled objects
118 --
119 withMany :: (a -> (b -> res) -> res)  -- withXXX combinator for one object
120          -> [a]                       -- storable objects
121          -> ([b] -> res)              -- action on list of marshalled obj.s
122          -> res
123 withMany _       []     f = f []
124 withMany withFoo (x:xs) f = withFoo x $ \x' ->
125                               withMany withFoo xs (\xs' -> f (x':xs'))
126
127
128 -- Haskellish interface to memcpy and memmove
129 -- ------------------------------------------
130
131 -- copies the given number of bytes from the second area (source) into the
132 -- first (destination); the copied areas may *not* overlap
133 --
134 copyBytes               :: Ptr a -> Ptr a -> Int -> IO ()
135 copyBytes dest src size  = memcpy dest src (fromIntegral size)
136
137 -- copies the given number of elements from the second area (source) into the
138 -- first (destination); the copied areas *may* overlap
139 --
140 moveBytes               :: Ptr a -> Ptr a -> Int -> IO ()
141 moveBytes dest src size  = memmove dest src (fromIntegral size)
142
143
144 -- auxilliary routines
145 -- -------------------
146
147 -- basic C routines needed for memory copying
148 --
149 foreign import unsafe memcpy  :: Ptr a -> Ptr a -> CSize -> IO ()
150 foreign import unsafe memmove :: Ptr a -> Ptr a -> CSize -> IO ()
151
152 \end{code}