{-# LINE 1 "Data/UnixTime/Types.hsc" #-}
{-# LANGUAGE DeriveGeneric #-}

module Data.UnixTime.Types where

import Control.Applicative ((<$>), (<*>))
import Data.ByteString
import Data.ByteString.Char8 ()
import Data.Int

{-# LINE 12 "Data/UnixTime/Types.hsc" #-}
import Foreign.C.Types
import Foreign.Storable

{-# LINE 15 "Data/UnixTime/Types.hsc" #-}
import Data.Binary

{-# LINE 17 "Data/UnixTime/Types.hsc" #-}
import GHC.Generics



-- |
-- Data structure for Unix time.
--
-- Please note that this uses GHC-derived 'Eq' and 'Ord' instances.
-- Notably
--
-- >>> UnixTime 1 0 > UnixTime 0 999999999
-- True
--
-- You should instead use 'UnixDiffTime' along with its helpers such
-- as 'Data.UnixTime.microSecondsToUnixDiffTime' which will ensure
-- that such unusual values are never created.
data UnixTime = UnixTime {
    -- | Seconds from 1st Jan 1970
    UnixTime -> CTime
utSeconds :: {-# UNPACK #-} !CTime
    -- | Micro seconds (i.e. 10^(-6))
  , UnixTime -> Int32
utMicroSeconds :: {-# UNPACK #-} !Int32
  } deriving (UnixTime -> UnixTime -> Bool
(UnixTime -> UnixTime -> Bool)
-> (UnixTime -> UnixTime -> Bool) -> Eq UnixTime
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UnixTime -> UnixTime -> Bool
== :: UnixTime -> UnixTime -> Bool
$c/= :: UnixTime -> UnixTime -> Bool
/= :: UnixTime -> UnixTime -> Bool
Eq,Eq UnixTime
Eq UnixTime =>
(UnixTime -> UnixTime -> Ordering)
-> (UnixTime -> UnixTime -> Bool)
-> (UnixTime -> UnixTime -> Bool)
-> (UnixTime -> UnixTime -> Bool)
-> (UnixTime -> UnixTime -> Bool)
-> (UnixTime -> UnixTime -> UnixTime)
-> (UnixTime -> UnixTime -> UnixTime)
-> Ord UnixTime
UnixTime -> UnixTime -> Bool
UnixTime -> UnixTime -> Ordering
UnixTime -> UnixTime -> UnixTime
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: UnixTime -> UnixTime -> Ordering
compare :: UnixTime -> UnixTime -> Ordering
$c< :: UnixTime -> UnixTime -> Bool
< :: UnixTime -> UnixTime -> Bool
$c<= :: UnixTime -> UnixTime -> Bool
<= :: UnixTime -> UnixTime -> Bool
$c> :: UnixTime -> UnixTime -> Bool
> :: UnixTime -> UnixTime -> Bool
$c>= :: UnixTime -> UnixTime -> Bool
>= :: UnixTime -> UnixTime -> Bool
$cmax :: UnixTime -> UnixTime -> UnixTime
max :: UnixTime -> UnixTime -> UnixTime
$cmin :: UnixTime -> UnixTime -> UnixTime
min :: UnixTime -> UnixTime -> UnixTime
Ord,Int -> UnixTime -> ShowS
[UnixTime] -> ShowS
UnixTime -> String
(Int -> UnixTime -> ShowS)
-> (UnixTime -> String) -> ([UnixTime] -> ShowS) -> Show UnixTime
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> UnixTime -> ShowS
showsPrec :: Int -> UnixTime -> ShowS
$cshow :: UnixTime -> String
show :: UnixTime -> String
$cshowList :: [UnixTime] -> ShowS
showList :: [UnixTime] -> ShowS
Show,(forall x. UnixTime -> Rep UnixTime x)
-> (forall x. Rep UnixTime x -> UnixTime) -> Generic UnixTime
forall x. Rep UnixTime x -> UnixTime
forall x. UnixTime -> Rep UnixTime x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. UnixTime -> Rep UnixTime x
from :: forall x. UnixTime -> Rep UnixTime x
$cto :: forall x. Rep UnixTime x -> UnixTime
to :: forall x. Rep UnixTime x -> UnixTime
Generic)

instance Storable UnixTime where
    sizeOf :: UnixTime -> Int
sizeOf UnixTime
_    = ((Int
16))
{-# LINE 42 "Data/UnixTime/Types.hsc" #-}
    alignment _ = (8)
{-# LINE 43 "Data/UnixTime/Types.hsc" #-}

{-# LINE 67 "Data/UnixTime/Types.hsc" #-}
    -- On Unix, the struct `timeval` is defined as
    --
    --      struct timeval
    --      {
    --          time_t      tv_sec;
    --          suseconds_t tv_usec;
    --      };
    --
    -- The type `suseconds_t` is a signed integer type capable of storing
    -- values at least in the range `[-1, 1000000]`. It's size is platform
    -- specific, and it is 8 bytes long on 64-bit platforms.
    --
    -- Here we peek `tv_usec` using the `CSUSeconds` type and then convert it
    -- to `Int32` (the type of `utMicroSeconds`) relying on the fact that
    -- `tv_usec` is no bigger than `1000000`, and hence we will not overflow.
    peek :: Ptr UnixTime -> IO UnixTime
peek Ptr UnixTime
ptr    = do
            CTime
sec <- ((\Ptr UnixTime
hsc_ptr -> Ptr UnixTime -> Int -> IO CTime
forall b. Ptr b -> Int -> IO CTime
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr UnixTime
hsc_ptr Int
0)) Ptr UnixTime
ptr
{-# LINE 84 "Data/UnixTime/Types.hsc" #-}
            CSUSeconds Int64
msec <- ((\Ptr UnixTime
hsc_ptr -> Ptr UnixTime -> Int -> IO CSUSeconds
forall b. Ptr b -> Int -> IO CSUSeconds
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr UnixTime
hsc_ptr Int
8)) Ptr UnixTime
ptr
{-# LINE 85 "Data/UnixTime/Types.hsc" #-}
            UnixTime -> IO UnixTime
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (UnixTime -> IO UnixTime) -> UnixTime -> IO UnixTime
forall a b. (a -> b) -> a -> b
$ CTime -> Int32 -> UnixTime
UnixTime CTime
sec (Int64 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
msec)
    poke :: Ptr UnixTime -> UnixTime -> IO ()
poke Ptr UnixTime
ptr UnixTime
ut = do
            let msec :: CSUSeconds
msec = Int64 -> CSUSeconds
CSUSeconds (Int64 -> CSUSeconds) -> Int64 -> CSUSeconds
forall a b. (a -> b) -> a -> b
$ Int32 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (UnixTime -> Int32
utMicroSeconds UnixTime
ut)
            ((\Ptr UnixTime
hsc_ptr -> Ptr UnixTime -> Int -> CTime -> IO ()
forall b. Ptr b -> Int -> CTime -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr UnixTime
hsc_ptr Int
0))  Ptr UnixTime
ptr (UnixTime -> CTime
utSeconds UnixTime
ut)
{-# LINE 89 "Data/UnixTime/Types.hsc" #-}
            ((\Ptr UnixTime
hsc_ptr -> Ptr UnixTime -> Int -> CSUSeconds -> IO ()
forall b. Ptr b -> Int -> CSUSeconds -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr UnixTime
hsc_ptr Int
8)) Ptr UnixTime
ptr CSUSeconds
msec
{-# LINE 90 "Data/UnixTime/Types.hsc" #-}

{-# LINE 91 "Data/UnixTime/Types.hsc" #-}


{-# LINE 93 "Data/UnixTime/Types.hsc" #-}
instance Binary UnixTime where
        put (UnixTime (CTime sec) msec) = do
            put sec
            put msec
        get = UnixTime <$> (CTime `fmap` get) <*> get

{-# LINE 99 "Data/UnixTime/Types.hsc" #-}

-- |
-- Format of the strptime()/strftime() style.
type Format = ByteString

-- |
-- Data structure for UnixTime diff.
--
-- It is up to the user to ensure that @'udtMicroSeconds' < 1000000@.
-- Helpers such as 'Data.UnixTime.microSecondsToUnixDiffTime' can help
-- you to create valid values. For example, it's a mistake to use
-- 'Data.Text.addUnixDiffTime' with a value @UnixDiffTime 0 9999999@
-- as it will produce an incorrect value back. You should instead use
-- functions such as 'Data.UnixTime.microSecondsToUnixDiffTime' to
-- create values that are in-range. This avoids any gotchas when then
-- doing comparisons.
data UnixDiffTime = UnixDiffTime {
    -- | Seconds
    UnixDiffTime -> CTime
udtSeconds :: {-# UNPACK #-} !CTime
    -- | Micro seconds (i.e. 10^(-6))
  , UnixDiffTime -> Int32
udtMicroSeconds :: {-# UNPACK #-} !Int32
  } deriving (UnixDiffTime -> UnixDiffTime -> Bool
(UnixDiffTime -> UnixDiffTime -> Bool)
-> (UnixDiffTime -> UnixDiffTime -> Bool) -> Eq UnixDiffTime
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UnixDiffTime -> UnixDiffTime -> Bool
== :: UnixDiffTime -> UnixDiffTime -> Bool
$c/= :: UnixDiffTime -> UnixDiffTime -> Bool
/= :: UnixDiffTime -> UnixDiffTime -> Bool
Eq,Eq UnixDiffTime
Eq UnixDiffTime =>
(UnixDiffTime -> UnixDiffTime -> Ordering)
-> (UnixDiffTime -> UnixDiffTime -> Bool)
-> (UnixDiffTime -> UnixDiffTime -> Bool)
-> (UnixDiffTime -> UnixDiffTime -> Bool)
-> (UnixDiffTime -> UnixDiffTime -> Bool)
-> (UnixDiffTime -> UnixDiffTime -> UnixDiffTime)
-> (UnixDiffTime -> UnixDiffTime -> UnixDiffTime)
-> Ord UnixDiffTime
UnixDiffTime -> UnixDiffTime -> Bool
UnixDiffTime -> UnixDiffTime -> Ordering
UnixDiffTime -> UnixDiffTime -> UnixDiffTime
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: UnixDiffTime -> UnixDiffTime -> Ordering
compare :: UnixDiffTime -> UnixDiffTime -> Ordering
$c< :: UnixDiffTime -> UnixDiffTime -> Bool
< :: UnixDiffTime -> UnixDiffTime -> Bool
$c<= :: UnixDiffTime -> UnixDiffTime -> Bool
<= :: UnixDiffTime -> UnixDiffTime -> Bool
$c> :: UnixDiffTime -> UnixDiffTime -> Bool
> :: UnixDiffTime -> UnixDiffTime -> Bool
$c>= :: UnixDiffTime -> UnixDiffTime -> Bool
>= :: UnixDiffTime -> UnixDiffTime -> Bool
$cmax :: UnixDiffTime -> UnixDiffTime -> UnixDiffTime
max :: UnixDiffTime -> UnixDiffTime -> UnixDiffTime
$cmin :: UnixDiffTime -> UnixDiffTime -> UnixDiffTime
min :: UnixDiffTime -> UnixDiffTime -> UnixDiffTime
Ord,Int -> UnixDiffTime -> ShowS
[UnixDiffTime] -> ShowS
UnixDiffTime -> String
(Int -> UnixDiffTime -> ShowS)
-> (UnixDiffTime -> String)
-> ([UnixDiffTime] -> ShowS)
-> Show UnixDiffTime
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> UnixDiffTime -> ShowS
showsPrec :: Int -> UnixDiffTime -> ShowS
$cshow :: UnixDiffTime -> String
show :: UnixDiffTime -> String
$cshowList :: [UnixDiffTime] -> ShowS
showList :: [UnixDiffTime] -> ShowS
Show)