#pragma once #include #include namespace LtsUtils { template void inline set8Byte(const T in, QByteArray& out) { static_assert(std::is_integral::value || std::is_enum::value, "Only integrals allowed for raw byte accessd"); out += (in & 0xFF00000000000000UL) >> 56; out += (in & 0x00FF000000000000UL) >> 48; out += (in & 0x0000FF0000000000UL) >> 40; out += (in & 0x000000FF00000000UL) >> 32; out += (in & 0x00000000FF000000UL) >> 24; out += (in & 0x0000000000FF0000UL) >> 16; out += (in & 0x000000000000FF00UL) >> 8; out += (in & 0x00000000000000FFUL); } template<> void inline set8Byte(const double in, QByteArray &out) { union hack { double d; int64_t i; } h; h.d = in; set8Byte(h.i, out); } template bool inline get8Byte(const QByteArray& baData, size_t &pos, T& out) { static_assert(std::is_integral::value || std::is_enum::value, "Only integrals allowed for raw byte accessd"); static_assert(sizeof(T) >= 8, "sizeof(out) is smaller than 8 bytes - will not fit"); out = T(); if(size_t(baData.size()) < pos + 8) return false; const char *data = baData.data() + pos; if(std::numeric_limits::is_signed) out |= static_cast(data[0]) << 56; else out |= (data[0] & 0xFFULL) << 56; out |= (data[1] & 0xFFULL) << 48; out |= (data[2] & 0xFFULL) << 40; out |= (data[3] & 0xFFULL) << 32; out |= (data[4] & 0xFFULL) << 24; out |= (data[5] & 0xFFULL) << 16; out |= (data[6] & 0xFFULL) << 8; out |= (data[7] & 0xFFULL); pos += 8; return true; } template<> bool inline get8Byte(const QByteArray& baData, size_t &pos, double& out) { out = 0.; union hack { double d; int64_t i; } h; if (!get8Byte(baData, pos, h.i)) return false; out = h.d; return true; } template bool inline get8Byte(const QByteArray& data, T& out) { size_t pos = 0; return get8Byte(data, pos, out); } template void inline set4Byte(const T in, QByteArray& out) { static_assert(std::is_integral::value || std::is_enum::value, "Only integrals allowed for raw byte accessd"); out += (in & 0xFF000000) >> 24; out += (in & 0x00FF0000) >> 16; out += (in & 0x0000FF00) >> 8; out += (in & 0x000000FF); } template<> void inline set4Byte(const double in, QByteArray& out) { int tmp = qRound(in); return set4Byte(tmp, out); } template bool inline get4Byte(const QByteArray& baData, size_t &pos, T& out) { static_assert(std::is_integral::value || std::is_enum::value, "Only integrals allowed for raw byte accessd"); static_assert(sizeof(T) >= 4, "sizeof(out) is smaller than 4 bytes - will not fit"); out = T(); if(size_t(baData.size()) < pos + 4) return false; const char *data = baData.data() + pos; if(std::numeric_limits::is_signed) out |= data[0] << 24; else out |= (data[0] & 0xFFU) << 24; out |= (data[1] & 0xFFU) << 16; out |= (data[2] & 0xFFU) << 8; out |= (data[3] & 0xFFU); pos += 4; return true; } template<> bool inline get4Byte(const QByteArray& baData, size_t &pos, double& out) { out = 0.; int tmp; if(!get4Byte(baData, pos, tmp)) return false; out = tmp; return true; } template bool inline get4Byte(const QByteArray& data, T& out) { size_t pos = 0; return get4Byte(data, pos, out); } template void inline set3Byte(const T in, QByteArray& out) { static_assert(std::is_integral::value || std::is_enum::value, "Only integrals allowed for raw byte accessd"); out += (in & 0x00FF0000) >> 16; out += (in & 0x0000FF00) >> 8; out += (in & 0x000000FF); } template bool inline get3Byte(const QByteArray& baData, size_t &pos, T& out) { static_assert(std::is_integral::value || std::is_enum::value, "Only integrals allowed for raw byte accessd"); static_assert(sizeof(T) >= 3, "sizeof(out) is smaller than 3 bytes - will not fit"); out = T(); if(size_t(baData.size()) < pos + 3) return false; const char *data = baData.data() + pos; if(std::numeric_limits::is_signed) out |= data[0] << 16; else out |= (data[0] & 0xFFU) << 16; out |= (data[1] & 0xFFU) << 8; out |= (data[2] & 0xFFU); pos += 3; return true; } template bool inline get3Byte(const QByteArray& data, T& out) { size_t pos = 0; return get3Byte(data, pos, out); } template void inline set2Byte(const T in, QByteArray& out) { static_assert(std::is_integral::value || std::is_enum::value, "Only integrals allowed for raw byte accessd"); out += (in & 0x0000FF00) >> 8; out += (in & 0x000000FF); } template bool inline get2Byte(const QByteArray& baData, size_t &pos, T& out) { static_assert(std::is_integral::value || std::is_enum::value, "Only integrals allowed for raw byte accessd"); static_assert(sizeof(T) >= 2, "sizeof(out) is smaller than 2 bytes - will not fit"); out = T(); if(size_t(baData.size()) < pos + 2) return false; const char *data = baData.data() + pos; if(std::numeric_limits::is_signed) out |= data[0] << 8; else out |= (data[0] & 0xFFU) << 8; out |= data[1] & 0xFFU; pos += 2; return true; } template bool inline get2Byte(const QByteArray& data, T& out) { size_t pos = 0; return get2Byte(data, pos, out); } template void inline set1Byte(const T in, QByteArray& out) { static_assert(std::is_integral::value || std::is_enum::value, "Only integrals allowed for raw byte accessd"); unsigned char c = in; out += c; } template bool inline get1Byte(const QByteArray& baData, size_t &pos, T& out) { static_assert(std::is_integral::value || std::is_enum::value, "Only integrals allowed for raw byte accessd"); out = T(); if(size_t(baData.size()) < pos + 1) return false; const char *data = baData.data() + pos; if(std::numeric_limits::is_signed) out = (T)(data[0]); else out = (T)(data[0] & 0xFF); pos += 1; return true; } template bool inline get1Byte(const QByteArray& data, T& out) { size_t pos = 0; return get1Byte(data, pos, out); } }