module Network.QUIC.Packet.Number (
    encodePacketNumber,
    decodePacketNumber,
) where

import Network.QUIC.Imports
import Network.QUIC.Types

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

-- |
--
-- >>> encodePacketNumber 0xabe8bc 0xac5c02 == (0x5c02,2)
-- True
-- >>> encodePacketNumber 0xa82f30ea 0xa82f9b32 == (0x9b32,2)
-- True
-- >>> encodePacketNumber 0xabe8bc 0xace8fe == (0xace8fe, 3)
-- True
{- FOURMOLU_DISABLE -}
encodePacketNumber :: PacketNumber -> PacketNumber -> (EncodedPacketNumber, Int)
encodePacketNumber :: PacketNumber -> PacketNumber -> (EncodedPacketNumber, PacketNumber)
encodePacketNumber PacketNumber
largestPN PacketNumber
pn = (EncodedPacketNumber
diff, PacketNumber
bytes)
  where
    enoughRange :: PacketNumber
enoughRange = (PacketNumber
pn forall a. Num a => a -> a -> a
- PacketNumber
largestPN) forall a. Num a => a -> a -> a
* PacketNumber
2
    (PacketNumber
pnMask, PacketNumber
bytes)
--      | enoughRange <      256 = (0x000000ff, 1)
      | PacketNumber
enoughRange forall a. Ord a => a -> a -> Bool
<    PacketNumber
65536 = (PacketNumber
0x0000ffff, PacketNumber
2)
      | PacketNumber
enoughRange forall a. Ord a => a -> a -> Bool
< PacketNumber
16777216 = (PacketNumber
0x00ffffff, PacketNumber
3)
      | Bool
otherwise              = (PacketNumber
0xffffffff, PacketNumber
4)
    diff :: EncodedPacketNumber
diff = forall a b. (Integral a, Num b) => a -> b
fromIntegral (PacketNumber
pn forall a. Bits a => a -> a -> a
.&. PacketNumber
pnMask)
{- FOURMOLU_ENABLE -}

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

-- |
--
-- >>> decodePacketNumber 0xabe8bc 0x5c02 2 == 0xac5c02
-- True
-- >>> decodePacketNumber 0xa82f30ea 0x9b32 2 == 0xa82f9b32
-- True
-- >>> decodePacketNumber 0xabe8bc 0xace8fe 3 == 0xace8fe
-- True
{- FOURMOLU_DISABLE -}
decodePacketNumber :: PacketNumber -> EncodedPacketNumber -> Int -> PacketNumber
decodePacketNumber :: PacketNumber -> EncodedPacketNumber -> PacketNumber -> PacketNumber
decodePacketNumber PacketNumber
largestPN EncodedPacketNumber
truncatedPN PacketNumber
bytes
  | PacketNumber
candidatePN forall a. Ord a => a -> a -> Bool
<= PacketNumber
expectedPN forall a. Num a => a -> a -> a
- PacketNumber
pnHwin
 Bool -> Bool -> Bool
&& PacketNumber
candidatePN forall a. Ord a => a -> a -> Bool
<  PacketNumber
mx forall a. Num a => a -> a -> a
- PacketNumber
pnWin          = PacketNumber
candidatePN forall a. Num a => a -> a -> a
+ PacketNumber
pnWin
  | PacketNumber
candidatePN forall a. Ord a => a -> a -> Bool
>  PacketNumber
expectedPN forall a. Num a => a -> a -> a
+ PacketNumber
pnHwin
 Bool -> Bool -> Bool
&& PacketNumber
candidatePN forall a. Ord a => a -> a -> Bool
>= PacketNumber
pnWin               = PacketNumber
candidatePN forall a. Num a => a -> a -> a
- PacketNumber
pnWin
  | Bool
otherwise                          = PacketNumber
candidatePN
  where
    mx :: PacketNumber
mx = PacketNumber
1 forall a. Bits a => a -> PacketNumber -> a
!<<. PacketNumber
62
    pnNbits :: PacketNumber
pnNbits = PacketNumber
bytes forall a. Num a => a -> a -> a
* PacketNumber
8
    expectedPN :: PacketNumber
expectedPN = PacketNumber
largestPN forall a. Num a => a -> a -> a
+ PacketNumber
1
    pnWin :: PacketNumber
pnWin = PacketNumber
1 forall a. Bits a => a -> PacketNumber -> a
!<<. PacketNumber
pnNbits
    pnHwin :: PacketNumber
pnHwin = PacketNumber
pnWin forall a. Bits a => a -> PacketNumber -> a
!>>. PacketNumber
1
    pnMask :: PacketNumber
pnMask = PacketNumber
pnWin forall a. Num a => a -> a -> a
- PacketNumber
1
    candidatePN :: PacketNumber
candidatePN = (PacketNumber
expectedPN forall a. Bits a => a -> a -> a
.&. forall a. Bits a => a -> a
complement PacketNumber
pnMask)
              forall a. Bits a => a -> a -> a
.|. forall a b. (Integral a, Num b) => a -> b
fromIntegral EncodedPacketNumber
truncatedPN
{- FOURMOLU_ENABLE -}