Byte Order Swapping Function
Christian Manning
cmanning999 at gmail.com
Sun Jul 17 06:32:21 PDT 2011
Christian Manning wrote:
> How about this?:
>
> private template Eqsize(T) {
> static if (T.sizeof == 4) {
> alias uint S;
> }
> else static if (T.sizeof == 8) {
> alias ulong S;
> }
> }
>
> private union IntFloat {
> uint _int;
> float _float;
> }
>
> private union IntDouble {
> ulong _long;
> double _double;
> }
>
> T byteSwap(T)(T val) if (isIntegral!T || isSomeChar!T) {
> static if (T.sizeof == 2) {
> return cast(T) ((cast(ushort) val >> 8) | (cast(ushort) val <<
> 8));
> }
> else static if (T.sizeof == 4) {
> return cast(T) bswap(cast(uint) val);
> }
> else static if (T.sizeof == 8) {
> return cast(T)bswap(cast(uint) (val >> 32)) |
> (cast(T)bswap(cast(uint) val) << 32);
> }
> }
>
> Eqsize!(T).S byteSwap(T)(T val) if (isFloatingPoint!T) {
> static if (T.sizeof == 4) {
> IntFloat _if;
> _if._float = val;
> _if._int = bswap(_if._int);
> return _if._int;
> }
> else static if (T.sizeof == 8) {
> IntDouble id;
> id._double = val;
> id._long = byteSwap(id._long);
> return id._long;
> }
> }
>
> unittest {
> float a = 45.17249;
> IntFloat _if;
> _if._int = byteSwap(byteSwap(a));
> assert(a is _if._float);
> assert(a == _if._float);
>
> double b = 835.48502;
> IntDouble id;
> id._long = cast(ulong) byteSwap(byteSwap(b));
> assert(b is id._double);
> assert(b == id._double);
>
> long c = 0x0102040880402010;
> long d = 0x1020408008040201;
> assert(byteSwap(c) == d);
> assert(byteSwap(c) is d);
> assert(byteSwap(byteSwap(c)) == c);
> assert(byteSwap(byteSwap(c)) is c);
>
> assert(byteSwap(cast(short) -45) == -11265);
> assert(byteSwap(cast(short) -45) is -11265);
>
> assert(byteSwap(0x18244281) == 0x81422418);
> assert(byteSwap(0x18244281) is 0x81422418);
> }
>
> T bigEndianToNative(T)(T val) if (isNumeric!T || isSomeChar!T) {
> static if (endian == Endian.BigEndian) {
> return val;
> }
> else {
> return byteSwap(val);
> }
> }
>
> alias bigEndianToNative nativeToBigEndian;
>
> T littleEndianToNative(T)(T val) if (isNumeric!T || isSomeChar!T) {
> static if (endian == Endian.LittleEndian) {
> return val;
> }
> else {
> return byteSwap(val);
> }
> }
>
> alias littleEndianToNative nativeToLittleEndian;
Forgot to change bigEndianToNative and littleEndianToNative, woops. You get
the idea though.
More information about the Digitalmars-d
mailing list