Is there some ready-made function that converts Word32
and Word64
between big/little/host-endian representations? As pointed out in the comments, this shouldn't be needed if (de)serialization is performed correctly, but could be handy in some specific situations when dealing with low-level code.
I found the following solutions, neither perfect:
Use byteorder to determine the current host order, and if little-endian, use byteSwap32
on each word (or alternatively the one from base-compat.
case byteOrder of
LittleEndian -> byteSwap32
_ -> id
Serialize the words with cereal's putWord32be
and immediately read them with getWord32host
(or alternativly putWord32host
and read with getWord32be
). This adds somewhat more heavy-weight dependency, but gives more flexibility for conversions to other formats.
either (error "Unexpected error when converting ip address") id
. runGet getWord32host . runPut . putWord32be
Import the native functions:
foreign import ccall unsafe "htonl" htonl :: Word32 -> Word32
foreign import ccall unsafe "ntohl" ntohl :: Word32 -> Word32
Is there anything better or more convenient?
Yes, there are in System.Endian
module within cpu
package. I also needed it for my purposes.
It has many utility functions for that like:
getSystemEndianness :: Endianness
gets the current CPU endianess
fromLE64 :: Word64 -> Word64
from LE64 to platform endianess
fromBE64 :: Word64 -> Word64
same as above but from BE 64
toLE64 :: Word64 -> Word64
from CPU's Endianess to LE64
toBE64 :: Word64 -> Word64
from CPU's Endianess to BE64
Please note that the module provides same functions for Word32 and Word16: https://hackage.haskell.org/package/cpu-0.1.2/docs/System-Endian.html