{-# OPTIONS_GHC -funbox-strict-fields #-}

{-|
Module      : Database.MySQL.Protocol.Packet
Description : MySQL packet type and various helpers.
Copyright   : (c) Winterland, 2016
License     : BSD
Maintainer  : drkoster@qq.com
Stability   : experimental
Portability : PORTABLE

MySQL packet decoder&encoder, and varities utility.

-}

module Database.MySQL.Protocol.Packet where

import           Control.Exception     (Exception (..), throwIO)
import           Data.Binary.Parser
import           Data.Binary.Put
import           Data.Binary           (Binary(..), encode)
import           Data.Bits
import qualified Data.ByteString       as B
import           Data.ByteString.Char8 as BC
import qualified Data.ByteString.Lazy  as L
import           Data.Int.Int24
import           Data.Int
import           Data.Word
import           Data.Typeable
import           Data.Word.Word24

--------------------------------------------------------------------------------
-- | MySQL packet type
--
data Packet = Packet
    { Packet -> Int64
pLen  :: !Int64
    , Packet -> Word8
pSeqN :: !Word8
    , Packet -> ByteString
pBody :: !L.ByteString
    } deriving (Int -> Packet -> ShowS
[Packet] -> ShowS
Packet -> String
(Int -> Packet -> ShowS)
-> (Packet -> String) -> ([Packet] -> ShowS) -> Show Packet
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Packet -> ShowS
showsPrec :: Int -> Packet -> ShowS
$cshow :: Packet -> String
show :: Packet -> String
$cshowList :: [Packet] -> ShowS
showList :: [Packet] -> ShowS
Show, Packet -> Packet -> Bool
(Packet -> Packet -> Bool)
-> (Packet -> Packet -> Bool) -> Eq Packet
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Packet -> Packet -> Bool
== :: Packet -> Packet -> Bool
$c/= :: Packet -> Packet -> Bool
/= :: Packet -> Packet -> Bool
Eq)

putPacket :: Packet -> Put
putPacket :: Packet -> Put
putPacket (Packet Int64
len Word8
seqN ByteString
body)  = do
    Word32 -> Put
putWord24le (Int64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
len)
    Word8 -> Put
putWord8 Word8
seqN
    ByteString -> Put
putLazyByteString ByteString
body
{-# INLINE putPacket #-}

getPacket :: Get Packet
getPacket :: Get Packet
getPacket = do
    Int64
len <- Word32 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int64) -> Get Word32 -> Get Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
getWord24le
    Word8
seqN <- Get Word8
getWord8
    ByteString
body <- Int64 -> Get ByteString
getLazyByteString Int64
len
    Packet -> Get Packet
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int64 -> Word8 -> ByteString -> Packet
Packet Int64
len Word8
seqN ByteString
body)
{-# INLINE getPacket #-}

instance Binary Packet where
    put :: Packet -> Put
put = Packet -> Put
putPacket
    {-# INLINE put #-}
    get :: Get Packet
get = Get Packet
getPacket
    {-# INLINE get #-}

isERR :: Packet -> Bool
isERR :: Packet -> Bool
isERR Packet
p = HasCallStack => ByteString -> Int64 -> Word8
ByteString -> Int64 -> Word8
L.index (Packet -> ByteString
pBody Packet
p) Int64
0 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0xFF
{-# INLINE isERR #-}

isOK :: Packet -> Bool
isOK :: Packet -> Bool
isOK Packet
p  = HasCallStack => ByteString -> Int64 -> Word8
ByteString -> Int64 -> Word8
L.index (Packet -> ByteString
pBody Packet
p) Int64
0 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0x00
{-# INLINE isOK #-}

isEOF :: Packet -> Bool
isEOF :: Packet -> Bool
isEOF Packet
p = HasCallStack => ByteString -> Int64 -> Word8
ByteString -> Int64 -> Word8
L.index (Packet -> ByteString
pBody Packet
p) Int64
0 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0xFE
{-# INLINE isEOF #-}

-- | Is there more packet to be read?
--
--  https://dev.mysql.com/doc/internals/en/status-flags.html
isThereMore :: OK -> Bool
isThereMore :: OK -> Bool
isThereMore OK
p  = OK -> Word16
okStatus OK
p Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0x08 Word16 -> Word16 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word16
0
{-# INLINE isThereMore #-}

-- | Decoding packet inside IO, throw 'DecodePacketException' on fail parsing,
-- here we choose stability over correctness by omit incomplete consumed case:
-- if we successful parse a packet, then we don't care if there're bytes left.
--
decodeFromPacket :: Binary a => Packet -> IO a
decodeFromPacket :: forall a. Binary a => Packet -> IO a
decodeFromPacket = Get a -> Packet -> IO a
forall a. Get a -> Packet -> IO a
getFromPacket Get a
forall t. Binary t => Get t
get
{-# INLINE decodeFromPacket #-}

getFromPacket :: Get a -> Packet -> IO a
getFromPacket :: forall a. Get a -> Packet -> IO a
getFromPacket Get a
g (Packet Int64
_ Word8
_ ByteString
body) = case Get a
-> ByteString
-> Either (ByteString, Int64, String) (ByteString, Int64, a)
forall a.
Get a
-> ByteString
-> Either (ByteString, Int64, String) (ByteString, Int64, a)
parseDetailLazy Get a
g ByteString
body of
    Left  (ByteString
buf, Int64
offset, String
errmsg) -> DecodePacketException -> IO a
forall e a. Exception e => e -> IO a
throwIO (ByteString -> Int64 -> String -> DecodePacketException
DecodePacketFailed ByteString
buf Int64
offset String
errmsg)
    Right (ByteString
_,   Int64
_,      a
r     ) -> a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
{-# INLINE getFromPacket #-}

data DecodePacketException = DecodePacketFailed ByteString ByteOffset String
  deriving (Typeable, Int -> DecodePacketException -> ShowS
[DecodePacketException] -> ShowS
DecodePacketException -> String
(Int -> DecodePacketException -> ShowS)
-> (DecodePacketException -> String)
-> ([DecodePacketException] -> ShowS)
-> Show DecodePacketException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DecodePacketException -> ShowS
showsPrec :: Int -> DecodePacketException -> ShowS
$cshow :: DecodePacketException -> String
show :: DecodePacketException -> String
$cshowList :: [DecodePacketException] -> ShowS
showList :: [DecodePacketException] -> ShowS
Show)
instance Exception DecodePacketException

encodeToPacket :: Binary a => Word8 -> a -> Packet
encodeToPacket :: forall a. Binary a => Word8 -> a -> Packet
encodeToPacket Word8
seqN a
payload =
    let s :: ByteString
s = a -> ByteString
forall a. Binary a => a -> ByteString
encode a
payload
        l :: Int64
l = ByteString -> Int64
L.length ByteString
s
    in Int64 -> Word8 -> ByteString -> Packet
Packet Int64
l Word8
seqN ByteString
s
{-# INLINE encodeToPacket #-}

putToPacket :: Word8 -> Put -> Packet
putToPacket :: Word8 -> Put -> Packet
putToPacket Word8
seqN Put
payload =
    let s :: ByteString
s = Put -> ByteString
runPut Put
payload
        l :: Int64
l = ByteString -> Int64
L.length ByteString
s
    in Int64 -> Word8 -> ByteString -> Packet
Packet Int64
l Word8
seqN ByteString
s
{-# INLINE putToPacket #-}

--------------------------------------------------------------------------------
-- OK, ERR, EOF

-- | You may get interested in 'OK' packet because it provides information about
-- successful operations.
--
data OK = OK
    { OK -> Int
okAffectedRows :: !Int      -- ^ affected row number
    , OK -> Int
okLastInsertID :: !Int      -- ^ last insert's ID
    , OK -> Word16
okStatus       :: !Word16
    , OK -> Word16
okWarningCnt   :: !Word16
    } deriving (Int -> OK -> ShowS
[OK] -> ShowS
OK -> String
(Int -> OK -> ShowS)
-> (OK -> String) -> ([OK] -> ShowS) -> Show OK
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> OK -> ShowS
showsPrec :: Int -> OK -> ShowS
$cshow :: OK -> String
show :: OK -> String
$cshowList :: [OK] -> ShowS
showList :: [OK] -> ShowS
Show, OK -> OK -> Bool
(OK -> OK -> Bool) -> (OK -> OK -> Bool) -> Eq OK
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: OK -> OK -> Bool
== :: OK -> OK -> Bool
$c/= :: OK -> OK -> Bool
/= :: OK -> OK -> Bool
Eq)

getOK :: Get OK
getOK :: Get OK
getOK = Int -> Int -> Word16 -> Word16 -> OK
OK (Int -> Int -> Word16 -> Word16 -> OK)
-> Get () -> Get (Int -> Int -> Word16 -> Word16 -> OK)
forall a b. a -> Get b -> Get a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Int -> Get ()
skipN Int
1
           Get (Int -> Int -> Word16 -> Word16 -> OK)
-> Get Int -> Get (Int -> Word16 -> Word16 -> OK)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Int
getLenEncInt
           Get (Int -> Word16 -> Word16 -> OK)
-> Get Int -> Get (Word16 -> Word16 -> OK)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Int
getLenEncInt
           Get (Word16 -> Word16 -> OK) -> Get Word16 -> Get (Word16 -> OK)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word16
getWord16le
           Get (Word16 -> OK) -> Get Word16 -> Get OK
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word16
getWord16le
{-# INLINE getOK #-}

putOK :: OK -> Put
putOK :: OK -> Put
putOK (OK Int
row Int
lid Word16
stat Word16
wcnt) = do
    Word8 -> Put
putWord8 Word8
0x00
    Int -> Put
putLenEncInt Int
row
    Int -> Put
putLenEncInt Int
lid
    Word16 -> Put
putWord16le Word16
stat
    Word16 -> Put
putWord16le Word16
wcnt
{-# INLINE putOK #-}

instance Binary OK where
    get :: Get OK
get = Get OK
getOK
    {-# INLINE get #-}
    put :: OK -> Put
put = OK -> Put
putOK
    {-# INLINE put #-}

data ERR = ERR
    { ERR -> Word16
errCode  :: !Word16
    , ERR -> ByteString
errState :: !ByteString
    , ERR -> ByteString
errMsg   :: !ByteString
    } deriving (Int -> ERR -> ShowS
[ERR] -> ShowS
ERR -> String
(Int -> ERR -> ShowS)
-> (ERR -> String) -> ([ERR] -> ShowS) -> Show ERR
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ERR -> ShowS
showsPrec :: Int -> ERR -> ShowS
$cshow :: ERR -> String
show :: ERR -> String
$cshowList :: [ERR] -> ShowS
showList :: [ERR] -> ShowS
Show, ERR -> ERR -> Bool
(ERR -> ERR -> Bool) -> (ERR -> ERR -> Bool) -> Eq ERR
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ERR -> ERR -> Bool
== :: ERR -> ERR -> Bool
$c/= :: ERR -> ERR -> Bool
/= :: ERR -> ERR -> Bool
Eq)

getERR :: Get ERR
getERR :: Get ERR
getERR = Word16 -> ByteString -> ByteString -> ERR
ERR (Word16 -> ByteString -> ByteString -> ERR)
-> Get () -> Get (Word16 -> ByteString -> ByteString -> ERR)
forall a b. a -> Get b -> Get a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$  Int -> Get ()
skipN Int
1
             Get (Word16 -> ByteString -> ByteString -> ERR)
-> Get Word16 -> Get (ByteString -> ByteString -> ERR)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word16
getWord16le
             Get (ByteString -> ByteString -> ERR)
-> Get () -> Get (ByteString -> ByteString -> ERR)
forall a b. Get a -> Get b -> Get a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*  Int -> Get ()
skipN Int
1
             Get (ByteString -> ByteString -> ERR)
-> Get ByteString -> Get (ByteString -> ERR)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> Get ByteString
getByteString Int
5
             Get (ByteString -> ERR) -> Get ByteString -> Get ERR
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get ByteString
getRemainingByteString
{-# INLINE getERR #-}

putERR :: ERR -> Put
putERR :: ERR -> Put
putERR (ERR Word16
code ByteString
stat ByteString
msg) = do
    Word8 -> Put
putWord8 Word8
0xFF
    Word16 -> Put
putWord16le Word16
code
    Word8 -> Put
putWord8 Word8
35 -- '#'
    ByteString -> Put
putByteString ByteString
stat
    ByteString -> Put
putByteString ByteString
msg
{-# INLINE putERR #-}

instance Binary ERR where
    get :: Get ERR
get = Get ERR
getERR
    {-# INLINE get #-}
    put :: ERR -> Put
put = ERR -> Put
putERR
    {-# INLINE put #-}

data EOF = EOF
    { EOF -> Word16
eofWarningCnt :: !Word16
    , EOF -> Word16
eofStatus     :: !Word16
    } deriving (Int -> EOF -> ShowS
[EOF] -> ShowS
EOF -> String
(Int -> EOF -> ShowS)
-> (EOF -> String) -> ([EOF] -> ShowS) -> Show EOF
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EOF -> ShowS
showsPrec :: Int -> EOF -> ShowS
$cshow :: EOF -> String
show :: EOF -> String
$cshowList :: [EOF] -> ShowS
showList :: [EOF] -> ShowS
Show, EOF -> EOF -> Bool
(EOF -> EOF -> Bool) -> (EOF -> EOF -> Bool) -> Eq EOF
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EOF -> EOF -> Bool
== :: EOF -> EOF -> Bool
$c/= :: EOF -> EOF -> Bool
/= :: EOF -> EOF -> Bool
Eq)

getEOF :: Get EOF
getEOF :: Get EOF
getEOF = Word16 -> Word16 -> EOF
EOF (Word16 -> Word16 -> EOF)
-> Get () -> Get (Word16 -> Word16 -> EOF)
forall a b. a -> Get b -> Get a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$  Int -> Get ()
skipN Int
1
             Get (Word16 -> Word16 -> EOF) -> Get Word16 -> Get (Word16 -> EOF)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word16
getWord16le
             Get (Word16 -> EOF) -> Get Word16 -> Get EOF
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word16
getWord16le
{-# INLINE getEOF #-}

putEOF :: EOF -> Put
putEOF :: EOF -> Put
putEOF (EOF Word16
wcnt Word16
stat) = do
    Word8 -> Put
putWord8 Word8
0xFE
    Word16 -> Put
putWord16le Word16
wcnt
    Word16 -> Put
putWord16le Word16
stat
{-# INLINE putEOF #-}

instance Binary EOF where
    get :: Get EOF
get = Get EOF
getEOF
    {-# INLINE get #-}
    put :: EOF -> Put
put = EOF -> Put
putEOF
    {-# INLINE put #-}

--------------------------------------------------------------------------------
--  Helpers

getByteStringNul :: Get ByteString
getByteStringNul :: Get ByteString
getByteStringNul = ByteString -> ByteString
L.toStrict (ByteString -> ByteString) -> Get ByteString -> Get ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get ByteString
getLazyByteStringNul
{-# INLINE getByteStringNul #-}

getRemainingByteString :: Get ByteString
getRemainingByteString :: Get ByteString
getRemainingByteString = ByteString -> ByteString
L.toStrict (ByteString -> ByteString) -> Get ByteString -> Get ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get ByteString
getRemainingLazyByteString
{-# INLINE getRemainingByteString #-}

putLenEncBytes :: ByteString -> Put
putLenEncBytes :: ByteString -> Put
putLenEncBytes ByteString
c = do
    Int -> Put
putLenEncInt (ByteString -> Int
B.length ByteString
c)
    ByteString -> Put
putByteString ByteString
c
{-# INLINE putLenEncBytes #-}

getLenEncBytes :: Get ByteString
getLenEncBytes :: Get ByteString
getLenEncBytes = Get Int
getLenEncInt Get Int -> (Int -> Get ByteString) -> Get ByteString
forall a b. Get a -> (a -> Get b) -> Get b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Get ByteString
getByteString
{-# INLINE getLenEncBytes #-}

-- | length encoded int
-- https://dev.mysql.com/doc/internals/en/integer.html#packet-Protocol::LengthEncodedInteger
getLenEncInt:: Get Int
getLenEncInt :: Get Int
getLenEncInt = Get Word8
getWord8 Get Word8 -> (Word8 -> Get Int) -> Get Int
forall a b. Get a -> (a -> Get b) -> Get b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Word8 -> Get Int
forall {a} {a}. (Integral a, Num a, Show a) => a -> Get a
word2Len
  where
    word2Len :: a -> Get a
word2Len a
l
         | a
l a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<  a
0xFB  = a -> Get a
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
l)
         | a
l a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xFC  = Word16 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> a) -> Get Word16 -> Get a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
getWord16le
         | a
l a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xFD  = Word32 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> a) -> Get Word32 -> Get a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
getWord24le
         | a
l a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xFE  = Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> a) -> Get Word64 -> Get a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
getWord64le
         | Bool
otherwise = String -> Get a
forall a. String -> Get a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Get a) -> String -> Get a
forall a b. (a -> b) -> a -> b
$ String
"invalid length val " String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
l
{-# INLINE getLenEncInt #-}

putLenEncInt:: Int -> Put
putLenEncInt :: Int -> Put
putLenEncInt Int
x
         | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<  Int
251      = Word8 -> Put
putWord8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x)
         | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
65536     = Word8 -> Put
putWord8 Word8
0xFC Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word16 -> Put
putWord16le (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x)
         | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
16777216  = Word8 -> Put
putWord8 Word8
0xFD Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word32 -> Put
putWord24le (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x)
         | Bool
otherwise     = Word8 -> Put
putWord8 Word8
0xFE Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word64 -> Put
putWord64le (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x)
{-# INLINE putLenEncInt #-}

putWord24le :: Word32 -> Put
putWord24le :: Word32 -> Put
putWord24le Word32
v = do
    Word16 -> Put
putWord16le (Word16 -> Put) -> Word16 -> Put
forall a b. (a -> b) -> a -> b
$ Word32 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
v
    Word8 -> Put
putWord8 (Word8 -> Put) -> Word8 -> Put
forall a b. (a -> b) -> a -> b
$ Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
v Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
16)
{-# INLINE putWord24le #-}

getWord24le :: Get Word32
getWord24le :: Get Word32
getWord24le = do
    Word32
a <- Word16 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word32) -> Get Word16 -> Get Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
getWord16le
    Word32
b <- Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word32) -> Get Word8 -> Get Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8
    Word32 -> Get Word32
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word32 -> Get Word32) -> Word32 -> Get Word32
forall a b. (a -> b) -> a -> b
$! Word32
a Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. (Word32
b Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
16)
{-# INLINE getWord24le #-}

putWord48le :: Word64 -> Put
putWord48le :: Word64 -> Put
putWord48le Word64
v = do
    Word32 -> Put
putWord32le (Word32 -> Put) -> Word32 -> Put
forall a b. (a -> b) -> a -> b
$ Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
v
    Word16 -> Put
putWord16le (Word16 -> Put) -> Word16 -> Put
forall a b. (a -> b) -> a -> b
$ Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
v Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
32)
{-# INLINE putWord48le #-}

getWord48le :: Get Word64
getWord48le :: Get Word64
getWord48le = do
    Word64
a <- Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word64) -> Get Word32 -> Get Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
getWord32le
    Word64
b <- Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word64) -> Get Word16 -> Get Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
getWord16le
    Word64 -> Get Word64
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word64 -> Get Word64) -> Word64 -> Get Word64
forall a b. (a -> b) -> a -> b
$! Word64
a Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64
b Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32)
{-# INLINE getWord48le #-}

getWord24be :: Get Word24
getWord24be :: Get Word24
getWord24be = do
    Word24
a <- Word16 -> Word24
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word24) -> Get Word16 -> Get Word24
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
getWord16be
    Word24
b <- Word8 -> Word24
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word24) -> Get Word8 -> Get Word24
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8
    Word24 -> Get Word24
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word24 -> Get Word24) -> Word24 -> Get Word24
forall a b. (a -> b) -> a -> b
$! Word24
b Word24 -> Word24 -> Word24
forall a. Bits a => a -> a -> a
.|. (Word24
a Word24 -> Int -> Word24
forall a. Bits a => a -> Int -> a
`shiftL` Int
8)
{-# INLINE getWord24be #-}

getInt24be :: Get Int24
getInt24be :: Get Int24
getInt24be = do
    Word24
a <- Word16 -> Word24
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word24) -> Get Word16 -> Get Word24
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
getWord16be
    Word24
b <- Word8 -> Word24
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word24) -> Get Word8 -> Get Word24
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8
    Int24 -> Get Int24
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int24 -> Get Int24) -> Int24 -> Get Int24
forall a b. (a -> b) -> a -> b
$! Word24 -> Int24
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word24 -> Int24) -> Word24 -> Int24
forall a b. (a -> b) -> a -> b
$ (Word24
b Word24 -> Word24 -> Word24
forall a. Bits a => a -> a -> a
.|. (Word24
a Word24 -> Int -> Word24
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) :: Word24)
{-# INLINE getInt24be #-}

getWord40be, getWord48be, getWord56be :: Get Word64
getWord40be :: Get Word64
getWord40be = do
    Word64
a <- Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word64) -> Get Word32 -> Get Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
getWord32be
    Word64
b <- Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word64) -> Get Word8 -> Get Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8
    Word64 -> Get Word64
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word64 -> Get Word64) -> Word64 -> Get Word64
forall a b. (a -> b) -> a -> b
$! (Word64
a Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
b
getWord48be :: Get Word64
getWord48be = do
    Word64
a <- Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word64) -> Get Word32 -> Get Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
getWord32be
    Word64
b <- Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word64) -> Get Word16 -> Get Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
getWord16be
    Word64 -> Get Word64
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word64 -> Get Word64) -> Word64 -> Get Word64
forall a b. (a -> b) -> a -> b
$! (Word64
a Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
16) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
b
getWord56be :: Get Word64
getWord56be = do
    Word64
a <- Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word64) -> Get Word32 -> Get Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
getWord32be
    Word64
b <- Word24 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word24 -> Word64) -> Get Word24 -> Get Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word24
getWord24be
    Word64 -> Get Word64
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word64 -> Get Word64) -> Word64 -> Get Word64
forall a b. (a -> b) -> a -> b
$! (Word64
a Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
24) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
b
{-# INLINE getWord40be #-}
{-# INLINE getWord48be #-}
{-# INLINE getWord56be #-}