endianI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #ifdef __GNUC__
29  #define USE_BUILTIN_BYTESWAP
30 #else
31  #undef USE_BUILTIN_BYTESWAP
32 #endif
33 
34 // for Debugging:
35 // #undef USE_BUILTIN_BYTESWAP
36 
37 
38 // Some ideas about a templated approach for swapping bytes:
39 // http://www.cplusplus.com/forum/general/27544/
40 
41 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
42 
43 inline bool Foam::endian::isBig()
44 {
45  const short testBig = 0x0100;
46 
47  // Yields 0x01 for big endian
48  return *(reinterpret_cast<const char*>(&testBig));
49 }
50 
51 
53 {
54  const short testLittle = 0x0001;
55 
56  // Yields 0x01 for little endian
57  return *(reinterpret_cast<const char*>(&testLittle));
58 }
59 
60 
61 inline uint32_t Foam::endian::swap32(uint32_t u)
62 {
63 #ifdef USE_BUILTIN_BYTESWAP
64  return __builtin_bswap32(u);
65 #else
66  return
67  (
68  (((u) & 0xff000000) >> 24) // 3 -> 0
69  | (((u) & 0x00ff0000) >> 8) // 2 -> 1
70  | (((u) & 0x0000ff00) << 8) // 2 <- 1
71  | (((u) & 0x000000ff) << 24) // 3 <- 0
72  );
73 
74  // Alternative formulation
75  //
76  // u = ((u<<8) & 0xFF00FF00) | ((u>>8) & 0x00FF00FF);
77  // u = (u>>16) | (u<<16);
78  // return u;
79 #endif
80 }
81 
82 
83 inline uint64_t Foam::endian::swap64(uint64_t u)
84 {
85 #ifdef USE_BUILTIN_BYTESWAP
86  return __builtin_bswap64(u);
87 #else
88  return
89  (
90  (((u) & 0xff00000000000000ull) >> 56) // 7 -> 0
91  | (((u) & 0x00ff000000000000ull) >> 40) // 6 -> 1
92  | (((u) & 0x0000ff0000000000ull) >> 24) // 5 -> 2
93  | (((u) & 0x000000ff00000000ull) >> 8) // 4 -> 3
94  | (((u) & 0x00000000ff000000ull) << 8) // 4 <- 3
95  | (((u) & 0x0000000000ff0000ull) << 24) // 5 <- 2
96  | (((u) & 0x000000000000ff00ull) << 40) // 6 <- 1
97  | (((u) & 0x00000000000000ffull) << 56) // 7 <- 0
98  );
99 
100  // Alternative formulation
101  /*
102  u = ((u<< 8) & 0xFF00FF00FF00FF00ull) | ((u>> 8) & 0x00FF00FF00FF00FFull);
103  u = ((u<<16) & 0xFFFF0000FFFF0000ull) | ((u>>16) & 0x0000FFFF0000FFFFull);
104  return (u >> 32) | (u << 32);
105  */
106 #endif
107 }
108 
109 
110 // ************************************************************************* //
Foam::endian::isBig
static bool isBig()
Runtime check for big endian.
Definition: endianI.H:43
Foam::endian::swap32
static uint32_t swap32(uint32_t)
Byte endian swapping for 32-bits.
Definition: endianI.H:61
Foam::endian::isLittle
static bool isLittle()
Runtime check for little endian.
Definition: endianI.H:52
Foam::endian::swap64
static uint64_t swap64(uint64_t)
Byte endian swapping for 64-bits.
Definition: endianI.H:83