{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
module Raaz.Core.Transfer.Unsafe
(
Transfer, ReadFrom, WriteTo
, unsafeMakeTransfer
, unsafeTransfer
, unsafeInterleave
, unsafeReadIntoPtr, unsafeReadInto
, unsafeWriteFrom
, unsafeWriteFromPtr
, writeByteString
, transferSize
) where
import Data.ByteString (ByteString)
import Data.ByteString.Internal (unsafeCreate)
import Raaz.Core.Prelude
import Raaz.Core.MonoidalAction
import Raaz.Core.Types.Copying
import Raaz.Core.Types.Endian
import Raaz.Core.Types.Pointer
import Raaz.Core.Encode
import Raaz.Core.Util.ByteString as BU
data Mode = ReadFromBuffer
| WriteToBuffer
newtype TransferM (t :: Mode) = TransferM { TransferM t -> IO ()
unTransferM :: IO () }
instance Semigroup (TransferM t) where
<> :: TransferM t -> TransferM t -> TransferM t
(<>) TransferM t
wa TransferM t
wb = IO () -> TransferM t
forall (t :: Mode). IO () -> TransferM t
TransferM (IO () -> TransferM t) -> IO () -> TransferM t
forall a b. (a -> b) -> a -> b
$ TransferM t -> IO ()
forall (t :: Mode). TransferM t -> IO ()
unTransferM TransferM t
wa IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TransferM t -> IO ()
forall (t :: Mode). TransferM t -> IO ()
unTransferM TransferM t
wb
{-# INLINE (<>) #-}
instance Monoid (TransferM t) where
mempty :: TransferM t
mempty = IO () -> TransferM t
forall (t :: Mode). IO () -> TransferM t
TransferM (IO () -> TransferM t) -> IO () -> TransferM t
forall a b. (a -> b) -> a -> b
$ () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
{-# INLINE mempty #-}
mappend :: TransferM t -> TransferM t -> TransferM t
mappend = TransferM t -> TransferM t -> TransferM t
forall a. Semigroup a => a -> a -> a
(<>)
{-# INLINE mappend #-}
mconcat :: [TransferM t] -> TransferM t
mconcat = IO () -> TransferM t
forall (t :: Mode). IO () -> TransferM t
TransferM (IO () -> TransferM t)
-> ([TransferM t] -> IO ()) -> [TransferM t] -> TransferM t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TransferM t -> IO ()) -> [TransferM t] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ TransferM t -> IO ()
forall (t :: Mode). TransferM t -> IO ()
unTransferM
{-# INLINE mconcat #-}
type TransferAction t = Ptr Word8 -> TransferM t
instance LAction (BYTES Int) (TransferAction t) where
BYTES Int
offset <.> :: BYTES Int -> TransferAction t -> TransferAction t
<.> TransferAction t
action = TransferAction t
action TransferAction t -> (Ptr Word8 -> Ptr Word8) -> TransferAction t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BYTES Int
offsetBYTES Int -> Ptr Word8 -> Ptr Word8
forall m space. LAction m space => m -> space -> space
<.>)
{-# INLINE (<.>) #-}
instance Distributive (BYTES Int) (TransferAction t)
type Transfer t = SemiR (TransferAction t) (BYTES Int)
transferSize :: Transfer t -> BYTES Int
transferSize :: Transfer t -> BYTES Int
transferSize = Transfer t -> BYTES Int
forall space m. SemiR space m -> m
semiRMonoid
unsafeMakeTransfer :: LengthUnit u
=> u
-> (Ptr Word8 -> IO ())
-> Transfer t
{-# INLINE unsafeMakeTransfer #-}
unsafeMakeTransfer :: u -> (Ptr Word8 -> IO ()) -> Transfer t
unsafeMakeTransfer u
sz Ptr Word8 -> IO ()
action = (Ptr Word8 -> TransferM t) -> BYTES Int -> Transfer t
forall space m. space -> m -> SemiR space m
SemiR (IO () -> TransferM t
forall (t :: Mode). IO () -> TransferM t
TransferM (IO () -> TransferM t)
-> (Ptr Word8 -> IO ()) -> Ptr Word8 -> TransferM t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Word8 -> IO ()
action) (BYTES Int -> Transfer t) -> BYTES Int -> Transfer t
forall a b. (a -> b) -> a -> b
$ u -> BYTES Int
forall u. LengthUnit u => u -> BYTES Int
inBytes u
sz
unsafeInterleave :: IO a
-> Transfer t
unsafeInterleave :: IO a -> Transfer t
unsafeInterleave = BYTES Int -> (Ptr Word8 -> IO ()) -> Transfer t
forall u (t :: Mode).
LengthUnit u =>
u -> (Ptr Word8 -> IO ()) -> Transfer t
unsafeMakeTransfer (BYTES Int
0 :: BYTES Int) ((Ptr Word8 -> IO ()) -> Transfer t)
-> (IO a -> Ptr Word8 -> IO ()) -> IO a -> Transfer t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO () -> Ptr Word8 -> IO ()
forall a b. a -> b -> a
const (IO () -> Ptr Word8 -> IO ())
-> (IO a -> IO ()) -> IO a -> Ptr Word8 -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void
unsafeTransfer :: Pointer ptr
=> Transfer t
-> ptr a
-> IO ()
unsafeTransfer :: Transfer t -> ptr a -> IO ()
unsafeTransfer Transfer t
tr = (Ptr Word8 -> IO ()) -> ptr a -> IO ()
forall (ptr :: * -> *) a b something.
Pointer ptr =>
(Ptr a -> b) -> ptr something -> b
unsafeWithPointerCast Ptr Word8 -> IO ()
transferIt
where transferIt :: Ptr Word8 -> IO ()
transferIt = TransferM t -> IO ()
forall (t :: Mode). TransferM t -> IO ()
unTransferM (TransferM t -> IO ())
-> (Ptr Word8 -> TransferM t) -> Ptr Word8 -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transfer t -> Ptr Word8 -> TransferM t
forall space m. SemiR space m -> space
semiRSpace Transfer t
tr
type ReadFrom = Transfer 'ReadFromBuffer
unsafeReadIntoPtr :: (Pointer ptr, LengthUnit sz)
=> sz
-> Dest (ptr Word8)
-> ReadFrom
unsafeReadIntoPtr :: sz -> Dest (ptr Word8) -> ReadFrom
unsafeReadIntoPtr sz
sz Dest (ptr Word8)
dest = sz -> (Ptr Word8 -> IO ()) -> ReadFrom
forall u (t :: Mode).
LengthUnit u =>
u -> (Ptr Word8 -> IO ()) -> Transfer t
unsafeMakeTransfer sz
sz
((Ptr Word8 -> IO ()) -> ReadFrom)
-> (Ptr Word8 -> IO ()) -> ReadFrom
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
ptr -> Dest (ptr Word8) -> Src (Ptr Word8) -> sz -> IO ()
forall l (ptrS :: * -> *) (ptrD :: * -> *) dest src.
(LengthUnit l, Pointer ptrS, Pointer ptrD) =>
Dest (ptrD dest) -> Src (ptrS src) -> l -> IO ()
memcpy Dest (ptr Word8)
dest (Ptr Word8 -> Src (Ptr Word8)
forall a. a -> Src a
source Ptr Word8
ptr) sz
sz
unsafeReadInto :: EndianStore a
=> Int
-> Dest (Ptr a)
-> ReadFrom
unsafeReadInto :: Int -> Dest (Ptr a) -> ReadFrom
unsafeReadInto Int
n Dest (Ptr a)
dest = BYTES Int -> (Ptr Word8 -> IO ()) -> ReadFrom
forall u (t :: Mode).
LengthUnit u =>
u -> (Ptr Word8 -> IO ()) -> Transfer t
unsafeMakeTransfer (Dest (Ptr a) -> BYTES Int
sz Dest (Ptr a)
dest)
((Ptr Word8 -> IO ()) -> ReadFrom)
-> (Ptr Word8 -> IO ()) -> ReadFrom
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
ptr -> Dest (Ptr a) -> Src (Ptr Word8) -> Int -> IO ()
forall w.
EndianStore w =>
Dest (Ptr w) -> Src (Ptr Word8) -> Int -> IO ()
copyFromBytes Dest (Ptr a)
dest (Ptr Word8 -> Src (Ptr Word8)
forall a. a -> Src a
source Ptr Word8
ptr) Int
n
where sz :: Dest (Ptr a) -> BYTES Int
sz = BYTES Int -> BYTES Int -> BYTES Int
forall a. Num a => a -> a -> a
(*) (Int -> BYTES Int
forall a. Enum a => Int -> a
toEnum Int
n) (BYTES Int -> BYTES Int)
-> (Dest (Ptr a) -> BYTES Int) -> Dest (Ptr a) -> BYTES Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy a -> BYTES Int
forall a. Storable a => Proxy a -> BYTES Int
sizeOf (Proxy a -> BYTES Int)
-> (Dest (Ptr a) -> Proxy a) -> Dest (Ptr a) -> BYTES Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dest (Ptr a) -> Proxy a
forall a. Dest (Ptr a) -> Proxy a
proxy
proxy :: Dest (Ptr a) -> Proxy a
proxy :: Dest (Ptr a) -> Proxy a
proxy = Proxy a -> Dest (Ptr a) -> Proxy a
forall a b. a -> b -> a
const Proxy a
forall k (t :: k). Proxy t
Proxy
type WriteTo = Transfer 'WriteToBuffer
unsafeWriteFrom :: EndianStore a => Int -> Src (Ptr a) -> WriteTo
unsafeWriteFrom :: Int -> Src (Ptr a) -> WriteTo
unsafeWriteFrom Int
n Src (Ptr a)
src = BYTES Int -> (Ptr Word8 -> IO ()) -> WriteTo
forall u (t :: Mode).
LengthUnit u =>
u -> (Ptr Word8 -> IO ()) -> Transfer t
unsafeMakeTransfer (Src (Ptr a) -> BYTES Int
sz Src (Ptr a)
src)
((Ptr Word8 -> IO ()) -> WriteTo)
-> (Ptr Word8 -> IO ()) -> WriteTo
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
ptr -> Dest (Ptr Word8) -> Src (Ptr a) -> Int -> IO ()
forall w.
EndianStore w =>
Dest (Ptr Word8) -> Src (Ptr w) -> Int -> IO ()
copyToBytes (Ptr Word8 -> Dest (Ptr Word8)
forall a. a -> Dest a
destination Ptr Word8
ptr) Src (Ptr a)
src Int
n
where sz :: Src (Ptr a) -> BYTES Int
sz = BYTES Int -> BYTES Int -> BYTES Int
forall a. Num a => a -> a -> a
(*) (Int -> BYTES Int
forall a. Enum a => Int -> a
toEnum Int
n) (BYTES Int -> BYTES Int)
-> (Src (Ptr a) -> BYTES Int) -> Src (Ptr a) -> BYTES Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy a -> BYTES Int
forall a. Storable a => Proxy a -> BYTES Int
sizeOf (Proxy a -> BYTES Int)
-> (Src (Ptr a) -> Proxy a) -> Src (Ptr a) -> BYTES Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Src (Ptr a) -> Proxy a
forall a. Src (Ptr a) -> Proxy a
proxy
proxy :: Src (Ptr a) -> Proxy a
proxy :: Src (Ptr a) -> Proxy a
proxy = Proxy a -> Src (Ptr a) -> Proxy a
forall a b. a -> b -> a
const Proxy a
forall k (t :: k). Proxy t
Proxy
unsafeWriteFromPtr ::(Pointer ptr, LengthUnit sz)
=> sz
-> Src (ptr Word8)
-> WriteTo
unsafeWriteFromPtr :: sz -> Src (ptr Word8) -> WriteTo
unsafeWriteFromPtr sz
sz Src (ptr Word8)
src = sz -> (Ptr Word8 -> IO ()) -> WriteTo
forall u (t :: Mode).
LengthUnit u =>
u -> (Ptr Word8 -> IO ()) -> Transfer t
unsafeMakeTransfer sz
sz
((Ptr Word8 -> IO ()) -> WriteTo)
-> (Ptr Word8 -> IO ()) -> WriteTo
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
ptr -> Dest (Ptr Word8) -> Src (ptr Word8) -> sz -> IO ()
forall l (ptrS :: * -> *) (ptrD :: * -> *) dest src.
(LengthUnit l, Pointer ptrS, Pointer ptrD) =>
Dest (ptrD dest) -> Src (ptrS src) -> l -> IO ()
memcpy (Ptr Word8 -> Dest (Ptr Word8)
forall a. a -> Dest a
destination Ptr Word8
ptr) Src (ptr Word8)
src sz
sz
instance IsString WriteTo where
fromString :: String -> WriteTo
fromString = ByteString -> WriteTo
writeByteString (ByteString -> WriteTo)
-> (String -> ByteString) -> String -> WriteTo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
forall a. IsString a => String -> a
fromString
instance Encodable WriteTo where
{-# INLINE toByteString #-}
toByteString :: WriteTo -> ByteString
toByteString WriteTo
w = Int -> (Ptr Word8 -> IO ()) -> ByteString
unsafeCreate Int
n ((Ptr Word8 -> IO ()) -> ByteString)
-> (Ptr Word8 -> IO ()) -> ByteString
forall a b. (a -> b) -> a -> b
$ WriteTo -> Ptr Word8 -> IO ()
forall (ptr :: * -> *) (t :: Mode) a.
Pointer ptr =>
Transfer t -> ptr a -> IO ()
unsafeTransfer WriteTo
w
where BYTES Int
n = WriteTo -> BYTES Int
forall (t :: Mode). Transfer t -> BYTES Int
transferSize WriteTo
w
{-# INLINE unsafeFromByteString #-}
unsafeFromByteString :: ByteString -> WriteTo
unsafeFromByteString = ByteString -> WriteTo
writeByteString
{-# INLINE fromByteString #-}
fromByteString :: ByteString -> Maybe WriteTo
fromByteString = WriteTo -> Maybe WriteTo
forall a. a -> Maybe a
Just (WriteTo -> Maybe WriteTo)
-> (ByteString -> WriteTo) -> ByteString -> Maybe WriteTo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> WriteTo
writeByteString
writeByteString :: ByteString -> WriteTo
writeByteString :: ByteString -> WriteTo
writeByteString ByteString
bs = BYTES Int -> (Ptr Word8 -> IO ()) -> WriteTo
forall u (t :: Mode).
LengthUnit u =>
u -> (Ptr Word8 -> IO ()) -> Transfer t
unsafeMakeTransfer (ByteString -> BYTES Int
BU.length ByteString
bs) ((Ptr Word8 -> IO ()) -> WriteTo)
-> (Ptr Word8 -> IO ()) -> WriteTo
forall a b. (a -> b) -> a -> b
$ ByteString -> Ptr Word8 -> IO ()
forall (ptr :: * -> *) a.
Pointer ptr =>
ByteString -> ptr a -> IO ()
BU.unsafeCopyToPointer ByteString
bs