forked from depressed-pho/HsOpenSSL
/
Stack.hsc
59 lines (42 loc) · 1.32 KB
/
Stack.hsc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
module OpenSSL.Stack
( STACK
, mapStack
, withStack
, withForeignStack
)
where
import Control.Exception
import Foreign
data STACK
foreign import ccall unsafe "sk_new_null"
skNewNull :: IO (Ptr STACK)
foreign import ccall unsafe "sk_free"
skFree :: Ptr STACK -> IO ()
foreign import ccall unsafe "sk_push"
skPush :: Ptr STACK -> Ptr () -> IO ()
foreign import ccall unsafe "sk_num"
skNum :: Ptr STACK -> IO Int
foreign import ccall unsafe "sk_value"
skValue :: Ptr STACK -> Int -> IO (Ptr ())
mapStack :: (Ptr a -> IO b) -> Ptr STACK -> IO [b]
mapStack m st
= do num <- skNum st
mapM (\ i -> skValue st i >>= return . castPtr >>= m)
$ take num [0..]
newStack :: [Ptr a] -> IO (Ptr STACK)
newStack values
= do st <- skNewNull
mapM_ (skPush st . castPtr) values
return st
withStack :: [Ptr a] -> (Ptr STACK -> IO b) -> IO b
withStack values f
= bracket (newStack values) skFree f
withForeignStack :: (fp -> Ptr obj)
-> (fp -> IO ())
-> [fp]
-> (Ptr STACK -> IO ret)
-> IO ret
withForeignStack unsafeFpToPtr touchFp fps action
= do ret <- withStack (map unsafeFpToPtr fps) action
mapM_ touchFp fps
return ret