How do I swap thy bytes? Let me count the ways
-
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.
-
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.
-
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.
-
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.
-
Foundation
Foundation’s byte-order functions bear all the same capabilities as the CF Byte-Order Utilities. In fact, they are implemented with them.
-
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>.
-
Core Endian
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).
April 28th, 2007 at 17:51:06
“The Const versions always swap; the others swap conditionally.”
I’m not sure what you mean- for example, OSSwapInt32 always swaps…
April 28th, 2007 at 18:38:16
Ah, good catch—I had misread the OSByteOrder.h header. It looks like this:
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.”.