-- | 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)