haskellendiannessbytestring

How to convert a ByteString to an Int and dealing with endianness?


I need to read a binary format in Haskell. The format is fairly simple: four octets indicating the length of the data, followed by the data. The four octets represent an integer in network byte-order.

How can I convert a ByteString of four bytes to an integer? I want a direct cast (in C, that would be *(int*)&data), not a lexicographical conversion. Also, how would I go about endianness? The serialized integer is in network byte-order, but the machine may use a different byte-order.

I tried Googling but that only yold results about lexicographical conversion.


Solution

  • The binary package contains tools to get integer types of various sizes and endianness from ByteStrings.

    λ> :set -XOverloadedStrings
    λ> import qualified Data.Binary.Get as B
    λ> B.runGet B.getWord32be "\STX\SOH\SOH\SOH"
    33620225
    λ> B.runGet B.getWord32be "\STX\SOH\SOH\SOHtrailing characters are ignored"
    33620225
    λ> B.runGet B.getWord32be "\STX\SOH\SOH" -- remember to use `catch`:
    *** Exception: Data.Binary.Get.runGet at position 0: not enough bytes
    CallStack (from HasCallStack):
      error, called at libraries/binary/src/Data/Binary/Get.hs:351:5 in binary-0.8.5.1:Data.Binary.Get