Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 从Bytestring获取任意位片_Haskell_Binary_Bits_Bytestring_Bitstream - Fatal编程技术网

Haskell 从Bytestring获取任意位片

Haskell 从Bytestring获取任意位片,haskell,binary,bits,bytestring,bitstream,Haskell,Binary,Bits,Bytestring,Bitstream,我想使用惰性的Bytestring来表示位流。我需要能够有效地从这个流中获取任意比特片。例如,我可能有一个长度为10的ByteString,我想切片一个新的ByteString,它由原始ByteString的24-36位组成 问题是ByteStrings是Word8s的数组,因此很难获取不是8的倍数的范围。我能想到的最好的方法就是使用Data.Binary和Data.Binary.Bits。请注意,get32BitRange专门用于范围如果将ByteString作为API类型,则无法有效地实现这

我想使用惰性的
Bytestring
来表示位流。我需要能够有效地从这个流中获取任意比特片。例如,我可能有一个长度为10的
ByteString
,我想切片一个新的
ByteString
,它由原始
ByteString
的24-36位组成


问题是
ByteStrings
Word8
s的数组,因此很难获取不是8的倍数的范围。我能想到的最好的方法就是使用
Data.Binary
Data.Binary.Bits
。请注意,
get32BitRange
专门用于范围如果将
ByteString
作为API类型,则无法有效地实现这一点,因为它不携带您想要的“位”真正从某个偏移量开始进入第一个字节的信息

最好的办法是制作包装器类型:

data BitStream =
    BitStream {
        info :: ByteString,
        -- values from 0-7: ignore all bits in the first byte up to
        -- but not including this offset
        firstBitOffset :: !Int,to but not including this offset
        -- values from 0-7: ignore all bits in the last byte after
        -- but not including this offset
        lastBitOffset :: !Int
    }

然后,您可以围绕这一点设计一个基于位的API。

如果将
ByteString
作为API类型,则无法有效地实现这一点,因为它不携带您想要的“位”真正从某个偏移量开始进入第一个字节的信息

最好的办法是制作包装器类型:

data BitStream =
    BitStream {
        info :: ByteString,
        -- values from 0-7: ignore all bits in the first byte up to
        -- but not including this offset
        firstBitOffset :: !Int,to but not including this offset
        -- values from 0-7: ignore all bits in the last byte after
        -- but not including this offset
        lastBitOffset :: !Int
    }

然后,您可以围绕这一点设计基于位的API。

我认为其他解决方案要好得多,但您可以使用内部模块了解底层结构:


然后,您可以使用标准指针工具,通过直接操作
ForeignPtr
,通过testring生成指向您想要的位置的

我认为其他解决方案更好,但您可以使用内部模块来获得底层结构:


然后,您可以使用标准指针工具,通过直接操纵
ForeignPtr
,通过testring
s生成指向您想要的位置的

我将此标记为已解决。这就是我最终使用的:

get32BitRange :: Int -> Int -> ByteString -> Word32
get32BitRange lo hi = assert (lo < hi) $
    runGet (runBitGet bitGet)
    where bitGet = block $ byteString byteOff
                         *> word8 bitOff
                         *> word32be len
          len = hi - lo
          (byteOff, bitOff) = lo `quotRem` 8
get32BitRange::Int->Int->ByteString->Word32
get32BitRange lo hi=断言(lo字8比特
*>word32be len
len=高-低
(byteOff,bitOff)=loquotrem`8

我要将此标记为已解决。这就是我最终使用的:

get32BitRange :: Int -> Int -> ByteString -> Word32
get32BitRange lo hi = assert (lo < hi) $
    runGet (runBitGet bitGet)
    where bitGet = block $ byteString byteOff
                         *> word8 bitOff
                         *> word32be len
          len = hi - lo
          (byteOff, bitOff) = lo `quotRem` 8
get32BitRange::Int->Int->ByteString->Word32
get32BitRange lo hi=断言(lo字8比特
*>word32be len
len=高-低
(byteOff,bitOff)=loquotrem`8

这当然有助于清理我的示例函数,但我更感兴趣的是一种实际提取位片的方法。之后您想对它们做什么?将它们作为二进制数据解析,可能是一个
字或
Int
类型这当然有助于清理我的示例函数,但我更感兴趣的是一种实际提取位片的方法。你想在之后对它们做什么?将它们作为二进制数据解析,可能是一个
Int
类型。你知道吗,如果它包含
Bool
,那么简单、乏味的老
UArray
已经使用了非常紧凑的表示法?为什么不使用它?@DanielWagner:我没有想到这一点,这将是解决我问题的一个优雅的解决方案,但不幸的是,我需要通过testring
s使用lazy
,我认为在转换为
UAarray
或unbox
Vector
时,我无法保持这种惰性。我可以尝试一种盒式表示,看看它是如何公平的,但效率在这里是关键。你知道吗,如果它包含
Bool
,那么简单、乏味的老
UArray
已经使用了非常紧凑的表示了?为什么不使用它?@DanielWagner:我没有想到这一点,这将是解决我问题的一个优雅的解决方案,但不幸的是,我需要通过testring
s使用lazy
,我认为在转换为
UAarray
或unbox
Vector
时,我无法保持这种惰性。我可以尝试一种盒装的表示,看看它是如何公平的,但效率是关键。
get32BitRange :: Int -> Int -> ByteString -> Word32
get32BitRange lo hi = assert (lo < hi) $
    runGet (runBitGet bitGet)
    where bitGet = block $ byteString byteOff
                         *> word8 bitOff
                         *> word32be len
          len = hi - lo
          (byteOff, bitOff) = lo `quotRem` 8