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