libxcks  0.1.0.1
checksumex.hpp
Go to the documentation of this file.
1 /*
2  * libxcks
3  * Copyright (C) 2022 Julien Couot
4  *
5  * This program is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13  * License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
24 #ifndef INC_CHECKSUMEX_HPP_4824BBD5_CC92_4894_B227_01821AE7FAFD
25 #define INC_CHECKSUMEX_HPP_4824BBD5_CC92_4894_B227_01821AE7FAFD
26 
27 //---------------------------------------------------------------------------
28 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
29  #if __has_include(<byteswap.h>)
30  #include <byteswap.h>
31  #elif defined(__i386__) && __has_include(<intrin_x86.h>)
32  #include <intrin_x86.h>
33  #elif defined(_PPC_) && __has_include(<intrin_ppc.h>)
34  #include <intrin_ppc.h>
35  #elif defined(_MIPS_) && __has_include(<intrin_mips.h>)
36  #include <intrin_mips.h>
37  #elif defined(__x86_64__) && __has_include(<intrin_x86_64.h>)
38  #include <intrin_x86_64.h>
39  #else
40  #define LIBXCKS_CHECKSUMEX_NOINTRIN
41  #endif
42 #elif defined(_MSC_VER)
43 #include <intrin.h>
44 #else
45 #define LIBXCKS_CHECKSUMEX_NOINTRIN
46 #endif
47 
48 #include "libxcks/checksum.hpp"
49 //---------------------------------------------------------------------------
50 
51 
52 namespace libxcks
53 {
54 // Endianness
55 #define LIBXCKS_BIG_ENDIAN 4321
56 #define LIBXCKS_LITTLE_ENDIAN 1234
57 
58 #ifdef WORDS_BIGENDIAN
59 #define LIBXCKS_BYTE_ORDER LIBXCKS_BIG_ENDIAN
60 #else
61 #define LIBXCKS_BYTE_ORDER LIBXCKS_LITTLE_ENDIAN
62 #endif
63 //---------------------------------------------------------------------------
64 
65 
71 class ChecksumEx : public Checksum
72 {
73  public:
77  virtual void reset() = 0;
78 
86  std::string toString(const bool hexInUpperCase = false) const override;
87 
88  protected:
95  inline static uint32_t swapOnLE(const uint32_t value)
96  {
97  #if (LIBXCKS_BYTE_ORDER == LIBXCKS_BIG_ENDIAN)
98  return value;
99  #else
100  #if !defined(LIBXCKS_CHECKSUMEX_NOINTRIN) && (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__))
101  return __builtin_bswap32(value);
102  #elif !defined(LIBXCKS_CHECKSUMEX_NOINTRIN) && defined(_MSC_VER)
103  return _byteswap_ulong(value);
104  #else
105  return ((uint32_t) ( \
106  (((uint32_t) (value) & (uint32_t) 0x000000ffU) << 24) | \
107  (((uint32_t) (value) & (uint32_t) 0x0000ff00U) << 8) | \
108  (((uint32_t) (value) & (uint32_t) 0x00ff0000U) >> 8) | \
109  (((uint32_t) (value) & (uint32_t) 0xff000000U) >> 24)));
110  #endif
111  #endif
112  }
113 
120  inline static uint32_t swapOnBE(const uint32_t value)
121  {
122  #if (LIBXCKS_BYTE_ORDER == LIBXCKS_LITTLE_ENDIAN)
123  return value;
124  #else
125  #if !defined(LIBXCKS_CHECKSUMEX_NOINTRIN) && (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__))
126  return __builtin_bswap32(value);
127  #elif !defined(LIBXCKS_CHECKSUMEX_NOINTRIN) && defined(_MSC_VER)
128  return _byteswap_ulong(value);
129  #else
130  return ((uint32_t) ( \
131  (((uint32_t) (value) & (uint32_t) 0x000000ffU) << 24) | \
132  (((uint32_t) (value) & (uint32_t) 0x0000ff00U) << 8) | \
133  (((uint32_t) (value) & (uint32_t) 0x00ff0000U) >> 8) | \
134  (((uint32_t) (value) & (uint32_t) 0xff000000U) >> 24)));
135  #endif
136  #endif
137  }
138 
145  inline static uint64_t swapOnLE(const uint64_t value)
146  {
147  #if (LIBXCKS_BYTE_ORDER == LIBXCKS_BIG_ENDIAN)
148  return value;
149  #else
150  #if !defined(LIBXCKS_CHECKSUMEX_NOINTRIN) && (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__))
151  return __builtin_bswap64(value);
152  #elif !defined(LIBXCKS_CHECKSUMEX_NOINTRIN) && defined(_MSC_VER)
153  return _byteswap_uint64(value);
154  #else
155  return ((uint64_t) ( \
156  (((uint64_t) (value) & (uint64_t) UINT64_C(0x00000000000000ff)) << 56) | \
157  (((uint64_t) (value) & (uint64_t) UINT64_C(0x000000000000ff00)) << 40) | \
158  (((uint64_t) (value) & (uint64_t) UINT64_C(0x0000000000ff0000)) << 24) | \
159  (((uint64_t) (value) & (uint64_t) UINT64_C(0x00000000ff000000)) << 8) | \
160  (((uint64_t) (value) & (uint64_t) UINT64_C(0x000000ff00000000)) >> 8) | \
161  (((uint64_t) (value) & (uint64_t) UINT64_C(0x0000ff0000000000)) >> 24) | \
162  (((uint64_t) (value) & (uint64_t) UINT64_C(0x00ff000000000000)) >> 40) | \
163  (((uint64_t) (value) & (uint64_t) UINT64_C(0xff00000000000000)) >> 56)));
164  #endif
165  #endif
166  }
167 
174  inline static uint64_t swapOnBE(const uint64_t value)
175  {
176  #if (LIBXCKS_BYTE_ORDER == LIBXCKS_LITTLE_ENDIAN)
177  return value;
178  #else
179  #if !defined(LIBXCKS_CHECKSUMEX_NOINTRIN) && (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__))
180  return __builtin_bswap64(value);
181  #elif !defined(LIBXCKS_CHECKSUMEX_NOINTRIN) && defined(_MSC_VER)
182  return _byteswap_uint64(value);
183  #else
184  return ((uint64_t) ( \
185  (((uint64_t) (value) & (uint64_t) UINT64_C(0x00000000000000ff)) << 56) | \
186  (((uint64_t) (value) & (uint64_t) UINT64_C(0x000000000000ff00)) << 40) | \
187  (((uint64_t) (value) & (uint64_t) UINT64_C(0x0000000000ff0000)) << 24) | \
188  (((uint64_t) (value) & (uint64_t) UINT64_C(0x00000000ff000000)) << 8) | \
189  (((uint64_t) (value) & (uint64_t) UINT64_C(0x000000ff00000000)) >> 8) | \
190  (((uint64_t) (value) & (uint64_t) UINT64_C(0x0000ff0000000000)) >> 24) | \
191  (((uint64_t) (value) & (uint64_t) UINT64_C(0x00ff000000000000)) >> 40) | \
192  (((uint64_t) (value) & (uint64_t) UINT64_C(0xff00000000000000)) >> 56)));
193  #endif
194  #endif
195  }
196 };
197 //---------------------------------------------------------------------------
198 } // namespace libxcks
199 //---------------------------------------------------------------------------
200 
201 #endif // INC_LIBGCRYPTHASH_HPP_4824BBD5_CC92_4894_B227_01821AE7FAFD
Interface for classes that compute checksums.
Computes a hash from a byte stream.
Definition: checksumex.hpp:72
virtual void reset()=0
Resets the checksum to initial value.
static uint64_t swapOnBE(const uint64_t value)
Swaps bytes on big endian architectures.
Definition: checksumex.hpp:174
std::string toString(const bool hexInUpperCase=false) const override
Returns the hash value has a string.
Definition: checksumex.cpp:42
static uint64_t swapOnLE(const uint64_t value)
Swaps bytes on little endian architectures.
Definition: checksumex.hpp:145
static uint32_t swapOnLE(const uint32_t value)
Swaps bytes on little endian architectures.
Definition: checksumex.hpp:95
static uint32_t swapOnBE(const uint32_t value)
Swaps bytes on big endian architectures.
Definition: checksumex.hpp:120
Computes a checksum from a byte stream.
Definition: checksum.hpp:54