module Data.Array.Repa.ByteString
( toByteString
, fromByteString
, copyFromPtrWord8
, copyToPtrWord8)
where
import Data.Word
import Data.Array.Repa
import Foreign.Marshal.Alloc
import Foreign.Ptr
import Foreign.Storable
import System.IO.Unsafe
import qualified Data.Vector.Unboxed as V
import qualified Data.ByteString as BS
import Data.ByteString (ByteString)
toByteString
:: Shape sh
=> Array sh Word8
-> ByteString
toByteString arr
= withManifest' (force arr) $ \arr'
-> unsafePerformIO
$ allocaBytes (size $ extent arr') $ \(bufDest :: Ptr Word8) ->
let vec = toVector arr'
len = size $ extent arr'
copy offset
| offset >= len
= return ()
| otherwise
= do pokeByteOff bufDest offset (vec `V.unsafeIndex` offset)
copy (offset + 1)
in do
copy 0
BS.packCStringLen (castPtr bufDest, len)
fromByteString
:: Shape sh
=> sh
-> ByteString
-> Array sh Word8
fromByteString sh str
| size sh /= BS.length str
= error "Data.Array.Repa.fromByteString: given array size does not match length of string"
| otherwise
= fromFunction sh (\ix -> str `BS.index` toIndex sh ix)
copyFromPtrWord8
:: Shape sh
=> sh
-> Ptr Word8
-> IO (Array sh Word8)
copyFromPtrWord8 sh ptr
= do return $ fromFunction sh (\ix -> unsafePerformIO (peekElemOff ptr (toIndex sh ix)))
copyToPtrWord8
:: Shape sh
=> Ptr Word8
-> Array sh Word8
-> IO ()
copyToPtrWord8 ptr arr
= let vec = toVector arr
len = size $ extent arr
copy offset
| offset >= len
= return ()
| otherwise
= do pokeByteOff ptr offset (vec `V.unsafeIndex` offset)
copy (offset + 1)
in do
copy 0
return ()