[project @ 2001-03-15 20:35:49 by qrczak]
[ghc-hetmet.git] / ghc / lib / std / PrelMarshalUtils.lhs
1 % -----------------------------------------------------------------------------
2 % $Id: PrelMarshalUtils.lhs,v 1.2 2001/03/15 20:35:49 qrczak 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,destruct) )
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  =
70   alloca $ \ptr -> do
71     poke ptr val
72     res <- f ptr
73     destruct ptr
74     return res
75
76
77 -- marshalling of Boolean values (non-zero corresponds to `True')
78 -- -----------------------------
79
80 -- convert a Haskell Boolean to its numeric representation
81 --
82 fromBool       :: Num a => Bool -> a
83 fromBool False  = 0
84 fromBool True   = 1
85
86 -- convert a Boolean in numeric representation to a Haskell value
87 --
88 toBool :: Num a => a -> Bool
89 toBool  = (/= 0)
90
91
92 -- marshalling of Maybe values
93 -- ---------------------------
94
95 -- allocate storage and marshall a storable value wrapped into a `Maybe'
96 --
97 -- * the `nullPtr' is used to represent `Nothing'
98 --
99 maybeNew :: (      a -> IO (Ptr a))
100          -> (Maybe a -> IO (Ptr a))
101 maybeNew  = maybe (return nullPtr)
102
103 -- converts a withXXX combinator into one marshalling a value wrapped into a
104 -- `Maybe'
105 --
106 maybeWith :: (      a -> (Ptr b -> IO c) -> IO c) 
107           -> (Maybe a -> (Ptr b -> IO c) -> IO c)
108 maybeWith  = maybe ($ nullPtr)
109
110 -- convert a peek combinator into a one returning `Nothing' if applied to a
111 -- `nullPtr' 
112 --
113 maybePeek                           :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
114 maybePeek peek ptr | ptr == nullPtr  = return Nothing
115                    | otherwise       = liftM Just $ peek ptr
116
117
118 -- marshalling lists of storable objects
119 -- -------------------------------------
120
121 -- replicates a withXXX combinator over a list of objects, yielding a list of
122 -- marshalled objects
123 --
124 withMany :: (a -> (b -> res) -> res)  -- withXXX combinator for one object
125          -> [a]                       -- storable objects
126          -> ([b] -> res)              -- action on list of marshalled obj.s
127          -> res
128 withMany _       []     f = f []
129 withMany withFoo (x:xs) f = withFoo x $ \x' ->
130                               withMany withFoo xs (\xs' -> f (x':xs'))
131
132
133 -- Haskellish interface to memcpy and memmove
134 -- ------------------------------------------
135
136 -- copies the given number of bytes from the second area (source) into the
137 -- first (destination); the copied areas may *not* overlap
138 --
139 copyBytes               :: Ptr a -> Ptr a -> Int -> IO ()
140 copyBytes dest src size  = memcpy dest src (fromIntegral size)
141
142 -- copies the given number of elements from the second area (source) into the
143 -- first (destination); the copied areas *may* overlap
144 --
145 moveBytes               :: Ptr a -> Ptr a -> Int -> IO ()
146 moveBytes dest src size  = memmove dest src (fromIntegral size)
147
148
149 -- auxilliary routines
150 -- -------------------
151
152 -- basic C routines needed for memory copying
153 --
154 foreign import unsafe memcpy  :: Ptr a -> Ptr a -> CSize -> IO ()
155 foreign import unsafe memmove :: Ptr a -> Ptr a -> CSize -> IO ()
156
157 \end{code}