{-# LINE 1 "OpenSSL/Stack.hsc" #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE ForeignFunctionInterface #-} module OpenSSL.Stack ( STACK , mapStack , withStack , withForeignStack ) where import Control.Exception import Foreign import Foreign.C data STACK {-# LINE 20 "OpenSSL/Stack.hsc" #-} foreign import ccall unsafe "OPENSSL_sk_new_null" skNewNull :: IO (Ptr STACK) foreign import ccall unsafe "OPENSSL_sk_free" skFree :: Ptr STACK -> IO () foreign import ccall unsafe "OPENSSL_sk_push" skPush :: Ptr STACK -> Ptr () -> IO () foreign import ccall unsafe "OPENSSL_sk_num" skNum :: Ptr STACK -> IO CInt foreign import ccall unsafe "OPENSSL_sk_value" skValue :: Ptr STACK -> CInt -> IO (Ptr ()) {-# LINE 50 "OpenSSL/Stack.hsc" #-} mapStack :: (Ptr a -> IO b) -> Ptr STACK -> IO [b] mapStack m st = do num <- skNum st mapM (\ i -> fmap castPtr (skValue st i) >>= m) $ take (fromIntegral 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 = bracket (newStack values) skFree 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