feat: add support for all endianesses
This commit is contained in:
92
include/sp/common/ByteSwapping.h
Normal file
92
include/sp/common/ByteSwapping.h
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace sp {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void SwapBytes(T& value) {
|
||||||
|
char* ptr = reinterpret_cast<char*>(&value);
|
||||||
|
std::reverse(ptr, ptr + sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSystemBigEndian() {
|
||||||
|
std::uint16_t test = 0;
|
||||||
|
reinterpret_cast<std::uint8_t*>(&test)[1] = 1;
|
||||||
|
return test == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Serialize value to (network byte order) big endian
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
void ToNetwork(T& value) {}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void ToNetwork<std::uint16_t>(std::uint16_t& value) {
|
||||||
|
value = htons(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void ToNetwork<std::uint32_t>(std::uint32_t& value) {
|
||||||
|
value = htonl(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void ToNetwork<std::uint64_t>(std::uint64_t& value) {
|
||||||
|
if (IsSystemBigEndian())
|
||||||
|
return;
|
||||||
|
SwapBytes(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Deserialize value from (network byte order) big endian
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
void FromNetwork(T& value) {}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FromNetwork<std::uint16_t>(std::uint16_t& value) {
|
||||||
|
value = ntohs(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FromNetwork<std::uint32_t>(std::uint32_t& value) {
|
||||||
|
value = ntohl(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FromNetwork<std::uint64_t>(std::uint64_t& value) {
|
||||||
|
if (IsSystemBigEndian())
|
||||||
|
return;
|
||||||
|
SwapBytes(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Swap bytes if the value is any kind of integer
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
void TrySwapBytes(T& value) {}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void TrySwapBytes<std::uint16_t>(std::uint16_t& value) {
|
||||||
|
SwapBytes(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void TrySwapBytes<std::uint32_t>(std::uint32_t& value) {
|
||||||
|
SwapBytes(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void TrySwapBytes<std::uint64_t>(std::uint64_t& value) {
|
||||||
|
SwapBytes(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sp
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <sp/protocol/Options.h>
|
#include <sp/protocol/Options.h>
|
||||||
|
#include <sp/common/ByteSwapping.h>
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
namespace details {
|
namespace details {
|
||||||
@@ -83,13 +84,13 @@ class MessageInterfaceBigEndian : public TBase {
|
|||||||
protected:
|
protected:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ReadData(T& value, DataBuffer& buffer) {
|
void ReadData(T& value, DataBuffer& buffer) {
|
||||||
//TODO: use big endian
|
|
||||||
buffer >> value;
|
buffer >> value;
|
||||||
|
FromNetwork(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void WriteData(T value, DataBuffer& buffer) {
|
void WriteData(T value, DataBuffer& buffer) {
|
||||||
//TODO: use big endian
|
ToNetwork(value);
|
||||||
buffer << value;
|
buffer << value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -100,13 +101,15 @@ class MessageInterfaceLittleEndian : public TBase {
|
|||||||
protected:
|
protected:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ReadData(T& value, DataBuffer& buffer) {
|
void ReadData(T& value, DataBuffer& buffer) {
|
||||||
//TODO: use little endian
|
|
||||||
buffer >> value;
|
buffer >> value;
|
||||||
|
TrySwapBytes(value);
|
||||||
|
FromNetwork(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void WriteData(const T& value, DataBuffer& buffer) {
|
void WriteData(const T& value, DataBuffer& buffer) {
|
||||||
//TODO: use little endian
|
ToNetwork(value);
|
||||||
|
TrySwapBytes(value);
|
||||||
buffer << value;
|
buffer << value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user