Files
qt6-migration-pipeline/Lts/Common/LtsUtils/LtsUtilsCore/qbytearray_byteaccess.h
T

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