93 lines
1.7 KiB
C++
93 lines
1.7 KiB
C++
#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() {
|
|
static constexpr std::uint16_t test = 10;
|
|
static const bool isBigEndian = reinterpret_cast<const std::uint8_t*>(&test)[1] == 10;
|
|
return isBigEndian;
|
|
}
|
|
|
|
/**
|
|
* \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
|