Search code examples
haskellnetwork-programmingipv6endianness

Host byte order and network's HostAddress6


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:

  1. 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
    
  2. 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
    
  3. 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?


Solution

  • 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