{-# LANGUAGE NoImplicitPrelude #-} -- | A short module to work with C's struct timeval. -- Copied from the package "time" - Data.Time.Clock.CTimeval module Timeval ( withTimeval ) where -------------------------------------------------------------------------------- -- Imports -------------------------------------------------------------------------------- -- from base: import Control.Monad ( return ) import Data.Function ( (.) ) import Foreign.C.Types ( CLong ) import Foreign.Marshal.Utils ( with ) import Foreign.Ptr ( Ptr, castPtr ) import Foreign.Storable ( Storable(..) ) import Prelude ( (*), quotRem, fromIntegral, undefined, Int ) import System.IO ( IO ) -- from bindings-libusb: import Bindings.Libusb.PollingAndTiming ( C'timeval ) -------------------------------------------------------------------------------- -- Timeval -------------------------------------------------------------------------------- data CTimeval = MkCTimeval CLong CLong instance Storable CTimeval where sizeOf _ = (sizeOf (undefined :: CLong)) * 2 alignment _ = alignment (undefined :: CLong) peek p = do s <- peekElemOff (castPtr p) 0 mus <- peekElemOff (castPtr p) 1 return (MkCTimeval s mus) poke p (MkCTimeval s mus) = do pokeElemOff (castPtr p) 0 s pokeElemOff (castPtr p) 1 mus -- Every things done so far in libusb was in milliseconds. So this -- function should accept a time in milliseconds too ! withTimeval :: Int -> (Ptr C'timeval -> IO α) -> IO α withTimeval milliseconds action = let (seconds, mseconds) = milliseconds `quotRem` 1000 timeval = MkCTimeval (fromIntegral seconds) (fromIntegral (1000 * mseconds)) -- micro-seconds in with timeval (action . castPtr)