From 0e04dbeea1508cd30039109a867f9fa59bf0511b Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Mon, 26 Aug 2019 14:15:44 +0100 Subject: [PATCH] Allow SwapBE to swap non-uint types If we want to have more semantically meaningful types (like Direction), it's useful to be able to support those in the DataSerializer too. Swapping bytes for entire structures is probably never going to make sense, but for types that are pure wrappers around integer types, we want to be able to swap them as if they were the integer they wrap. --- src/openrct2/core/Endianness.h | 8 ++++++- test/tests/Endianness.cpp | 43 ++++++++++++++++++++++++++++++++++ test/tests/tests.vcxproj | 1 + 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 test/tests/Endianness.cpp diff --git a/src/openrct2/core/Endianness.h b/src/openrct2/core/Endianness.h index 16d024cfbc..e0d065f512 100644 --- a/src/openrct2/core/Endianness.h +++ b/src/openrct2/core/Endianness.h @@ -17,6 +17,7 @@ template struct ByteSwapT template<> struct ByteSwapT<1> { + typedef uint8_t UIntType; static uint8_t SwapBE(uint8_t value) { return value; @@ -25,6 +26,7 @@ template<> struct ByteSwapT<1> template<> struct ByteSwapT<2> { + typedef uint16_t UIntType; static uint16_t SwapBE(uint16_t value) { return (uint16_t)((value << 8) | (value >> 8)); @@ -33,6 +35,7 @@ template<> struct ByteSwapT<2> template<> struct ByteSwapT<4> { + typedef uint32_t UIntType; static uint32_t SwapBE(uint32_t value) { return (uint32_t)(((value << 24) | ((value << 8) & 0x00FF0000) | ((value >> 8) & 0x0000FF00) | (value >> 24))); @@ -41,6 +44,7 @@ template<> struct ByteSwapT<4> template<> struct ByteSwapT<8> { + typedef uint64_t UIntType; static uint64_t SwapBE(uint64_t value) { value = (value & 0x00000000FFFFFFFF) << 32 | (value & 0xFFFFFFFF00000000) >> 32; @@ -52,5 +56,7 @@ template<> struct ByteSwapT<8> template static T ByteSwapBE(const T& value) { - return ByteSwapT::SwapBE(value); + typedef ByteSwapT ByteSwap; + typename ByteSwap::UIntType result = ByteSwap::SwapBE(reinterpret_cast(value)); + return *reinterpret_cast(&result); } diff --git a/test/tests/Endianness.cpp b/test/tests/Endianness.cpp new file mode 100644 index 0000000000..b673360797 --- /dev/null +++ b/test/tests/Endianness.cpp @@ -0,0 +1,43 @@ +#include "openrct2/core/Endianness.h" + +#include + +TEST(SwapBETest, ForUInt8_DoesNothing) +{ + uint8_t before = 0x12; + uint8_t after = ByteSwapBE(before); + ASSERT_EQ(before, after); +} + +TEST(SwapBETest, ForUInt16_SwapsBytes) +{ + uint16_t before = 0x1234; + uint16_t after = ByteSwapBE(before); + ASSERT_EQ(0x3412u, after); +} + +TEST(SwapBETest, ForUInt32_SwapsBytes) +{ + uint32_t before = 0x12345678; + uint32_t after = ByteSwapBE(before); + ASSERT_EQ(0x78563412u, after); +} + +TEST(SwapBETest, ForUInt64_SwapsBytes) +{ + uint64_t before = 0x1234567887654321; + uint64_t after = ByteSwapBE(before); + ASSERT_EQ(0x2143658778563412u, after); +} + +TEST(SwapBETest, ForCustomBlittableType_SwapsBytes) +{ + struct MyStruct + { + uint16_t value; + }; + + MyStruct before = { 0x1234 }; + MyStruct after = ByteSwapBE(before); + ASSERT_EQ(0x3412, after.value); +} diff --git a/test/tests/tests.vcxproj b/test/tests/tests.vcxproj index f4d448af46..cc19c85c7f 100644 --- a/test/tests/tests.vcxproj +++ b/test/tests/tests.vcxproj @@ -58,6 +58,7 @@ +