242 lines
6.5 KiB
C++
242 lines
6.5 KiB
C++
|
|
|
|
#pragma once
|
|
|
|
#include <QtCore/QByteArray>
|
|
#include <limits>
|
|
|
|
namespace LtsUtils {
|
|
|
|
template <typename T> void inline set8Byte(const T in, QByteArray &out) {
|
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
|
|
"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 <typename T>
|
|
bool inline get8Byte(const QByteArray &baData, size_t &pos, T &out) {
|
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
|
|
"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<T>::is_signed)
|
|
out |= static_cast<signed long long>(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 <typename T> bool inline get8Byte(const QByteArray &data, T &out) {
|
|
size_t pos = 0;
|
|
return get8Byte(data, pos, out);
|
|
}
|
|
|
|
template <typename T> void inline set4Byte(const T in, QByteArray &out) {
|
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
|
|
"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 <typename T>
|
|
bool inline get4Byte(const QByteArray &baData, size_t &pos, T &out) {
|
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
|
|
"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<T>::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 <typename T> bool inline get4Byte(const QByteArray &data, T &out) {
|
|
size_t pos = 0;
|
|
return get4Byte(data, pos, out);
|
|
}
|
|
|
|
template <typename T> void inline set3Byte(const T in, QByteArray &out) {
|
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
|
|
"Only integrals allowed for raw byte accessd");
|
|
out += (in & 0x00FF0000) >> 16;
|
|
out += (in & 0x0000FF00) >> 8;
|
|
out += (in & 0x000000FF);
|
|
}
|
|
|
|
template <typename T>
|
|
bool inline get3Byte(const QByteArray &baData, size_t &pos, T &out) {
|
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
|
|
"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<T>::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 <typename T> bool inline get3Byte(const QByteArray &data, T &out) {
|
|
size_t pos = 0;
|
|
return get3Byte(data, pos, out);
|
|
}
|
|
|
|
template <typename T> void inline set2Byte(const T in, QByteArray &out) {
|
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
|
|
"Only integrals allowed for raw byte accessd");
|
|
out += (in & 0x0000FF00) >> 8;
|
|
out += (in & 0x000000FF);
|
|
}
|
|
|
|
template <typename T>
|
|
bool inline get2Byte(const QByteArray &baData, size_t &pos, T &out) {
|
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
|
|
"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<T>::is_signed)
|
|
out |= data[0] << 8;
|
|
else
|
|
out |= (data[0] & 0xFFU) << 8;
|
|
out |= data[1] & 0xFFU;
|
|
|
|
pos += 2;
|
|
|
|
return true;
|
|
}
|
|
|
|
template <typename T> bool inline get2Byte(const QByteArray &data, T &out) {
|
|
size_t pos = 0;
|
|
return get2Byte(data, pos, out);
|
|
}
|
|
|
|
template <typename T> void inline set1Byte(const T in, QByteArray &out) {
|
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
|
|
"Only integrals allowed for raw byte accessd");
|
|
unsigned char c = in;
|
|
out += c;
|
|
}
|
|
|
|
template <typename T>
|
|
bool inline get1Byte(const QByteArray &baData, size_t &pos, T &out) {
|
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>,
|
|
"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<T>::is_signed)
|
|
out = (T)(data[0]);
|
|
else
|
|
out = (T)(data[0] & 0xFF);
|
|
|
|
pos += 1;
|
|
|
|
return true;
|
|
}
|
|
|
|
template <typename T> bool inline get1Byte(const QByteArray &data, T &out) {
|
|
size_t pos = 0;
|
|
return get1Byte(data, pos, out);
|
|
}
|
|
} // namespace LtsUtils
|