module Ptr.Poking
where
import Ptr.Prelude
import qualified Ptr.IO as A
import qualified Ptr.Poke as C
import qualified Ptr.PokeAndPeek as D
import qualified Data.ByteString.Internal as B
data Poking =
Poking !Int !(Ptr Word8 -> IO ())
instance Semigroup Poking where
(<>) (Poking space1 action1) (Poking space2 action2) =
Poking (space1 + space2) (\ptr -> action1 ptr *> action2 (plusPtr ptr space1))
instance Monoid Poking where
mempty =
Poking 0 (const (pure ()))
mappend =
(<>)
prependConc :: Poking -> Poking -> Poking
prependConc (Poking space1 action1) (Poking space2 action2) =
Poking (space1 + space2) action
where
action ptr =
do
lock <- newEmptyMVar
forkIO $ do
action1 ptr
putMVar lock ()
action2 (plusPtr ptr space1)
takeMVar lock
word8 :: Word8 -> Poking
word8 x =
Poking 1 (flip A.pokeWord8 x)
beWord32 :: Word32 -> Poking
beWord32 x =
Poking 4 (flip A.pokeBEWord32 x)
beWord64 :: Word64 -> Poking
beWord64 x =
Poking 8 (flip A.pokeBEWord64 x)
bytes :: ByteString -> Poking
bytes (B.PS bytesFPtr offset length) =
Poking length (\ptr -> withForeignPtr bytesFPtr (\bytesPtr -> B.memcpy ptr (plusPtr bytesPtr offset) length))
poke :: C.Poke input -> input -> Poking
poke (C.Poke space poke) input =
Poking space (\ptr -> poke ptr input)
pokeAndPeek :: D.PokeAndPeek input output -> input -> Poking
pokeAndPeek (D.PokeAndPeek space poke _) input =
Poking space (\ptr -> poke ptr input)