14

Storable.Vector Word8在和严格之间转换的最佳方法是什么ByteString

当然,非复制(无操作)方式将不胜感激。

我应该只是unsafeCoerce或者是否有一个库函数(我找不到)?

此外,对于 a 的方法是否相同Unboxed.Vector Word8

4

2 回答 2

11

一个简单unsafeCoerce的行不通,因为数据构造函数的布局不同:

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

对比

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

您可以导入Data.Array.Storable.InternalsData.ByteString.Internal访问原始构造函数,然后在不复制数据的情况下构建另一个构造函数:

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

(我删除了相当长的提示Prelude Data.Array.Storable.Internals Data.ByteString.Internal Data.ByteString>)。

这不适用于Data.Vector.Unboxed,因为这里的数据在 Haskell 堆上并由 GHC 运行时管理,而另外两个在 Haskell 堆外管理数据。

于 2013-09-08T17:12:44.803 回答
5
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

于 2013-09-19T07:46:00.467 回答