-- Low level interface to byte arrays. module Data.Array.Byte( ByteArray, sizeOfByteArray, newByteArray, indexWord8, byteArrayToByteString, byteStringToByteArray, withByteArrayPtr, MutableByteArray, sizeOfMutableByteArray, newMutableByteArray, freezeMutableByteArray, unsafeFreezeMutableByteArray, readWord8, writeWord8, withMutableByteArrayPtr, ) where import Control.Monad.ST import Control.Monad.ST_Type import Data.ByteString as BS import Data.ByteString.Internal(primBS2FPtr) import Data.Word import Foreign.ForeignPtr(withForeignPtr) import Foreign.Ptr(Ptr, castPtr) newtype ByteArray = A BS.ByteString deriving newtype (Eq, Ord, Show) sizeOfByteArray :: ByteArray -> Int sizeOfByteArray (A bs) = BS.length bs newByteArray :: [Word8] -> ByteArray newByteArray bs = A (BS.pack bs) indexWord8 :: ByteArray -> Int -> Word8 indexWord8 (A bs) i = BS.index bs i byteStringToByteArray :: BS.ByteString -> ByteArray byteStringToByteArray bs = A bs byteArrayToByteString :: ByteArray -> BS.ByteString byteArrayToByteString (A bs) = bs withByteArrayPtr :: ByteArray -> (Ptr Word8 -> IO a) -> IO a withByteArrayPtr (A bs) act = withForeignPtr (primBS2FPtr bs) (act . castPtr) ---------------------------------------------------- -- Be careful about sequencing since the ByteString -- operations have pure types. newtype MutableByteArray s = M BS.ByteString newMutableByteArray :: Int -> ST s (MutableByteArray s) newMutableByteArray n = return $! M (BS.replicate n 0) freezeMutableByteArray :: MutableByteArray s -> ST s ByteArray freezeMutableByteArray (M bs) = return $! A (BS.copy bs) writeWord8 :: MutableByteArray s -> Int -> Word8 -> ST s () writeWord8 (M bs) n b = ST (primBSwrite bs n b) readWord8 :: MutableByteArray s -> Int -> ST s Word8 readWord8 (M bs) i = return $! BS.index bs i sizeOfMutableByteArray :: MutableByteArray s -> ST s Int sizeOfMutableByteArray (M bs) = return $! BS.length bs primBSwrite :: BS.ByteString -> Int -> Word8 -> IO () primBSwrite = _primitive "bswrite" unsafeFreezeMutableByteArray :: MutableByteArray s -> ST s ByteArray unsafeFreezeMutableByteArray (M bs) = return (A bs) withMutableByteArrayPtr :: MutableByteArray s -> (Ptr Word8 -> IO a) -> IO a withMutableByteArrayPtr (M bs) act = withForeignPtr (primBS2FPtr bs) (act . castPtr)