module Ros.Internal.Util.BytesToVector (unsafeBytesToVector, bytesToVectorL,
bytesToVector, unsafeVectorToBytes,
vectorToBytes) where
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString as BS
import qualified Data.ByteString.Unsafe as BU
import qualified Data.Vector.Storable as V
import Foreign.Ptr (castPtr, plusPtr)
import Foreign.ForeignPtr (newForeignPtr_, withForeignPtr,
mallocForeignPtrBytes)
import Foreign.Marshal.Utils (copyBytes)
import Foreign.Storable (sizeOf)
import System.IO.Unsafe (unsafePerformIO)
unsafeBytesToVector :: V.Storable a => Int -> BS.ByteString -> V.Vector a
unsafeBytesToVector n bs = unsafePerformIO $
BU.unsafeUseAsCStringLen bs $
(\(p,_) -> do fp <- newForeignPtr_ (castPtr p)
return $ V.unsafeFromForeignPtr fp 0 n)
bytesToVector :: V.Storable a => Int -> BS.ByteString -> V.Vector a
bytesToVector n bs = unsafePerformIO $
BU.unsafeUseAsCStringLen bs $
(\(p,len) -> do fp <- mallocForeignPtrBytes len
withForeignPtr fp $
\dst -> copyBytes (castPtr dst) p len
return $ V.unsafeFromForeignPtr fp 0 n)
bytesToVectorL :: V.Storable a => Int -> BL.ByteString -> V.Vector a
bytesToVectorL n = bytesToVector n . BS.concat . BL.toChunks
unsafeVectorToBytes :: forall a. V.Storable a => V.Vector a -> BS.ByteString
unsafeVectorToBytes v =
unsafePerformIO $
withForeignPtr fp (\p -> let p' = castPtr $ plusPtr p offset
in BU.unsafePackCStringLen (p', len*sz))
where (fp,offset,len) = V.unsafeToForeignPtr v
sz = sizeOf (undefined::a)
vectorToBytes :: forall a. V.Storable a => V.Vector a-> BS.ByteString
vectorToBytes v =
unsafePerformIO $
withForeignPtr fp (\p -> let p' = castPtr $ plusPtr p offset
in BS.packCStringLen (p', len*sz))
where (fp,offset,len) = V.unsafeToForeignPtr v
sz = sizeOf (undefined::a)