module Ptr.PokeAndPeek
where
import Ptr.Prelude
import qualified Ptr.IO as A
data PokeAndPeek input output =
PokeAndPeek !Int (Ptr Word8 -> input -> IO ()) (Ptr Word8 -> IO output)
type InvPokeAndPeek value =
PokeAndPeek value value
instance Profunctor PokeAndPeek where
dimap fn1 fn2 (PokeAndPeek size poke peek) =
PokeAndPeek size (\ptr -> poke ptr . fn1) (\ptr -> fmap fn2 (peek ptr))
instance Functor (PokeAndPeek input) where
fmap fn (PokeAndPeek size poke peek) =
PokeAndPeek size poke (fmap fn . peek)
instance Applicative (PokeAndPeek input) where
pure x =
PokeAndPeek 0 (\_ _ -> pure ()) (\_ -> pure x)
(<*>) (PokeAndPeek leftSize leftPoke leftPeek) (PokeAndPeek rightSize rightPoke rightPeek) =
PokeAndPeek (leftSize + rightSize) poke peek
where
poke ptr input =
leftPoke ptr input *> rightPoke (plusPtr ptr leftSize) input
peek ptr =
leftPeek ptr <*> rightPeek (plusPtr ptr leftSize)
word8 :: InvPokeAndPeek Word8
word8 =
PokeAndPeek 1 A.pokeWord8 A.peekWord8
beWord16 :: InvPokeAndPeek Word16
beWord16 =
PokeAndPeek 2 A.pokeBEWord16 A.peekBEWord16
beWord32 :: InvPokeAndPeek Word32
beWord32 =
PokeAndPeek 4 A.pokeBEWord32 A.peekBEWord32
beWord64 :: InvPokeAndPeek Word64
beWord64 =
PokeAndPeek 8 A.pokeBEWord64 A.peekBEWord64
bytes :: Int -> InvPokeAndPeek ByteString
bytes amount =
PokeAndPeek amount (\ptr -> A.pokeBytesTrimming ptr amount) (\ptr -> A.peekBytes ptr amount)