Haskell Attoparsec:从data.Word和data.Int解析数据类型的更简单方法?
我目前正在使用Haskell Attoparsec:从data.Word和data.Int解析数据类型的更简单方法?,haskell,attoparsec,Haskell,Attoparsec,我目前正在使用bytestring和attoparsec在游戏netcode中分别进行序列化和反序列化。我最初被吸引在groove上使用这些库,因为bytestring提供了对构建器的非常精细的控制,包括有用的和有用的。我认为这将是一个很好的选择,因为这将确保我能够更好地处理项目中稍后可能遇到的任何延迟/GC问题 虽然bytestring为数据包字段(主要是data.Word和data.Int中的类型,如Word16,Word16和Int8)中遇到的常见数据类型提供了许多组合符,当我在attop
bytestring
和attoparsec
在游戏netcode中分别进行序列化和反序列化。我最初被吸引在groove
上使用这些库,因为bytestring
提供了对构建器的非常精细的控制,包括有用的和有用的。我认为这将是一个很好的选择,因为这将确保我能够更好地处理项目中稍后可能遇到的任何延迟/GC问题
虽然bytestring
为数据包字段(主要是data.Word
和data.Int
中的类型,如Word16
,Word16
和Int8
)中遇到的常见数据类型提供了许多组合符,当我在attoparsec
中找不到任何互补组合词时,我很失望。我错过什么了吗?我可以用提供的组合器模拟一些等价的东西吗
如果功能缺失,那么在中添加此功能的常用方法是什么?我当然不是第一个需要在图书馆破译签名短片的人。这个功能不存在有什么原因吗?是否有一个我不知道的公共库可以补充attoparsec
?或者我应该这样做:
import Data.Bits
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as B
import qualified Data.Attoparsec.ByteString as Decode
import Data.Int
decodeInt16BE :: Decode.Parser Int16
decodeInt16BE = do
bs <- Decode.take 2
return $! (fromIntegral (bs `B.unsafeIndex` 0) `shiftL` 8) .|.
(fromIntegral (bs `B.unsafeIndex` 1) 1))
导入数据.位
将限定数据.ByteString作为B导入
将限定数据.ByteString.Unsafe作为B导入
将限定数据.Attoparsec.ByteString作为解码导入
导入数据.Int
decodeInt16BE::Decode.Parser Int16
decodeInt16BE=do
bs你应该更详细地解释你在用这些数据包做什么。大多数网络数据包处理不需要回溯,因此ATOPASSERC有点过火。此外,attoparsec(以及二进制和谷物)要求您访问数据包的每个字节。然而,大多数网络数据包中字段的位置是固定偏移量。因此,您可以在检查报头后“随机访问”字段,以确定您拥有的数据包的类型
我认为您可以实现(接近)零分配实现——只需像在C中那样编写算法:将包数据加载到可变的非固定向量中;保持到当前数据包开始的偏移量;如果您的缓冲区中没有完整的数据包,请将所需的数据移动到向量顶部,并用新的数据包数据填充其余的数据包。如果您知道字符串足够长,那么B.unsafeIndex
是完全安全的。