blob: 31b9814ef8dde1df59cf11854eac2e866cf01241 [file] [log] [blame]
Jake Farrellb95b0ff2012-03-22 21:49:10 +00001/*
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 */
23module thrift.internal.endian;
24
25import core.bitop : bswap;
26import std.traits : isIntegral;
27
28union IntBuf(T) {
29 ubyte[T.sizeof] bytes;
30 T value;
31}
32
33T 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
44T doNothing(T)(T val) { return val; }
45
46version (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
58unittest {
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}