Implement PacketReader endianness

This commit is contained in:
DankParrot 2020-07-31 17:49:07 -07:00
parent 9eaef8630f
commit 89a8121e60
2 changed files with 64 additions and 8 deletions

View File

@ -1,6 +1,7 @@
#pragma once
#include "Common.h"
#include "util/ByteUtil.h"
#include <cstdio>
#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()
{
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()
{
T value = Peek<T>();
T value = Peek<T, endianMode>();
m_offset += sizeof(T);
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>
inline T ReadVarInt()
{
@ -41,7 +54,7 @@ namespace Feather
uint8_t read;
do
{
read = Read<uint8_t>();
read = ReadByte();
int value = (read & 0b01111111);
result |= (value << (7 * numRead));
@ -62,10 +75,8 @@ namespace Feather
string str;
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;
}
@ -77,4 +88,11 @@ namespace Feather
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(); }
}

38
src/util/ByteUtil.h Normal file
View File

@ -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.");
}