mirror of https://gitee.com/bigwinds/arangodb
Fix undefined behaviour (#7108)
This commit is contained in:
parent
5b71dff64f
commit
84de3f6052
|
@ -25,31 +25,6 @@
|
|||
|
||||
#include "Endian.h"
|
||||
|
||||
// aligned / unaligned access
|
||||
|
||||
#if defined(__sparc__) || defined(__arm__)
|
||||
/* unaligned accesses not allowed */
|
||||
#undef FUERTE_UNALIGNED_ACCESS
|
||||
#elif defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC)
|
||||
/* unaligned accesses are slow */
|
||||
#undef FUERTE_UNALIGNED_ACCESS
|
||||
#elif defined(__i386__) || defined(__x86_64__) || \
|
||||
defined(_M_IX86) || defined(_M_X64)
|
||||
/* unaligned accesses should work */
|
||||
#define FUERTE_UNALIGNED_ACCESS 1
|
||||
#else
|
||||
/* unknown platform. better not use unaligned accesses */
|
||||
#undef FUERTE_UNALIGNED_ACCESS
|
||||
#endif
|
||||
|
||||
// enable unaligned little-endian data access
|
||||
#undef FUERTE_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
#ifdef FUERTE_UNALIGNED_ACCESS
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define FUERTE_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace arangodb { namespace fuerte { namespace basics {
|
||||
|
||||
/*
|
||||
|
@ -57,73 +32,20 @@ namespace arangodb { namespace fuerte { namespace basics {
|
|||
*/
|
||||
|
||||
template<typename T>
|
||||
inline T uintFromPersistentLittleEndian(uint8_t const* ptr) {
|
||||
inline T uintFromPersistentLittleEndian(uint8_t const* p) {
|
||||
static_assert(std::is_unsigned<T>::value, "type must be unsigned");
|
||||
#ifdef FUERTE_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
static_assert(basics::isLittleEndian(), "");
|
||||
return *reinterpret_cast<T const*>(ptr);
|
||||
#else
|
||||
T value = 0;
|
||||
T x = 0;
|
||||
uint8_t const* end = ptr + sizeof(T);
|
||||
do {
|
||||
value += static_cast<T>(*ptr++) << x;
|
||||
x += 8;
|
||||
} while (ptr < end);
|
||||
return value;
|
||||
#endif
|
||||
T value;
|
||||
memcpy(&value, p, sizeof(T));
|
||||
return basics::littleToHost<T>(value);
|
||||
}
|
||||
|
||||
/*template<typename T>
|
||||
inline T uintFromPersistentBigEndian(uint8_t const* p) {
|
||||
//return basics::bigToHost(uintFromPersistentLittleEndian<T>(p));
|
||||
static_assert(std::is_unsigned<T>::value, "type must be unsigned");
|
||||
#ifdef FUERTE_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
return basics::bigToHost(*reinterpret_cast<T const*>(p));
|
||||
#else
|
||||
T value = 0;
|
||||
T x = sizeof(T) * 8;
|
||||
uint8_t const* end = ptr + sizeof(T);
|
||||
do {
|
||||
x -= 8;
|
||||
value += static_cast<T>(*ptr++) << x;
|
||||
} while (ptr < end);
|
||||
TRI_ASSERT(x == 0);
|
||||
return value;
|
||||
#endif
|
||||
}*/
|
||||
|
||||
template<typename T>
|
||||
inline void uintToPersistentLittleEndian(uint8_t* ptr, T value) {
|
||||
inline void uintToPersistentLittleEndian(uint8_t* p, T value) {
|
||||
static_assert(std::is_unsigned<T>::value, "type must be unsigned");
|
||||
#ifdef FUERTE_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
static_assert(basics::isLittleEndian(), "");
|
||||
*reinterpret_cast<T*>(ptr) = value;
|
||||
#else
|
||||
uint8_t* end = ptr + sizeof(T);
|
||||
do {
|
||||
*ptr++ = static_cast<uint8_t>(value & 0xffU);
|
||||
value >>= 8;
|
||||
} while (ptr < end);
|
||||
#endif
|
||||
value = basics::hostToLittle(value);
|
||||
memcpy(p, &value, sizeof(T));
|
||||
}
|
||||
|
||||
/*template<typename T>
|
||||
inline void uintToPersistentBigEndian(std::string& p, T value) {
|
||||
//uintToPersistentLittleEndian<T>(p, basics::hostToBig(value));
|
||||
static_assert(std::is_unsigned<T>::value, "type must be unsigned");
|
||||
#ifdef FUERTE_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
value = basics::hostToBig(value);
|
||||
p.append(reinterpret_cast<const char*>(&value), sizeof(T));
|
||||
#else
|
||||
size_t len = sizeof(T) * 8;
|
||||
do {
|
||||
len -= 8;
|
||||
p.push_back(static_cast<char>((value >> len) & 0xFF));
|
||||
} while (len != 0);
|
||||
#endif
|
||||
}*/
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,13 +27,6 @@
|
|||
#include "Basics/Endian.h"
|
||||
#include "RocksDBEngine/RocksDBTypes.h"
|
||||
|
||||
#undef TRI_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
#ifdef TRI_UNALIGNED_ACCESS
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define TRI_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace arangodb {
|
||||
|
||||
namespace rocksutils {
|
||||
|
@ -65,71 +58,32 @@ inline double intToDouble(uint64_t i) {
|
|||
template<typename T>
|
||||
inline T uintFromPersistentLittleEndian(char const* p) {
|
||||
static_assert(std::is_unsigned<T>::value, "type must be unsigned");
|
||||
#ifdef TRI_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
static_assert(basics::isLittleEndian(), "");
|
||||
return *reinterpret_cast<T const*>(p);
|
||||
#else
|
||||
T value = 0;
|
||||
T x = 0;
|
||||
uint8_t const* ptr = reinterpret_cast<uint8_t const*>(p);
|
||||
uint8_t const* end = ptr + sizeof(T);
|
||||
do {
|
||||
value += static_cast<T>(*ptr++) << x;
|
||||
x += 8;
|
||||
} while (ptr < end);
|
||||
return value;
|
||||
#endif
|
||||
T value;
|
||||
memcpy(&value, p, sizeof(T));
|
||||
return basics::littleToHost<T>(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T uintFromPersistentBigEndian(char const* p) {
|
||||
//return basics::bigToHost(uintFromPersistentLittleEndian<T>(p));
|
||||
static_assert(std::is_unsigned<T>::value, "type must be unsigned");
|
||||
#ifdef TRI_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
return basics::bigToHost(*reinterpret_cast<T const*>(p));
|
||||
#else
|
||||
T value = 0;
|
||||
T x = sizeof(T) * 8;
|
||||
uint8_t const* ptr = reinterpret_cast<uint8_t const*>(p);
|
||||
uint8_t const* end = ptr + sizeof(T);
|
||||
do {
|
||||
x -= 8;
|
||||
value += static_cast<T>(*ptr++) << x;
|
||||
} while (ptr < end);
|
||||
TRI_ASSERT(x == 0);
|
||||
return value;
|
||||
#endif
|
||||
T value;
|
||||
memcpy(&value, p, sizeof(T));
|
||||
return basics::bigToHost<T>(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void uintToPersistentLittleEndian(std::string& p, T value) {
|
||||
static_assert(std::is_unsigned<T>::value, "type must be unsigned");
|
||||
#ifdef TRI_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
static_assert(basics::isLittleEndian(), "");
|
||||
value = basics::hostToLittle(value);
|
||||
p.append(reinterpret_cast<const char*>(&value), sizeof(T));
|
||||
#else
|
||||
size_t len = 0;
|
||||
do {
|
||||
p.push_back(static_cast<char>(value & 0xffU));
|
||||
value >>= 8;
|
||||
} while (++len < sizeof(T));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void uintToPersistentBigEndian(std::string& p, T value) {
|
||||
//uintToPersistentLittleEndian<T>(p, basics::hostToBig(value));
|
||||
static_assert(std::is_unsigned<T>::value, "type must be unsigned");
|
||||
#ifdef TRI_USE_FAST_UNALIGNED_DATA_ACCESS
|
||||
value = basics::hostToBig(value);
|
||||
p.append(reinterpret_cast<const char*>(&value), sizeof(T));
|
||||
#else
|
||||
size_t len = sizeof(T) * 8;
|
||||
do {
|
||||
len -= 8;
|
||||
p.push_back(static_cast<char>((value >> len) & 0xFF));
|
||||
} while (len != 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace rocksutils
|
||||
|
|
Loading…
Reference in New Issue