1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 /* 21 * Simple helpers for handling typical byte order-related issues. 22 */ 23 module thrift.internal.endian; 24 25 import core.bitop : bswap; 26 import std.traits : isIntegral; 27 28 union IntBuf(T) { 29 ubyte[T.sizeof] bytes; 30 T value; 31 } 32 33 T byteSwap(T)(T t) pure nothrow @trusted if (isIntegral!T) { 34 static if (T.sizeof == 2) { 35 return cast(T)((t & 0xff) << 8) | cast(T)((t & 0xff00) >> 8); 36 } else static if (T.sizeof == 4) { 37 return cast(T)bswap(cast(uint)t); 38 } else static if (T.sizeof == 8) { 39 return cast(T)byteSwap(cast(uint)(t & 0xffffffff)) << 32 | 40 cast(T)bswap(cast(uint)(t >> 32)); 41 } else static assert(false, "Type of size " ~ to!string(T.sizeof) ~ " not supported."); 42 } 43 44 T doNothing(T)(T val) { return val; } 45 46 version (BigEndian) { 47 alias doNothing hostToNet; 48 alias doNothing netToHost; 49 alias byteSwap hostToLe; 50 alias byteSwap leToHost; 51 } else { 52 alias byteSwap hostToNet; 53 alias byteSwap netToHost; 54 alias doNothing hostToLe; 55 alias doNothing leToHost; 56 } 57 58 unittest { 59 import std.exception; 60 61 IntBuf!short s; 62 s.bytes = [1, 2]; 63 s.value = byteSwap(s.value); 64 enforce(s.bytes == [2, 1]); 65 66 IntBuf!int i; 67 i.bytes = [1, 2, 3, 4]; 68 i.value = byteSwap(i.value); 69 enforce(i.bytes == [4, 3, 2, 1]); 70 71 IntBuf!long l; 72 l.bytes = [1, 2, 3, 4, 5, 6, 7, 8]; 73 l.value = byteSwap(l.value); 74 enforce(l.bytes == [8, 7, 6, 5, 4, 3, 2, 1]); 75 }