/*! * * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * \copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * \file types.h * \author (last) Behrouz NematiPour * \date (last) 08-Sep-2020 * \author (original) Behrouz NematiPour * \date (original) 16-Dec-2019 * */ #pragma once // Qt #include #include #include // stl #include // Project #include "format.h" #include "Logger.h" // defines #define GetValue(vData, vIndex, vValue ) Types::getValue<>(vData, vIndex, vValue, QT_STRINGIFY(vValue)) #define GetBits( vData, vIndex, vFlags, vLen) Types::getBits( vData, vIndex, vFlags, vLen ) class Types { public: class Flags : public QBitArray { public: Flags() : QBitArray() { } QString toString(QString vByteSeparator = " ") const { QString tmp; for (int i = 0; i < count(); i++) { if (i % 4 == 0 && i != 0) tmp += vByteSeparator; tmp += at(i) ? '1' : '0'; } return tmp; } }; /*! * \brief The F32 union * \details This is the union which will be used to extract the bytes of a float type value * 4 bytes */ union F32 { // F32 float value = 0; quint8 bytes[sizeof(float)]; }; /*! * \brief The U32 union * \details This is the union which will be used to extract the bytes of an unsigned int type value * 4 bytes */ union U32 { // U32 quint32 value = 0; quint8 bytes[sizeof(quint32)]; }; /*! * \brief The S32 union * \details This is the union which will be used to extract the bytes of an signed int type value * 4 bytes */ union S32 { // S32 qint32 value = 0; quint8 bytes[sizeof(qint32)]; }; /*! * \brief The U16 union * \details This is the union which will be used to extract the bytes of an unsigned char type value * 2 bytes */ union U16 { // U16 quint16 value = 0; quint8 bytes[sizeof(quint16)]; }; /*! * \brief The S32 union * \details This is the union which will be used to extract the bytes of an signed int type value * 4 bytes */ union S16 { // S16 qint16 value = 0; quint8 bytes[sizeof(qint16)]; }; /*! * \brief The U08 union * \details This is the union which will be used to extract the byte of an unsigned char type value * 1 byte */ union U08 { // U08 quint8 value = 0; quint8 bytes[sizeof(quint8)]; }; /*! * \brief The S08 union * \details This is the union which will be used to extract the byte of an signed char type value * 1 byte */ union S08 { // S08 qint8 value = 0; qint8 bytes[sizeof(qint8)]; }; static bool floatCompare(float f1, float f2); template < typename T > static bool getValue(const QByteArray &vData, int &vStartIndex, T &vValue, QString vValueName = ""); static bool getBits (const QByteArray &vData, int &vStartIndex, QBitArray &vFlags, int vLen); template < typename T > static bool setValue(const T &vValue, QByteArray &vData); template < typename T > static T safeIncrement(T &vValue, quint8 vStep = 1) { // step can't be zero if (!vStep) vStep = 1; T mMax = (T)(pow(2, sizeof(T) * 8) - 1); if ( vValue + vStep <= mMax ) { vValue += vStep; } else { vValue = vValue + vStep - mMax - 1; } return vValue; } }; template < typename T > bool Types::getValue(const QByteArray &vData, int &vStartIndex, T &vValue, QString vValueName) { int end = vStartIndex + sizeof(T); if (vData.length() < end) { LOG_DEBUG(QString("Not enough data from position %1 to the length of %2 to get data of type '%3' in buffer %4%5") .arg(vStartIndex) .arg(sizeof(T)) .arg(typeid(T).name()) .arg(Format::toHexString(vData)) .arg(vValueName.isEmpty() ? "" : QString("for value %1").arg(vValueName)) ); return false; } int i = 0; while (vStartIndex < end) { vValue.bytes[i] = vData[vStartIndex]; i++; vStartIndex++; } return true; } template < typename T > bool Types::setValue(const T &vValue, QByteArray &vData) { int end = sizeof(T); int i = 0; while (i < end) { vData[i] = vValue.bytes[i]; i++; } return true; }