簡體   English   中英

有效地將Foreign.Ptr Word8(或ByteString)轉換為UArray Int Word8

[英]Efficiently convert Foreign.Ptr Word8 (or ByteString) to UArray Int Word8

我正在使用Network.Pcappcap )進行一些網絡捕獲,並計划使用Net.PacketParsing網絡中心 )進行一些檢查。 為此,看起來我必須將我的數據包解析

Pcap.Callback :: PktHdr -> Ptr Word8 -> IO ()

要么

Pcap.CallbackBS :: PktHdr -> ByteString -> IO ().

並將數據包作為'Ptr Word8'或'ByteString'處理。 在數據包解析方面,我有:

Net.Packet.toInPack :: UArray Int Word8 -> InPacket

獲取解析所需的InPacket類型。 那么,剩下的就是將'Ptr'或'ByteString'轉換為'UArray' - 無論是純粹還是IO。 我想我可以將ByteString解壓縮到[Word8] ,然后從那里解壓縮到UArray ,但似乎必須有更好的方法。

我也很關心我選擇的庫。 我過去曾經使用過網絡設備並發現它非常好,但它已經老了並且使用了UArray,它本身看起來有點陳舊。 因此歡迎提出更好的起點建議。

ByteStringPtr Word8指向外部堆,而UArray在GHC堆上,因此任何轉換函數都必須復制數據。

我還沒有在庫中找到任何直接轉換函數,但幸運的是有一個GHC原語完全符合我們的要求,稱為copyAddrToByteArray# 這讓我們可以用最小的開銷進行轉換:

{-# language MagicHash, UnboxedTuples #-}

import qualified Data.ByteString as B
import qualified Data.ByteString.Internal as B
import qualified Data.Array.Base as A

import GHC.Types
import GHC.Prim
import GHC.Magic (runRW#)
import GHC.ForeignPtr
import Data.Word

-- when using GHC 8.2.x or later:
byteStringToUArray :: B.ByteString -> A.UArray Int Word8
byteStringToUArray (B.PS (ForeignPtr addr _) (I# start) (I# len)) =
  runRW# $ \s -> case newByteArray# len s of
    (# s, marr #) -> case copyAddrToByteArray# (plusAddr# addr start) marr 0# len s of
      s -> case unsafeFreezeByteArray# marr s of
        (# _, arr #) -> A.UArray 0 (I# (len -# 1#)) (I# len) arr
{-# inline byteStringToUArray #-}

-- when using GHC 8.0.x:
byteStringToUArray :: B.ByteString -> A.UArray Int Word8
byteStringToUArray (B.PS (ForeignPtr addr _) (I# start) (I# len)) =
  case (runRW# $ \s -> case newByteArray# len s of
    (# s, marr #) -> case copyAddrToByteArray# (plusAddr# addr start) marr 0# len s of
      s -> case unsafeFreezeByteArray# marr s of
        (# s, arr #) -> (# s, A.UArray 0 (I# (len -# 1#)) (I# len) arr #)) of
    (# _, res #) -> res
{-# inline byteStringToUArray #-}

但總的來說,你是對的, array已經過時,現在很少使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM