endian: complete reimplementation
Old implementation was overly verbose. We can just rely on gcc builtins as we can't actually build on anything else anyway.
This commit is contained in:
parent
b18353f546
commit
fba15db34b
87
endian.cpp
87
endian.cpp
@ -14,92 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with libgim. If not, see <http://www.gnu.org/licenses/>.
|
* along with libgim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright 2010 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2010-2014 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "endian.hpp"
|
#include "endian.hpp"
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
using std::is_fundamental;
|
|
||||||
using std::is_unsigned;
|
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
/* Big endian doesn't need swapping */
|
|
||||||
template <typename T>
|
|
||||||
T hton (T val) {
|
|
||||||
static_assert (is_fundamental <T>(), "hton implementation assumes fundamental types");
|
|
||||||
static_assert (is_unsigned <T>(), "hton implementation does not handle signed");
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T ntoh (T val) {
|
|
||||||
static_assert (is_fundamental <T>(), "ntoh implementation assumes fundamental types");
|
|
||||||
static_assert (is_unsigned <T>(), "ntoh implementation does not handle signed");
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> uint8_t hton ( uint8_t);
|
|
||||||
template <> uint16_t hton (uint16_t);
|
|
||||||
template <> uint32_t hton (uint32_t);
|
|
||||||
template <> uint64_t hton (uint64_t);
|
|
||||||
|
|
||||||
template <> uint8_t ntoh ( uint8_t);
|
|
||||||
template <> uint16_t ntoh (uint16_t);
|
|
||||||
template <> uint32_t ntoh (uint32_t);
|
|
||||||
template <> uint64_t ntoh (uint64_t);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static void
|
|
||||||
byte_swap (uint8_t *restrict dst, uint8_t *restrict src, size_t len) {
|
|
||||||
for (unsigned int i = 0; i < len; ++i)
|
|
||||||
dst[len - i - 1] = src[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T
|
|
||||||
hton (T i) {
|
|
||||||
// Unsure if this will really be sensible for non-intrinsic types, or types larger than 8 bytes.
|
|
||||||
static_assert (is_fundamental <T>::value, "hton implementation assumes fundamental types");
|
|
||||||
static_assert (is_unsigned <T>::value, "hton implementation does not handle signed");
|
|
||||||
|
|
||||||
T swapped;
|
|
||||||
byte_swap (reinterpret_cast <uint8_t*>(&swapped),
|
|
||||||
reinterpret_cast <uint8_t*>(&i),
|
|
||||||
sizeof (T));
|
|
||||||
return swapped;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T
|
|
||||||
ntoh (T i) {
|
|
||||||
// Unsure if this will really be sensible for non-intrinsic types, or types larger than 8 bytes.
|
|
||||||
static_assert (is_fundamental <T>::value, "ntoh implementation assumes fundamental types");
|
|
||||||
static_assert (is_unsigned <T>::value, "ntoh implementation does not handle signed");
|
|
||||||
|
|
||||||
T swapped;
|
|
||||||
byte_swap (reinterpret_cast <uint8_t*>(&swapped),
|
|
||||||
reinterpret_cast <uint8_t*>(&i),
|
|
||||||
sizeof (T));
|
|
||||||
return swapped;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> uint8_t hton (uint8_t i) { return i; }
|
|
||||||
template <> uint8_t ntoh (uint8_t i) { return i; }
|
|
||||||
|
|
||||||
template uint16_t ntoh<uint16_t> (uint16_t);
|
|
||||||
template uint32_t ntoh<uint32_t> (uint32_t);
|
|
||||||
template uint64_t ntoh<uint64_t> (uint64_t);
|
|
||||||
|
|
||||||
template uint16_t hton<uint16_t> (uint16_t);
|
|
||||||
template uint32_t hton<uint32_t> (uint32_t);
|
|
||||||
template uint64_t hton<uint64_t> (uint64_t);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
79
endian.hpp
79
endian.hpp
@ -14,69 +14,54 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with libgim. If not, see <http://www.gnu.org/licenses/>.
|
* along with libgim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright 2010 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2010-2014 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UTIL_ENDIAN_HPP
|
#ifndef __UTIL_ENDIAN_HPP
|
||||||
#define __UTIL_ENDIAN_HPP
|
#define __UTIL_ENDIAN_HPP
|
||||||
|
|
||||||
#include "platform.hpp"
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
enum {
|
//-----------------------------------------------------------------------------
|
||||||
ENDIAN_BIG,
|
template <typename T>
|
||||||
ENDIAN_LITTLE
|
constexpr T
|
||||||
};
|
bswap (T);
|
||||||
|
|
||||||
|
template <> constexpr uint8_t bswap ( uint8_t v) { return v; }
|
||||||
|
template <> constexpr uint16_t bswap (uint16_t v) { return __builtin_bswap16 (v); }
|
||||||
|
template <> constexpr uint32_t bswap (uint32_t v) { return __builtin_bswap32 (v); }
|
||||||
|
template <> constexpr uint64_t bswap (uint64_t v) { return __builtin_bswap64 (v); }
|
||||||
|
|
||||||
|
|
||||||
constexpr uint8_t hton (uint8_t h) { return h; }
|
//-----------------------------------------------------------------------------
|
||||||
constexpr uint8_t ntoh (uint8_t n) { return n; }
|
template <typename T>
|
||||||
|
constexpr T
|
||||||
|
identity (T &&v) {
|
||||||
constexpr uint16_t hton (uint16_t h) {
|
return v;
|
||||||
return ((h & 0xFF00) >> 8) |
|
|
||||||
((h & 0x00FF) << 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr uint16_t ntoh (uint16_t n)
|
|
||||||
{ return hton (n); }
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#if defined(WORDS_BIGENDIAN)
|
||||||
|
template <typename T> constexpr T hton (T v) { return v; }
|
||||||
|
template <typename T> constexpr T ntoh (T v) { return v; }
|
||||||
|
|
||||||
constexpr uint32_t hton (uint32_t h) {
|
template <typename T> constexpr T htob (T v) { return v; }
|
||||||
#if defined(COMPILER_GCC)
|
template <typename T> constexpr T htol (T v) { return bswap (v); }
|
||||||
return __builtin_bswap32 (h);
|
|
||||||
|
template <typename T> constexpr T btoh (T v) { return v; }
|
||||||
|
template <typename T> constexpr T ltoh (T v) { return bswap (v); }
|
||||||
#else
|
#else
|
||||||
return (h & 0xFF000000U) >> 24 |
|
template <typename T> constexpr T hton (T v) { return bswap (v); }
|
||||||
(h & 0x00FF0000U) >> 8 |
|
template <typename T> constexpr T ntoh (T v) { return bswap (v); }
|
||||||
(h & 0x0000FF00U) << 8 |
|
|
||||||
(h & 0x000000FFU) << 24;
|
template <typename T> constexpr T htob (T v) { return bswap (v); }
|
||||||
|
template <typename T> constexpr T htol (T v) { return v; }
|
||||||
|
|
||||||
|
template <typename T> constexpr T btoh (T v) { return bswap (v); }
|
||||||
|
template <typename T> constexpr T ltoh (T v) { return v; }
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
constexpr uint32_t ntoh (uint32_t n)
|
|
||||||
{ return hton (n); }
|
|
||||||
|
|
||||||
|
|
||||||
constexpr uint64_t hton (uint64_t h) {
|
|
||||||
#if defined(COMPILER_GCC)
|
|
||||||
return __builtin_bswap64 (h);
|
|
||||||
#else
|
|
||||||
return (h & 0xFF00000000000000UL) >> 56 |
|
|
||||||
(h & 0x00FF000000000000UL) >> 40 |
|
|
||||||
(h & 0x0000FF0000000000UL) >> 24 |
|
|
||||||
(h & 0x000000FF00000000UL) >> 8 |
|
|
||||||
(h & 0x00000000FF000000UL) << 8 |
|
|
||||||
(h & 0x0000000000FF0000UL) << 24 |
|
|
||||||
(h & 0x000000000000FF00UL) << 40 |
|
|
||||||
(h & 0x00000000000000FFUL) << 56;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
constexpr uint64_t ntoh (uint64_t n)
|
|
||||||
{ return hton (n); }
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user