Byte Order Swapping Function

Christian Manning cmanning999 at gmail.com
Fri Jul 15 15:40:42 PDT 2011


Jonathan M Davis wrote:

> 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

I realise this, but I was doing this with static ifs and std.system like:

T littleEndianToNative(T)(T val) if (isArithmetic!T || isSomeChar!T) {
    static if (endian == Endian.LittleEndian) {
        return val;
    }
    else {
        return byteSwap(val);
    }
}

alias littleEndianToNative toLittleEndian;

And the same for BigEndian.

Chris


More information about the Digitalmars-d mailing list