2021-01-02 04:24:29 +00:00
|
|
|
#pragma once
|
|
|
|
|
2022-06-02 22:48:52 +00:00
|
|
|
#include <cinttypes>
|
2021-12-03 20:57:05 +00:00
|
|
|
#include <cstdint>
|
2022-06-02 22:48:52 +00:00
|
|
|
#include <cstdio>
|
|
|
|
#include <cstring>
|
2021-01-09 00:38:28 +00:00
|
|
|
#include <limits>
|
2021-01-02 04:24:29 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2022-06-02 22:48:52 +00:00
|
|
|
#define ALIGN8(val) (((val) + 7) & ~7)
|
|
|
|
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
|
|
|
|
#define ALIGN64(val) (((val) + 0x3F) & ~0x3F)
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
#define __PRETTY_FUNCTION__ __FUNCSIG__
|
|
|
|
#endif
|
|
|
|
|
2021-01-02 04:24:29 +00:00
|
|
|
class BitConverter
|
|
|
|
{
|
|
|
|
public:
|
2022-06-02 22:48:52 +00:00
|
|
|
static inline int8_t ToInt8BE(const std::vector<uint8_t>& data, size_t offset)
|
|
|
|
{
|
|
|
|
if (offset + 0 > data.size())
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
|
|
|
fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n");
|
|
|
|
fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size());
|
|
|
|
fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset);
|
|
|
|
}
|
|
|
|
return (int8_t)data.at(offset + 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint8_t ToUInt8BE(const std::vector<uint8_t>& data, size_t offset)
|
|
|
|
{
|
|
|
|
if (offset + 0 > data.size())
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
|
|
|
fprintf(stderr, "Error: Trying an out-of-bounds reading from a data buffer\n");
|
|
|
|
fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size());
|
|
|
|
fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset);
|
|
|
|
}
|
|
|
|
return (uint8_t)data.at(offset + 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int16_t ToInt16BE(const std::vector<uint8_t>& data, size_t offset)
|
|
|
|
{
|
|
|
|
if (offset + 1 > data.size())
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
|
|
|
fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n");
|
|
|
|
fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size());
|
|
|
|
fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset);
|
|
|
|
}
|
|
|
|
return ((uint16_t)data.at(offset + 0) << 8) + (uint16_t)data.at(offset + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint16_t ToUInt16BE(const std::vector<uint8_t>& data, size_t offset)
|
|
|
|
{
|
|
|
|
if (offset + 1 > data.size())
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
|
|
|
fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n");
|
|
|
|
fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size());
|
|
|
|
fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset);
|
|
|
|
}
|
|
|
|
return ((uint16_t)data.at(offset + 0) << 8) + (uint16_t)data.at(offset + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int32_t ToInt32BE(const std::vector<uint8_t>& data, size_t offset)
|
|
|
|
{
|
|
|
|
if (offset + 3 > data.size())
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
|
|
|
fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n");
|
|
|
|
fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size());
|
|
|
|
fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset);
|
|
|
|
}
|
|
|
|
return ((uint32_t)data.at(offset + 0) << 24) + ((uint32_t)data.at(offset + 1) << 16) +
|
2023-10-25 01:36:10 +00:00
|
|
|
((uint32_t)data.at(offset + 2) << 8) + (uint32_t)data.at(offset + 3);
|
2022-06-02 22:48:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint32_t ToUInt32BE(const std::vector<uint8_t>& data, size_t offset)
|
|
|
|
{
|
|
|
|
if (offset + 3 > data.size())
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
|
|
|
fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n");
|
|
|
|
fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size());
|
|
|
|
fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset);
|
|
|
|
}
|
|
|
|
return ((uint32_t)data.at(offset + 0) << 24) + ((uint32_t)data.at(offset + 1) << 16) +
|
2023-10-25 01:36:10 +00:00
|
|
|
((uint32_t)data.at(offset + 2) << 8) + (uint32_t)data.at(offset + 3);
|
2022-06-02 22:48:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline int64_t ToInt64BE(const std::vector<uint8_t>& data, size_t offset)
|
|
|
|
{
|
|
|
|
if (offset + 7 > data.size())
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
|
|
|
fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n");
|
|
|
|
fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size());
|
|
|
|
fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset);
|
|
|
|
}
|
|
|
|
return ((uint64_t)data.at(offset + 0) << 56) + ((uint64_t)data.at(offset + 1) << 48) +
|
2023-10-25 01:36:10 +00:00
|
|
|
((uint64_t)data.at(offset + 2) << 40) + ((uint64_t)data.at(offset + 3) << 32) +
|
|
|
|
((uint64_t)data.at(offset + 4) << 24) + ((uint64_t)data.at(offset + 5) << 16) +
|
|
|
|
((uint64_t)data.at(offset + 6) << 8) + ((uint64_t)data.at(offset + 7));
|
2022-06-02 22:48:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint64_t ToUInt64BE(const std::vector<uint8_t>& data, size_t offset)
|
|
|
|
{
|
|
|
|
if (offset + 7 > data.size())
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
|
|
|
fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n");
|
|
|
|
fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size());
|
|
|
|
fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset);
|
|
|
|
}
|
|
|
|
return ((uint64_t)data.at(offset + 0) << 56) + ((uint64_t)data.at(offset + 1) << 48) +
|
2023-10-25 01:36:10 +00:00
|
|
|
((uint64_t)data.at(offset + 2) << 40) + ((uint64_t)data.at(offset + 3) << 32) +
|
|
|
|
((uint64_t)data.at(offset + 4) << 24) + ((uint64_t)data.at(offset + 5) << 16) +
|
|
|
|
((uint64_t)data.at(offset + 6) << 8) + ((uint64_t)data.at(offset + 7));
|
2022-06-02 22:48:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline float ToFloatBE(const std::vector<uint8_t>& data, size_t offset)
|
|
|
|
{
|
|
|
|
if (offset + 3 > data.size())
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
|
|
|
fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n");
|
|
|
|
fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size());
|
|
|
|
fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset);
|
|
|
|
}
|
2021-01-09 00:38:28 +00:00
|
|
|
float value;
|
2022-06-02 22:48:52 +00:00
|
|
|
uint32_t floatData = ((uint32_t)data.at(offset + 0) << 24) +
|
2023-10-25 01:36:10 +00:00
|
|
|
((uint32_t)data.at(offset + 1) << 16) +
|
|
|
|
((uint32_t)data.at(offset + 2) << 8) + (uint32_t)data.at(offset + 3);
|
2021-07-28 02:16:03 +00:00
|
|
|
static_assert(sizeof(uint32_t) == sizeof(float), "expected 32-bit float");
|
2021-01-09 00:38:28 +00:00
|
|
|
std::memcpy(&value, &floatData, sizeof(value));
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2022-06-02 22:48:52 +00:00
|
|
|
static inline double ToDoubleBE(const std::vector<uint8_t>& data, size_t offset)
|
2021-01-02 04:24:29 +00:00
|
|
|
{
|
2022-06-02 22:48:52 +00:00
|
|
|
if (offset + 7 > data.size())
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
|
|
|
|
fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n");
|
|
|
|
fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size());
|
|
|
|
fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset);
|
|
|
|
}
|
2021-01-09 00:38:28 +00:00
|
|
|
double value;
|
2021-03-20 16:02:12 +00:00
|
|
|
uint64_t floatData =
|
2022-06-02 22:48:52 +00:00
|
|
|
((uint64_t)data.at(offset + 0) << 56) + ((uint64_t)data.at(offset + 1) << 48) +
|
|
|
|
((uint64_t)data.at(offset + 2) << 40) + ((uint64_t)data.at(offset + 3) << 32) +
|
|
|
|
((uint64_t)data.at(offset + 4) << 24) + ((uint64_t)data.at(offset + 5) << 16) +
|
|
|
|
((uint64_t)data.at(offset + 6) << 8) + ((uint64_t)data.at(offset + 7));
|
2021-07-28 02:16:03 +00:00
|
|
|
static_assert(sizeof(uint64_t) == sizeof(double), "expected 64-bit double");
|
2021-03-20 16:02:12 +00:00
|
|
|
// Checks if the float format on the platform the ZAPD binary is running on supports the
|
|
|
|
// same float format as the object file.
|
2021-10-17 11:32:09 +00:00
|
|
|
static_assert(std::numeric_limits<double>::is_iec559,
|
|
|
|
"expected IEC559 doubles on host machine");
|
2021-01-09 00:38:28 +00:00
|
|
|
std::memcpy(&value, &floatData, sizeof(value));
|
|
|
|
return value;
|
2021-01-02 04:24:29 +00:00
|
|
|
}
|
2021-01-09 00:38:28 +00:00
|
|
|
};
|