#ifdef LANGUAGE_Unsafe
#endif
module Data.ByteArrayElem.Unsafe
( ByteArrayElem (..)
, plusByteSizeDefault
, readByteOffDefault
, writeByteOffDefault
) where
import Control.Monad.Prim
import Data.Int
import Data.Prim.ByteArray
import Data.Proxy
import Data.Word
import Foreign.Ptr
import Foreign.StablePtr
#include "MachDeps.h"
class ByteArrayElem a where
byteSize :: t a -> Int
readElemOff :: MutableByteArray s -> Int -> Prim s a
writeElemOff :: MutableByteArray s -> Int -> a -> Prim s ()
instance ByteArrayElem Bool where
byteSize _ = 1
readElemOff array = fmap (/= 0) . readInt8Array array
writeElemOff array i e = writeInt8Array array i $! if e then 1 else 0
instance ByteArrayElem Char where
byteSize _ = SIZEOF_HSCHAR
readElemOff = readWideCharArray
writeElemOff = writeWideCharArray
instance ByteArrayElem Int where
byteSize _ = SIZEOF_HSINT
readElemOff = readIntArray
writeElemOff = writeIntArray
instance ByteArrayElem Word where
byteSize _ = SIZEOF_HSWORD
readElemOff = readWordArray
writeElemOff = writeWordArray
instance ByteArrayElem Float where
byteSize _ = SIZEOF_HSFLOAT
readElemOff = readFloatArray
writeElemOff = writeFloatArray
instance ByteArrayElem Double where
byteSize _ = SIZEOF_HSDOUBLE
readElemOff = readDoubleArray
writeElemOff = writeDoubleArray
instance ByteArrayElem Int8 where
byteSize _ = SIZEOF_INT8
readElemOff = readInt8Array
writeElemOff = writeInt8Array
instance ByteArrayElem Int16 where
byteSize _ = SIZEOF_INT16
readElemOff = readInt16Array
writeElemOff = writeInt16Array
instance ByteArrayElem Int32 where
byteSize _ = SIZEOF_INT32
readElemOff = readInt32Array
writeElemOff = writeInt32Array
instance ByteArrayElem Int64 where
byteSize _ = SIZEOF_INT64
readElemOff = readInt64Array
writeElemOff = writeInt64Array
instance ByteArrayElem Word8 where
byteSize _ = SIZEOF_WORD8
readElemOff = readWord8Array
writeElemOff = writeWord8Array
instance ByteArrayElem Word16 where
byteSize _ = SIZEOF_WORD16
readElemOff = readWord16Array
writeElemOff = writeWord16Array
instance ByteArrayElem Word32 where
byteSize _ = SIZEOF_WORD32
readElemOff = readWord32Array
writeElemOff = writeWord32Array
instance ByteArrayElem Word64 where
byteSize _ = SIZEOF_WORD64
readElemOff = readWord64Array
writeElemOff = writeWord64Array
instance ByteArrayElem (StablePtr a) where
byteSize _ = SIZEOF_HSWORD
readElemOff = readStablePtrArray
writeElemOff = writeStablePtrArray
instance ByteArrayElem (FunPtr a) where
byteSize _ = SIZEOF_HSWORD
readElemOff = readFunPtrArray
writeElemOff = writeFunPtrArray
instance ByteArrayElem (Ptr a) where
byteSize _ = SIZEOF_HSWORD
readElemOff = readPtrArray
writeElemOff = writePtrArray
plusByteSizeDefault :: ByteArrayElem a => Int -> t a -> Int
plusByteSizeDefault i a = case i `rem` byteSize' of
0 -> i + byteSize'
i' -> i + (byteSize' i') + byteSize'
where
byteSize' = byteSize a
readByteOffDefault :: ByteArrayElem a => MutableByteArray s -> Int -> Prim s a
readByteOffDefault array i = m
where
m = readElemOff array $ case i `quotRem'` byteSize' of
(q, 0) -> q
(q, _) -> q + 1
byteSize' = byteSize m
writeByteOffDefault :: ByteArrayElem a => MutableByteArray s -> Int -> a -> Prim s ()
writeByteOffDefault array i a = writeElemOff array i' a
where
i' = case i `quotRem'` byteSize (proxy a) of
(q, 0) -> q
(q, _) -> q + 1
quotRem' :: Integral a => a -> a -> (a, a)
quotRem' x y = (x `quot` y, x `rem` y)