I am implementing a protocol that dictates that a string representing a password should be serialized to a fixed length, 10-byte field. I am using Data.Cereal to perform this task. Here's my most recent go at it:
padText :: Int -> Text -> Text
padText fieldLen = T.justifyLeft fieldLen '\NUL'
putPassword :: Putter Password
putPassword = put . TE.encodeUtf8 . padText 10
put on ByteStrings prepends an additional 8-byte chunk onto the front of what it is encoding making:
runPut $ putPassword "Friend"
result in :
"\NUL\NUL\NUL\NUL\NUL\NUL\NUL\nFriend\NUL\NUL\NUL\NUL"
I don't want the extra chunk. Why is put behaving this way?
Does anyone know how to serialize only the 10 original bytes?
I assume by "the extra chunk" you mean the first bit of "\NUL\NUL\NUL\NUL\NUL\NUL\NUL\n
. That is a 64 bit length field (notice it's value is 10
) which is part of the Serialize definition for ByteString
. Since you already have a bytestring after calling TE.encodeUtf8
, I suggest you just use putByteString
to avoid the length field (or putLazyByteString
if you're importing a lazy text encoding module).
As Thomas stated put
on ByteStrings prepends the encoded length. Shown
below is the actual instance:
instance Serialize B.ByteString where
put bs = do put (B.length bs :: Int)
putByteString bs
...
putByteString
alone does not. The solution is to use putByteString
:
putPassword :: Putter Password
putPassword = putByteString . TE.encodeUtf8 . padText 10
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With