{-# LANGUAGE ForeignFunctionInterface #-} module Storage( PrefStorage, createStorage, pokePref, peekPref ) where import Foreign import Foreign.C foreign import ccall "create_pref_array" c_createPrefArray :: CInt -> CInt -> IO (Ptr PrefArray) foreign import ccall "free_pref_array" c_freePrefArray :: CInt -> CInt -> Ptr PrefArray -> IO () foreign import ccall "wrapper" wrap :: (Ptr PrefArray -> IO ()) -> IO (FunPtr (Ptr PrefArray -> IO ())) foreign import ccall "poke_pref_array" c_pokePrefArray :: CInt -> CInt -> Ptr PrefArray -> CInt -> CInt -> CInt -> IO () foreign import ccall "peek_pref_array" c_peekPrefArray :: CInt -> CInt -> Ptr PrefArray -> CInt -> CInt -> CInt -> IO CInt newtype PrefArray = PrefArray (Ptr PrefArray) data PrefStorage = PrefStorage { pointer :: ForeignPtr PrefArray , numBallots :: Int , sizeOfBallot :: Int } createStorage :: Int -> Int -> IO PrefStorage createStorage n s = do x <- c_createPrefArray (fromIntegral n) (fromIntegral s) f <- wrap (c_freePrefArray (fromIntegral n) (fromIntegral s)) y <- newForeignPtr f x return (PrefStorage y n s) pokePref :: PrefStorage -> Int -> Int -> Int -> IO () pokePref p n s r = do let numBal = fromIntegral (numBallots p) sizeBal = fromIntegral (sizeOfBallot p) func a = c_pokePrefArray numBal sizeBal a (fromIntegral n) (fromIntegral s) (fromIntegral r) withForeignPtr (pointer p) func peekPref :: PrefStorage -> Int -> Int -> Int -> IO Bool peekPref p n s r = do let numBal = fromIntegral (numBallots p) sizeBal = fromIntegral (sizeOfBallot p) func a = c_peekPrefArray numBal sizeBal a (fromIntegral n) (fromIntegral s) (fromIntegral r) result <- withForeignPtr (pointer p) func return (result /= 0)