2013-09-08 10 views
11

Storable.Vector Word8 ile sıkı bir ByteString arasında dönüştürmenin en iyi yolu nedir? Tabii kiByteString ve Storable Vector arasında dönüştürme nasıl yapılır?

olmayan bir kopyalama (no-op) yolu, en takdir.

Gerekir Sadece unsafeCoerce veya bunun için bir kütüphane işlevi (Birini bulamadım) var mı?

Ayrıca

, yaklaşım Unboxed.Vector Word8 için aynı olacak?

+1

Bazı durumlarda kopyalamak için yararlı olacaktır. Bayt dizileriniz daha uzun bir orijinal bytestring'in kısa segmentleri ise, örn. ('BS.take 10 someLongByteString'), tüm uzun yığın' ForeignPtr' tarafından korunacaktır. Bu durumda kopyalama daha iyidir çünkü daha az bellek kullanır. Bu özel bir durum, ama sık sık ortaya çıkıyor gibi görünüyor. –

cevap

9

Basit unsafeCoerce veri inşaatçı düzeni farklı olduğu, çalışmaz: Çiğ kurucular erişmek için Data.Array.Storable.Internals ve Data.ByteString.Internal alabilirsiniz

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

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

vs

> 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)) 
0: ve sonra da verileri kopyalama olmadan başka üzerinden bir inşa

(Çok uzun bir istem Prelude Data.Array.Storable.Internals Data.ByteString.Internal Data.ByteString> kaldırıldı). Burada veri Haskell öbek üzerinde ve GHC çalışma zamanı tarafından yönetilen çünkü diğer iki Haskell yığın dışında verileri yönetmek ise

Bu, Data.Vector.Unboxed için çalışmaz.

3
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

Bunu Hackage'a koyduğunuz için teşekkürler! – nh2

İlgili konular