{-# LANGUAGE UnboxedTuples #-}
module Bytezap.Struct where
import GHC.Exts
import Raehik.Compat.GHC.Exts.GHC908MemcpyPrimops ( setAddrRange# )
import Raehik.Compat.Data.Primitive.Types
import Control.Monad.Primitive ( MonadPrim, primitive )
import Data.Word ( Word8 )
import Data.ByteString qualified as BS
import Data.ByteString.Internal qualified as BS
import GHC.Word ( Word8(W8#) )
type Poke# s = Addr# -> Int# -> State# s -> State# s
newtype Poke s = Poke { forall s. Poke s -> Poke# s
unPoke :: Poke# s }
unsafeRunPokeBS :: Int -> Poke RealWorld -> BS.ByteString
unsafeRunPokeBS :: Int -> Poke RealWorld -> ByteString
unsafeRunPokeBS Int
len Poke RealWorld
p = Int -> (Ptr Word8 -> IO ()) -> ByteString
BS.unsafeCreate Int
len (Poke RealWorld -> Ptr Word8 -> IO ()
forall s (m :: Type -> Type).
MonadPrim s m =>
Poke s -> Ptr Word8 -> m ()
unsafeRunPoke Poke RealWorld
p)
unsafeRunPoke :: MonadPrim s m => Poke s -> Ptr Word8 -> m ()
unsafeRunPoke :: forall s (m :: Type -> Type).
MonadPrim s m =>
Poke s -> Ptr Word8 -> m ()
unsafeRunPoke (Poke Poke# s
p) (Ptr Addr#
base#) = (State# (PrimState m) -> (# State# (PrimState m), () #)) -> m ()
forall a.
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: Type -> Type) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState m) -> (# State# (PrimState m), () #)) -> m ())
-> (State# (PrimState m) -> (# State# (PrimState m), () #)) -> m ()
forall a b. (a -> b) -> a -> b
$ \State# (PrimState m)
s0 -> (# Poke# s
p Addr#
base# Int#
0# State# s
State# (PrimState m)
s0, () #)
prim :: forall a s. Prim' a => a -> Poke s
prim :: forall a s. Prim' a => a -> Poke s
prim a
a = Poke# s -> Poke s
forall s. Poke# s -> Poke s
Poke (Poke# s -> Poke s) -> Poke# s -> Poke s
forall a b. (a -> b) -> a -> b
$ \Addr#
base# Int#
os# State# s
s0 -> Addr# -> Int# -> a -> State# s -> State# s
forall s. Addr# -> Int# -> a -> State# s -> State# s
forall a s. Prim' a => Addr# -> Int# -> a -> State# s -> State# s
writeWord8OffAddrAs# Addr#
base# Int#
os# a
a State# s
s0
emptyPoke :: Poke s
emptyPoke :: forall s. Poke s
emptyPoke = Poke# s -> Poke s
forall s. Poke# s -> Poke s
Poke (Poke# s -> Poke s) -> Poke# s -> Poke s
forall a b. (a -> b) -> a -> b
$ \Addr#
_base# Int#
_os# State# s
s0 -> State# s
s0
sequencePokes :: Poke s -> Int -> Poke s -> Poke s
sequencePokes :: forall s. Poke s -> Int -> Poke s -> Poke s
sequencePokes (Poke Poke# s
pl) (I# Int#
ll#) (Poke Poke# s
pr) = Poke# s -> Poke s
forall s. Poke# s -> Poke s
Poke (Poke# s -> Poke s) -> Poke# s -> Poke s
forall a b. (a -> b) -> a -> b
$ \Addr#
base# Int#
os# State# s
s0 -> do
case Poke# s
pl Addr#
base# Int#
os# State# s
s0 of State# s
s1 -> Poke# s
pr Addr#
base# (Int#
os# Int# -> Int# -> Int#
+# Int#
ll#) State# s
s1
replicateByte :: Int -> Word8 -> Poke RealWorld
replicateByte :: Int -> Word8 -> Poke RealWorld
replicateByte (I# Int#
len#) (W8# Word8#
byte#) = Poke# RealWorld -> Poke RealWorld
forall s. Poke# s -> Poke s
Poke (Poke# RealWorld -> Poke RealWorld)
-> Poke# RealWorld -> Poke RealWorld
forall a b. (a -> b) -> a -> b
$ \Addr#
base# Int#
os# State# RealWorld
s0 ->
Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld
setAddrRange# (Addr#
base# Addr# -> Int# -> Addr#
`plusAddr#` Int#
os#) Int#
len# Int#
byteAsInt# State# RealWorld
s0
where
byteAsInt# :: Int#
byteAsInt# = Word# -> Int#
word2Int# (Word8# -> Word#
word8ToWord# Word8#
byte#)