{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Network.QUIC.Types.Time (
    Milliseconds(..)
  , Microseconds(..)
  , milliToMicro
  , microToMilli
  , TimeMicrosecond
  , timeMicrosecond0
  , getTimeMicrosecond
  , getElapsedTimeMicrosecond
  , elapsedTimeMicrosecond
  , getTimeoutInMicrosecond
  , getPastTimeMicrosecond
  , getFutureTimeMicrosecond
  , addMicroseconds
  ) where

import Data.UnixTime
import Foreign.C.Types (CTime(..))

import Network.QUIC.Imports

----------------------------------------------------------------

newtype Milliseconds = Milliseconds Int64 deriving (Milliseconds -> Milliseconds -> Bool
(Milliseconds -> Milliseconds -> Bool)
-> (Milliseconds -> Milliseconds -> Bool) -> Eq Milliseconds
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Milliseconds -> Milliseconds -> Bool
$c/= :: Milliseconds -> Milliseconds -> Bool
== :: Milliseconds -> Milliseconds -> Bool
$c== :: Milliseconds -> Milliseconds -> Bool
Eq, Eq Milliseconds
Eq Milliseconds
-> (Milliseconds -> Milliseconds -> Ordering)
-> (Milliseconds -> Milliseconds -> Bool)
-> (Milliseconds -> Milliseconds -> Bool)
-> (Milliseconds -> Milliseconds -> Bool)
-> (Milliseconds -> Milliseconds -> Bool)
-> (Milliseconds -> Milliseconds -> Milliseconds)
-> (Milliseconds -> Milliseconds -> Milliseconds)
-> Ord Milliseconds
Milliseconds -> Milliseconds -> Bool
Milliseconds -> Milliseconds -> Ordering
Milliseconds -> Milliseconds -> Milliseconds
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
min :: Milliseconds -> Milliseconds -> Milliseconds
$cmin :: Milliseconds -> Milliseconds -> Milliseconds
max :: Milliseconds -> Milliseconds -> Milliseconds
$cmax :: Milliseconds -> Milliseconds -> Milliseconds
>= :: Milliseconds -> Milliseconds -> Bool
$c>= :: Milliseconds -> Milliseconds -> Bool
> :: Milliseconds -> Milliseconds -> Bool
$c> :: Milliseconds -> Milliseconds -> Bool
<= :: Milliseconds -> Milliseconds -> Bool
$c<= :: Milliseconds -> Milliseconds -> Bool
< :: Milliseconds -> Milliseconds -> Bool
$c< :: Milliseconds -> Milliseconds -> Bool
compare :: Milliseconds -> Milliseconds -> Ordering
$ccompare :: Milliseconds -> Milliseconds -> Ordering
$cp1Ord :: Eq Milliseconds
Ord, Integer -> Milliseconds
Milliseconds -> Milliseconds
Milliseconds -> Milliseconds -> Milliseconds
(Milliseconds -> Milliseconds -> Milliseconds)
-> (Milliseconds -> Milliseconds -> Milliseconds)
-> (Milliseconds -> Milliseconds -> Milliseconds)
-> (Milliseconds -> Milliseconds)
-> (Milliseconds -> Milliseconds)
-> (Milliseconds -> Milliseconds)
-> (Integer -> Milliseconds)
-> Num Milliseconds
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Milliseconds
$cfromInteger :: Integer -> Milliseconds
signum :: Milliseconds -> Milliseconds
$csignum :: Milliseconds -> Milliseconds
abs :: Milliseconds -> Milliseconds
$cabs :: Milliseconds -> Milliseconds
negate :: Milliseconds -> Milliseconds
$cnegate :: Milliseconds -> Milliseconds
* :: Milliseconds -> Milliseconds -> Milliseconds
$c* :: Milliseconds -> Milliseconds -> Milliseconds
- :: Milliseconds -> Milliseconds -> Milliseconds
$c- :: Milliseconds -> Milliseconds -> Milliseconds
+ :: Milliseconds -> Milliseconds -> Milliseconds
$c+ :: Milliseconds -> Milliseconds -> Milliseconds
Num, Eq Milliseconds
Milliseconds
Eq Milliseconds
-> (Milliseconds -> Milliseconds -> Milliseconds)
-> (Milliseconds -> Milliseconds -> Milliseconds)
-> (Milliseconds -> Milliseconds -> Milliseconds)
-> (Milliseconds -> Milliseconds)
-> (Milliseconds -> Int -> Milliseconds)
-> (Milliseconds -> Int -> Milliseconds)
-> Milliseconds
-> (Int -> Milliseconds)
-> (Milliseconds -> Int -> Milliseconds)
-> (Milliseconds -> Int -> Milliseconds)
-> (Milliseconds -> Int -> Milliseconds)
-> (Milliseconds -> Int -> Bool)
-> (Milliseconds -> Maybe Int)
-> (Milliseconds -> Int)
-> (Milliseconds -> Bool)
-> (Milliseconds -> Int -> Milliseconds)
-> (Milliseconds -> Int -> Milliseconds)
-> (Milliseconds -> Int -> Milliseconds)
-> (Milliseconds -> Int -> Milliseconds)
-> (Milliseconds -> Int -> Milliseconds)
-> (Milliseconds -> Int -> Milliseconds)
-> (Milliseconds -> Int)
-> Bits Milliseconds
Int -> Milliseconds
Milliseconds -> Bool
Milliseconds -> Int
Milliseconds -> Maybe Int
Milliseconds -> Milliseconds
Milliseconds -> Int -> Bool
Milliseconds -> Int -> Milliseconds
Milliseconds -> Milliseconds -> Milliseconds
forall a.
Eq a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
popCount :: Milliseconds -> Int
$cpopCount :: Milliseconds -> Int
rotateR :: Milliseconds -> Int -> Milliseconds
$crotateR :: Milliseconds -> Int -> Milliseconds
rotateL :: Milliseconds -> Int -> Milliseconds
$crotateL :: Milliseconds -> Int -> Milliseconds
unsafeShiftR :: Milliseconds -> Int -> Milliseconds
$cunsafeShiftR :: Milliseconds -> Int -> Milliseconds
shiftR :: Milliseconds -> Int -> Milliseconds
$cshiftR :: Milliseconds -> Int -> Milliseconds
unsafeShiftL :: Milliseconds -> Int -> Milliseconds
$cunsafeShiftL :: Milliseconds -> Int -> Milliseconds
shiftL :: Milliseconds -> Int -> Milliseconds
$cshiftL :: Milliseconds -> Int -> Milliseconds
isSigned :: Milliseconds -> Bool
$cisSigned :: Milliseconds -> Bool
bitSize :: Milliseconds -> Int
$cbitSize :: Milliseconds -> Int
bitSizeMaybe :: Milliseconds -> Maybe Int
$cbitSizeMaybe :: Milliseconds -> Maybe Int
testBit :: Milliseconds -> Int -> Bool
$ctestBit :: Milliseconds -> Int -> Bool
complementBit :: Milliseconds -> Int -> Milliseconds
$ccomplementBit :: Milliseconds -> Int -> Milliseconds
clearBit :: Milliseconds -> Int -> Milliseconds
$cclearBit :: Milliseconds -> Int -> Milliseconds
setBit :: Milliseconds -> Int -> Milliseconds
$csetBit :: Milliseconds -> Int -> Milliseconds
bit :: Int -> Milliseconds
$cbit :: Int -> Milliseconds
zeroBits :: Milliseconds
$czeroBits :: Milliseconds
rotate :: Milliseconds -> Int -> Milliseconds
$crotate :: Milliseconds -> Int -> Milliseconds
shift :: Milliseconds -> Int -> Milliseconds
$cshift :: Milliseconds -> Int -> Milliseconds
complement :: Milliseconds -> Milliseconds
$ccomplement :: Milliseconds -> Milliseconds
xor :: Milliseconds -> Milliseconds -> Milliseconds
$cxor :: Milliseconds -> Milliseconds -> Milliseconds
.|. :: Milliseconds -> Milliseconds -> Milliseconds
$c.|. :: Milliseconds -> Milliseconds -> Milliseconds
.&. :: Milliseconds -> Milliseconds -> Milliseconds
$c.&. :: Milliseconds -> Milliseconds -> Milliseconds
$cp1Bits :: Eq Milliseconds
Bits)
newtype Microseconds = Microseconds Int deriving (Microseconds -> Microseconds -> Bool
(Microseconds -> Microseconds -> Bool)
-> (Microseconds -> Microseconds -> Bool) -> Eq Microseconds
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Microseconds -> Microseconds -> Bool
$c/= :: Microseconds -> Microseconds -> Bool
== :: Microseconds -> Microseconds -> Bool
$c== :: Microseconds -> Microseconds -> Bool
Eq, Eq Microseconds
Eq Microseconds
-> (Microseconds -> Microseconds -> Ordering)
-> (Microseconds -> Microseconds -> Bool)
-> (Microseconds -> Microseconds -> Bool)
-> (Microseconds -> Microseconds -> Bool)
-> (Microseconds -> Microseconds -> Bool)
-> (Microseconds -> Microseconds -> Microseconds)
-> (Microseconds -> Microseconds -> Microseconds)
-> Ord Microseconds
Microseconds -> Microseconds -> Bool
Microseconds -> Microseconds -> Ordering
Microseconds -> Microseconds -> Microseconds
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
min :: Microseconds -> Microseconds -> Microseconds
$cmin :: Microseconds -> Microseconds -> Microseconds
max :: Microseconds -> Microseconds -> Microseconds
$cmax :: Microseconds -> Microseconds -> Microseconds
>= :: Microseconds -> Microseconds -> Bool
$c>= :: Microseconds -> Microseconds -> Bool
> :: Microseconds -> Microseconds -> Bool
$c> :: Microseconds -> Microseconds -> Bool
<= :: Microseconds -> Microseconds -> Bool
$c<= :: Microseconds -> Microseconds -> Bool
< :: Microseconds -> Microseconds -> Bool
$c< :: Microseconds -> Microseconds -> Bool
compare :: Microseconds -> Microseconds -> Ordering
$ccompare :: Microseconds -> Microseconds -> Ordering
$cp1Ord :: Eq Microseconds
Ord, Integer -> Microseconds
Microseconds -> Microseconds
Microseconds -> Microseconds -> Microseconds
(Microseconds -> Microseconds -> Microseconds)
-> (Microseconds -> Microseconds -> Microseconds)
-> (Microseconds -> Microseconds -> Microseconds)
-> (Microseconds -> Microseconds)
-> (Microseconds -> Microseconds)
-> (Microseconds -> Microseconds)
-> (Integer -> Microseconds)
-> Num Microseconds
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Microseconds
$cfromInteger :: Integer -> Microseconds
signum :: Microseconds -> Microseconds
$csignum :: Microseconds -> Microseconds
abs :: Microseconds -> Microseconds
$cabs :: Microseconds -> Microseconds
negate :: Microseconds -> Microseconds
$cnegate :: Microseconds -> Microseconds
* :: Microseconds -> Microseconds -> Microseconds
$c* :: Microseconds -> Microseconds -> Microseconds
- :: Microseconds -> Microseconds -> Microseconds
$c- :: Microseconds -> Microseconds -> Microseconds
+ :: Microseconds -> Microseconds -> Microseconds
$c+ :: Microseconds -> Microseconds -> Microseconds
Num, Eq Microseconds
Microseconds
Eq Microseconds
-> (Microseconds -> Microseconds -> Microseconds)
-> (Microseconds -> Microseconds -> Microseconds)
-> (Microseconds -> Microseconds -> Microseconds)
-> (Microseconds -> Microseconds)
-> (Microseconds -> Int -> Microseconds)
-> (Microseconds -> Int -> Microseconds)
-> Microseconds
-> (Int -> Microseconds)
-> (Microseconds -> Int -> Microseconds)
-> (Microseconds -> Int -> Microseconds)
-> (Microseconds -> Int -> Microseconds)
-> (Microseconds -> Int -> Bool)
-> (Microseconds -> Maybe Int)
-> (Microseconds -> Int)
-> (Microseconds -> Bool)
-> (Microseconds -> Int -> Microseconds)
-> (Microseconds -> Int -> Microseconds)
-> (Microseconds -> Int -> Microseconds)
-> (Microseconds -> Int -> Microseconds)
-> (Microseconds -> Int -> Microseconds)
-> (Microseconds -> Int -> Microseconds)
-> (Microseconds -> Int)
-> Bits Microseconds
Int -> Microseconds
Microseconds -> Bool
Microseconds -> Int
Microseconds -> Maybe Int
Microseconds -> Microseconds
Microseconds -> Int -> Bool
Microseconds -> Int -> Microseconds
Microseconds -> Microseconds -> Microseconds
forall a.
Eq a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
popCount :: Microseconds -> Int
$cpopCount :: Microseconds -> Int
rotateR :: Microseconds -> Int -> Microseconds
$crotateR :: Microseconds -> Int -> Microseconds
rotateL :: Microseconds -> Int -> Microseconds
$crotateL :: Microseconds -> Int -> Microseconds
unsafeShiftR :: Microseconds -> Int -> Microseconds
$cunsafeShiftR :: Microseconds -> Int -> Microseconds
shiftR :: Microseconds -> Int -> Microseconds
$cshiftR :: Microseconds -> Int -> Microseconds
unsafeShiftL :: Microseconds -> Int -> Microseconds
$cunsafeShiftL :: Microseconds -> Int -> Microseconds
shiftL :: Microseconds -> Int -> Microseconds
$cshiftL :: Microseconds -> Int -> Microseconds
isSigned :: Microseconds -> Bool
$cisSigned :: Microseconds -> Bool
bitSize :: Microseconds -> Int
$cbitSize :: Microseconds -> Int
bitSizeMaybe :: Microseconds -> Maybe Int
$cbitSizeMaybe :: Microseconds -> Maybe Int
testBit :: Microseconds -> Int -> Bool
$ctestBit :: Microseconds -> Int -> Bool
complementBit :: Microseconds -> Int -> Microseconds
$ccomplementBit :: Microseconds -> Int -> Microseconds
clearBit :: Microseconds -> Int -> Microseconds
$cclearBit :: Microseconds -> Int -> Microseconds
setBit :: Microseconds -> Int -> Microseconds
$csetBit :: Microseconds -> Int -> Microseconds
bit :: Int -> Microseconds
$cbit :: Int -> Microseconds
zeroBits :: Microseconds
$czeroBits :: Microseconds
rotate :: Microseconds -> Int -> Microseconds
$crotate :: Microseconds -> Int -> Microseconds
shift :: Microseconds -> Int -> Microseconds
$cshift :: Microseconds -> Int -> Microseconds
complement :: Microseconds -> Microseconds
$ccomplement :: Microseconds -> Microseconds
xor :: Microseconds -> Microseconds -> Microseconds
$cxor :: Microseconds -> Microseconds -> Microseconds
.|. :: Microseconds -> Microseconds -> Microseconds
$c.|. :: Microseconds -> Microseconds -> Microseconds
.&. :: Microseconds -> Microseconds -> Microseconds
$c.&. :: Microseconds -> Microseconds -> Microseconds
$cp1Bits :: Eq Microseconds
Bits)

instance Show Milliseconds where
  show :: Milliseconds -> String
show (Milliseconds Int64
n) = Int64 -> String
forall a. Show a => a -> String
show Int64
n

instance Show Microseconds where
  show :: Microseconds -> String
show (Microseconds Int
n) = Int -> String
forall a. Show a => a -> String
show Int
n

{-# INLINE milliToMicro #-}
milliToMicro :: Milliseconds -> Microseconds
milliToMicro :: Milliseconds -> Microseconds
milliToMicro (Milliseconds Int64
n) = Int -> Microseconds
Microseconds (Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
1000)

microToMilli :: Microseconds -> Milliseconds
microToMilli :: Microseconds -> Milliseconds
microToMilli (Microseconds Int
n) = Int64 -> Milliseconds
Milliseconds (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n Int64 -> Int64 -> Int64
forall a. Integral a => a -> a -> a
`div` Int64
1000)

----------------------------------------------------------------

type TimeMicrosecond = UnixTime

timeMicrosecond0 :: UnixTime
timeMicrosecond0 :: UnixTime
timeMicrosecond0 = CTime -> Int32 -> UnixTime
UnixTime CTime
0 Int32
0

----------------------------------------------------------------

getTimeMicrosecond :: IO TimeMicrosecond
getTimeMicrosecond :: IO UnixTime
getTimeMicrosecond = IO UnixTime
getUnixTime

----------------------------------------------------------------

getElapsedTimeMicrosecond :: TimeMicrosecond -> IO Microseconds
getElapsedTimeMicrosecond :: UnixTime -> IO Microseconds
getElapsedTimeMicrosecond UnixTime
base = do
    UnixTime
c <- IO UnixTime
getTimeMicrosecond
    Microseconds -> IO Microseconds
forall (m :: * -> *) a. Monad m => a -> m a
return (Microseconds -> IO Microseconds)
-> Microseconds -> IO Microseconds
forall a b. (a -> b) -> a -> b
$ UnixTime -> UnixTime -> Microseconds
elapsedTimeMicrosecond UnixTime
c UnixTime
base

elapsedTimeMicrosecond :: UnixTime -> UnixTime -> Microseconds
elapsedTimeMicrosecond :: UnixTime -> UnixTime -> Microseconds
elapsedTimeMicrosecond UnixTime
c UnixTime
base = Int -> Microseconds
Microseconds Int
elapsed
  where
    UnixDiffTime (CTime Int64
s) Int32
u = UnixTime
c UnixTime -> UnixTime -> UnixDiffTime
`diffUnixTime` UnixTime
base
    elapsed :: Int
elapsed = Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64
s Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
* Int64
1000000 Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
+ Int32 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
u)

getTimeoutInMicrosecond :: TimeMicrosecond -> IO Microseconds
getTimeoutInMicrosecond :: UnixTime -> IO Microseconds
getTimeoutInMicrosecond UnixTime
tmout = do
    UnixTime
c <- IO UnixTime
getTimeMicrosecond
    let UnixDiffTime (CTime Int64
s) Int32
u = UnixTime
tmout UnixTime -> UnixTime -> UnixDiffTime
`diffUnixTime` UnixTime
c
        timeout :: Int
timeout = Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
s Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
1000000 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
u
    Microseconds -> IO Microseconds
forall (m :: * -> *) a. Monad m => a -> m a
return (Microseconds -> IO Microseconds)
-> Microseconds -> IO Microseconds
forall a b. (a -> b) -> a -> b
$ Int -> Microseconds
Microseconds Int
timeout

----------------------------------------------------------------

getPastTimeMicrosecond :: Microseconds -> IO TimeMicrosecond
getPastTimeMicrosecond :: Microseconds -> IO UnixTime
getPastTimeMicrosecond (Microseconds Int
us) = do
    let diff :: UnixDiffTime
diff = Int -> UnixDiffTime
forall a. Integral a => a -> UnixDiffTime
microSecondsToUnixDiffTime (Int -> UnixDiffTime) -> Int -> UnixDiffTime
forall a b. (a -> b) -> a -> b
$ Int -> Int
forall a. Num a => a -> a
negate Int
us
    UnixTime
c <- IO UnixTime
getTimeMicrosecond
    let past :: UnixTime
past = UnixTime
c UnixTime -> UnixDiffTime -> UnixTime
`addUnixDiffTime` UnixDiffTime
diff
    UnixTime -> IO UnixTime
forall (m :: * -> *) a. Monad m => a -> m a
return UnixTime
past

getFutureTimeMicrosecond :: Microseconds -> IO TimeMicrosecond
getFutureTimeMicrosecond :: Microseconds -> IO UnixTime
getFutureTimeMicrosecond (Microseconds Int
us) = do
    let diff :: UnixDiffTime
diff = Int -> UnixDiffTime
forall a. Integral a => a -> UnixDiffTime
microSecondsToUnixDiffTime Int
us
    UnixTime
c <- IO UnixTime
getTimeMicrosecond
    let future :: UnixTime
future = UnixTime
c UnixTime -> UnixDiffTime -> UnixTime
`addUnixDiffTime` UnixDiffTime
diff
    UnixTime -> IO UnixTime
forall (m :: * -> *) a. Monad m => a -> m a
return UnixTime
future

addMicroseconds :: TimeMicrosecond -> Microseconds -> TimeMicrosecond
addMicroseconds :: UnixTime -> Microseconds -> UnixTime
addMicroseconds UnixTime
t (Microseconds Int
n) = UnixTime
t UnixTime -> UnixDiffTime -> UnixTime
`addUnixDiffTime` Int -> UnixDiffTime
forall a. Integral a => a -> UnixDiffTime
microSecondsToUnixDiffTime Int
n