mirror of https://github.com/OpenRCT2/OpenRCT2.git
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.
This commit is contained in:
parent
5ff78e48c7
commit
0e04dbeea1
|
@ -17,6 +17,7 @@ template<size_t size> 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<typename T> static T ByteSwapBE(const T& value)
|
||||
{
|
||||
return ByteSwapT<sizeof(T)>::SwapBE(value);
|
||||
typedef ByteSwapT<sizeof(T)> ByteSwap;
|
||||
typename ByteSwap::UIntType result = ByteSwap::SwapBE(reinterpret_cast<const typename ByteSwap::UIntType&>(value));
|
||||
return *reinterpret_cast<T*>(&result);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#include "openrct2/core/Endianness.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
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);
|
||||
}
|
|
@ -58,6 +58,7 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="CircularBuffer.cpp" />
|
||||
<ClCompile Include="CryptTests.cpp" />
|
||||
<ClCompile Include="Endianness.cpp" />
|
||||
<ClCompile Include="LanguagePackTest.cpp" />
|
||||
<ClCompile Include="ImageImporterTests.cpp" />
|
||||
<ClCompile Include="IniReaderTest.cpp" />
|
||||
|
|
Loading…
Reference in New Issue