quic-0.3.3: Network/QUIC/Utils.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
module Network.QUIC.Utils where
import qualified Control.Exception as E
import Control.Monad (replicateM)
import qualified Data.ByteString as BS
import Data.ByteString.Base16
import qualified Data.ByteString.Char8 as C8
import Data.ByteString.Internal (ByteString (..))
import Data.ByteString.Short (ShortByteString)
import qualified Data.ByteString.Short as Short
import Data.Char (chr)
#if __GLASGOW_HASKELL__ < 910
import Data.List (foldl')
#endif
import Data.Word
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Ptr (Ptr, plusPtr)
import System.Random (randomIO)
-- GHC 8.0 does not provide fromRight.
fromRight :: b -> Either a b -> b
fromRight _ (Right b) = b
fromRight b _ = b
dec16 :: ByteString -> ByteString
dec16 = fromRight "" . decode
enc16 :: ByteString -> ByteString
enc16 = encode
dec16s :: ShortByteString -> ShortByteString
dec16s = Short.toShort . fromRight "" . decode . Short.fromShort
enc16s :: ShortByteString -> ShortByteString
enc16s = Short.toShort . encode . Short.fromShort
shortToString :: ShortByteString -> String
shortToString = map (chr . fromIntegral) . Short.unpack
getRandomOneByte :: IO Word8
getRandomOneByte = randomIO
getRandomBytes :: Int -> IO ShortByteString
getRandomBytes n = Short.pack <$> replicateM n getRandomOneByte
{-# INLINE totalLen #-}
totalLen :: [ByteString] -> Int
totalLen = foldl' (\n bs -> n + BS.length bs) 0
sum' :: (Functor f, Foldable f) => f Int -> Int
sum' = foldl' (+) 0
withByteString :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteString (PS fptr off _) f = withForeignPtr fptr $ \ptr ->
f (ptr `plusPtr` off)
shortpack :: String -> ShortByteString
shortpack = Short.toShort . C8.pack
ignore :: E.SomeException -> IO ()
ignore se
| isAsyncException se = E.throwIO se
| otherwise = return ()
isAsyncException :: E.Exception e => e -> Bool
isAsyncException e =
case E.fromException (E.toException e) of
Just (E.SomeAsyncException _) -> True
Nothing -> False
throughAsync :: IO a -> E.SomeException -> IO a
throughAsync action (E.SomeException e)
| isAsyncException e = E.throwIO e
| otherwise = action