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

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

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 20 "src/Data/Time/Exts/C.hsc" #-}

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

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


{-# LINE 24 "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" #-}
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 36 "src/Data/Time/Exts/C.hsc" #-}


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

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

{-# LINE 40 "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 41 "src/Data/Time/Exts/C.hsc" #-}


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

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

{-# LINE 45 "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 46 "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 48 "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 49 "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 50 "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

-- | Gets 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 $ "Error in call to gettimeofday: " ++ show err