{-# LINE 1 "src/Data/Time/Exts/C.hsc" #-}
------------------------------------------------------------------------------
{-# LINE 2 "src/Data/Time/Exts/C.hsc" #-}
-- Copyright (c) 2014, Enzo Haussecker, Nathan Howell. All rights reserved. --
------------------------------------------------------------------------------

{-# LANGUAGE MultiParamTypeClasses #-}
{-# OPTIONS -Wall                  #-}

-- | Haskell bindings to the C time library.
module Data.Time.Exts.C where

import Data.Convertible (Convertible(..))
import Foreign.C.String (CString)
import Foreign.C.Types (CInt(..), CLong, CTime(..))
import Foreign.Marshal.Alloc (alloca)
import Foreign.Marshal.Unsafe (unsafeLocalState)
import Foreign.Marshal.Utils (with)
import Foreign.Ptr (FunPtr, Ptr, nullPtr, plusPtr)
import Foreign.Storable (Storable(..))


{-# LINE 21 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 22 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 23 "src/Data/Time/Exts/C.hsc" #-}


{-# LINE 25 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 26 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 27 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 28 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 29 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 30 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 31 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 32 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 33 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 34 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 35 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 36 "src/Data/Time/Exts/C.hsc" #-}
data C'tm = C'tm{
  c'tm'tm_sec :: CInt,
  c'tm'tm_min :: CInt,
  c'tm'tm_hour :: CInt,
  c'tm'tm_mday :: CInt,
  c'tm'tm_mon :: CInt,
  c'tm'tm_year :: CInt,
  c'tm'tm_wday :: CInt,
  c'tm'tm_yday :: CInt,
  c'tm'tm_isdst :: CInt,
  c'tm'tm_gmtoff :: CLong,
  c'tm'tm_zone :: CString
} deriving (Eq,Show)
p'tm'tm_sec p = plusPtr p 0
p'tm'tm_sec :: Ptr (C'tm) -> Ptr (CInt)
p'tm'tm_min p = plusPtr p 4
p'tm'tm_min :: Ptr (C'tm) -> Ptr (CInt)
p'tm'tm_hour p = plusPtr p 8
p'tm'tm_hour :: Ptr (C'tm) -> Ptr (CInt)
p'tm'tm_mday p = plusPtr p 12
p'tm'tm_mday :: Ptr (C'tm) -> Ptr (CInt)
p'tm'tm_mon p = plusPtr p 16
p'tm'tm_mon :: Ptr (C'tm) -> Ptr (CInt)
p'tm'tm_year p = plusPtr p 20
p'tm'tm_year :: Ptr (C'tm) -> Ptr (CInt)
p'tm'tm_wday p = plusPtr p 24
p'tm'tm_wday :: Ptr (C'tm) -> Ptr (CInt)
p'tm'tm_yday p = plusPtr p 28
p'tm'tm_yday :: Ptr (C'tm) -> Ptr (CInt)
p'tm'tm_isdst p = plusPtr p 32
p'tm'tm_isdst :: Ptr (C'tm) -> Ptr (CInt)
p'tm'tm_gmtoff p = plusPtr p 40
p'tm'tm_gmtoff :: Ptr (C'tm) -> Ptr (CLong)
p'tm'tm_zone p = plusPtr p 48
p'tm'tm_zone :: Ptr (C'tm) -> Ptr (CString)
instance Storable C'tm where
  sizeOf _ = 56
  alignment _ = 8
  peek p = do
    v0 <- peekByteOff p 0
    v1 <- peekByteOff p 4
    v2 <- peekByteOff p 8
    v3 <- peekByteOff p 12
    v4 <- peekByteOff p 16
    v5 <- peekByteOff p 20
    v6 <- peekByteOff p 24
    v7 <- peekByteOff p 28
    v8 <- peekByteOff p 32
    v9 <- peekByteOff p 40
    v10 <- peekByteOff p 48
    return $ C'tm v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10
  poke p (C'tm v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10) = do
    pokeByteOff p 0 v0
    pokeByteOff p 4 v1
    pokeByteOff p 8 v2
    pokeByteOff p 12 v3
    pokeByteOff p 16 v4
    pokeByteOff p 20 v5
    pokeByteOff p 24 v6
    pokeByteOff p 28 v7
    pokeByteOff p 32 v8
    pokeByteOff p 40 v9
    pokeByteOff p 48 v10
    return ()

{-# LINE 37 "src/Data/Time/Exts/C.hsc" #-}


{-# LINE 39 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 40 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 41 "src/Data/Time/Exts/C.hsc" #-}
data C'timespec = C'timespec{
  c'timespec'tv_sec :: CLong,
  c'timespec'tv_nsec :: CLong
} deriving (Eq,Show)
p'timespec'tv_sec p = plusPtr p 0
p'timespec'tv_sec :: Ptr (C'timespec) -> Ptr (CLong)
p'timespec'tv_nsec p = plusPtr p 8
p'timespec'tv_nsec :: Ptr (C'timespec) -> Ptr (CLong)
instance Storable C'timespec where
  sizeOf _ = 16
  alignment _ = 8
  peek p = do
    v0 <- peekByteOff p 0
    v1 <- peekByteOff p 8
    return $ C'timespec v0 v1
  poke p (C'timespec v0 v1) = do
    pokeByteOff p 0 v0
    pokeByteOff p 8 v1
    return ()

{-# LINE 42 "src/Data/Time/Exts/C.hsc" #-}


{-# LINE 44 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 45 "src/Data/Time/Exts/C.hsc" #-}

{-# LINE 46 "src/Data/Time/Exts/C.hsc" #-}
data C'timeval = C'timeval{
  c'timeval'tv_sec :: CLong,
  c'timeval'tv_usec :: CLong
} deriving (Eq,Show)
p'timeval'tv_sec p = plusPtr p 0
p'timeval'tv_sec :: Ptr (C'timeval) -> Ptr (CLong)
p'timeval'tv_usec p = plusPtr p 8
p'timeval'tv_usec :: Ptr (C'timeval) -> Ptr (CLong)
instance Storable C'timeval where
  sizeOf _ = 16
  alignment _ = 8
  peek p = do
    v0 <- peekByteOff p 0
    v1 <- peekByteOff p 8
    return $ C'timeval v0 v1
  poke p (C'timeval v0 v1) = do
    pokeByteOff p 0 v0
    pokeByteOff p 8 v1
    return ()

{-# LINE 47 "src/Data/Time/Exts/C.hsc" #-}

foreign import ccall "timegm" c'timegm
  :: Ptr C'tm -> IO CTime
foreign import ccall "&timegm" p'timegm
  :: FunPtr (Ptr C'tm -> IO CTime)

{-# LINE 49 "src/Data/Time/Exts/C.hsc" #-}
foreign import ccall "gmtime_r" c'gmtime_r
  :: Ptr CTime -> Ptr C'tm -> IO (Ptr C'tm)
foreign import ccall "&gmtime_r" p'gmtime_r
  :: FunPtr (Ptr CTime -> Ptr C'tm -> IO (Ptr C'tm))

{-# LINE 50 "src/Data/Time/Exts/C.hsc" #-}
foreign import ccall "gettimeofday" c'gettimeofday
  :: Ptr C'timeval -> Ptr () -> IO CInt
foreign import ccall "&gettimeofday" p'gettimeofday
  :: FunPtr (Ptr C'timeval -> Ptr () -> IO CInt)

{-# LINE 51 "src/Data/Time/Exts/C.hsc" #-}

instance Convertible CTime C'tm where
  safeConvert = Right . unsafeLocalState . flip with f
    where f x = alloca $ \ ptr -> c'gmtime_r x ptr >>= peek

instance Convertible C'tm CTime where
  safeConvert = Right . unsafeLocalState . flip with c'timegm

-- | Get the current Unix date and time from the system clock.
getTimeOfDay :: IO C'timeval
getTimeOfDay = with (C'timeval 0 0) $ \ ptr -> c'gettimeofday ptr nullPtr >>= getResult ptr
  where getResult ptr 0 = peek ptr
        getResult _ err = error $ "getTimeOfDay: " ++ show err