{-# LANGUAGE NoImplicitPrelude, UnicodeSyntax #-} -- | 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 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 base-unicode-symbols: import Data.Function.Unicode ( (∘) ) -- 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)