mirror of https://github.com/qt/qtgrpc.git
QtProtobuf: Provide support for Qt types in a separate library
Task-number: QTBUG-103985 Change-Id: I2086f5cf46e1424b62b2044d0bcab315a5d447d9 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
fdd1d0339f
commit
6637773cbd
|
|
@ -14,4 +14,5 @@ add_subdirectory(tools)
|
||||||
|
|
||||||
if(TARGET Qt6::qtprotobufgen AND TARGET WrapProtobuf::WrapLibProtobuf)
|
if(TARGET Qt6::qtprotobufgen AND TARGET WrapProtobuf::WrapLibProtobuf)
|
||||||
add_subdirectory(wellknown)
|
add_subdirectory(wellknown)
|
||||||
|
add_subdirectory(protobufqttypes)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,6 @@ function(qt_internal_add_protobuf_module target)
|
||||||
${arg_PROTO_FILES}
|
${arg_PROTO_FILES}
|
||||||
OUTPUT_TARGETS generated_targets
|
OUTPUT_TARGETS generated_targets
|
||||||
GENERATE_PACKAGE_SUBFOLDERS
|
GENERATE_PACKAGE_SUBFOLDERS
|
||||||
EXTRA_NAMESPACE ${QT_NAMESPACE}
|
|
||||||
)
|
)
|
||||||
qt_internal_module_info(module ${target})
|
qt_internal_module_info(module ${target})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
add_subdirectory(protobufqtcoretypes)
|
||||||
|
|
||||||
|
if(TARGET Qt6::Gui)
|
||||||
|
add_subdirectory(protobufqtguitypes)
|
||||||
|
endif()
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\module QtProtobufQtTypes
|
||||||
|
\title Protobuf Qt types module
|
||||||
|
\brief Provides support for using native Qt types in protobuf.
|
||||||
|
|
||||||
|
Qt::ProtobufQtCoreTypes, Qt::ProtobufQtGuiTypes are libraries with
|
||||||
|
pre-defined protobuf messages designed to encapsulate a selection
|
||||||
|
of Qt Core and Qt Gui types.
|
||||||
|
|
||||||
|
List of supported types:
|
||||||
|
|
||||||
|
\list QtCore
|
||||||
|
\li QByteArray \note Type reflects the \e bytes protobuf type.
|
||||||
|
\li QChar
|
||||||
|
\li QDate
|
||||||
|
\li QDateTime
|
||||||
|
\li QPoint
|
||||||
|
\li QPointF
|
||||||
|
\li QRect
|
||||||
|
\li QRectF
|
||||||
|
\li QSize
|
||||||
|
\li QSizeF
|
||||||
|
\li QString \note Type reflects the \e string protobuf type.
|
||||||
|
\li QTime
|
||||||
|
\li QUrl
|
||||||
|
\li QUuid
|
||||||
|
\li QVersionNumber
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\list QtGui
|
||||||
|
\li QImage
|
||||||
|
\li QMatrix4x4
|
||||||
|
\li QQuaternion
|
||||||
|
\li QRgba64
|
||||||
|
\li QTransform
|
||||||
|
\li QVector2D
|
||||||
|
\li QVector3D
|
||||||
|
\li QVector4D
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\section1 Qt Core usage
|
||||||
|
To enable QtCore types support add ProtobufQtCoreTypes as a dependency
|
||||||
|
to your CMake project:
|
||||||
|
\badcode
|
||||||
|
...
|
||||||
|
find_package(Qt REQUIRED COMPONENTS Protobuf ProtobufQtCoreTypes)
|
||||||
|
... # After target creation
|
||||||
|
target_link_libraries(${TARGET} PRIVATE Qt::ProtobufQtCoreTypes)
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
Before any serialization/deserialization of messages that use QtCore types
|
||||||
|
as fields, call the registration method:
|
||||||
|
\code
|
||||||
|
// e.g. in main.cpp
|
||||||
|
QtProtobuf::qRegisterProtobufQtCoreTypes();
|
||||||
|
...
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
\section1 Qt Gui usage
|
||||||
|
To enable QtGui types support add ProtobufQtGuiTypes as a dependency
|
||||||
|
to your CMake project:
|
||||||
|
\badcode
|
||||||
|
...
|
||||||
|
find_package(Qt REQUIRED COMPONENTS Protobuf ProtobufQtGuiTypes)
|
||||||
|
... # After target creation
|
||||||
|
target_link_libraries(${TARGET} PRIVATE Qt::ProtobufQtGuiTypes)
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
Before any serialization/deserialization of messages that use QtGui types
|
||||||
|
as fields, call the registration method:
|
||||||
|
\code
|
||||||
|
// e.g. in main.cpp
|
||||||
|
QtProtobuf::qRegisterProtobufQtGuiTypes();
|
||||||
|
...
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
All supported messages are described in special .proto files:
|
||||||
|
|
||||||
|
- QtCore.proto - describes Qt types from QtCore module
|
||||||
|
- QtGui.proto - describes Qt types from QtGui module
|
||||||
|
|
||||||
|
These files are also useful if you would like to generate code for other
|
||||||
|
languages or frameworks.
|
||||||
|
|
||||||
|
Import the required Qt types module in your interface .proto file,
|
||||||
|
for example:
|
||||||
|
\badcode
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package project.module.component;
|
||||||
|
|
||||||
|
import "QtCore/QtCore.proto";
|
||||||
|
|
||||||
|
message QUrlMessage {
|
||||||
|
QtCore.QUrl url = 1;
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
The QtProtobuf generator detects Qt types, supplied by the
|
||||||
|
ProtobufQtCoreTypes and ProtobufQtGuiTypes packages, and
|
||||||
|
uses them directly. This gives you flexibility to use these
|
||||||
|
types without additional conversion.
|
||||||
|
*/
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
qt_internal_add_protobuf_module(ProtobufQtCoreTypes
|
||||||
|
SOURCES
|
||||||
|
qtprotobufqtcoretypes.cpp
|
||||||
|
qtprotobufqtcoretypes.h
|
||||||
|
qtprotobufqtcoretypesglobal.h
|
||||||
|
qtprotobufqttypescommon_p.h
|
||||||
|
GENERATE_CPP_EXPORTS
|
||||||
|
LIBRARIES
|
||||||
|
Qt::Core
|
||||||
|
Qt::Protobuf
|
||||||
|
Qt::ProtobufPrivate
|
||||||
|
PROTO_FILES
|
||||||
|
QtCore/QtCore.proto
|
||||||
|
PRIVATE_HEADER_FILTERS
|
||||||
|
".*\\.qpb\\.h"
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package QtCore;
|
||||||
|
|
||||||
|
message QUrl {
|
||||||
|
string url = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QChar {
|
||||||
|
uint32 utf16_code_point = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QUuid {
|
||||||
|
bytes rfc4122_uuid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QTime {
|
||||||
|
int32 milliseconds_since_midnight = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QDate {
|
||||||
|
int64 julian_day = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QDateTime {
|
||||||
|
int64 utc_msecs_since_unix_epoch = 1;
|
||||||
|
// TBD: QTBUG-109658 - QTimeZone support
|
||||||
|
}
|
||||||
|
|
||||||
|
message QSize {
|
||||||
|
int32 width = 1;
|
||||||
|
int32 height = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QSizeF {
|
||||||
|
double width = 1;
|
||||||
|
double height = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QPoint {
|
||||||
|
sint32 x = 1;
|
||||||
|
sint32 y = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QPointF {
|
||||||
|
double x = 1;
|
||||||
|
double y = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QRect {
|
||||||
|
sint32 x = 1;
|
||||||
|
sint32 y = 2;
|
||||||
|
int32 width = 3;
|
||||||
|
int32 height = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QRectF {
|
||||||
|
double x = 1;
|
||||||
|
double y = 2;
|
||||||
|
double width = 3;
|
||||||
|
double height = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QVersionNumber {
|
||||||
|
repeated int32 segments = 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,250 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "qtprotobufqtcoretypes.h"
|
||||||
|
#include "qtprotobufqttypescommon_p.h"
|
||||||
|
#include "private/QtCore.qpb.h"
|
||||||
|
|
||||||
|
#include <QtCore/qurl.h>
|
||||||
|
#include <QtCore/qchar.h>
|
||||||
|
#include <QtCore/quuid.h>
|
||||||
|
#include <QtCore/qtimezone.h>
|
||||||
|
#include <QtCore/qdatetime.h>
|
||||||
|
#include <QtCore/qdatastream.h>
|
||||||
|
#include <QtCore/qsize.h>
|
||||||
|
#include <QtCore/qpoint.h>
|
||||||
|
#include <QtCore/qrect.h>
|
||||||
|
#include <QtCore/qbuffer.h>
|
||||||
|
#include <QtCore/qversionnumber.h>
|
||||||
|
#include <QtCore/qendian.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
std::optional<QUrl> convert(const QtProtobufPrivate::QtCore::QUrl &from)
|
||||||
|
{
|
||||||
|
QUrl url(from.url());
|
||||||
|
return (url.isValid() || url.isEmpty()) ? std::optional<QUrl>(url) : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QtProtobufPrivate::QtCore::QUrl> convert(const QUrl &from)
|
||||||
|
{
|
||||||
|
if (from.isValid() || from.isEmpty()) {
|
||||||
|
QtProtobufPrivate::QtCore::QUrl url;
|
||||||
|
url.setUrl(from.url());
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
QChar convert(const QtProtobufPrivate::QtCore::QChar &from)
|
||||||
|
{
|
||||||
|
return QChar(from.utf16CodePoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QChar convert(const QChar &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtCore::QChar symbol;
|
||||||
|
symbol.setUtf16CodePoint(from.unicode());
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QUuid> convert(const QtProtobufPrivate::QtCore::QUuid &from)
|
||||||
|
{
|
||||||
|
if (from.rfc4122Uuid().size() != 16)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return QUuid::fromRfc4122(from.rfc4122Uuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QtProtobufPrivate::QtCore::QUuid> convert(const QUuid &from)
|
||||||
|
{
|
||||||
|
if (from.toRfc4122().size() != 16)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QUuid uuid;
|
||||||
|
uuid.setRfc4122Uuid(from.toRfc4122());
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QTime> convert(const QtProtobufPrivate::QtCore::QTime &from)
|
||||||
|
{
|
||||||
|
QTime time = QTime::fromMSecsSinceStartOfDay(from.millisecondsSinceMidnight());
|
||||||
|
return time.isValid() ? std::optional<QTime>(time) : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QtProtobufPrivate::QtCore::QTime> convert(const QTime &from)
|
||||||
|
{
|
||||||
|
if (!from.isValid())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QTime time;
|
||||||
|
time.setMillisecondsSinceMidnight(from.msecsSinceStartOfDay());
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QDate> convert(const QtProtobufPrivate::QtCore::QDate &from)
|
||||||
|
{
|
||||||
|
QDate date = QDate::fromJulianDay(from.julianDay());
|
||||||
|
return date.isValid() ? std::optional<QDate>(date) : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QtProtobufPrivate::QtCore::QDate> convert(const QDate &from)
|
||||||
|
{
|
||||||
|
if (!from.isValid())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QDate date;
|
||||||
|
date.setJulianDay(from.toJulianDay());
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QDateTime> convert(const QtProtobufPrivate::QtCore::QDateTime &from)
|
||||||
|
{
|
||||||
|
QDateTime dateTime(QDateTime::fromMSecsSinceEpoch(from.utcMsecsSinceUnixEpoch(),
|
||||||
|
QTimeZone::UTC));
|
||||||
|
return dateTime.isValid() ? std::optional<QDateTime>(dateTime) : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QtProtobufPrivate::QtCore::QDateTime> convert(const QDateTime &from)
|
||||||
|
{
|
||||||
|
if (!from.isValid())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QDateTime datetime;
|
||||||
|
datetime.setUtcMsecsSinceUnixEpoch(from.toMSecsSinceEpoch());
|
||||||
|
return datetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize convert(const QtProtobufPrivate::QtCore::QSize &from)
|
||||||
|
{
|
||||||
|
return QSize(from.width(), from.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QSize convert(const QSize &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtCore::QSize size;
|
||||||
|
size.setWidth(from.width());
|
||||||
|
size.setHeight(from.height());
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF convert(const QtProtobufPrivate::QtCore::QSizeF &from)
|
||||||
|
{
|
||||||
|
return QSizeF(from.width(), from.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QSizeF convert(const QSizeF &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtCore::QSizeF sizeF;
|
||||||
|
sizeF.setWidth(from.width());
|
||||||
|
sizeF.setHeight(from.height());
|
||||||
|
return sizeF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint convert(const QtProtobufPrivate::QtCore::QPoint &from)
|
||||||
|
{
|
||||||
|
return QPoint(from.x(), from.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QPoint convert(const QPoint &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtCore::QPoint pointT;
|
||||||
|
pointT.setX(from.x());
|
||||||
|
pointT.setY(from.y());
|
||||||
|
return pointT;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF convert(const QtProtobufPrivate::QtCore::QPointF &from)
|
||||||
|
{
|
||||||
|
return QPointF(from.x(), from.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QPointF convert(const QPointF &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtCore::QPointF pointF;
|
||||||
|
pointF.setX(from.x());
|
||||||
|
pointF.setY(from.y());
|
||||||
|
return pointF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect convert(const QtProtobufPrivate::QtCore::QRect &from)
|
||||||
|
{
|
||||||
|
return QRect(QPoint(from.x(), from.y()),
|
||||||
|
QSize(from.width(), from.height()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QRect convert(const QRect &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtCore::QRect rect;
|
||||||
|
rect.setX(from.x());
|
||||||
|
rect.setY(from.y());
|
||||||
|
rect.setWidth(from.width());
|
||||||
|
rect.setHeight(from.height());
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF convert(const QtProtobufPrivate::QtCore::QRectF &from)
|
||||||
|
{
|
||||||
|
return QRectF(QPointF(from.x(), from.y()),
|
||||||
|
QSizeF(from.width(), from.height()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QRectF convert(const QRectF &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtCore::QRectF rectF;
|
||||||
|
rectF.setX(from.x());
|
||||||
|
rectF.setY(from.y());
|
||||||
|
rectF.setWidth(from.width());
|
||||||
|
rectF.setHeight(from.height());
|
||||||
|
return rectF;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QVersionNumber> convert(const QtProtobufPrivate::QtCore::QVersionNumber &from)
|
||||||
|
{
|
||||||
|
if (from.segments().size() == 0)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
QList<int> versionList;
|
||||||
|
const auto segments = from.segments();
|
||||||
|
for (const auto &segment : segments)
|
||||||
|
versionList.append(segment);
|
||||||
|
return QVersionNumber(versionList);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QtProtobufPrivate::QtCore::QVersionNumber> convert(const QVersionNumber &from)
|
||||||
|
{
|
||||||
|
if (from.segments().size() == 0)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtCore::QVersionNumber version;
|
||||||
|
const auto segments = from.segments();
|
||||||
|
for (const auto &segment : segments)
|
||||||
|
version.segments().append(segment);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QtProtobuf {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Registers serializers for the Qt::ProtobufQtCoreTypes library.
|
||||||
|
*/
|
||||||
|
void qRegisterProtobufQtCoreTypes() {
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QUrl, QtProtobufPrivate::QtCore::QUrl>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QChar, QtProtobufPrivate::QtCore::QChar>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QUuid, QtProtobufPrivate::QtCore::QUuid>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QTime, QtProtobufPrivate::QtCore::QTime>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QDate, QtProtobufPrivate::QtCore::QDate>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QDateTime, QtProtobufPrivate::QtCore::QDateTime>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QSize, QtProtobufPrivate::QtCore::QSize>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QSizeF, QtProtobufPrivate::QtCore::QSizeF>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QPoint, QtProtobufPrivate::QtCore::QPoint>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QPointF, QtProtobufPrivate::QtCore::QPointF>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QRect, QtProtobufPrivate::QtCore::QRect>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QRectF, QtProtobufPrivate::QtCore::QRectF>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QVersionNumber,
|
||||||
|
QtProtobufPrivate::QtCore::QVersionNumber>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#ifndef QTPROTOBUFQTCORETYPES_H
|
||||||
|
#define QTPROTOBUFQTCORETYPES_H
|
||||||
|
|
||||||
|
#include <QtProtobufQtCoreTypes/qtprotobufqtcoretypesglobal.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace QtProtobuf {
|
||||||
|
|
||||||
|
Q_PROTOBUFQTCORETYPES_EXPORT void qRegisterProtobufQtCoreTypes();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QTPROTOBUFQTCORETYPES_H
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#ifndef QTPROTOBUFQTCORETYPESGLOBAL_H
|
||||||
|
#define QTPROTOBUFQTCORETYPESGLOBAL_H
|
||||||
|
|
||||||
|
#include <QtProtobufQtCoreTypes/qtprotobufqtcoretypesexports.h>
|
||||||
|
#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
|
#endif // QTPROTOBUFQTCORETYPESGLOBAL_H
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#ifndef QTPROTOBUFQTTYPESCOMMON_P_H
|
||||||
|
#define QTPROTOBUFQTTYPESCOMMON_P_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// W A R N I N G
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// This file is not part of the Qt API. It exists purely as an
|
||||||
|
// implementation detail. This header file may change from version to
|
||||||
|
// version without notice, or even be removed.
|
||||||
|
//
|
||||||
|
// We mean it.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <QtProtobuf/qtprotobuftypes.h>
|
||||||
|
#include <QtProtobuf/qprotobufserializer.h>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QVariant>
|
||||||
|
#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace QtProtobufPrivate {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr inline bool is_optional_v = false;
|
||||||
|
template <typename T>
|
||||||
|
constexpr inline bool is_optional_v<std::optional<T>> = true;
|
||||||
|
|
||||||
|
template<typename QType, typename PType>
|
||||||
|
void registerQtTypeHandler()
|
||||||
|
{
|
||||||
|
registerHandler(
|
||||||
|
QMetaType::fromType<QType>(),
|
||||||
|
{ [](const QProtobufSerializer *serializer, const QVariant &value,
|
||||||
|
const QProtobufPropertyOrderingInfo &info, QByteArray &buffer) {
|
||||||
|
auto do_convert = [](const QType &qtype) {
|
||||||
|
auto res = convert(qtype);
|
||||||
|
if constexpr (is_optional_v<decltype(res)>) {
|
||||||
|
if (!res) {
|
||||||
|
qWarning() << "Qt Proto Type conversion error.";
|
||||||
|
return PType();
|
||||||
|
}
|
||||||
|
return PType(std::move(*res));
|
||||||
|
} else {
|
||||||
|
return PType(std::move(res));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PType object = do_convert(value.value<QType>());
|
||||||
|
buffer.append(serializer->serializeObject(&object,
|
||||||
|
PType::propertyOrdering, info));
|
||||||
|
},
|
||||||
|
[](const QProtobufSerializer *serializer, QProtobufSelfcheckIterator &it,
|
||||||
|
QVariant &value) {
|
||||||
|
PType object;
|
||||||
|
serializer->deserializeObject(&object, PType::propertyOrdering, it);
|
||||||
|
auto res = convert(object);
|
||||||
|
if constexpr (is_optional_v<decltype(res)>) {
|
||||||
|
if (!res)
|
||||||
|
qWarning() << "Qt Proto Type conversion error.";
|
||||||
|
else
|
||||||
|
value = QVariant::fromValue<QType>(*res);
|
||||||
|
} else {
|
||||||
|
value = QVariant::fromValue<QType>(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} // namespace QtProtobufPrivate
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QTPROTOBUFQTTYPESCOMMON_P_H
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
qt_internal_add_protobuf_module(ProtobufQtGuiTypes
|
||||||
|
SOURCES
|
||||||
|
qtprotobufqtguitypes.cpp
|
||||||
|
qtprotobufqtguitypes.h
|
||||||
|
qtprotobufqtguitypesglobal.h
|
||||||
|
GENERATE_CPP_EXPORTS
|
||||||
|
LIBRARIES
|
||||||
|
Qt::Core
|
||||||
|
Qt::Gui
|
||||||
|
Qt::Protobuf
|
||||||
|
Qt::ProtobufPrivate
|
||||||
|
Qt::ProtobufQtCoreTypesPrivate
|
||||||
|
PROTO_FILES
|
||||||
|
QtGui/QtGui.proto
|
||||||
|
PRIVATE_HEADER_FILTERS
|
||||||
|
".*\\.qpb\\.h"
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package QtGui;
|
||||||
|
|
||||||
|
message QRgba64 {
|
||||||
|
uint64 rgba64 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QMatrix4x4 {
|
||||||
|
// 16 floats in row-major order
|
||||||
|
repeated float m = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QVector2D {
|
||||||
|
float x_pos = 1;
|
||||||
|
float y_pos = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QVector3D {
|
||||||
|
float x_pos = 1;
|
||||||
|
float y_pos = 2;
|
||||||
|
float z_pos = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QVector4D {
|
||||||
|
float x_pos = 1;
|
||||||
|
float y_pos = 2;
|
||||||
|
float z_pos = 3;
|
||||||
|
float w_pos = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QTransform {
|
||||||
|
repeated double m = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QQuaternion {
|
||||||
|
float scalar = 1;
|
||||||
|
float x = 2;
|
||||||
|
float y = 3;
|
||||||
|
float z = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QImage {
|
||||||
|
bytes data = 1;
|
||||||
|
string format = 2; // see QImageWriter::supportedImageFormats()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,173 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "qtprotobufqtguitypes.h"
|
||||||
|
#include "private/QtGui.qpb.h"
|
||||||
|
|
||||||
|
#include <QtProtobufQtCoreTypes/private/qtprotobufqttypescommon_p.h>
|
||||||
|
|
||||||
|
#include <QtGui/qrgba64.h>
|
||||||
|
#include <QtGui/qmatrix4x4.h>
|
||||||
|
#include <QtGui/qvector2d.h>
|
||||||
|
#include <QtGui/qtransform.h>
|
||||||
|
#include <QtGui/qquaternion.h>
|
||||||
|
#include <QtGui/qimage.h>
|
||||||
|
#include <QtCore/qbuffer.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
QRgba64 convert(const QtProtobufPrivate::QtGui::QRgba64 &from)
|
||||||
|
{
|
||||||
|
return QRgba64::fromRgba64(from.rgba64());
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtGui::QRgba64 convert(const QRgba64 &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtGui::QRgba64 rgba64;
|
||||||
|
rgba64.setRgba64((quint64)from);
|
||||||
|
return rgba64;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QMatrix4x4> convert(const QtProtobufPrivate::QtGui::QMatrix4x4 &from)
|
||||||
|
{
|
||||||
|
QtProtobuf::floatList list = from.m();
|
||||||
|
if (list.size() == 16) {
|
||||||
|
return QMatrix4x4(list[0], list[1], list[2], list[3],
|
||||||
|
list[4], list[5], list[6], list[7],
|
||||||
|
list[8], list[9], list[10], list[11],
|
||||||
|
list[12], list[13], list[14], list[15]);
|
||||||
|
}
|
||||||
|
qWarning() << "Input for QMatrix4x4 should provide 16 values, but size = "
|
||||||
|
<< list.size();
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtGui::QMatrix4x4 convert(const QMatrix4x4 &from)
|
||||||
|
{
|
||||||
|
const float *matrixData = from.data();
|
||||||
|
QtProtobufPrivate::QtGui::QMatrix4x4 matrix;
|
||||||
|
// QMatrix4x4::data returned in column-major format
|
||||||
|
matrix.setM({matrixData[0], matrixData[4], matrixData[8], matrixData[12],
|
||||||
|
matrixData[1], matrixData[5], matrixData[9], matrixData[13],
|
||||||
|
matrixData[2], matrixData[6], matrixData[10], matrixData[14],
|
||||||
|
matrixData[3], matrixData[7], matrixData[11], matrixData[15]});
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector2D convert(const QtProtobufPrivate::QtGui::QVector2D &from)
|
||||||
|
{
|
||||||
|
return QVector2D(from.xPos(), from.yPos());;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtGui::QVector2D convert(const QVector2D &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtGui::QVector2D vector2D;
|
||||||
|
vector2D.setXPos(from.x());
|
||||||
|
vector2D.setYPos(from.y());
|
||||||
|
return vector2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector3D convert(const QtProtobufPrivate::QtGui::QVector3D &from)
|
||||||
|
{
|
||||||
|
return QVector3D(from.xPos(), from.yPos(), from.zPos());
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtGui::QVector3D convert(const QVector3D &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtGui::QVector3D vector3D;
|
||||||
|
vector3D.setXPos(from.x());
|
||||||
|
vector3D.setYPos(from.y());
|
||||||
|
vector3D.setZPos(from.z());
|
||||||
|
return vector3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector4D convert(const QtProtobufPrivate::QtGui::QVector4D &from)
|
||||||
|
{
|
||||||
|
return QVector4D(from.xPos(), from.yPos(), from.zPos(), from.wPos());
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtGui::QVector4D convert(const QVector4D &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtGui::QVector4D vector4D;
|
||||||
|
vector4D.setXPos(from.x());
|
||||||
|
vector4D.setYPos(from.y());
|
||||||
|
vector4D.setZPos(from.z());
|
||||||
|
vector4D.setWPos(from.w());
|
||||||
|
return vector4D;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QTransform> convert(const QtProtobufPrivate::QtGui::QTransform &from)
|
||||||
|
{
|
||||||
|
QtProtobuf::doubleList list = from.m();
|
||||||
|
if (list.size() == 9) {
|
||||||
|
return QTransform(list[0], list[1], list[2],
|
||||||
|
list[3], list[4], list[5],
|
||||||
|
list[6], list[7], list[8]);
|
||||||
|
}
|
||||||
|
qWarning() << "Input list for QTransform should provide 9 members. But size = "
|
||||||
|
<< list.size();
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtGui::QTransform convert(const QTransform &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtGui::QTransform transform;
|
||||||
|
transform.setM({from.m11(), from.m12(), from.m13(),
|
||||||
|
from.m21(), from.m22(), from.m23(),
|
||||||
|
from.m31(), from.m32(), from.m33()});
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
QQuaternion convert(const QtProtobufPrivate::QtGui::QQuaternion &from)
|
||||||
|
{
|
||||||
|
return QQuaternion(from.scalar(), from.x(), from.y(), from.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProtobufPrivate::QtGui::QQuaternion convert(const QQuaternion &from)
|
||||||
|
{
|
||||||
|
QtProtobufPrivate::QtGui::QQuaternion quaternion;
|
||||||
|
quaternion.setScalar(from.scalar());
|
||||||
|
quaternion.setX(from.x());
|
||||||
|
quaternion.setY(from.y());
|
||||||
|
quaternion.setZ(from.z());
|
||||||
|
return quaternion;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage convert(const QtProtobufPrivate::QtGui::QImage &from)
|
||||||
|
{
|
||||||
|
return QImage::fromData(from.data(), from.format().toLatin1().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QtProtobufPrivate::QtGui::QImage> convert(const QImage &from)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QBuffer buffer(&data);
|
||||||
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
if (from.save(&buffer, "PNG")) {
|
||||||
|
QtProtobufPrivate::QtGui::QImage image;
|
||||||
|
image.setData(data);
|
||||||
|
image.setFormat(QLatin1StringView("PNG"));
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QtProtobuf {
|
||||||
|
/*!
|
||||||
|
Registers serializers for the Qt::ProtobufQtGuiTypes library.
|
||||||
|
*/
|
||||||
|
void qRegisterProtobufQtGuiTypes() {
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QRgba64, QtProtobufPrivate::QtGui::QRgba64>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QMatrix4x4, QtProtobufPrivate::QtGui::QMatrix4x4>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QVector2D, QtProtobufPrivate::QtGui::QVector2D>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QVector3D, QtProtobufPrivate::QtGui::QVector3D>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QVector4D, QtProtobufPrivate::QtGui::QVector4D>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QTransform, QtProtobufPrivate::QtGui::QTransform>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QQuaternion, QtProtobufPrivate::QtGui::QQuaternion>();
|
||||||
|
QtProtobufPrivate::registerQtTypeHandler<QImage, QtProtobufPrivate::QtGui::QImage>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#ifndef QTPROTOBUFQTGUITYPES_H
|
||||||
|
#define QTPROTOBUFQTGUITYPES_H
|
||||||
|
|
||||||
|
#include <QtProtobufQtGuiTypes/qtprotobufqtguitypesglobal.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace QtProtobuf {
|
||||||
|
|
||||||
|
Q_PROTOBUFQTGUITYPES_EXPORT void qRegisterProtobufQtGuiTypes();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QTPROTOBUFQTGUITYPES_H
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#ifndef QTPROTOBUFQTTYPESGLOBAL_H
|
||||||
|
#define QTPROTOBUFQTTYPESGLOBAL_H
|
||||||
|
|
||||||
|
#include <QtProtobufQtGuiTypes/qtprotobufqtguitypesexports.h>
|
||||||
|
#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
|
#endif // QTPROTOBUFQTTYPESGLOBAL_H
|
||||||
|
|
@ -135,16 +135,16 @@ void QProtobufGenerator::GenerateHeader(const FileDescriptor *file,
|
||||||
externalIncludes.insert("QByteArray");
|
externalIncludes.insert("QByteArray");
|
||||||
externalIncludes.insert("QString");
|
externalIncludes.insert("QString");
|
||||||
|
|
||||||
bool hasQtTypes = false;
|
|
||||||
bool hasOneofFields = false;
|
bool hasOneofFields = false;
|
||||||
|
std::unordered_set<std::string> qtTypesSet;
|
||||||
common::iterateMessages(
|
common::iterateMessages(
|
||||||
file, [&externalIncludes, &hasQtTypes, &hasOneofFields](const Descriptor *message) {
|
file, [&](const Descriptor *message) {
|
||||||
for (int i = 0; i < message->field_count(); ++i) {
|
for (int i = 0; i < message->field_count(); ++i) {
|
||||||
const auto *field = message->field(i);
|
const auto *field = message->field(i);
|
||||||
if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map()
|
if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map()
|
||||||
&& !field->is_repeated() && common::isQtType(field)) {
|
&& !field->is_repeated() && common::isQtType(field)) {
|
||||||
externalIncludes.insert(field->message_type()->name());
|
externalIncludes.insert(field->message_type()->name());
|
||||||
hasQtTypes = true;
|
qtTypesSet.insert(field->message_type()->file()->package());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,13 +162,13 @@ void QProtobufGenerator::GenerateHeader(const FileDescriptor *file,
|
||||||
if (hasOneofFields)
|
if (hasOneofFields)
|
||||||
externalIncludes.insert("QProtobufOneof");
|
externalIncludes.insert("QProtobufOneof");
|
||||||
|
|
||||||
if (hasQtTypes) {
|
for (const auto &qtTypeInclude: qtTypesSet) {
|
||||||
externalIncludes.insert("QtProtobufQtTypes");
|
externalIncludes.insert("QtProtobuf" + qtTypeInclude + "Types");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < file->dependency_count(); ++i) {
|
for (int i = 0; i < file->dependency_count(); ++i) {
|
||||||
if (file->dependency(i)->name() == "QtProtobuf/QtCore.proto"
|
if (file->dependency(i)->name() == "QtCore/QtCore.proto"
|
||||||
|| file->dependency(i)->name() == "QtProtobuf/QtGui.proto") {
|
|| file->dependency(i)->name() == "QtGui/QtGui.proto") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Override the any.proto include with our own specific support
|
// Override the any.proto include with our own specific support
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,13 @@ void GeneratorBase::OpenFileNamespaces(
|
||||||
google::protobuf::io::Printer *printer) const
|
google::protobuf::io::Printer *printer) const
|
||||||
{
|
{
|
||||||
assert(printer != nullptr);
|
assert(printer != nullptr);
|
||||||
|
assert(file != nullptr);
|
||||||
const bool hasQtNamespace = (Options::instance().extraNamespace() == "QT_NAMESPACE");
|
const bool hasQtNamespace = (Options::instance().extraNamespace() == "QT_NAMESPACE");
|
||||||
const std::string scopeNamespaces = file->message_type_count() > 0
|
const std::string scopeNamespaces = file->message_type_count() > 0
|
||||||
? common::getFullNamespace(file->message_type(0), "::")
|
? common::getFullNamespace(file->message_type(0), "::")
|
||||||
: common::getFullNamespace(file->enum_type(0), "::");
|
: common::getFullNamespace(file->enum_type(0), "::");
|
||||||
printer->Print("\n");
|
printer->Print("\n");
|
||||||
if (hasQtNamespace)
|
if (hasQtNamespace || file->package() == "QtCore" || file->package() == "QtGui")
|
||||||
printer->PrintRaw("QT_BEGIN_NAMESPACE\n");
|
printer->PrintRaw("QT_BEGIN_NAMESPACE\n");
|
||||||
if (!scopeNamespaces.empty()) {
|
if (!scopeNamespaces.empty()) {
|
||||||
printer->Print({ { "scope_namespaces", scopeNamespaces } },
|
printer->Print({ { "scope_namespaces", scopeNamespaces } },
|
||||||
|
|
@ -79,7 +80,7 @@ void GeneratorBase::CloseFileNamespaces(
|
||||||
printer->Print({ { "scope_namespaces", scopeNamespaces } },
|
printer->Print({ { "scope_namespaces", scopeNamespaces } },
|
||||||
CommonTemplates::NamespaceClosingTemplate());
|
CommonTemplates::NamespaceClosingTemplate());
|
||||||
}
|
}
|
||||||
if (hasQtNamespace)
|
if (hasQtNamespace || file->package() == "QtCore" || file->package() == "QtGui")
|
||||||
printer->PrintRaw("QT_END_NAMESPACE\n");
|
printer->PrintRaw("QT_END_NAMESPACE\n");
|
||||||
printer->Print("\n");
|
printer->Print("\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ std::string common::getFullNamespace(std::string_view fullDescriptorName,
|
||||||
return output;
|
return output;
|
||||||
std::string namespacesStr =
|
std::string namespacesStr =
|
||||||
utils::replace(fullDescriptorName.substr(0, nameIndex), ".", separator);
|
utils::replace(fullDescriptorName.substr(0, nameIndex), ".", separator);
|
||||||
|
if (namespacesStr == "QtCore" || namespacesStr == "QtGui")
|
||||||
|
namespacesStr = "QtProtobufPrivate" + std::string(separator) + namespacesStr;
|
||||||
if (!output.empty() && !namespacesStr.empty())
|
if (!output.empty() && !namespacesStr.empty())
|
||||||
output += separator;
|
output += separator;
|
||||||
output += namespacesStr;
|
output += namespacesStr;
|
||||||
|
|
@ -393,9 +395,10 @@ TypeMap common::produceClientTypeMap(const ServiceDescriptor *service, const Des
|
||||||
|
|
||||||
bool common::isQtType(const FieldDescriptor *field)
|
bool common::isQtType(const FieldDescriptor *field)
|
||||||
{
|
{
|
||||||
return utils::startsWith(field->message_type()->full_name(), "QtProtobuf.")
|
const auto fullName = field->message_type()->full_name();
|
||||||
&& field->file()->package() != "QtProtobuf"; // Used for qttypes library to avoid types
|
const auto package = field->file()->package();
|
||||||
// conversion inside library
|
return (utils::startsWith(fullName, "QtCore.") || utils::startsWith(fullName, "QtGui."))
|
||||||
|
&& package != "QtCore" && package != "QtGui";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool common::isOverridden(const FieldDescriptor *field)
|
bool common::isOverridden(const FieldDescriptor *field)
|
||||||
|
|
|
||||||
|
|
@ -12,3 +12,9 @@ add_subdirectory(protobuf)
|
||||||
if(QT_FEATURE_grpc AND TARGET Qt6::qtprotobufgen AND TARGET Qt6::qtgrpcgen)
|
if(QT_FEATURE_grpc AND TARGET Qt6::qtprotobufgen AND TARGET Qt6::qtgrpcgen)
|
||||||
add_subdirectory(grpc)
|
add_subdirectory(grpc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(TARGET Qt6::ProtobufQtCoreTypes
|
||||||
|
AND TARGET Qt6::ProtobufQtGuiTypes
|
||||||
|
AND TARGET Qt6::qtprotobufgen)
|
||||||
|
add_subdirectory(protobufqttypes)
|
||||||
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
qt_internal_add_test(tst_protobuf_qtcoretypes
|
||||||
|
SOURCES
|
||||||
|
qtprotobufqttypescoretest.cpp
|
||||||
|
INCLUDE_DIRECTORIES
|
||||||
|
../protobuf/shared
|
||||||
|
LIBRARIES
|
||||||
|
Qt::Test
|
||||||
|
Qt::Protobuf
|
||||||
|
Qt::ProtobufQtCoreTypes
|
||||||
|
Qt::Core
|
||||||
|
DEFINES
|
||||||
|
PROTOC_EXECUTABLE="$<TARGET_FILE:WrapProtoc::WrapProtoc>"
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_add_protobuf(tst_protobuf_qtcoretypes
|
||||||
|
PROTO_FILES
|
||||||
|
../shared/data/proto/qtcoretypes.proto
|
||||||
|
PROTO_INCLUDES
|
||||||
|
$<TARGET_PROPERTY:Qt6::ProtobufQtCoreTypes,QT_PROTO_INCLUDES>
|
||||||
|
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/generated"
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_autogen_tools_initial_setup(tst_protobuf_qtcoretypes)
|
||||||
|
|
||||||
|
if(QT_FEATURE_gui)
|
||||||
|
qt_internal_add_test(tst_protobuf_qtguitypes
|
||||||
|
SOURCES
|
||||||
|
qtprotobufqttypesguitest.cpp
|
||||||
|
INCLUDE_DIRECTORIES
|
||||||
|
../protobuf/shared
|
||||||
|
LIBRARIES
|
||||||
|
Qt::Test
|
||||||
|
Qt::Protobuf
|
||||||
|
Qt::ProtobufQtGuiTypes
|
||||||
|
Qt::Core
|
||||||
|
Qt::Gui
|
||||||
|
DEFINES
|
||||||
|
PROTOC_EXECUTABLE="$<TARGET_FILE:WrapProtoc::WrapProtoc>"
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_add_protobuf(tst_protobuf_qtguitypes
|
||||||
|
PROTO_FILES
|
||||||
|
../shared/data/proto/qtguitypes.proto
|
||||||
|
PROTO_INCLUDES
|
||||||
|
$<TARGET_PROPERTY:Qt6::ProtobufQtGuiTypes,QT_PROTO_INCLUDES>
|
||||||
|
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/generated_gui"
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_autogen_tools_initial_setup(tst_protobuf_qtguitypes)
|
||||||
|
endif()
|
||||||
|
|
@ -0,0 +1,322 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// Copyright (C) 2020 Alexey Edelev <semlanik@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "qtcoretypes.qpb.h"
|
||||||
|
|
||||||
|
#include <qtprotobuftestscommon.h>
|
||||||
|
#include <QProtobufSerializer>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
const QTime testTime = QTime(7, 30, 18, 321);
|
||||||
|
const QDate testDate = QDate(1856, 6, 10);
|
||||||
|
|
||||||
|
class QtProtobufQtTypesQtCoreTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase();
|
||||||
|
void qUrl();
|
||||||
|
void qChar();
|
||||||
|
void qUuid();
|
||||||
|
void qTime();
|
||||||
|
void qDate();
|
||||||
|
void qDateTime();
|
||||||
|
void qSize();
|
||||||
|
void qPoint();
|
||||||
|
void qPointF();
|
||||||
|
void qSizeF();
|
||||||
|
void qRect();
|
||||||
|
void qRectF();
|
||||||
|
void qVersionNumber();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QProtobufSerializer serializer;
|
||||||
|
};
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::initTestCase()
|
||||||
|
{
|
||||||
|
QtProtobuf::qRegisterProtobufQtCoreTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace qtprotobufnamespace::qttypes::tests;
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qUrl()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QUrlMessage, QUrl>(1, "QUrl", "testField");
|
||||||
|
|
||||||
|
QUrlMessage msg;
|
||||||
|
const char *qtUrl = "https://www.qt.io/product/framework";
|
||||||
|
const char *hexUrlValue
|
||||||
|
= "0a250a2368747470733a2f2f7777772e71742e696f2f70726f647563742f6672616d65776f726b";
|
||||||
|
msg.setTestField(QUrl(qtUrl));
|
||||||
|
|
||||||
|
QCOMPARE(QByteArray::fromHex(hexUrlValue), msg.serialize(&serializer));
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex(hexUrlValue));
|
||||||
|
|
||||||
|
QCOMPARE(QString::fromLatin1(qtUrl), msg.testField().url());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qChar()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QCharMessage, QChar>(1, "QChar", "testField");
|
||||||
|
|
||||||
|
QCharMessage msg;
|
||||||
|
msg.setTestField(QChar('q'));
|
||||||
|
QCOMPARE(QByteArray::fromHex("0a020871"), msg.serialize(&serializer));
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.setTestField({QChar(8364)});
|
||||||
|
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a0308ac41"));
|
||||||
|
QCOMPARE(QChar(8364), msg.testField());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qUuid()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QUuidMessage, QUuid>(1, "QUuid", "testField");
|
||||||
|
|
||||||
|
const char *hexUuidValue = "0a120a104bcbcdc3c5b34d3497feaf78c825cc7d";
|
||||||
|
const char *uuidValue = "{4bcbcdc3-c5b3-4d34-97fe-af78c825cc7d}";
|
||||||
|
|
||||||
|
QUuidMessage msg;
|
||||||
|
msg.setTestField(QUuid(uuidValue));
|
||||||
|
QCOMPARE(QByteArray::fromHex(hexUuidValue), msg.serialize(&serializer));
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex(hexUuidValue));
|
||||||
|
|
||||||
|
QCOMPARE(QUuid(uuidValue), msg.testField());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qTime()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QTimeMessage, QTime>(1, "QTime", "testField");
|
||||||
|
QTimeMessage msg;
|
||||||
|
msg.setTestField(QTime(5, 30, 48, 123));
|
||||||
|
QByteArray result = msg.serialize(&serializer);
|
||||||
|
|
||||||
|
QCOMPARE(QByteArray::fromHex("0a0508bbb7bb09"), result);
|
||||||
|
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a0508d188f10c"));
|
||||||
|
QCOMPARE(msg.testField().hour(), testTime.hour());
|
||||||
|
QCOMPARE(msg.testField().minute(), testTime.minute());
|
||||||
|
QCOMPARE(msg.testField().second(), testTime.second());
|
||||||
|
QCOMPARE(msg.testField().msec(), testTime.msec());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qDate()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QDateMessage, QDate>(1, "QDate", "testField");
|
||||||
|
QDateMessage msg;
|
||||||
|
msg.setTestField(testDate);
|
||||||
|
QByteArray result = msg.serialize(&serializer);
|
||||||
|
|
||||||
|
QCOMPARE(QByteArray::fromHex("0a050887b79201"), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a0508aeab9301"));
|
||||||
|
QCOMPARE(msg.testField().year(), 1897);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qDateTime()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QDateTimeMessage, QDateTime>(1,
|
||||||
|
"QDateTime",
|
||||||
|
"testField");
|
||||||
|
QDateTimeMessage msg;
|
||||||
|
|
||||||
|
const QDate checkingDate = QDate(1897, 3, 14);
|
||||||
|
msg.setTestField({checkingDate, testTime, QTimeZone::UTC});
|
||||||
|
|
||||||
|
QByteArray result = msg.serialize(&serializer);
|
||||||
|
|
||||||
|
const char *hexValue = "0a0b08d1f8d1da91bdffffff01";
|
||||||
|
QCOMPARE(QByteArray::fromHex(hexValue), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex(hexValue));
|
||||||
|
QCOMPARE(msg.testField(), QDateTime(checkingDate, testTime, QTimeZone::UTC));
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.setTestField(QDateTime(testDate, testTime, QTimeZone::UTC));
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a0b08d1f0918dda97ffffff01"));
|
||||||
|
|
||||||
|
QCOMPARE(msg.testField(), QDateTime(testDate, testTime, QTimeZone::UTC));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qSize()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QSizeMessage, QSize>(1, "QSize", "testField");
|
||||||
|
QSizeMessage msg;
|
||||||
|
const QSize size({1024, 768});
|
||||||
|
msg.setTestField(size);
|
||||||
|
|
||||||
|
QByteArray result = msg.serialize(&serializer);
|
||||||
|
const char *hexValue = "0a06088008108006";
|
||||||
|
|
||||||
|
QCOMPARE(QByteArray::fromHex(hexValue), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex(hexValue));
|
||||||
|
QCOMPARE(msg.testField().width(), size.width());
|
||||||
|
QCOMPARE(msg.testField().height(), size.height());
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a06088006108008"));
|
||||||
|
QCOMPARE(msg.testField().width(), size.height());
|
||||||
|
QCOMPARE(msg.testField().height(), size.width());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qSizeF()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QSizeFMessage, QSizeF>(1, "QSizeF", "testField");
|
||||||
|
QSizeFMessage msg;
|
||||||
|
|
||||||
|
const QSizeF sizeF = {1024.0, 768.0};
|
||||||
|
msg.setTestField(sizeF);
|
||||||
|
|
||||||
|
QByteArray result = msg.serialize(&serializer);
|
||||||
|
const char *hexValue = "0a12090000000000009040110000000000008840";
|
||||||
|
QCOMPARE(QByteArray::fromHex(hexValue), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex(hexValue));
|
||||||
|
QCOMPARE(msg.testField().width(), sizeF.width());
|
||||||
|
QCOMPARE(msg.testField().height(), sizeF.height());
|
||||||
|
|
||||||
|
msg.deserialize(&serializer,
|
||||||
|
QByteArray::fromHex("0a12090000000000008840110000000000009040"));
|
||||||
|
QCOMPARE(msg.testField().width(), sizeF.height());
|
||||||
|
QCOMPARE(msg.testField().height(), sizeF.width());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qPoint()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QPointMessage, QPoint>(1, "QPoint", "testField");
|
||||||
|
QPointMessage msg;
|
||||||
|
const QPoint point = {1024, 768};
|
||||||
|
msg.setTestField(point);
|
||||||
|
|
||||||
|
QByteArray result = msg.serialize(&serializer);
|
||||||
|
QCOMPARE(QByteArray::fromHex("0a0608801010800c"), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a0608801010800c"));
|
||||||
|
QCOMPARE(msg.testField().x(), point.x());
|
||||||
|
QCOMPARE(msg.testField().y(), point.y());
|
||||||
|
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a0608800c108010"));
|
||||||
|
QCOMPARE(msg.testField().x(), point.y());
|
||||||
|
QCOMPARE(msg.testField().y(), point.x());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qPointF()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QPointFMessage, QPointF>(1, "QPointF", "testField");
|
||||||
|
QPointFMessage msg;
|
||||||
|
|
||||||
|
const QPointF pointF = {1024.0, 768.0};
|
||||||
|
msg.setTestField(pointF);
|
||||||
|
|
||||||
|
QByteArray result = msg.serialize(&serializer);
|
||||||
|
const char *hexValue = "0a12090000000000009040110000000000008840";
|
||||||
|
QCOMPARE(QByteArray::fromHex(hexValue), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex(hexValue));
|
||||||
|
QCOMPARE(msg.testField().x(), pointF.x());
|
||||||
|
QCOMPARE(msg.testField().y(), pointF.y());
|
||||||
|
|
||||||
|
msg.deserialize(&serializer,
|
||||||
|
QByteArray::fromHex("0a12090000000000008840110000000000009040"));
|
||||||
|
QCOMPARE(msg.testField().x(), pointF.y());
|
||||||
|
QCOMPARE(msg.testField().y(), pointF.x());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qRect()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QRectMessage, QRect>(1, "QRect", "testField");
|
||||||
|
QRectMessage msg;
|
||||||
|
QPoint point(768, 768);
|
||||||
|
QSize size(500, 1212);
|
||||||
|
msg.setTestField({point, size});
|
||||||
|
|
||||||
|
QByteArray result = msg.serialize(&serializer);
|
||||||
|
|
||||||
|
const char *hexValue = "0a0c08800c10800c18f40320bc09";
|
||||||
|
QCOMPARE(QByteArray::fromHex(hexValue), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex(hexValue));
|
||||||
|
QCOMPARE(msg.testField().x(), point.x());
|
||||||
|
QCOMPARE(msg.testField().y(), point.y());
|
||||||
|
QCOMPARE(msg.testField().width(), size.width());
|
||||||
|
QCOMPARE(msg.testField().height(), size.height());
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a06188008208006"));
|
||||||
|
QCOMPARE(msg.testField().x(), 0);
|
||||||
|
QCOMPARE(msg.testField().y(), 0);
|
||||||
|
QCOMPARE(msg.testField().width(), 1024);
|
||||||
|
QCOMPARE(msg.testField().height(), 768);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qRectF()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QRectFMessage, QRectF>(1, "QRectF", "testField");
|
||||||
|
QRectFMessage msg;
|
||||||
|
QPointF pointF(768.0, 768.0);
|
||||||
|
QSizeF sizeF(1024.0, 1024.0);
|
||||||
|
msg.setTestField({pointF.x(), pointF.y(), sizeF.width(), sizeF.height()});
|
||||||
|
|
||||||
|
QByteArray result = msg.serialize(&serializer);
|
||||||
|
|
||||||
|
const char *hexValue
|
||||||
|
= "0a24090000000000008840110000000000008840190000000000009040210000000000009040";
|
||||||
|
QCOMPARE(QByteArray::fromHex(hexValue), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex(hexValue));
|
||||||
|
QCOMPARE(msg.testField().x(), pointF.x());
|
||||||
|
QCOMPARE(msg.testField().y(), pointF.y());
|
||||||
|
QCOMPARE(msg.testField().width(), sizeF.width());
|
||||||
|
QCOMPARE(msg.testField().height(),sizeF.height());
|
||||||
|
|
||||||
|
msg.setTestField({QPointF(0.0, 0.0), QSizeF(1024.0, 768.0)});
|
||||||
|
msg.deserialize(&serializer,
|
||||||
|
QByteArray::fromHex("0a24090000000000000000110000000000000"
|
||||||
|
"000190000000000009040210000000000008840"));
|
||||||
|
QCOMPARE(msg.testField().x(), 0.0);
|
||||||
|
QCOMPARE(msg.testField().y(), 0.0);
|
||||||
|
QCOMPARE(msg.testField().width(), 1024.0);
|
||||||
|
QCOMPARE(msg.testField().height(), 768.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtCoreTest::qVersionNumber()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QVersionNumberFMessage,
|
||||||
|
QVersionNumber>(1, "QVersionNumber", "testField");
|
||||||
|
QVersionNumberFMessage msg;
|
||||||
|
QVersionNumber version(1, 1, 0);
|
||||||
|
msg.setTestField({version});
|
||||||
|
|
||||||
|
QByteArray result = msg.serialize(&serializer);
|
||||||
|
const char *hexValue = "0a050a03010100";
|
||||||
|
QCOMPARE(QByteArray::fromHex(hexValue), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex(hexValue));
|
||||||
|
QCOMPARE(msg.testField(), version);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(QtProtobufQtTypesQtCoreTest)
|
||||||
|
#include "qtprotobufqttypescoretest.moc"
|
||||||
|
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// Copyright (C) 2020 Alexey Edelev <semlanik@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "qtguitypes.qpb.h"
|
||||||
|
|
||||||
|
#include <qtprotobuftestscommon.h>
|
||||||
|
#include <QProtobufSerializer>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtGui/QPainter>
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class QtProtobufQtTypesQtGuiTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase() {
|
||||||
|
QtProtobuf::qRegisterProtobufQtGuiTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void qMatrix4x4();
|
||||||
|
void qVector2D();
|
||||||
|
void qVector3D();
|
||||||
|
void qVector4D();
|
||||||
|
void qTransform();
|
||||||
|
void qQuaternion();
|
||||||
|
void qImage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QProtobufSerializer serializer;
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace qtprotobufnamespace::qttypes::tests;
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtGuiTest::qMatrix4x4()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QMatrix4x4Message,
|
||||||
|
QMatrix4x4>(1, "QMatrix4x4", "testField");
|
||||||
|
|
||||||
|
QMatrix4x4Message msg;
|
||||||
|
const QMatrix4x4 matrix = QMatrix4x4(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
|
||||||
|
msg.setTestField(matrix);
|
||||||
|
auto result = msg.serialize(&serializer);
|
||||||
|
const char *matrixHex = "0a420a40000000000000803f0000004000004040000080400000a040"
|
||||||
|
"0000c0400000e0400000004100001041000020410000304100004041"
|
||||||
|
"000050410000604100007041";
|
||||||
|
|
||||||
|
QCOMPARE(QByteArray::fromHex(matrixHex), result);
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex(matrixHex));
|
||||||
|
|
||||||
|
QCOMPARE(matrix, msg.testField());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtGuiTest::qVector2D()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QVector2DMessage,
|
||||||
|
QVector2D>(1, "QVector2D", "testField");
|
||||||
|
|
||||||
|
QVector2DMessage msg;
|
||||||
|
QVector2D vector(42, 24);
|
||||||
|
msg.setTestField(vector);
|
||||||
|
auto result = msg.serialize(&serializer);
|
||||||
|
|
||||||
|
QCOMPARE(QByteArray::fromHex("0a0a0d00002842150000c041"), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a0a0d0000c0411500002842"));
|
||||||
|
|
||||||
|
QCOMPARE(QVector2D(vector.y(), vector.x()), msg.testField());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtGuiTest::qVector3D()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QVector3DMessage,
|
||||||
|
QVector3D>(1, "QVector3D", "testField");
|
||||||
|
|
||||||
|
QVector3DMessage msg;
|
||||||
|
QVector3D vector(42, 24, 11);
|
||||||
|
msg.setTestField(vector);
|
||||||
|
auto result = msg.serialize(&serializer);
|
||||||
|
|
||||||
|
QCOMPARE(QByteArray::fromHex("0a0f0d00002842150000c0411d00003041"), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a0f0d0000c04115000030411d00002842"));
|
||||||
|
|
||||||
|
QCOMPARE(QVector3D(vector.y(), vector.z(), vector.x()), msg.testField());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtGuiTest::qVector4D()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QVector4DMessage,
|
||||||
|
QVector4D>(1, "QVector4D", "testField");
|
||||||
|
|
||||||
|
QVector4DMessage msg;
|
||||||
|
const QVector4D vector({24, 11, 42, 0});
|
||||||
|
msg.setTestField(vector);
|
||||||
|
auto result = msg.serialize(&serializer);
|
||||||
|
|
||||||
|
QCOMPARE(QByteArray::fromHex("0a140d0000c04115000030411d000028422500000000"), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, QByteArray::fromHex("0a0f0d0000c04115000030411d00002842"));
|
||||||
|
|
||||||
|
QCOMPARE(vector, msg.testField());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtGuiTest::qTransform()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QTransformMessage,
|
||||||
|
QTransform>(1, "QTransform", "testField");
|
||||||
|
|
||||||
|
QTransformMessage msg;
|
||||||
|
msg.setTestField(QTransform(0, 1, 2, 3, 4, 5, 6, 7, 8));
|
||||||
|
auto result = msg.serialize(&serializer);
|
||||||
|
const char * transformHex = "0a4a0a480000000000000000000000000000f03f0000000000000040000"
|
||||||
|
"00000000008400000000000001040000000000000144000000000000018"
|
||||||
|
"400000000000001c400000000000002040";
|
||||||
|
QCOMPARE(QByteArray::fromHex(transformHex), result);
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer,
|
||||||
|
QByteArray::fromHex("0a4a0a4800000000000020400000000000001c40000000000"
|
||||||
|
"0001840000000000000144000000000000010400000000000"
|
||||||
|
"0008400000000000000040000000000000f03f0000000000000000"));
|
||||||
|
QCOMPARE(QTransform(8, 7, 6, 5, 4, 3, 2, 1, 0), msg.testField());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtGuiTest::qQuaternion()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QQuaternionMessage, QQuaternion>(1, "QQuaternion",
|
||||||
|
"testField");
|
||||||
|
|
||||||
|
QQuaternionMessage msg;
|
||||||
|
const QQuaternion quater(14, 10, 24, 22);
|
||||||
|
msg.setTestField(quater);
|
||||||
|
auto result = msg.serialize(&serializer);
|
||||||
|
const char *hexValue = "0a140d0000604115000020411d0000c041250000b041";
|
||||||
|
QCOMPARE(QByteArray::fromHex(hexValue), result);
|
||||||
|
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer,
|
||||||
|
QByteArray::fromHex(hexValue));
|
||||||
|
|
||||||
|
QCOMPARE(quater, msg.testField());
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillTestImage(QImage &testImage)
|
||||||
|
{
|
||||||
|
testImage.fill(Qt::transparent);
|
||||||
|
QPainter painter;
|
||||||
|
painter.begin(&testImage);
|
||||||
|
QColor color_1(255, 0, 0, 255);
|
||||||
|
QColor color_2(0, 255, 0, 255);
|
||||||
|
QRect rect_1(0, 0, 100, 100);
|
||||||
|
QRect rect_2(50, 50, 10, 50);
|
||||||
|
painter.fillRect(rect_1, color_1);
|
||||||
|
painter.fillRect(rect_2, color_2);
|
||||||
|
painter.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtProtobufQtTypesQtGuiTest::qImage()
|
||||||
|
{
|
||||||
|
qProtobufAssertMessagePropertyRegistered<QImageMessage,
|
||||||
|
QImage>(1, "QImage", "testField");
|
||||||
|
|
||||||
|
QImageMessage msg;
|
||||||
|
QSize imgSize(200, 200);
|
||||||
|
QImage initialImage(imgSize, QImage::Format_RGBA64);
|
||||||
|
fillTestImage(initialImage);
|
||||||
|
|
||||||
|
msg.setTestField(initialImage);
|
||||||
|
QVERIFY(!msg.testField().isNull());
|
||||||
|
|
||||||
|
auto result = msg.serialize(&serializer);
|
||||||
|
msg.setTestField({});
|
||||||
|
msg.deserialize(&serializer, result);
|
||||||
|
QCOMPARE(initialImage, msg.testField());
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(QtProtobufQtTypesQtGuiTest)
|
||||||
|
#include "qtprotobufqttypesguitest.moc"
|
||||||
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package qtprotobufnamespace.qttypes.tests;
|
||||||
|
import "QtCore/QtCore.proto";
|
||||||
|
|
||||||
|
message QUrlMessage {
|
||||||
|
QtCore.QUrl testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QUuidMessage {
|
||||||
|
QtCore.QUuid testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QCharMessage {
|
||||||
|
QtCore.QChar testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QTimeMessage {
|
||||||
|
QtCore.QTime testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QDateMessage {
|
||||||
|
QtCore.QDate testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QDateTimeMessage {
|
||||||
|
QtCore.QDateTime testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QSizeMessage {
|
||||||
|
QtCore.QSize testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QSizeFMessage {
|
||||||
|
QtCore.QSizeF testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QPointMessage {
|
||||||
|
QtCore.QPoint testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QPointFMessage {
|
||||||
|
QtCore.QPointF testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QRectMessage {
|
||||||
|
QtCore.QRect testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QRectFMessage {
|
||||||
|
QtCore.QRectF testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QVersionNumberFMessage {
|
||||||
|
QtCore.QVersionNumber testField = 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package qtprotobufnamespace.qttypes.tests;
|
||||||
|
import "QtGui/QtGui.proto";
|
||||||
|
|
||||||
|
message QMatrix4x4Message {
|
||||||
|
QtGui.QMatrix4x4 testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QVector2DMessage {
|
||||||
|
QtGui.QVector2D testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QVector3DMessage {
|
||||||
|
QtGui.QVector3D testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QVector4DMessage {
|
||||||
|
QtGui.QVector4D testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QTransformMessage {
|
||||||
|
QtGui.QTransform testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QQuaternionMessage {
|
||||||
|
QtGui.QQuaternion testField = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QImageMessage {
|
||||||
|
QtGui.QImage testField = 1;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue