1 #ifndef PROTOZERO_BYTESWAP_HPP
2 #define PROTOZERO_BYTESWAP_HPP
3 
4 /*****************************************************************************
5 
6 protozero - Minimalistic protocol buffer decoder and encoder in C++.
7 
8 This file is from https://github.com/mapbox/protozero where you can find more
9 documentation.
10 
11 *****************************************************************************/
12 
13 /**
14  * @file byteswap.hpp
15  *
16  * @brief Contains functions to swap bytes in values (for different endianness).
17  */
18 
19 #include <cassert>
20 #include <cstdint>
21 
22 #include <protozero/config.hpp>
23 
24 namespace protozero {
25 namespace detail {
26 
byteswap_impl(uint32_t value)27 inline uint32_t byteswap_impl(uint32_t value) noexcept {
28 #ifdef PROTOZERO_USE_BUILTIN_BSWAP
29     return __builtin_bswap32(value);
30 #else
31     return ((value & 0xff000000) >> 24) |
32            ((value & 0x00ff0000) >>  8) |
33            ((value & 0x0000ff00) <<  8) |
34            ((value & 0x000000ff) << 24);
35 #endif
36 }
37 
byteswap_impl(uint64_t value)38 inline uint64_t byteswap_impl(uint64_t value) noexcept {
39 #ifdef PROTOZERO_USE_BUILTIN_BSWAP
40     return __builtin_bswap64(value);
41 #else
42     return ((value & 0xff00000000000000ULL) >> 56) |
43            ((value & 0x00ff000000000000ULL) >> 40) |
44            ((value & 0x0000ff0000000000ULL) >> 24) |
45            ((value & 0x000000ff00000000ULL) >>  8) |
46            ((value & 0x00000000ff000000ULL) <<  8) |
47            ((value & 0x0000000000ff0000ULL) << 24) |
48            ((value & 0x000000000000ff00ULL) << 40) |
49            ((value & 0x00000000000000ffULL) << 56);
50 #endif
51 }
52 
byteswap_inplace(uint32_t * ptr)53 inline void byteswap_inplace(uint32_t* ptr) noexcept {
54     *ptr = byteswap_impl(*ptr);
55 }
56 
byteswap_inplace(uint64_t * ptr)57 inline void byteswap_inplace(uint64_t* ptr) noexcept {
58     *ptr = byteswap_impl(*ptr);
59 }
60 
byteswap_inplace(int32_t * ptr)61 inline void byteswap_inplace(int32_t* ptr) noexcept {
62     auto bptr = reinterpret_cast<uint32_t*>(ptr);
63     *bptr = byteswap_impl(*bptr);
64 }
65 
byteswap_inplace(int64_t * ptr)66 inline void byteswap_inplace(int64_t* ptr) noexcept {
67     auto bptr = reinterpret_cast<uint64_t*>(ptr);
68     *bptr = byteswap_impl(*bptr);
69 }
70 
byteswap_inplace(float * ptr)71 inline void byteswap_inplace(float* ptr) noexcept {
72     auto bptr = reinterpret_cast<uint32_t*>(ptr);
73     *bptr = byteswap_impl(*bptr);
74 }
75 
byteswap_inplace(double * ptr)76 inline void byteswap_inplace(double* ptr) noexcept {
77     auto bptr = reinterpret_cast<uint64_t*>(ptr);
78     *bptr = byteswap_impl(*bptr);
79 }
80 
81 } // end namespace detail
82 } // end namespace protozero
83 
84 #endif // PROTOZERO_BYTESWAP_HPP
85