Byte Order Swapping Function

Jonathan M Davis jmdavisProg at gmx.com
Fri Jul 15 14:40:29 PDT 2011


On 2011-07-15 14:23, Christian Manning wrote:
> Andrei Alexandrescu wrote:
> > On 7/14/11 5:51 AM, Regan Heath wrote:
> >> That's my point. I need 8/16/32/64/128 bit versions and it really would
> >> be better if there were general variants. My version are less than
> >> optimal, but do use intrinsics where possible. Someone else can do a far
> >> better job than I, and it really should be done once, by that person.
> >> Surely we have the infrastructure for someone to add this to phobos? If
> >> something this simple can't or won't be done, what hope do we have!?
> > 
> > I think we should have these functions in std.bitmanip:
> > 
> > T toBigEndian(T)(T val) if (isArithmetic!T || isSomeChar!T);
> > T toLittleEndian(T)(T val) if (isArithmetic!T || isSomeChar!T);
> > T bigEndianToNative(T)(T val) if (isArithmetic!T || isSomeChar!T);
> > T littleEndianToNative(T)(T val) if (isArithmetic!T || isSomeChar!T);
> > 
> > That means all characters, all integers, and all floating point numbers.
> > The implementations would opportunistically use intrinsics and other
> > specialized means.
> > 
> > The documentation should specify the relationship to htonl and ntohl.
> > 
> > If there's a need for converting endianness of larger buffers, we might
> > add:
> > 
> > ubyte[] toBigEndian(ubyte[] val);
> > ubyte[] toLittleEndian(ubyte[] val);
> > ubyte[] bigEndianToNative(ubyte[] val);
> > ubyte[] littleEndianToNative(ubyte[] val);
> > 
> > They'd use std.algorithm.reverse internally as needed.
> > 
> > It's a sweet piece of work. Anyone have the time to prepare a pull
> > request?
> > 
> > 
> > Andrei
> 
> Am I being naïve in thinking I can just do this:
> alias littleEndianToNative toLittleEndian;
> alias bigEndianToNative toBigEndian;
> ?

What you do is have a function called swapEndian (or byteSwap or whatever you 
want to call it) and a function which returns the original value. Then you 
alias them based on versions. e.g.

version(BigEndian)
{
 alias doNothing bigEndianToNative;
 alias swapEndian littleEndianToNative;
 alias doNothing nativeToBigEndian;
 alias swapEndian nativeToLittleEndian;
}
else
{
 alias swapEndian bigEndianToNative;
 alias doNothing littleEndianToNative;
 alias swapEndian nativeToBigEndian;
 alias doNothing nativeToLittleEndian;
}

But you must base your conversions (and thus your aliases) on whether the 
machine is big endian or little endian, otherwise they're going to be wrong.

- Jonathan M Davis


More information about the Digitalmars-d mailing list