dahdit-0.2.0: src/Dahdit/Binary.hs
module Dahdit.Binary
( Binary (..)
)
where
import Dahdit.Free (Get, Put)
import Dahdit.Funs
( getDoubleBE
, getDoubleLE
, getFloatBE
, getFloatLE
, getInt16BE
, getInt16LE
, getInt24BE
, getInt24LE
, getInt32BE
, getInt32LE
, getInt64BE
, getInt64LE
, getInt8
, getList
, getSeq
, getWord16BE
, getWord16LE
, getWord24BE
, getWord24LE
, getWord32BE
, getWord32LE
, getWord64BE
, getWord64LE
, getWord8
, putDoubleBE
, putDoubleLE
, putFloatBE
, putFloatLE
, putInt16BE
, putInt16LE
, putInt24BE
, putInt24LE
, putInt32BE
, putInt32LE
, putInt64BE
, putInt64LE
, putInt8
, putList
, putSeq
, putWord16BE
, putWord16LE
, putWord24BE
, putWord24LE
, putWord32BE
, putWord32LE
, putWord64BE
, putWord64LE
, putWord8
)
import Dahdit.Nums
( DoubleBE (..)
, DoubleLE (..)
, FloatBE (..)
, FloatLE (..)
, Int16BE (..)
, Int16LE (..)
, Int24BE (..)
, Int24LE (..)
, Int32BE (..)
, Int32LE (..)
, Int64BE (..)
, Int64LE (..)
, Word16BE (..)
, Word16LE (..)
, Word24BE (..)
, Word24LE (..)
, Word32BE (..)
, Word32LE (..)
, Word64BE (..)
, Word64LE (..)
)
import Dahdit.Sizes (ElemCount (..))
import Data.ByteString.Internal (c2w, w2c)
import Data.Coerce (coerce)
import Data.Int (Int16, Int32, Int64, Int8)
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import Data.IntSet (IntSet)
import qualified Data.IntSet as IntSet
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Sequence (Seq (..))
import qualified Data.Sequence as Seq
import Data.Set (Set)
import qualified Data.Set as Set
import Data.ShortWord (Int24, Word24)
import Data.Word (Word16, Word32, Word64, Word8)
class Binary a where
get :: Get a
put :: a -> Put
-- Basic types
instance Binary () where
get = pure ()
put _ = pure ()
instance Binary Word8 where
get = getWord8
put = putWord8
instance Binary Int8 where
get = getInt8
put = putInt8
instance Binary Word16LE where
get = getWord16LE
put = putWord16LE
instance Binary Int16LE where
get = getInt16LE
put = putInt16LE
instance Binary Word24LE where
get = getWord24LE
put = putWord24LE
instance Binary Int24LE where
get = getInt24LE
put = putInt24LE
instance Binary Word32LE where
get = getWord32LE
put = putWord32LE
instance Binary Int32LE where
get = getInt32LE
put = putInt32LE
instance Binary Word64LE where
get = getWord64LE
put = putWord64LE
instance Binary Int64LE where
get = getInt64LE
put = putInt64LE
instance Binary FloatLE where
get = getFloatLE
put = putFloatLE
instance Binary DoubleLE where
get = getDoubleLE
put = putDoubleLE
instance Binary Word16BE where
get = getWord16BE
put = putWord16BE
instance Binary Int16BE where
get = getInt16BE
put = putInt16BE
instance Binary Word24BE where
get = getWord24BE
put = putWord24BE
instance Binary Int24BE where
get = getInt24BE
put = putInt24BE
instance Binary Word32BE where
get = getWord32BE
put = putWord32BE
instance Binary Int32BE where
get = getInt32BE
put = putInt32BE
instance Binary Word64BE where
get = getWord64BE
put = putWord64BE
instance Binary Int64BE where
get = getInt64BE
put = putInt64BE
instance Binary FloatBE where
get = getFloatBE
put = putFloatBE
instance Binary DoubleBE where
get = getDoubleBE
put = putDoubleBE
deriving via Word16LE instance Binary Word16
deriving via Int16LE instance Binary Int16
deriving via Word24LE instance Binary Word24
deriving via Int24LE instance Binary Int24
deriving via Word32LE instance Binary Word32
deriving via Int32LE instance Binary Int32
deriving via Word64LE instance Binary Word64
deriving via Int64LE instance Binary Int64
deriving via FloatLE instance Binary Float
deriving via DoubleLE instance Binary Double
instance Binary Bool where
get = fmap (/= 0) getWord8
put b = putWord8 (if b then 1 else 0)
instance Binary Char where
get = fmap w2c getWord8
put = putWord8 . c2w
instance Binary Int where
get = fmap fromIntegral getInt64LE
put = putInt64LE . fromIntegral
instance Binary a => Binary [a] where
get = do
ec <- get @Int
getList (coerce ec) get
put s = put @Int (length s) *> putList put s
instance Binary a => Binary (Seq a) where
get = do
ec <- get @Int
getSeq (coerce ec) get
put s = put @Int (Seq.length s) *> putSeq put s
instance Binary a => Binary (Set a) where
get = fmap Set.fromDistinctAscList get
put = put . Set.toAscList
instance (Binary k, Binary v) => Binary (Map k v) where
get = fmap Map.fromDistinctAscList get
put = put . Map.toAscList
instance Binary IntSet where
get = fmap IntSet.fromDistinctAscList get
put = put . IntSet.toAscList
instance Binary v => Binary (IntMap v) where
get = fmap IntMap.fromDistinctAscList get
put = put . IntMap.toAscList
instance Binary a => Binary (Maybe a) where
get = do
tag <- get @Int
case tag of
0 -> pure Nothing
1 -> fmap Just get
_ -> fail "Unknown encoding for constructor"
put = \case
Nothing -> put @Int 0
Just a -> put @Int 1 *> put a
instance (Binary b, Binary a) => Binary (Either b a) where
get = do
tag <- get @Int
case tag of
0 -> fmap Left get
1 -> fmap Right get
_ -> fail "Unknown encoding for constructor"
put = \case
Left b -> put @Int 0 *> put b
Right a -> put @Int 1 *> put a
instance (Binary a, Binary b) => Binary (a, b) where
get = do
a <- get
b <- get
pure (a, b)
put (a, b) = put a *> put b
instance (Binary a, Binary b, Binary c) => Binary (a, b, c) where
get = do
a <- get
b <- get
c <- get
pure (a, b, c)
put (a, b, c) = put a *> put b *> put c
instance (Binary a, Binary b, Binary c, Binary d) => Binary (a, b, c, d) where
get = do
a <- get
b <- get
c <- get
d <- get
pure (a, b, c, d)
put (a, b, c, d) = put a *> put b *> put c *> put d
instance (Binary a, Binary b, Binary c, Binary d, Binary e) => Binary (a, b, c, d, e) where
get = do
a <- get
b <- get
c <- get
d <- get
e <- get
pure (a, b, c, d, e)
put (a, b, c, d, e) = put a *> put b *> put c *> put d *> put e