使用Data.Cereal或Data.Binary序列化String

时间:2012-07-08 03:36:34

标签: haskell

我正在实现一个协议,该协议规定表示密码的字符串应序列化为固定长度的10字节字段。我正在使用Data.Cereal来执行此任务。这是我最近的一次:

padText :: Int -> Text -> Text
padText fieldLen = T.justifyLeft fieldLen '\NUL'

putPassword :: Putter Password
putPassword = put . TE.encodeUtf8 . padText 10

穿上ByteStrings,在它编码的前面添加一个额外的8字节块:

 runPut $ putPassword "Friend"

结果:

"\NUL\NUL\NUL\NUL\NUL\NUL\NUL\nFriend\NUL\NUL\NUL\NUL"

我不想要额外的块。为什么这样表现?

有谁知道如何仅序列化10个原始字节?

2 个答案:

答案 0 :(得分:7)

我认为“额外的块”是指"\NUL\NUL\NUL\NUL\NUL\NUL\NUL\n的第一位。这是一个64位长的字段(注意它的值是10),它是ByteString的序列化定义的一部分。由于您在调用TE.encodeUtf8后已经有一个字节字符串,我建议您只使用putByteString来避免长度字段(如果您要导入惰性文本编码模块,则使用putLazyByteString)。

答案 1 :(得分:2)

正如托马斯所说,ByteStrings put预先编码了编码长度。显示 下面是实际的实例:

instance Serialize B.ByteString where
    put bs = do put (B.length bs :: Int)
                putByteString bs
   ...

putByteString没有。解决方案是使用putByteString

putPassword :: Putter Password
putPassword = putByteString . TE.encodeUtf8 . padText 10