Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdbusargument.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qdbusargument.h"
5#include "qdbusargument_p.h"
6
7#include <qatomic.h>
8#include <qbytearray.h>
9#include <qdatetime.h>
10#include <qline.h>
11#include <qlist.h>
12#include <qmap.h>
13#include <qstring.h>
14#include <qstringlist.h>
15#include <qrect.h>
16#include <qtimezone.h>
17#include <qvariant.h>
18
19#include "qdbusmetatype_p.h"
20#include "qdbusutil_p.h"
21
22#ifndef QT_NO_DBUS
23
25
27
29{
30 if (message)
31 q_dbus_message_unref(message);
32}
33
35{
36 if (!qdbus_loadLibDBus())
37 return "";
38
39 QByteArray signature;
41 marshaller->ba = &signature;
42
43 // run it
44 QVariant v{QMetaType(id)};
46 QDBusMetaType::marshall(arg, v.metaType(), v.constData());
47 arg.d = nullptr;
48
49 // delete it
50 bool ok = marshaller->ok;
51 delete marshaller;
52
53 if (signature.isEmpty() || !ok || !QDBusUtil::isValidSingleSignature(QString::fromLatin1(signature))) {
54 qWarning("QDBusMarshaller: type '%s' produces invalid D-Bus signature '%s' "
55 "(Did you forget to call beginStructure() ?)",
56 QMetaType(id).name(), signature.isEmpty() ? "<empty>" : signature.constData());
57 return "";
58 } else if ((signature.at(0) != DBUS_TYPE_ARRAY && signature.at(0) != DBUS_STRUCT_BEGIN_CHAR) ||
59 (signature.at(0) == DBUS_TYPE_ARRAY && (signature.at(1) == DBUS_TYPE_BYTE ||
60 signature.at(1) == DBUS_TYPE_STRING))) {
61 qWarning("QDBusMarshaller: type '%s' attempts to redefine basic D-Bus type '%s' (%s) "
62 "(Did you forget to call beginStructure() ?)",
63 QMetaType(id).name(), signature.constData(),
65 return "";
66 }
67 return signature;
68}
69
71{
72 if (!d)
73 return false;
74 if (d->direction == Marshalling) {
75 if (!d->marshaller()->ok)
76 return false;
77
78 if (d->message && d->ref.loadRelaxed() != 1) {
79 QDBusMarshaller *dd = new QDBusMarshaller(d->capabilities);
80 dd->message = q_dbus_message_copy(d->message);
81 q_dbus_message_iter_init_append(dd->message, &dd->iterator);
82
83 if (!d->ref.deref())
84 delete d;
85 d = dd;
86 }
87 return true;
88 }
89
90#ifdef QT_DEBUG
91 qFatal("QDBusArgument: write from a read-only object");
92#else
93 qWarning("QDBusArgument: write from a read-only object");
94#endif
95 return false;
96}
97
99{
100 if (!d)
101 return false;
102 if (d->direction == Demarshalling)
103 return true;
104
105#ifdef QT_DEBUG
106 qFatal("QDBusArgument: read from a write-only object");
107#else
108 qWarning("QDBusArgument: read from a write-only object");
109#endif
110
111 return false;
112}
113
115{
116 if (!checkRead(d))
117 return false; // don't bother
118
119 if (d->ref.loadRelaxed() == 1)
120 return true; // no need to detach
121
122 QDBusDemarshaller *dd = new QDBusDemarshaller(d->capabilities);
123 dd->message = q_dbus_message_ref(d->message);
124 dd->iterator = static_cast<QDBusDemarshaller*>(d)->iterator;
125
126 if (!d->ref.deref())
127 delete d;
128 d = dd;
129 return true;
130}
131
257{
258 if (!qdbus_loadLibDBus()) {
259 d = nullptr;
260 return;
261 }
262
263 QDBusMarshaller *dd = new QDBusMarshaller(0);
264 d = dd;
265
266 // create a new message with any type, we won't sent it anyways
267 dd->message = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
268 q_dbus_message_iter_init_append(dd->message, &dd->iterator);
269}
270
279 : d(other.d)
280{
281 if (d)
282 d->ref.ref();
283}
284
289 : d(dd)
290{
291}
292
301{
303 return *this;
304}
305
311{
312 if (d && !d->ref.deref())
313 delete d;
314}
315
320{
322 d->marshaller()->append(arg);
323 return *this;
324}
325
331{
333 d->marshaller()->append(arg);
334 return *this;
335}
336
342{
344 d->marshaller()->append(arg);
345 return *this;
346}
347
353{
355 d->marshaller()->append(arg);
356 return *this;
357}
358
364{
366 d->marshaller()->append(arg);
367 return *this;
368}
369
375{
377 d->marshaller()->append(arg);
378 return *this;
379}
380
386{
388 d->marshaller()->append(arg);
389 return *this;
390}
391
397{
399 d->marshaller()->append(arg);
400 return *this;
401}
402
409{
411 d->marshaller()->append(arg);
412 return *this;
413}
414
421{
423 d->marshaller()->append(arg);
424 return *this;
425}
426
434{
436 d->marshaller()->append(arg);
437 return *this;
438}
439
447{
449 d->marshaller()->append(arg);
450 return *this;
451}
452
461{
463 d->marshaller()->append(arg);
464 return *this;
465}
466
475{
477 d->marshaller()->append(arg);
478 return *this;
479}
480
493{
495 d->marshaller()->append(arg);
496 return *this;
497}
498
511{
513 d->marshaller()->append(arg);
514 return *this;
515}
516
526{
529}
530
537{
538 if (!d)
539 return QString();
541 return d->demarshaller()->currentSignature();
542 else
543 return d->marshaller()->currentSignature();
544}
545
556{
557 if (!d)
558 return UnknownType;
560 return d->demarshaller()->currentType();
561 return UnknownType;
562}
563
569{
571 arg = d->demarshaller()->toByte();
572 else
573 arg = 0;
574 return *this;
575}
576
583{
585 arg = d->demarshaller()->toBool();
586 else
587 arg = false;
588 return *this;
589}
590
597{
599 arg = d->demarshaller()->toUShort();
600 else
601 arg = 0;
602 return *this;
603}
604
611{
613 arg = d->demarshaller()->toShort();
614 else
615 arg = 0;
616 return *this;
617}
618
625{
627 arg = d->demarshaller()->toInt();
628 else
629 arg = 0;
630 return *this;
631}
632
639{
641 arg = d->demarshaller()->toUInt();
642 else
643 arg = 0;
644 return *this;
645}
646
653{
656 else
657 arg = 0;
658 return *this;
659}
660
667{
670 else
671 arg = 0;
672 return *this;
673}
674
681{
683 arg = d->demarshaller()->toDouble();
684 else
685 arg = 0;
686 return *this;
687}
688
695{
697 arg = d->demarshaller()->toString();
698 return *this;
699}
700
708{
711 return *this;
712}
713
721{
724 return *this;
725}
726
735{
738 return *this;
739}
740
755{
757 arg = d->demarshaller()->toVariant();
758 return *this;
759}
760
773{
776 return *this;
777}
778
791{
794 return *this;
795}
796
813{
816}
817
825{
827 d = d->marshaller()->endStructure();
828}
829
848{
850 d = d->marshaller()->beginArray(id);
851}
852
860{
862 d = d->marshaller()->endArray();
863}
864
884void QDBusArgument::beginMap(QMetaType keyMetaType, QMetaType valueMetaType)
885{
887 d = d->marshaller()->beginMap(keyMetaType, valueMetaType);
888}
889
897{
899 d = d->marshaller()->endMap();
900}
901
912{
914 d = d->marshaller()->beginMapEntry();
915}
916
924{
926 d = d->marshaller()->endMapEntry();
927}
928
940{
943}
944
952{
955}
956
976{
978 d = d->demarshaller()->beginArray();
979}
980
988{
990 d = d->demarshaller()->endArray();
991}
992
1009{
1011 d = d->demarshaller()->beginMap();
1012}
1013
1021{
1023 d = d->demarshaller()->endMap();
1024}
1025
1035{
1037 d = d->demarshaller()->beginMapEntry();
1038}
1039
1047{
1049 d = d->demarshaller()->endMapEntry();
1050}
1051
1058{
1060 return d->demarshaller()->atEnd();
1061
1062 return true; // at least, stop reading
1063}
1064
1086{
1088 return d->demarshaller()->toVariantInternal();
1089
1090 return QVariant();
1091}
1092
1094
1095// for optimization purposes, we include the marshallers here
1096#include "qdbusmarshaller.cpp"
1097#include "qdbusdemarshaller.cpp"
1098
1100
1101// QDBusArgument operators
1102
1104{
1105 QDBusVariant dbv;
1106 a >> dbv;
1107 v = dbv.variant();
1108 return a;
1109}
1110
1111// QVariant types
1112#ifndef QDBUS_NO_SPECIALTYPES
1114{
1115 int y, m, d;
1116 a.beginStructure();
1117 a >> y >> m >> d;
1118 a.endStructure();
1119
1120 if (y != 0 && m != 0 && d != 0)
1121 date.setDate(y, m, d);
1122 else
1123 date = QDate();
1124 return a;
1125}
1126
1128{
1129 a.beginStructure();
1130 if (date.isValid())
1131 a << date.year() << date.month() << date.day();
1132 else
1133 a << 0 << 0 << 0;
1134 a.endStructure();
1135 return a;
1136}
1137
1139{
1140 int h, m, s, ms;
1141 a.beginStructure();
1142 a >> h >> m >> s >> ms;
1143 a.endStructure();
1144
1145 if (h < 0)
1146 time = QTime();
1147 else
1148 time.setHMS(h, m, s, ms);
1149 return a;
1150}
1151
1153{
1154 a.beginStructure();
1155 if (time.isValid())
1156 a << time.hour() << time.minute() << time.second() << time.msec();
1157 else
1158 a << -1 << -1 << -1 << -1;
1159 a.endStructure();
1160 return a;
1161}
1162
1164{
1165 QDate date;
1166 QTime time;
1167 int timespec;
1168
1169 a.beginStructure();
1170 a >> date >> time >> timespec;
1171 a.endStructure();
1172
1173 switch (Qt::TimeSpec(timespec)) {
1174 case Qt::TimeZone:
1175 qWarning("Restoring zoned date-time without zone info");
1176 Q_FALLTHROUGH(); // Treat as local time.
1177 case Qt::LocalTime:
1178 dt = QDateTime(date, time);
1179 break;
1180 case Qt::OffsetFromUTC:
1181 qWarning("Restoring date-time without its offset");
1182 Q_FALLTHROUGH(); // Use zero offset
1183 case Qt::UTC:
1185 break;
1186 }
1187 return a;
1188}
1189
1191{
1192 // TODO: Only viable for UTC and LocalTime
1193 if (Q_UNLIKELY(dt.timeSpec() != Qt::UTC && dt.timeSpec() != Qt::LocalTime)) {
1194 qWarning() << "Serializing a date-time with unsupported time-spec" << dt.timeSpec();
1195 // Coerce to a supported timespec. When a time-zone is the current
1196 // system zone, local time is suitable; so map all time-zones to local,
1197 // plain offsets to UTC.
1198 return a << (dt.timeSpec() == Qt::OffsetFromUTC ? dt.toUTC() : dt.toLocalTime());
1199 }
1200 a.beginStructure();
1201 a << dt.date() << dt.time() << int(dt.timeSpec());
1202 a.endStructure();
1203 return a;
1204}
1205
1207{
1208 int x, y, width, height;
1209 a.beginStructure();
1210 a >> x >> y >> width >> height;
1211 a.endStructure();
1212
1213 rect.setRect(x, y, width, height);
1214 return a;
1215}
1216
1218{
1219 a.beginStructure();
1220 a << rect.x() << rect.y() << rect.width() << rect.height();
1221 a.endStructure();
1222
1223 return a;
1224}
1225
1227{
1228 double x, y, width, height;
1229 a.beginStructure();
1230 a >> x >> y >> width >> height;
1231 a.endStructure();
1232
1233 rect.setRect(qreal(x), qreal(y), qreal(width), qreal(height));
1234 return a;
1235}
1236
1238{
1239 a.beginStructure();
1240 a << double(rect.x()) << double(rect.y()) << double(rect.width()) << double(rect.height());
1241 a.endStructure();
1242
1243 return a;
1244}
1245
1247{
1248 a.beginStructure();
1249 a >> size.rwidth() >> size.rheight();
1250 a.endStructure();
1251
1252 return a;
1253}
1254
1256{
1257 a.beginStructure();
1258 a << size.width() << size.height();
1259 a.endStructure();
1260
1261 return a;
1262}
1263
1265{
1266 double width, height;
1267 a.beginStructure();
1268 a >> width >> height;
1269 a.endStructure();
1270
1271 size.setWidth(qreal(width));
1272 size.setHeight(qreal(height));
1273 return a;
1274}
1275
1277{
1278 a.beginStructure();
1279 a << double(size.width()) << double(size.height());
1280 a.endStructure();
1281
1282 return a;
1283}
1284
1286{
1287 a.beginStructure();
1288 a >> pt.rx() >> pt.ry();
1289 a.endStructure();
1290
1291 return a;
1292}
1293
1295{
1296 a.beginStructure();
1297 a << pt.x() << pt.y();
1298 a.endStructure();
1299
1300 return a;
1301}
1302
1304{
1305 double x, y;
1306 a.beginStructure();
1307 a >> x >> y;
1308 a.endStructure();
1309
1310 pt.setX(qreal(x));
1311 pt.setY(qreal(y));
1312 return a;
1313}
1314
1316{
1317 a.beginStructure();
1318 a << double(pt.x()) << double(pt.y());
1319 a.endStructure();
1320
1321 return a;
1322}
1323
1325{
1326 QPoint p1, p2;
1327 a.beginStructure();
1328 a >> p1 >> p2;
1329 a.endStructure();
1330
1331 line = QLine(p1, p2);
1332 return a;
1333}
1334
1336{
1337 a.beginStructure();
1338 a << line.p1() << line.p2();
1339 a.endStructure();
1340
1341 return a;
1342}
1343
1345{
1346 QPointF p1, p2;
1347 a.beginStructure();
1348 a >> p1 >> p2;
1349 a.endStructure();
1350
1351 line = QLineF(p1, p2);
1352 return a;
1353}
1354
1356{
1357 a.beginStructure();
1358 a << line.p1() << line.p2();
1359 a.endStructure();
1360
1361 return a;
1362}
1363#endif
1364
1372
1373#endif // QT_NO_DBUS
bool ref() noexcept
bool deref() noexcept
\inmodule QtCore
Definition qbytearray.h:57
QDBusDemarshaller * demarshaller()
static bool checkReadAndDetach(QDBusArgumentPrivate *&d)
static QByteArray createSignature(int id)
enum QDBusArgumentPrivate::Direction direction
QDBusMarshaller * marshaller()
static bool checkRead(QDBusArgumentPrivate *d)
static bool checkWrite(QDBusArgumentPrivate *&d)
\inmodule QtDBus
QDBusArgument()
Constructs an empty QDBusArgument argument.
void appendVariant(const QVariant &v)
QDBusArgument & operator=(QDBusArgument &&other) noexcept
QDBusArgument & operator<<(uchar arg)
Appends the primitive value arg of type {BYTE} to the D-Bus stream.
void beginMapEntry()
Opens a D-Bus map entry suitable for appending the key and value entries.
void endArray()
Closes a D-Bus array opened with beginArray().
void beginMap() const
Recurses into the D-Bus map to allow extraction of the map's elements.
QDBusArgumentPrivate * d
QVariant asVariant() const
void endMapEntry()
Closes a D-Bus map entry opened with beginMapEntry().
~QDBusArgument()
Disposes of the resources associated with this QDBusArgument object.
void beginArray() const
Recurses into the D-Bus array to allow extraction of the array elements.
void beginStructure()
Opens a new D-Bus structure suitable for appending new arguments.
void endMap()
Closes a D-Bus map opened with beginMap().
const QDBusArgument & operator>>(uchar &arg) const
Extracts one D-Bus primitive argument of type {BYTE} from the D-Bus stream and puts it into arg.
bool atEnd() const
Returns true if there are no more elements to be extracted from this QDBusArgument.
QString currentSignature() const
void endStructure()
Closes a D-Bus structure opened with beginStructure().
ElementType currentType() const
QDBusDemarshaller * beginArray()
QDBusDemarshaller * endArray()
QDBusDemarshaller * endStructure()
QDBusDemarshaller * endMapEntry()
QDBusSignature toSignature()
QDBusUnixFileDescriptor toUnixFileDescriptor()
QDBusObjectPath toObjectPath()
QDBusDemarshaller * beginStructure()
QDBusDemarshaller * beginMapEntry()
DBusMessageIter iterator
QDBusDemarshaller * endMap()
QDBusDemarshaller * beginMap()
QDBusArgument::ElementType currentType()
void append(uchar arg)
QDBusMarshaller * endMapEntry()
QDBusMarshaller * endStructure()
QString currentSignature()
bool appendVariantInternal(const QVariant &arg)
QDBusMarshaller * beginMap(QMetaType kid, QMetaType vid)
QDBusMarshaller * endMap()
QDBusMarshaller * beginMapEntry()
QDBusMarshaller * beginStructure()
QDBusMarshaller * beginArray(QMetaType id)
DBusMessageIter iterator
QDBusMarshaller * endArray()
static bool marshall(QDBusArgument &, QMetaType id, const void *data)
static QMetaType signatureToMetaType(const char *signature)
\inmodule QtDBus
\inmodule QtDBus
\inmodule QtDBus
QVariant variant() const
Returns this D-Bus variant as a QVariant object.
\inmodule QtCore\reentrant
Definition qdatetime.h:257
QDateTime toUTC() const
Returns a copy of this datetime converted to UTC.
QTime time() const
Returns the time part of the datetime.
QDateTime toLocalTime() const
Returns a copy of this datetime converted to local time.
Qt::TimeSpec timeSpec() const
Returns the time specification of the datetime.
QDate date() const
Returns the date part of the datetime.
\inmodule QtCore \reentrant
Definition qdatetime.h:27
constexpr bool isValid() const
Returns true if this date is valid; otherwise returns false.
Definition qdatetime.h:86
int month() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int day() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int year() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool setDate(int year, int month, int day)
\inmodule QtCore
Definition qline.h:182
\inmodule QtCore
Definition qline.h:18
\inmodule QtCore
Definition qmetatype.h:320
constexpr const char * name() const
Definition qmetatype.h:2650
\inmodule QtCore\reentrant
Definition qpoint.h:214
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:333
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:338
constexpr void setY(qreal y) noexcept
Sets the y coordinate of this point to the given finite y coordinate.
Definition qpoint.h:348
constexpr void setX(qreal x) noexcept
Sets the x coordinate of this point to the given finite x coordinate.
Definition qpoint.h:343
\inmodule QtCore\reentrant
Definition qpoint.h:23
constexpr int & ry() noexcept
Returns a reference to the y coordinate of this point.
Definition qpoint.h:157
constexpr int & rx() noexcept
Returns a reference to the x coordinate of this point.
Definition qpoint.h:152
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:127
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:132
\inmodule QtCore\reentrant
Definition qrect.h:483
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore
Definition qsize.h:207
\inmodule QtCore
Definition qsize.h:25
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
\inmodule QtCore \reentrant
Definition qdatetime.h:189
int hour() const
Returns the hour part (0 to 23) of the time.
int minute() const
Returns the minute part (0 to 59) of the time.
bool isValid() const
Returns true if the time is valid; otherwise returns false.
int msec() const
Returns the millisecond part (0 to 999) of the time.
bool setHMS(int h, int m, int s, int ms=0)
Sets the time to hour h, minute m, seconds s and milliseconds ms.
int second() const
Returns the second part (0 to 59) of the time.
\inmodule QtCore
Definition qvariant.h:64
#define DBUS_MESSAGE_TYPE_METHOD_CALL
#define DBUS_TYPE_BYTE
#define DBUS_STRUCT_BEGIN_CHAR
#define DBUS_TYPE_STRING
#define DBUS_TYPE_ARRAY
QPixmap p2
QPixmap p1
[0]
QDate date
[1]
rect
[4]
bool isValidSingleSignature(const QString &signature)
Returns true if signature is a valid D-Bus type signature for exactly one full type.
Combined button and popup list for selecting options.
@ UTC
@ OffsetFromUTC
@ LocalTime
@ TimeZone
QT_WARNING_POP void qAtomicAssign(T *&d, T *x)
This is a helper for the assignment operators of implicitly shared classes.
Definition qatomic.h:180
#define Q_FALLTHROUGH()
#define Q_UNLIKELY(x)
bool qdbus_loadLibDBus()
QT_END_NAMESPACE QT_BEGIN_NAMESPACE const QDBusArgument & operator>>(const QDBusArgument &a, QVariant &v)
QDBusArgument & operator<<(QDBusArgument &a, const QDate &date)
#define qWarning
Definition qlogging.h:162
#define qFatal
Definition qlogging.h:164
#define QT_IMPL_METATYPE_EXTERN(TYPE)
Definition qmetatype.h:1369
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
const GLfloat * m
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei width
GLuint GLsizei const GLchar * message
GLuint name
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLdouble s
[6]
Definition qopenglext.h:235
SSL_CTX int(*) void arg)
unsigned char uchar
Definition qtypes.h:27
quint64 qulonglong
Definition qtypes.h:59
unsigned int uint
Definition qtypes.h:29
unsigned short ushort
Definition qtypes.h:28
double qreal
Definition qtypes.h:92
qint64 qlonglong
Definition qtypes.h:58
QSharedPointer< T > other(t)
[5]