283 lines
6.8 KiB
C++
Executable File
283 lines
6.8 KiB
C++
Executable File
|
|
|
|
|
|
#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<T>::value || std::is_enum<T>::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<typename T>
|
|
bool inline get8Byte(const QByteArray& baData,
|
|
size_t &pos,
|
|
T& out)
|
|
{
|
|
static_assert(std::is_integral<T>::value || std::is_enum<T>::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<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<T>::value || std::is_enum<T>::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<typename T>
|
|
bool inline get4Byte(const QByteArray& baData,
|
|
size_t &pos,
|
|
T& out)
|
|
{
|
|
static_assert(std::is_integral<T>::value || std::is_enum<T>::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<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<T>::value || std::is_enum<T>::value, "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<T>::value || std::is_enum<T>::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<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<T>::value || std::is_enum<T>::value, "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<T>::value || std::is_enum<T>::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<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<T>::value || std::is_enum<T>::value, "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<T>::value || std::is_enum<T>::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<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);
|
|
}
|
|
}
|