/
pi_coder
/
ByteMachine
Обзор
Документация
Войти
/
pi_coder
/
ByteMachine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/byte_convert.cpp
538 строк
18 KB
pimenov-and
Отказ от комментариев Doxygen
09 июл 2026, 16:13
09 июл 2026, 16:13
404da34
Код
Авторство
О чём код?
//////////////////////////////////////////////////////////////// // ByteMachine // Функции конвертации стандартных типов в байты и обратно //////////////////////////////////////////////////////////////// #include "byte_convert.h" #include "byte_list_helper.h" //============================================================== using std::distance; using std::copy; using std::optional; using std::nullopt; using std::size_t; using std::ptrdiff_t; //============================================================== // Конвертации значения типа QString в список байтов //============================================================== template<> ByteList valueToByteList<QString>(const QString &value, bool isLittleEndian) { constexpr int maxStrLen = 10000; if (value.size() > maxStrLen) { return ByteList{}; } const QByteArray strByteArray = value.toUtf8(); const ByteList strSizeByteList = valueToByteList<qint32>(strByteArray.size(), isLittleEndian); ByteList byteList(sizeof(qint32) + strByteArray.size()); copy(strSizeByteList.cbegin(), strSizeByteList.cend(), byteList.begin()); copy(strByteArray.cbegin(), strByteArray.cend(), byteList.begin() + sizeof(qint32)); return byteList; } //============================================================== // Конвертации значения типа QColor в список байтов //============================================================== template<> ByteList valueToByteList<QColor>(const QColor &value, bool) { ByteList byteList(4); byteList[0] = static_cast<quint8>(value.red()); byteList[1] = static_cast<quint8>(value.green()); byteList[2] = static_cast<quint8>(value.blue()); byteList[3] = static_cast<quint8>(value.alpha()); return byteList; } //============================================================== // Конвертации значения типа QPoint в список байтов //============================================================== template<> ByteList valueToByteList<QPoint>(const QPoint &value, bool isLittleEndian) { const qint32 x = static_cast<qint32>(value.x()); const qint32 y = static_cast<qint32>(value.y()); const ByteList byteListX = valueToByteList(x, isLittleEndian); const ByteList byteListY = valueToByteList(y, isLittleEndian); return ByteList{} << byteListX << byteListY; } //============================================================== // Конвертации значения типа QPointF в список байтов //============================================================== template<> ByteList valueToByteList<QPointF>(const QPointF &value, bool isLittleEndian) { const double x = static_cast<double>(value.x()); const double y = static_cast<double>(value.y()); const ByteList byteListX = valueToByteList(x, isLittleEndian); const ByteList byteListY = valueToByteList(y, isLittleEndian); return ByteList{} << byteListX << byteListY; } //============================================================== // Конвертации значения типа QSize в список байтов //============================================================== template<> ByteList valueToByteList<QSize>(const QSize &value, bool isLittleEndian) { const qint32 width = static_cast<qint32>(value.width()); const qint32 height = static_cast<qint32>(value.height()); const ByteList byteListWidth = valueToByteList(width, isLittleEndian); const ByteList byteListHeight = valueToByteList(height, isLittleEndian); return ByteList{} << byteListWidth << byteListHeight; } //============================================================== // Конвертации значения типа QSizeF в список байтов //============================================================== template<> ByteList valueToByteList<QSizeF>(const QSizeF &value, bool isLittleEndian) { const double width = static_cast<double>(value.width()); const double height = static_cast<double>(value.height()); const ByteList byteListWidth = valueToByteList(width, isLittleEndian); const ByteList byteListHeight = valueToByteList(height, isLittleEndian); return ByteList{} << byteListWidth << byteListHeight; } //============================================================== // Конвертации значения типа QRect в список байтов //============================================================== template<> [[nodiscard]] ByteList valueToByteList<QRect>(const QRect &value, bool isLittleEndian) { const QPoint topLeft = value.topLeft(); const QSize size = value.size(); const ByteList byteListTopLeft = valueToByteList(topLeft, isLittleEndian); const ByteList byteListSize = valueToByteList(size, isLittleEndian); return ByteList{} << byteListTopLeft << byteListSize; } //============================================================== // Конвертации значения типа QRectF в список байтов //============================================================== template<> ByteList valueToByteList<QRectF>(const QRectF &value, bool isLittleEndian) { const QPointF topLeft = value.topLeft(); const QSizeF size = value.size(); const ByteList byteListTopLeft = valueToByteList(topLeft, isLittleEndian); const ByteList byteListSize = valueToByteList(size, isLittleEndian); return ByteList{} << byteListTopLeft << byteListSize; } //============================================================== // Конвертации значения типа QLine в список байтов //============================================================== template<> ByteList valueToByteList<QLine>(const QLine &value, bool isLittleEndian) { const QPoint pt1 = value.p1(); const QPoint pt2 = value.p2(); const ByteList byteListPt1 = valueToByteList(pt1, isLittleEndian); const ByteList byteListPt2 = valueToByteList(pt2, isLittleEndian); return ByteList{} << byteListPt1 << byteListPt2; } //============================================================== // Конвертации значения типа QLineF в список байтов //============================================================== template<> ByteList valueToByteList<QLineF>(const QLineF &value, bool isLittleEndian) { const QPointF pt1 = value.p1(); const QPointF pt2 = value.p2(); const ByteList byteListPt1 = valueToByteList(pt1, isLittleEndian); const ByteList byteListPt2 = valueToByteList(pt2, isLittleEndian); return ByteList{} << byteListPt1 << byteListPt2; } //============================================================== // Конвертация списка байтов в значение типа QString //============================================================== template<> optional<QString> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { if (it == end) { return nullopt; } if (distance(it, end) < static_cast<ptrdiff_t>(sizeof(qint32))) { return nullopt; } // Чтение длины строки const optional<qint32> optStrSize = byteListToValue<qint32>(it, end, isLittleEndian); constexpr int maxStrLen = 10000; if (!optStrSize || (optStrSize.value() < 0) || (optStrSize.value() > maxStrLen)) { return nullopt; } const qint32 strSize = optStrSize.value(); if (distance(it, end) < static_cast<ptrdiff_t>(strSize)) { return nullopt; } // Чтение самой строки QByteArray strByteArray(strSize, 0); copy(it, it + strSize, strByteArray.begin()); it += strSize; return QString::fromUtf8(strByteArray); } //============================================================== // Конвертация списка байтов в значение типа QColor //============================================================== template<> optional<QColor> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { Q_UNUSED(isLittleEndian) if (it == end) { return nullopt; } if (distance(it, end) < static_cast<ptrdiff_t>(getTypeByteSize<QColor>())) { return nullopt; } QColor color{}; color.setRed(*it++); color.setGreen(*it++); color.setBlue(*it++); color.setAlpha(*it++); return color; } //============================================================== // Конвертация списка байтов в значение типа QPoint //============================================================== template<> optional<QPoint> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { if (it == end) { return nullopt; } if (distance(it, end) < static_cast<ptrdiff_t>(getTypeByteSize<QPoint>())) { return nullopt; } const optional<qint32> x = byteListToValue<qint32>(it, end, isLittleEndian); const optional<qint32> y = byteListToValue<qint32>(it, end, isLittleEndian); if (!x || !y) { return nullopt; } return QPoint{x.value(), y.value()}; } //============================================================== // Конвертация списка байтов в значение типа QPointF //============================================================== template<> optional<QPointF> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { if (it == end) { return nullopt; } if (distance(it, end) < static_cast<ptrdiff_t>(getTypeByteSize<QPointF>())) { return nullopt; } const optional<double> x = byteListToValue<double>(it, end, isLittleEndian); const optional<double> y = byteListToValue<double>(it, end, isLittleEndian); if (!x || !y) { return nullopt; } return QPointF{x.value(), y.value()}; } //============================================================== // Конвертация списка байтов в значение типа QSize //============================================================== template<> optional<QSize> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { if (it == end) { return nullopt; } if (distance(it, end) < static_cast<ptrdiff_t>(getTypeByteSize<QSize>())) { return nullopt; } const optional<qint32> width = byteListToValue<qint32>(it, end, isLittleEndian); const optional<qint32> height = byteListToValue<qint32>(it, end, isLittleEndian); if (!width || !height) { return nullopt; } return QSize{width.value(), height.value()}; } //============================================================== // Конвертация списка байтов в значение типа QSizeF //============================================================== template<> optional<QSizeF> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { if (it == end) { return nullopt; } if (distance(it, end) < static_cast<ptrdiff_t>(getTypeByteSize<QSizeF>())) { return nullopt; } const optional<double> width = byteListToValue<double>(it, end, isLittleEndian); const optional<double> height = byteListToValue<double>(it, end, isLittleEndian); if (!width || !height) { return nullopt; } return QSizeF{width.value(), height.value()}; } //============================================================== // Конвертация списка байтов в значение типа QRect //============================================================== template<> optional<QRect> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { if (it == end) { return nullopt; } if (distance(it, end) < static_cast<ptrdiff_t>(getTypeByteSize<QRect>())) { return nullopt; } const optional<QPoint> topLeft = byteListToValue<QPoint>(it, end, isLittleEndian); const optional<QSize> size = byteListToValue<QSize>(it, end, isLittleEndian); if (!topLeft || !size) { return nullopt; } return QRect{topLeft.value(), size.value()}; } //============================================================== // Конвертация списка байтов в значение типа QRectF //============================================================== template<> optional<QRectF> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { if (it == end) { return nullopt; } if (distance(it, end) < static_cast<ptrdiff_t>(getTypeByteSize<QRectF>())) { return nullopt; } const optional<QPointF> topLeft = byteListToValue<QPointF>(it, end, isLittleEndian); const optional<QSizeF> size = byteListToValue<QSizeF>(it, end, isLittleEndian); if (!topLeft || !size) { return nullopt; } return QRectF{topLeft.value(), size.value()}; } //============================================================= // Конвертация списка байтов в значение типа QLine //============================================================= template<> optional<QLine> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { if (it == end) { return nullopt; } if (distance(it, end) < static_cast<ptrdiff_t>(getTypeByteSize<QLine>())) { return nullopt; } const optional<QPoint> pt1 = byteListToValue<QPoint>(it, end, isLittleEndian); const optional<QPoint> pt2 = byteListToValue<QPoint>(it, end, isLittleEndian); if (!pt1 || !pt2) { return nullopt; } return QLine{pt1.value(), pt2.value()}; } //============================================================== // Конвертация списка байтов в значение типа QLineF //============================================================== template<> optional<QLineF> byteListToValue(ByteList::iterator &it, ByteList::iterator end, bool isLittleEndian) { if (it == end) { return nullopt; } if (distance(it, end) < static_cast<ptrdiff_t>(getTypeByteSize<QLineF>())) { return nullopt; } const optional<QPointF> pt1 = byteListToValue<QPointF>(it, end, isLittleEndian); const optional<QPointF> pt2 = byteListToValue<QPointF>(it, end, isLittleEndian); if (!pt1 || !pt2) { return nullopt; } return QLineF{pt1.value(), pt2.value()}; } //============================================================== // Получение размера значения типа QString в байтах //============================================================== template<> size_t getValueByteSize<QString>(const QString &value) { return sizeof(qint32) + value.toUtf8().size(); } //============================================================== // Получение размера значения типа QColor в байтах //============================================================== template<> size_t getValueByteSize<QColor>(const QColor&) { return getTypeByteSize<QColor>(); } //============================================================== // Получение размера значения типа QPoint в байтах //============================================================== template<> size_t getValueByteSize<QPoint>(const QPoint&) { return getTypeByteSize<QPoint>(); } //============================================================== // Получение размера значения типа QPointF в байтах //============================================================== template<> size_t getValueByteSize<QPointF>(const QPointF&) { return getTypeByteSize<QPointF>(); } //============================================================== // Получение размера значения типа QSize в байтах //============================================================== template<> size_t getValueByteSize<QSize>(const QSize&) { return getTypeByteSize<QSize>(); } //============================================================== // Получение размера значения типа QSizeF в байтах //============================================================== template<> size_t getValueByteSize<QSizeF>(const QSizeF&) { return getTypeByteSize<QSizeF>(); } //============================================================== // Получение размера значения типа QRect в байтах //============================================================== template<> size_t getValueByteSize<QRect>(const QRect&) { return getTypeByteSize<QRect>(); } //============================================================== // Получение размера значения типа QRectF в байтах //============================================================== template<> size_t getValueByteSize<QRectF>(const QRectF&) { return getTypeByteSize<QRectF>(); } //============================================================== // Получение размера значения типа QLine в байтах //============================================================== template<> size_t getValueByteSize<QLine>(const QLine&) { return getTypeByteSize<QLine>(); } //============================================================== // Получение размера значения типа QLineF в байтах //============================================================== template<> size_t getValueByteSize<QLineF>(const QLineF&) { return getTypeByteSize<QLineF>(); }