/
pi_coder
/
ByteMachine
Обзор
Документация
Войти
/
pi_coder
/
ByteMachine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/byte_convert.h
330 строк
12 KB
pimenov-and
Изменена структура файла, шаблонные функции разделены на объявление и реализацию
10 июл 2026, 00:16
10 июл 2026, 00:16
18748b3
Код
Авторство
О чём код?
//////////////////////////////////////////////////////////////// // ByteMachine // Функции конвертации стандартных типов в байты и обратно //////////////////////////////////////////////////////////////// #ifndef BYTE_CONVERT_H #define BYTE_CONVERT_H //============================================================== #include <QString> #include <QColor> #include <QPoint> #include <QPointF> #include <QSize> #include <QSizeF> #include <QRect> #include <QRectF> #include <QLine> #include <QLineF> #include <type_traits> #include <cstring> #include <algorithm> #include <optional> #include "type_defs.h" //////////////////////////////////////////////////////////////// // Прототипы функций //////////////////////////////////////////////////////////////// // Конвертация значения в список байтов template<typename T> [[nodiscard]] ByteList valueToByteList(const T &value, bool isLittleEndian = true); // Конвертации значения типа QString в список байтов template<> [[nodiscard]] ByteList valueToByteList<QString>(const QString &value, bool isLittleEndian); // Конвертации значения типа QColor в список байтов template<> [[nodiscard]] ByteList valueToByteList<QColor>(const QColor &value, bool); // Конвертации значения типа QPoint в список байтов template<> [[nodiscard]] ByteList valueToByteList<QPoint>(const QPoint &value, bool isLittleEndian); // Конвертации значения типа QPointF в список байтов template<> [[nodiscard]] ByteList valueToByteList<QPointF>(const QPointF &value, bool isLittleEndian); // Конвертации значения типа QSize в список байтов template<> [[nodiscard]] ByteList valueToByteList<QSize>(const QSize &value, bool isLittleEndian); // Конвертации значения типа QSizeF в список байтов template<> [[nodiscard]] ByteList valueToByteList<QSizeF>(const QSizeF &value, bool isLittleEndian); // Конвертации значения типа QRect в список байтов template<> [[nodiscard]] ByteList valueToByteList<QRect>(const QRect &value, bool isLittleEndian); // Конвертации значения типа QRectF в список байтов template<> [[nodiscard]] ByteList valueToByteList<QRectF>(const QRectF &value, bool isLittleEndian); // Конвертации значения типа QLine в список байтов template<> [[nodiscard]] ByteList valueToByteList<QLine>(const QLine &value, bool isLittleEndian); // Конвертации значения типа QLineF в список байтов template<> [[nodiscard]] ByteList valueToByteList<QLineF>(const QLineF &value, bool isLittleEndian); // Конвертация списка значений в список байтов template<typename T> [[nodiscard]] ByteList valueListToByteList(const QVector<T> &valueList, bool isLittleEndian = true); // Конвертация списка байтов в значение template<typename T> [[nodiscard]] std::optional<T> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian = true); // Конвертация списка байтов в значение типа QString template<> [[nodiscard]] std::optional<QString> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian); // Конвертация списка байтов в значение типа QColor template<> [[nodiscard]] std::optional<QColor> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian); // Конвертация списка байтов в значение типа QPoint template<> [[nodiscard]] std::optional<QPoint> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian); // Конвертация списка байтов в значение типа QPointF template<> [[nodiscard]] std::optional<QPointF> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian); // Конвертация списка байтов в значение типа QSize template<> [[nodiscard]] std::optional<QSize> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian); // Конвертация списка байтов в значение типа QSizeF template<> [[nodiscard]] std::optional<QSizeF> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian); // Конвертация списка байтов в значение типа QRect template<> [[nodiscard]] std::optional<QRect> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian); // Конвертация списка байтов в значение типа QRectF template<> [[nodiscard]] std::optional<QRectF> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian); // Конвертация списка байтов в значение типа QLine template<> [[nodiscard]] std::optional<QLine> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian); // Конвертация списка байтов в значение типа QLineF template<> [[nodiscard]] std::optional<QLineF> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian); // Получение данных по типу в байтах (только для POD-типов) template<typename T> [[nodiscard]] constexpr std::size_t getTypeByteSize(); // Получение размера данных в байтах по типу QColor template<> [[nodiscard]] constexpr std::size_t getTypeByteSize<QColor>() { return 4; } // Получение данных по типу QPoint в байтах template<> [[nodiscard]] constexpr std::size_t getTypeByteSize<QPoint>() { return 8; } // Получение данных по типу QPointF в байтах template<> [[nodiscard]] constexpr std::size_t getTypeByteSize<QPointF>() { return 16; } // Получение данных по типу QSize в байтах template<> [[nodiscard]] constexpr std::size_t getTypeByteSize<QSize>() { return 8; } // Получение данных по типу QSizeF в байтах template<> [[nodiscard]] constexpr std::size_t getTypeByteSize<QSizeF>() { return 16; } // Получение данных по типу QRect в байтах template<> [[nodiscard]] constexpr std::size_t getTypeByteSize<QRect>() { return 16; } // Получение данных по типу QRectF в байтах template<> [[nodiscard]] constexpr std::size_t getTypeByteSize<QRectF>() { return 32; } // Получение данных по типу QLine в байтах template<> [[nodiscard]] constexpr std::size_t getTypeByteSize<QLine>() { return 16; } // Получение данных по типу QLineF в байтах template<> [[nodiscard]] constexpr std::size_t getTypeByteSize<QLineF>() { return 32; } // Получение размера значения в байтах (только для POD-типов) template<typename T> [[nodiscard]] std::size_t getValueByteSize(const T &value); // Получение размера значения типа QString в байтах template<> [[nodiscard]] std::size_t getValueByteSize<QString>(const QString &value); // Получение размера значения типа QColor в байтах template<> [[nodiscard]] std::size_t getValueByteSize<QColor>(const QColor&); // Получение размера значения типа QPoint в байтах template<> [[nodiscard]] std::size_t getValueByteSize<QPoint>(const QPoint&); // Получение размера значения типа QPointF в байтах template<> [[nodiscard]] std::size_t getValueByteSize<QPointF>(const QPointF&); // Получение размера значения типа QSize в байтах template<> [[nodiscard]] std::size_t getValueByteSize<QSize>(const QSize&); // Получение размера значения типа QSizeF в байтах template<> [[nodiscard]] std::size_t getValueByteSize<QSizeF>(const QSizeF&); // Получение размера значения типа QRect в байтах template<> [[nodiscard]] std::size_t getValueByteSize<QRect>(const QRect&); // Получение размера значения типа QRectF в байтах template<> [[nodiscard]] std::size_t getValueByteSize<QRectF>(const QRectF&); // Получение размера значения типа QLine в байтах template<> [[nodiscard]] std::size_t getValueByteSize<QLine>(const QLine&); // Получение размера значения типа QLineF в байтах template<> [[nodiscard]] std::size_t getValueByteSize<QLineF>(const QLineF&); //////////////////////////////////////////////////////////////// // Реализация функций //////////////////////////////////////////////////////////////// //============================================================== // Конвертация значения в список байтов //============================================================== template<typename T> [[nodiscard]] ByteList valueToByteList(const T &value, bool isLittleEndian) { static_assert(std::is_trivially_copyable<T>::value); const quint8 *const data = reinterpret_cast<const quint8*>(&value); constexpr std::size_t typeByteSize = sizeof(T); constexpr bool isSystemLittleEndian = (std::endian::native == std::endian::little); if (isSystemLittleEndian == isLittleEndian) { return ByteList(data, data + typeByteSize); } else { ByteList byteList(typeByteSize); std::reverse_copy(data, data + typeByteSize, byteList.begin()); return byteList; } } //============================================================== // Конвертация списка значений в список байтов //============================================================== template<typename T> [[nodiscard]] ByteList valueListToByteList(const QVector<T> &valueList, bool isLittleEndian) { ByteList byteList{}; for (const T &v: valueList) { byteList << valueToByteList(v, isLittleEndian); } return byteList; } //============================================================== // Конвертация списка байтов в значение //============================================================== template<typename T> [[nodiscard]] std::optional<T> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { static_assert(std::is_trivially_copyable<T>::value); if (it == end) { return std::nullopt; } if (std::distance(it, end) < static_cast<std::ptrdiff_t>(sizeof(T))) { return std::nullopt; } T value{}; quint8 *const valuePtr = reinterpret_cast<quint8*>(&value); constexpr bool isSystemLittleEndian = (std::endian::native == std::endian::little); if (isSystemLittleEndian == isLittleEndian) { std::copy(it, it + sizeof(T), valuePtr); } else { std::reverse_copy(it, it + sizeof(T), valuePtr); } it += sizeof(T); return value; } //============================================================== // Получение данных по типу в байтах (только для POD-типов) //============================================================== template<typename T> [[nodiscard]] constexpr std::size_t getTypeByteSize() { static_assert(std::is_trivially_copyable<T>::value); return sizeof(T); } //============================================================== // Получение размера значения в байтах (только для POD-типов) //============================================================== template<typename T> [[nodiscard]] std::size_t getValueByteSize(const T &value) { static_assert(std::is_trivially_copyable<T>::value); return sizeof(value); } //============================================================== #endif // BYTE_CONVERT_H