Fix conversion to/from big endian.

This commit is contained in:
Vitaly Baranov 2021-07-13 11:12:43 +03:00
parent 81f3876506
commit 0f9ace257f
3 changed files with 29 additions and 18 deletions

View File

@ -6,6 +6,7 @@
#include <openssl/engine.h> #include <openssl/engine.h>
#include <IO/ReadBuffer.h> #include <IO/ReadBuffer.h>
#include <IO/ReadHelpers.h>
#include <IO/WriteBuffer.h> #include <IO/WriteBuffer.h>
#include <IO/WriteHelpers.h> #include <IO/WriteHelpers.h>
@ -50,28 +51,16 @@ public:
private: private:
String ToBigEndianString(DB::UInt128 value) const String ToBigEndianString(DB::UInt128 value) const
{ {
size_t size = kIVSize; WriteBufferFromOwnString out;
size_t dev = std::pow(2, CHAR_BIT); writeBinaryBigEndian(value, out);
String result(size, 0); return std::move(out.str());
for (size_t i = 0; i != size; ++i)
{
result[size - i - 1] = value % dev;
value /= dev;
}
return result;
} }
DB::UInt128 FromBigEndianString(const String & str) const DB::UInt128 FromBigEndianString(const String & str) const
{ {
size_t dev = std::pow(2, CHAR_BIT); ReadBufferFromMemory in{str.data(), str.length()};
DB::UInt128 result = 0; DB::UInt128 result;
readBinaryBigEndian(result, in);
for (auto c : str)
{
result *= dev;
result += c % dev;
}
return result; return result;
} }

View File

@ -921,6 +921,17 @@ readBinaryBigEndian(T & x, ReadBuffer & buf) /// Assuming little endian archi
x = __builtin_bswap64(x); x = __builtin_bswap64(x);
} }
template <typename T>
inline std::enable_if_t<is_big_int_v<T>, void>
readBinaryBigEndian(T & x, ReadBuffer & buf) /// Assuming little endian architecture.
{
for (size_t i = 0; i != std::size(x.items); ++i)
{
auto & item = x.items[std::size(x.items) - i - 1];
readBinaryBigEndian(item, buf);
}
}
/// Generic methods to read value in text tab-separated format. /// Generic methods to read value in text tab-separated format.
template <typename T> template <typename T>

View File

@ -1099,6 +1099,17 @@ writeBinaryBigEndian(T x, WriteBuffer & buf) /// Assuming little endian archi
writePODBinary(x, buf); writePODBinary(x, buf);
} }
template <typename T>
inline std::enable_if_t<is_big_int_v<T>, void>
writeBinaryBigEndian(const T & x, WriteBuffer & buf) /// Assuming little endian architecture.
{
for (size_t i = 0; i != std::size(x.items); ++i)
{
const auto & item = x.items[std::size(x.items) - i - 1];
writeBinaryBigEndian(item, buf);
}
}
struct PcgSerializer struct PcgSerializer
{ {
static void serializePcg32(const pcg32_fast & rng, WriteBuffer & buf) static void serializePcg32(const pcg32_fast & rng, WriteBuffer & buf)