Implement PacketReader endianness
This commit is contained in:
parent
9eaef8630f
commit
89a8121e60
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "util/ByteUtil.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -19,20 +20,32 @@ namespace Feather
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
// Peek the next value to be read
|
||||||
|
// If big endian (the default), will reverse byte order.
|
||||||
|
template <typename T, Endian endianMode = Endian::Big>
|
||||||
inline T Peek()
|
inline T Peek()
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<const T* const>(&m_data[m_offset]);
|
T value = *reinterpret_cast<const T *const>(&m_data[m_offset]);
|
||||||
|
|
||||||
|
return (endianMode == Endian::Big) ? ReverseBytes<T>(value) : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
// Read the next value
|
||||||
|
// If big endian (the default), will reverse byte order.
|
||||||
|
template <typename T, Endian endianMode = Endian::Big>
|
||||||
inline T Read()
|
inline T Read()
|
||||||
{
|
{
|
||||||
T value = Peek<T>();
|
T value = Peek<T, endianMode>();
|
||||||
m_offset += sizeof(T);
|
m_offset += sizeof(T);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fast way to peek the next byte
|
||||||
|
inline uint8_t PeekByte() { return m_data[m_offset]; }
|
||||||
|
|
||||||
|
// Fast way to read a byte
|
||||||
|
inline uint8_t ReadByte() { return m_data[m_offset++]; }
|
||||||
|
|
||||||
template <typename T = int32_t>
|
template <typename T = int32_t>
|
||||||
inline T ReadVarInt()
|
inline T ReadVarInt()
|
||||||
{
|
{
|
||||||
|
@ -41,7 +54,7 @@ namespace Feather
|
||||||
uint8_t read;
|
uint8_t read;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
read = Read<uint8_t>();
|
read = ReadByte();
|
||||||
int value = (read & 0b01111111);
|
int value = (read & 0b01111111);
|
||||||
result |= (value << (7 * numRead));
|
result |= (value << (7 * numRead));
|
||||||
|
|
||||||
|
@ -62,11 +75,9 @@ namespace Feather
|
||||||
string str;
|
string str;
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
str += Read<uint8_t>();
|
str += ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("Read string of length %d: %s\n", size, str);
|
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,4 +88,11 @@ namespace Feather
|
||||||
const uint32_t m_length;
|
const uint32_t m_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Use fast Read and Peek for uint8_t
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline uint8_t PacketReader::Peek<uint8_t>() { return PeekByte(); }
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline uint8_t PacketReader::Read<uint8_t>() { return ReadByte(); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum class Endian
|
||||||
|
{
|
||||||
|
Little,
|
||||||
|
Big
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reverses the byte order of a primitive value of any typical size
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr T ReverseBytes(T n)
|
||||||
|
{
|
||||||
|
// 1 byte, cannot reverse
|
||||||
|
if constexpr (sizeof(T) == 1) return n;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
// GCC intrinsic byte swaps
|
||||||
|
// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fbswap16
|
||||||
|
|
||||||
|
if constexpr (sizeof(T) == 2) return __builtin_bswap16(n); // 2 bytes
|
||||||
|
else if constexpr (sizeof(T) == 4) return __builtin_bswap32(n); // 4 bytes
|
||||||
|
else if constexpr (sizeof(T) == 8) return __builtin_bswap64(n); // 8 bytes
|
||||||
|
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
// MSVC intrinsic byteswaps
|
||||||
|
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/byteswap-uint64-byteswap-ulong-byteswap-ushort
|
||||||
|
|
||||||
|
if constexpr (sizeof(T) == 2) return _byteswap_ushort(n); // 2 bytes
|
||||||
|
else if constexpr (sizeof(T) == 4) return _byteswap_ulong(n); // 4 bytes
|
||||||
|
else if constexpr (sizeof(T) == 8) return _byteswap_uint64(n); // 8 bytes
|
||||||
|
#endif
|
||||||
|
//else static_assert(false, "Attempted to call ReverseBytes() on type with unusual size.");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue