How do I swap thy bytes? Let me count the ways

2007-04-28 05:35:07 -08:00

  1. swab

    swab(3) is a function that copies some bytes from one location to another, swapping each pair of bytes during the copy. Handy for structures.

    It has a feature that isn’t mentioned in the Darwin manpage for swab: If you pass a negative size, it does not swap. I have no idea why this magic behavior was added; if you want a swab that doesn’t swap bytes, just use bcopy. I shake my head at this use of a magic argument.

  2. ntohs, htons, ntohl, htonl

    These four functions swap the bytes of a 16-bit (‘s’) or 32-bit (‘l’, in ignorance of LP64) integer and return the transformed value.

    They are mainly used in network-I/O contexts, as they transform between network byte order (big-endian) and host byte order (whatever you’re running). But there’s nothing stopping you from using them for any other 16-bit/32-bit integral byte-swapping.

  3. OSByteOrder (Darwin)

    The Darwin kernel provides a number of handy-dandy macros for byte-swapping:

    • OSSwap{Const}?Int{16,32,64}
    • OSSwap{Host,Big,Little}To{Host,Big,Little}{Const}?Int{16,32,64}

    The {Host,Big,Little}To{Host,Big,Little} functions swap conditionally; the others always swap.

    According to the Universal Binary Programming Guidelines, it is safe to use these in applications.

  4. Core Foundation

    CF’s Byte-Order Utilities provide the same facilities as OSByteOrder, with a couple of twists:

    • The implementation uses assembly language when the environment is GCC on either PowerPC or x86. This is theoretically faster than OSByteOrder’s pure-C implementation. (CF falls back on pure C in all other environments.)
    • CF adds support for byte-swapping 32-bit and 64-bit floating-point numbers.
  5. Foundation

    Foundation’s byte-order functions bear all the same capabilities as the CF Byte-Order Utilities. In fact, they are implemented with them.

  6. NeXT byte-order utilities

    These utilities are equivalent to the Foundation functions, except that they are implemented using the OSByteOrder utilities. They are declared in <architecture/byte_order.h>.

  7. Core Endian

    Core Endian logo that I made up.

    I think that the “Core Endian” name itself is new in Panther. Three functions in the API have a “CoreEndian” prefix, and are marked as new in Panther, whereas the others have simply “Endian”, and are marked as having existed since 10.0. This suggests to me that the entire API was branded “Core Endian” in 10.3, with the older functions subsumed by it.

    The new functions have to do with “flipper” callbacks, which you can install so that things like Apple Event Manager can DTRT with your custom data types. The older functions are plain byte-swapping utilities, just like all the other APIs described here, and exist mainly for the benefit of QuickTime users (they exist on Windows, too, through QuickTime).

2 Responses to “How do I swap thy bytes? Let me count the ways”

  1. Blake C. Says:

    “The Const versions always swap; the others swap conditionally.”

    I’m not sure what you mean- for example, OSSwapInt32 always swaps…

  2. Peter Hosey Says:

    Ah, good catch—I had misread the OSByteOrder.h header. It looks like this:

    #if defined(__BIG_ENDIAN__)
    //All host=big implementations here
    #elif defined(__LITTLE_ENDIAN__)
    //All host=little implementations here
    #endif

    I didn’t see the #ifs at first.

    For posterity, here’s what that section said when Blake wrote his comment: “The Const versions always swap; the others swap conditionally.”.

Leave a Reply

Do not delete the second sentence.