From fb6dc83ef4a98ed40d3672ffc52cfb5b88b47f13 Mon Sep 17 00:00:00 2001 From: Matej Ferencevic Date: Wed, 7 Aug 2019 13:45:57 +0200 Subject: [PATCH] Replace bswap with proper endian functions Reviewers: teon.banek Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2290 --- src/communication/bolt/v1/decoder/decoder.hpp | 14 ++--- .../bolt/v1/encoder/base_encoder.hpp | 4 +- .../v1/encoder/chunked_encoder_buffer.hpp | 1 - src/durability/hashed_file_reader.hpp | 5 +- src/durability/hashed_file_writer.hpp | 7 +-- src/utils/bswap.hpp | 43 ------------- src/utils/endian.hpp | 61 +++++++++++++++++++ tests/unit/bolt_session.cpp | 2 +- 8 files changed, 76 insertions(+), 61 deletions(-) delete mode 100644 src/utils/bswap.hpp create mode 100644 src/utils/endian.hpp diff --git a/src/communication/bolt/v1/decoder/decoder.hpp b/src/communication/bolt/v1/decoder/decoder.hpp index 356836009..260942cff 100644 --- a/src/communication/bolt/v1/decoder/decoder.hpp +++ b/src/communication/bolt/v1/decoder/decoder.hpp @@ -6,8 +6,8 @@ #include "communication/bolt/v1/codes.hpp" #include "communication/bolt/v1/value.hpp" -#include "utils/bswap.hpp" #include "utils/cast.hpp" +#include "utils/endian.hpp" namespace communication::bolt { @@ -186,18 +186,18 @@ class Decoder { if (!buffer_.Read(reinterpret_cast(&tmp), sizeof(tmp))) { return false; } - ret = utils::Bswap(tmp); + ret = utils::BigEndianToHost(tmp); } else if (marker == Marker::Int32) { int32_t tmp; if (!buffer_.Read(reinterpret_cast(&tmp), sizeof(tmp))) { return false; } - ret = utils::Bswap(tmp); + ret = utils::BigEndianToHost(tmp); } else if (marker == Marker::Int64) { if (!buffer_.Read(reinterpret_cast(&ret), sizeof(ret))) { return false; } - ret = utils::Bswap(ret); + ret = utils::BigEndianToHost(ret); } else { return false; } @@ -212,7 +212,7 @@ class Decoder { if (!buffer_.Read(reinterpret_cast(&value), sizeof(value))) { return false; } - value = utils::Bswap(value); + value = utils::BigEndianToHost(value); ret = utils::MemcpyCast(value); *data = Value(ret); return true; @@ -233,14 +233,14 @@ class Decoder { if (!buffer_.Read(reinterpret_cast(&tmp), sizeof(tmp))) { return -1; } - tmp = utils::Bswap(tmp); + tmp = utils::BigEndianToHost(tmp); return tmp; } else if (marker == Marker32[type]) { uint32_t tmp; if (!buffer_.Read(reinterpret_cast(&tmp), sizeof(tmp))) { return -1; } - tmp = utils::Bswap(tmp); + tmp = utils::BigEndianToHost(tmp); return tmp; } else { return -1; diff --git a/src/communication/bolt/v1/encoder/base_encoder.hpp b/src/communication/bolt/v1/encoder/base_encoder.hpp index bed2153c3..76d4dd474 100644 --- a/src/communication/bolt/v1/encoder/base_encoder.hpp +++ b/src/communication/bolt/v1/encoder/base_encoder.hpp @@ -4,8 +4,8 @@ #include "communication/bolt/v1/codes.hpp" #include "communication/bolt/v1/value.hpp" -#include "utils/bswap.hpp" #include "utils/cast.hpp" +#include "utils/endian.hpp" static_assert(std::is_same_v || std::is_same_v, @@ -216,7 +216,7 @@ class BaseEncoder { private: template void WritePrimitiveValue(T value) { - value = utils::Bswap(value); + value = utils::HostToBigEndian(value); WriteRAW(reinterpret_cast(&value), sizeof(value)); } }; diff --git a/src/communication/bolt/v1/encoder/chunked_encoder_buffer.hpp b/src/communication/bolt/v1/encoder/chunked_encoder_buffer.hpp index 698d4eb2d..ab6e176fb 100644 --- a/src/communication/bolt/v1/encoder/chunked_encoder_buffer.hpp +++ b/src/communication/bolt/v1/encoder/chunked_encoder_buffer.hpp @@ -8,7 +8,6 @@ #include #include "communication/bolt/v1/constants.hpp" -#include "utils/bswap.hpp" namespace communication::bolt { diff --git a/src/durability/hashed_file_reader.hpp b/src/durability/hashed_file_reader.hpp index 3e1daa3f1..e012a051a 100644 --- a/src/durability/hashed_file_reader.hpp +++ b/src/durability/hashed_file_reader.hpp @@ -3,7 +3,7 @@ #include #include "hasher.hpp" -#include "utils/bswap.hpp" +#include "utils/endian.hpp" /** * Buffer reads data from file and calculates hash of read data. Implements @@ -50,8 +50,7 @@ class HashedFileReader { bool ReadType(TValue &val, bool hash = true) { if (!Read(reinterpret_cast(&val), sizeof(TValue), hash)) return false; - // TODO: must be platform specific in the future - val = utils::Bswap(val); + val = utils::BigEndianToHost(val); return true; } diff --git a/src/durability/hashed_file_writer.hpp b/src/durability/hashed_file_writer.hpp index 58d8eadea..ad9dd7be4 100644 --- a/src/durability/hashed_file_writer.hpp +++ b/src/durability/hashed_file_writer.hpp @@ -3,7 +3,7 @@ #include #include "hasher.hpp" -#include "utils/bswap.hpp" +#include "utils/endian.hpp" /** * Buffer that writes data to file and calculates hash of written data. @@ -54,9 +54,8 @@ class HashedFileWriter { */ template void WriteValue(const TValue &val, bool hash = true) { - TValue val_bswapped = utils::Bswap(val); - Write(reinterpret_cast(&val_bswapped), sizeof(TValue), - hash); + TValue val_big = utils::HostToBigEndian(val); + Write(reinterpret_cast(&val_big), sizeof(TValue), hash); } // TODO try to remove before diff diff --git a/src/utils/bswap.hpp b/src/utils/bswap.hpp deleted file mode 100644 index 2efe4e4da..000000000 --- a/src/utils/bswap.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace utils { - -template -inline T Bswap(T value); - -template <> -inline int16_t Bswap(int16_t value) { - return __bswap_16(value); -} - -template <> -inline uint16_t Bswap(uint16_t value) { - return __bswap_16(value); -} - -template <> -inline int32_t Bswap(int32_t value) { - return __bswap_32(value); -} - -template <> -inline uint32_t Bswap(uint32_t value) { - return __bswap_32(value); -} - -template <> -inline int64_t Bswap(int64_t value) { - return __bswap_64(value); -} - -template <> -inline uint64_t Bswap(uint64_t value) { - return __bswap_64(value); -} - -} // namespace utils diff --git a/src/utils/endian.hpp b/src/utils/endian.hpp new file mode 100644 index 000000000..5eb2ddc75 --- /dev/null +++ b/src/utils/endian.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include + +#include "utils/cast.hpp" + +namespace utils { + +inline uint16_t HostToLittleEndian(uint16_t value) { return htole16(value); } +inline uint32_t HostToLittleEndian(uint32_t value) { return htole32(value); } +inline uint64_t HostToLittleEndian(uint64_t value) { return htole64(value); } +inline int16_t HostToLittleEndian(int16_t value) { + return MemcpyCast(htole16(MemcpyCast(value))); +} +inline int32_t HostToLittleEndian(int32_t value) { + return MemcpyCast(htole32(MemcpyCast(value))); +} +inline int64_t HostToLittleEndian(int64_t value) { + return MemcpyCast(htole64(MemcpyCast(value))); +} + +inline uint16_t LittleEndianToHost(uint16_t value) { return le16toh(value); } +inline uint32_t LittleEndianToHost(uint32_t value) { return le32toh(value); } +inline uint64_t LittleEndianToHost(uint64_t value) { return le64toh(value); } +inline int16_t LittleEndianToHost(int16_t value) { + return MemcpyCast(le16toh(MemcpyCast(value))); +} +inline int32_t LittleEndianToHost(int32_t value) { + return MemcpyCast(le32toh(MemcpyCast(value))); +} +inline int64_t LittleEndianToHost(int64_t value) { + return MemcpyCast(le64toh(MemcpyCast(value))); +} + +inline uint16_t HostToBigEndian(uint16_t value) { return htobe16(value); } +inline uint32_t HostToBigEndian(uint32_t value) { return htobe32(value); } +inline uint64_t HostToBigEndian(uint64_t value) { return htobe64(value); } +inline int16_t HostToBigEndian(int16_t value) { + return MemcpyCast(htobe16(MemcpyCast(value))); +} +inline int32_t HostToBigEndian(int32_t value) { + return MemcpyCast(htobe32(MemcpyCast(value))); +} +inline int64_t HostToBigEndian(int64_t value) { + return MemcpyCast(htobe64(MemcpyCast(value))); +} + +inline uint16_t BigEndianToHost(uint16_t value) { return be16toh(value); } +inline uint32_t BigEndianToHost(uint32_t value) { return be32toh(value); } +inline uint64_t BigEndianToHost(uint64_t value) { return be64toh(value); } +inline int16_t BigEndianToHost(int16_t value) { + return MemcpyCast(be16toh(MemcpyCast(value))); +} +inline int32_t BigEndianToHost(int32_t value) { + return MemcpyCast(be32toh(MemcpyCast(value))); +} +inline int64_t BigEndianToHost(int64_t value) { + return MemcpyCast(be64toh(MemcpyCast(value))); +} + +} // namespace utils diff --git a/tests/unit/bolt_session.cpp b/tests/unit/bolt_session.cpp index a402959c6..21f8a0bd3 100644 --- a/tests/unit/bolt_session.cpp +++ b/tests/unit/bolt_session.cpp @@ -91,7 +91,7 @@ const uint8_t ignored_resp[] = {0x00, 0x02, 0xb0, 0x7e, 0x00, 0x00}; // Write bolt chunk header (length) void WriteChunkHeader(TestInputStream &input_stream, uint16_t len) { - len = utils::Bswap(len); + len = utils::HostToBigEndian(len); input_stream.Write(reinterpret_cast(&len), sizeof(len)); }