1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
-- | Convert between @ByteString@ and @Vector.Storable@
-- without copying.
module Data.Vector.Storable.ByteString
( -- | See also the caveats mentioned in the package's
-- top-level documentation.
byteStringToVector
, vectorToByteString
) where
import qualified Data.ByteString as BS
import qualified Data.ByteString.Internal as BS
import qualified Data.Vector.Storable as V
import Foreign.Storable
import Foreign.ForeignPtr
sizeOfElem :: (Storable a) => V.Vector a -> Int
sizeOfElem vec = sizeOf (undefined `asTypeOf` V.head vec)
-- | Convert a @'BS.ByteString'@ to a @'V.Vector'@.
--
-- This function can produce @'Vector'@s which do not obey
-- architectural alignment requirements. On @x86@ this should
-- not be an issue.
byteStringToVector :: (Storable a) => BS.ByteString -> V.Vector a
byteStringToVector bs = vec where
vec = V.unsafeFromForeignPtr (castForeignPtr fptr) (scale off) (scale len)
(fptr, off, len) = BS.toForeignPtr bs
scale = (`div` sizeOfElem vec)
-- | Convert a @'V.Vector'@ to a @'BS.ByteString'@.
vectorToByteString :: (Storable a) => V.Vector a -> BS.ByteString
vectorToByteString vec
= BS.fromForeignPtr (castForeignPtr fptr) (scale off) (scale len) where
(fptr, off, len) = V.unsafeToForeignPtr vec
scale = (* sizeOfElem vec)
|