Byteorder.h
1 /*
2  * Copyright (C) 2004-2006 Marc Boris Duerner
3  * Copyright (C) 2006 Aloysius Indrayanto
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * As a special exception, you may use this file as part of a free
11  * software library without restriction. Specifically, if other files
12  * instantiate templates or use macros or inline functions from this
13  * file, or you compile this file and link it with other files to
14  * produce an executable, this file does not by itself cause the
15  * resulting executable to be covered by the GNU General Public
16  * License. This exception does not however invalidate any other
17  * reasons why the executable file might be covered by the GNU Library
18  * General Public License.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28  */
29 
30 #ifndef Pt_Byteorder_h
31 #define Pt_Byteorder_h
32 
33 #include <Pt/Api.h>
34 #include <Pt/Types.h>
35 #include <cassert>
36 
37 // build systems can specify byte-order by defining PT_LE or PT_BE.
38 // If these are not defined it is still possible to detect the
39 // endianess correctly on many common targets.
40 #if defined(PT_LE) || defined(PT_BE)
41  // user defined endianess
42 #elif defined (_BYTE_ORDER)
43 # if (_BYTE_ORDER == _LITTLE_ENDIAN)
44 # define PT_LE
45 # elif (_BYTE_ORDER == _BIG_ENDIAN)
46 # define PT_BE
47 # else
48 # error: unknown _BYTE_ORDER
49 # endif
50 #elif defined (__BYTE_ORDER)
51 # if (__BYTE_ORDER == __LITTLE_ENDIAN)
52 # define PT_LE
53 # elif (__BYTE_ORDER == __BIG_ENDIAN)
54 # define PT_BE
55 # else
56 # error: unknown __BYTE_ORDER
57 # endif
58 #elif defined (__LITTLE_ENDIAN__) || \
59  defined (i386) || defined(__i386) || defined (__i386__) || \
60  defined(_X86_) || defined(sun386) || defined (_M_IX86) || \
61  defined (_M_IA64) || defined (__ia64__) || \
62  defined(__IA64__) || defined(_IA64) || \
63  defined (_M_AMD64) || defined (__amd64) || \
64  defined(MIPSEL) || defined(_MIPSEL) || \
65  defined (ARM) || defined(__arm__) || defined(_M_ARM) || defined(_M_ARMT) || \
66  defined (vax) || defined (__alpha) || defined(__THW_INTEL)
67  #define PT_LE
68 #elif defined(__BIG_ENDIAN__) || \
69  defined(__hppa__) || defined(__hppa) || defined(__hp9000) || \
70  defined(__hp9000s300) || defined(hp9000s300) || \
71  defined(__hp9000s700) || defined(hp9000s700) || \
72  defined(__hp9000s800) || defined(hp9000s800) || defined(hp9000s820) || \
73  defined(__sparc__) || defined(sparc) || defined(__sparc) || \
74  defined(ibm032) || defined(ibm370) || defined(_IBMR2) || \
75  defined(MIPSEB) || defined(_MIPSEB) || \
76  defined(mc68000) || defined(is68k) || defined(macII) || defined(m68k) || \
77  defined(apollo) || defined(__convex__) || defined(_CRAY) || defined(sel)
78  #define PT_BE
79 #else
80  #error: PT_LE or PT_BE is not defined
81 #endif
82 
83 namespace Pt {
84 
87  template <typename T>
88  inline T swab16(T value)
89  {
90  //union {
91  // uint16_t v;
92  // uint8_t b[2];
93  //} u;
94  //u.v = value;
95  //const uint8_t b0 = u.b[0];
96  //const uint8_t b1 = u.b[1];
97  //u.b[0] = b1;
98  //u.b[1] = b0;
99  //return(u.v);
100 
101  return ( (value & 0x00FF) << 8 ) |
102  ( (value & 0xFF00) >> 8 );
103  }
104 
107  template <typename T>
108  inline T swab32(T value)
109  {
110  return ( (value & 0x000000FF) << 24 ) |
111  ( (value & 0x0000FF00) << 8 ) |
112  ( (value & 0x00FF0000) >> 8 ) |
113  ( (value & 0xFF000000) >> 24 );
114  }
115 
116 #ifdef PT_WITH_INT64
117 
119  template <typename T>
120  inline T swab64(T value)
121  {
122  return ( (value & 0x00000000000000FFULL) << 56 ) |
123  ( (value & 0x000000000000FF00ULL) << 40 ) |
124  ( (value & 0x0000000000FF0000ULL) << 24 ) |
125  ( (value & 0x00000000FF000000ULL) << 8 ) |
126  ( (value & 0x000000FF00000000ULL) >> 8 ) |
127  ( (value & 0x0000FF0000000000ULL) >> 24 ) |
128  ( (value & 0x00FF000000000000ULL) >> 40 ) |
129  ( (value & 0xFF00000000000000ULL) >> 56 );
130  }
131 #endif
132 
133  inline int8_t swab(int8_t value)
134  { return value; }
135 
136  inline uint8_t swab(uint8_t value)
137  { return value; }
138 
139  inline int16_t swab(int16_t value)
140  { return swab16(value); }
141 
142  inline uint16_t swab(uint16_t value)
143  { return swab16(value); }
144 
149  inline int32_t swab(int32_t value)
150  { return swab32(value); }
151 
156  inline uint32_t swab(uint32_t value)
157  { return swab32(value); }
158 
159 #ifdef PT_WITH_INT64
160  inline int64_t swab(int64_t value)
161  { return swab64(value); }
162 
163  inline uint64_t swab(uint64_t value)
164  { return swab64(value); }
165 #endif
166 
171  inline bool isBigEndian()
172  {
173  const int i = 1;
174  return *reinterpret_cast<const int8_t*>(&i) == 0;
175  }
176 
181  inline bool isLittleEndian()
182  {
183  const int i = 1;
184  return *reinterpret_cast<const int8_t*>(&i) == 1;
185  }
186 
196  template <typename T>
197  inline T hostToLe(const T& value)
198  {
199 #ifdef PT_LE
200  return value;
201 #else
202  return swab(value);
203 #endif
204  }
205 
215  template <typename T>
216  inline T leToHost(const T& value)
217  {
218 #ifdef PT_LE
219  return value;
220 #else
221  return swab(value);
222 #endif
223  }
224 
234  template <typename T>
235  inline T hostToBe(const T& value)
236  {
237 #ifdef PT_LE
238  return swab(value);
239 #else
240  return value;
241 #endif
242  }
243 
253  template <typename T>
254  inline T beToHost(const T& value)
255  {
256 #ifdef PT_LE
257  return swab(value);
258 #else
259  return value;
260 #endif
261  }
262 
263 } // namespace Pt
264 
265 #endif
bool isLittleEndian()
Returns true, if the cpu is little-endian (low-byte first).
Definition: Byteorder.h:181
uint_type uint16_t
Unsigned 16-bit integer type.
Definition: Types.h:30
T beToHost(const T &value)
Converts a value from big-endian to host-byteorder.
Definition: Byteorder.h:254
int_type int16_t
Signed 16-bit integer type.
Definition: Types.h:24
int8_t swab(int8_t value)
Swaps the byteorder of an int32_t.
Definition: Byteorder.h:133
int_type int32_t
Signed 32-bit integer type.
Definition: Types.h:36
int_type int64_t
Signed 64-bit integer type.
Definition: Types.h:48
T hostToBe(const T &value)
Converts a value from the host-byteorder to big-endian.
Definition: Byteorder.h:235
T hostToLe(const T &value)
Converts a value from host-byteorder to little-endian.
Definition: Byteorder.h:197
int_type int8_t
Signed 8-bit integer type.
Definition: Types.h:12
uint_type uint64_t
Unsigned 64-bit integer type.
Definition: Types.h:54
uint_type uint32_t
Unsigned 32-bit integer type.
Definition: Types.h:42
uint_type uint8_t
Unsigned 8-bit integer type.
Definition: Types.h:18
T leToHost(const T &value)
Converts a value from little-endian to host-byteorder.
Definition: Byteorder.h:216
bool isBigEndian()
Returns true, if the cpu is big-endian (high-byte first).
Definition: Byteorder.h:171