#pragma once #include #include #include #include #include #include #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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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::is_iec559, "expected IEC559 doubles on host machine"); std::memcpy(&value, &floatData, sizeof(value)); return value; } };