How to convert between ByteString and Storable Vector?

前端 未结 2 1187
清歌不尽
清歌不尽 2021-02-13 17:50

What is the best way to convert between Storable.Vector Word8 and a strict ByteString?

Of course a non-copying (no-op) way would be most apprec

相关标签:
2条回答
  • 2021-02-13 18:30

    A simple unsafeCoerce will not work, as the layout of the data constructors is different:

    data StorableArray i e = StorableArray !i !i Int !(ForeignPtr e)
    

    vs.

    data ByteString = PS {-# UNPACK #-} !(ForeignPtr Word8) -- payload
                         {-# UNPACK #-} !Int                -- offset
                         {-# UNPACK #-} !Int                -- length
    

    You can import Data.Array.Storable.Internals and Data.ByteString.Internal to get access to the raw constructors and then construct one out of the other without copying the data:

    > let bs = pack [1,2,3]
    > bs
    "\SOH\STX\ETX"
    > let sa = case bs of (PS ptr 0 n) -> StorableArray 0 (n-1) n ptr
    > :t sa
    sa :: StorableArray Int GHC.Word.Word8
    > Data.Array.MArray.readArray sa 1
    2
    > Data.Array.MArray.readArray sa 0
    1
    > Data.Array.MArray.readArray sa 3
    *** Exception: Ix{Int}.index: Index (3) out of range ((0,2))
    

    (I removed the rather long prompt of Prelude Data.Array.Storable.Internals Data.ByteString.Internal Data.ByteString>).

    This will not work for Data.Vector.Unboxed, because here the data is on the Haskell heap and managed by the GHC runtime, while the other two manage the data outside the Haskell heap.

    0 讨论(0)
  • 2021-02-13 18:45
    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)
    
    sizeOfElem vec = sizeOf (undefined `asTypeOf` V.head vec)
    

    http://hackage.haskell.org/packages/archive/spool/0.1/doc/html/Data-Vector-Storable-ByteString.html

    0 讨论(0)
提交回复
热议问题