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 {
43  template <typename T, unsigned sizeofT>
44  class Reverser;
45 
46  template <typename T>
47  class Reverser<T, 2>
48  {
49  public:
50  T operator() (T value)
51  {
52  return value >> 8 & 0xff
53  | value << 8 & 0xff00;
54  }
55  };
56 
57  template <typename T>
58  class Reverser<T, 4>
59  {
60  public:
61  T operator() (T value)
62  {
63  return value >> 24 & 0xff
64  | value >> 8 & 0xff00
65  | value << 8 & 0xff0000
66  | value << 24 & 0xff000000;
67  }
68  };
69 
70  template <typename T>
71  class Reverser<T, 8>
72  {
73  public:
74  T operator() (T value)
75  {
76  return value >> 56 & 0xffll
77  | value >> 40 & 0xff00ll
78  | value >> 24 & 0xff0000ll
79  | value >> 8 & 0xff000000ll
80  | value << 8 & 0xff00000000ll
81  | value << 24 & 0xff0000000000ll
82  | value << 40 & 0xff000000000000ll
83  | value << 56 & 0xff00000000000000ll;
84  }
85  };
86 
87  template <typename T>
88  T reverse(T value)
89  {
90  return Reverser<T, sizeof(T)>() (value);
91  }
92 
95  inline bool isBigEndian()
96  {
97  const int i = 1;
98  return *reinterpret_cast<const int8_t*>(&i) == 0;
99  }
100 
103  inline bool isLittleEndian()
104  {
105  const int i = 1;
106  return *reinterpret_cast<const int8_t*>(&i) == 1;
107  }
108 
110  template <typename T>
111  T hostToLe(T value)
112  {
113 #if defined(CXXTOOLS_BIG_ENDIAN)
114  return reverse(value);
115 #elif defined(CXXTOOLS_LITTLE_ENDIAN)
116  return value;
117 #else
118  return isBigEndian() ? reverse(value) : value;
119 #endif
120  }
121 
123  template <typename T>
124  T leToHost(T value)
125  {
126 #if defined(CXXTOOLS_BIG_ENDIAN)
127  return reverse(value);
128 #elif defined(CXXTOOLS_LITTLE_ENDIAN)
129  return value;
130 #else
131  return isBigEndian() ? reverse(value) : value;
132 #endif
133  }
134 
136  template <typename T>
137  T hostToBe(T value)
138  {
139 #if defined(CXXTOOLS_BIG_ENDIAN)
140  return value;
141 #elif defined(CXXTOOLS_LITTLE_ENDIAN)
142  return reverse(value);
143 #else
144  return isBigEndian() ? value : reverse(value);
145 #endif
146  }
147 
149  template <typename T>
150  T beToHost(T value)
151  {
152 #if defined(CXXTOOLS_BIG_ENDIAN)
153  return value;
154 #elif defined(CXXTOOLS_LITTLE_ENDIAN)
155  return reverse(value);
156 #else
157  return isBigEndian() ? value : reverse(value);
158 #endif
159  }
160 
161 }
162 
163 #endif // CXXTOOLS_BYTEORDER_H