byteorder.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 Tommi Maekitalo
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 #ifndef CXXTOOLS_BYTEORDER_H
30 #define CXXTOOLS_BYTEORDER_H
31 
32 #include <algorithm>
33 #include <endian.h>
34 
35 #if __BYTE_ORDER == __LITTLE_ENDIAN
36  #define CXXTOOLS_LITTLE_ENDIAN
37 #elif __BYTE_ORDER == __BIG_ENDIAN
38  #define CXXTOOLS_BIG_ENDIAN
39 #endif
40 
41 namespace cxxtools
42 {
44  template <typename T, unsigned sizeofT>
45  class Reverser;
46 
48  template <typename T>
49  class Reverser<T, 2>
50  {
51  public:
52  T operator() (T value)
53  {
54  return value >> 8 & 0xff
55  | value << 8 & 0xff00;
56  }
57  };
58 
59  template <typename T>
60  class Reverser<T, 4>
61  {
62  public:
63  T operator() (T value)
64  {
65  return value >> 24 & 0xff
66  | value >> 8 & 0xff00
67  | value << 8 & 0xff0000
68  | value << 24 & 0xff000000;
69  }
70  };
71 
72  template <typename T>
73  class Reverser<T, 8>
74  {
75  public:
76  T operator() (T value)
77  {
78  return value >> 56 & 0xffll
79  | value >> 40 & 0xff00ll
80  | value >> 24 & 0xff0000ll
81  | value >> 8 & 0xff000000ll
82  | value << 8 & 0xff00000000ll
83  | value << 24 & 0xff0000000000ll
84  | value << 40 & 0xff000000000000ll
85  | value << 56 & 0xff00000000000000ll;
86  }
87  };
89 
91  template <typename T>
92  T reverse(T value)
93  {
94  return Reverser<T, sizeof(T)>() (value);
95  }
96 
99  inline bool isBigEndian()
100  {
101  const int i = 1;
102  return *reinterpret_cast<const int8_t*>(&i) == 0;
103  }
104 
107  inline bool isLittleEndian()
108  {
109  const int i = 1;
110  return *reinterpret_cast<const int8_t*>(&i) == 1;
111  }
112 
114  template <typename T>
115  T hostToLe(T value)
116  {
117 #if defined(CXXTOOLS_BIG_ENDIAN)
118  return reverse(value);
119 #elif defined(CXXTOOLS_LITTLE_ENDIAN)
120  return value;
121 #else
122  return isBigEndian() ? reverse(value) : value;
123 #endif
124  }
125 
127  template <typename T>
128  T leToHost(T value)
129  {
130 #if defined(CXXTOOLS_BIG_ENDIAN)
131  return reverse(value);
132 #elif defined(CXXTOOLS_LITTLE_ENDIAN)
133  return value;
134 #else
135  return isBigEndian() ? reverse(value) : value;
136 #endif
137  }
138 
140  template <typename T>
141  T hostToBe(T value)
142  {
143 #if defined(CXXTOOLS_BIG_ENDIAN)
144  return value;
145 #elif defined(CXXTOOLS_LITTLE_ENDIAN)
146  return reverse(value);
147 #else
148  return isBigEndian() ? value : reverse(value);
149 #endif
150  }
151 
153  template <typename T>
154  T beToHost(T value)
155  {
156 #if defined(CXXTOOLS_BIG_ENDIAN)
157  return value;
158 #elif defined(CXXTOOLS_LITTLE_ENDIAN)
159  return reverse(value);
160 #else
161  return isBigEndian() ? value : reverse(value);
162 #endif
163  }
164 
165 }
166 
167 #endif // CXXTOOLS_BYTEORDER_H