1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-12-28 15:56:51 +00:00
oot/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h

167 lines
6.5 KiB
C
Raw Normal View History

#pragma once
#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <limits>
#include <vector>
#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
class BitConverter
{
public:
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) +
((uint32_t)data.at(offset + 2) << 8) + (uint32_t)data.at(offset + 3);
}
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) +
((uint32_t)data.at(offset + 2) << 8) + (uint32_t)data.at(offset + 3);
}
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) +
((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));
}
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) +
((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));
}
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);
}
float value;
uint32_t floatData = ((uint32_t)data.at(offset + 0) << 24) +
((uint32_t)data.at(offset + 1) << 16) +
((uint32_t)data.at(offset + 2) << 8) + (uint32_t)data.at(offset + 3);
static_assert(sizeof(uint32_t) == sizeof(float), "expected 32-bit float");
std::memcpy(&value, &floatData, sizeof(value));
return value;
}
static inline double ToDoubleBE(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);
}
double value;
uint64_t floatData =
((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));
static_assert(sizeof(uint64_t) == sizeof(double), "expected 64-bit double");
// Checks if the float format on the platform the ZAPD binary is running on supports the
// same float format as the object file.
static_assert(std::numeric_limits<double>::is_iec559,
"expected IEC559 doubles on host machine");
std::memcpy(&value, &floatData, sizeof(value));
return value;
}
};