#ifdef LANGUAGE_DataKinds
#endif
#ifdef LANGUAGE_Unsafe
#endif
module Data.ByteArraySlice.Unsafe
( MutableByteArray
, module Control.Monad.Prim
, ByteArraySlice (..)
, plusByteSizeDefault
, readByteOffDefault
, writeByteOffDefault
, byteSizeOf
) where
import Control.Monad.Prim
import qualified Data.ByteArrayElem.Unsafe as ByteArrayElem
import Data.Int
import Data.Prim.ByteArray
import Data.Proxy
import Data.Tuple.ITuple
import Data.Tuple.ITuple.Proxy
import Data.Word
import GHC.Generics
import Foreign.Ptr
import Foreign.StablePtr
class ByteArraySlice a where
plusByteSize :: Int -> t a -> Int
readByteOff :: MutableByteArray s -> Int -> Prim s a
writeByteOff :: MutableByteArray s -> Int -> a -> Prim s ()
default plusByteSize :: (Generic a, GByteArraySlice (Rep a)) => Int -> t a -> Int
plusByteSize = plusByteSizeDefault
default readByteOff :: ( Generic a
, GByteArraySlice (Rep a)
) => MutableByteArray s -> Int -> Prim s a
readByteOff = readByteOffDefault
default writeByteOff :: ( Generic a
, GByteArraySlice (Rep a)
) => MutableByteArray s -> Int -> a -> Prim s ()
writeByteOff = writeByteOffDefault
plusByteSizeDefault :: (Generic a, GByteArraySlice (Rep a)) => Int -> t a -> Int
plusByteSizeDefault i = gplusByteSize i . reproxyRep
readByteOffDefault :: ( Generic a
, GByteArraySlice (Rep a)
) => MutableByteArray s -> Int -> Prim s a
readByteOffDefault array = fmap to . greadByteOff array
writeByteOffDefault :: ( Generic a
, GByteArraySlice (Rep a)
) => MutableByteArray s -> Int -> a -> Prim s ()
writeByteOffDefault array i = gwriteByteOff array i . from
byteSizeOf :: ByteArraySlice a => a -> Int
byteSizeOf = plusByteSize 0 . proxy
class GByteArraySlice a where
gplusByteSize :: Int -> t (a p) -> Int
greadByteOff :: MutableByteArray s -> Int -> Prim s (a p)
gwriteByteOff :: MutableByteArray s -> Int -> a p -> Prim s ()
instance GByteArraySlice U1 where
gplusByteSize = const
greadByteOff _ _ = return U1
gwriteByteOff _ _ _ = return ()
instance ByteArraySlice c => GByteArraySlice (K1 i c) where
gplusByteSize i = plusByteSize i . reproxyK1
greadByteOff array = fmap K1 . readByteOff array
gwriteByteOff array i = writeByteOff array i . unK1
instance GByteArraySlice f => GByteArraySlice (M1 i c f) where
gplusByteSize i = gplusByteSize i . reproxyM1
greadByteOff array = fmap M1 . greadByteOff array
gwriteByteOff array i = gwriteByteOff array i . unM1
instance (GByteArraySlice a, GByteArraySlice b) => GByteArraySlice (a :*: b) where
gplusByteSize i a =
gplusByteSize (gplusByteSize i (reproxyFst a)) (reproxySnd a)
greadByteOff array i = do
a <- greadByteOff array i
b <- greadByteOff array (gplusByteSize i (proxy a))
return $ a :*: b
gwriteByteOff array i (a :*: b) = do
gwriteByteOff array i a
gwriteByteOff array (gplusByteSize i (proxy a)) b
instance ByteArraySlice () where
plusByteSize = plusByteSizeDefault
readByteOff = readByteOffDefault
writeByteOff = writeByteOffDefault
instance (ByteArraySlice a, ByteArraySlice b) => ByteArraySlice (a, b) where
plusByteSize = plusByteSizeDefault
readByteOff = readByteOffDefault
writeByteOff = writeByteOffDefault
instance ( ByteArraySlice a
, ByteArraySlice b
, ByteArraySlice c
) => ByteArraySlice (a, b, c) where
plusByteSize = plusByteSizeDefault
readByteOff = readByteOffDefault
writeByteOff = writeByteOffDefault
instance ( ByteArraySlice a
, ByteArraySlice b
, ByteArraySlice c
, ByteArraySlice d
) => ByteArraySlice (a, b, c, d) where
plusByteSize = plusByteSizeDefault
readByteOff = readByteOffDefault
writeByteOff = writeByteOffDefault
instance ( ByteArraySlice a
, ByteArraySlice b
, ByteArraySlice c
, ByteArraySlice d
, ByteArraySlice e
) => ByteArraySlice (a, b, c, d, e) where
plusByteSize = plusByteSizeDefault
readByteOff = readByteOffDefault
writeByteOff = writeByteOffDefault
instance ( ByteArraySlice a
, ByteArraySlice b
, ByteArraySlice c
, ByteArraySlice d
, ByteArraySlice e
, ByteArraySlice f
) => ByteArraySlice (a, b, c, d, e, f) where
plusByteSize = plusByteSizeDefault
readByteOff = readByteOffDefault
writeByteOff = writeByteOffDefault
instance ( ByteArraySlice a
, ByteArraySlice b
, ByteArraySlice c
, ByteArraySlice d
, ByteArraySlice e
, ByteArraySlice f
, ByteArraySlice g
) => ByteArraySlice (a, b, c, d, e, f, g) where
plusByteSize = plusByteSizeDefault
readByteOff = readByteOffDefault
writeByteOff = writeByteOffDefault
instance ByteArraySlice Bool where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Char where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Int where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Word where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Float where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Double where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Int8 where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Int16 where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Int32 where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Int64 where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Word8 where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Word16 where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Word32 where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice Word64 where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice (StablePtr a) where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice (FunPtr a) where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice (Ptr a) where
plusByteSize = ByteArrayElem.plusByteSizeDefault
readByteOff = ByteArrayElem.readByteOffDefault
writeByteOff = ByteArrayElem.writeByteOffDefault
instance ByteArraySlice (Tuple Nil) where
plusByteSize = const
readByteOff _ _ = return U
writeByteOff _ _ _ = return ()
instance ( ByteArraySlice x
, ByteArraySlice (Tuple xs)
) => ByteArraySlice (Tuple (x :| xs)) where
plusByteSize i xs =
plusByteSize (plusByteSize i (reproxyHead xs)) (reproxyTail xs)
readByteOff array i = do
x <- readByteOff array i
xs <- readByteOff array (plusByteSize i (proxy x))
return $ x :* xs
writeByteOff array i (x :* xs) = do
writeByteOff array i x
writeByteOff array (plusByteSize i (proxy x)) xs