1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | #include <qmath.h> // qIsNan |
29 | #include <qvariant.h> |
30 | |
31 | #ifdef Q_OS_UNIX |
32 | # include <private/qcore_unix_p.h> |
33 | |
34 | static bool compareFileDescriptors(int fd1, int fd2) |
35 | { |
36 | QT_STATBUF st1, st2; |
37 | if (QT_FSTAT(fd: fd1, buf: &st1) == -1 || QT_FSTAT(fd: fd2, buf: &st2) == -1) { |
38 | perror(s: "fstat" ); |
39 | return false; |
40 | } |
41 | |
42 | return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino); |
43 | } |
44 | #endif |
45 | |
46 | typedef QMap<int, QString> IntStringMap; |
47 | typedef QMap<QString, QString> StringStringMap; |
48 | typedef QMap<QDBusObjectPath, QString> ObjectPathStringMap; |
49 | typedef QMap<qlonglong, QDateTime> LLDateTimeMap; |
50 | typedef QMap<QDBusSignature, QString> SignatureStringMap; |
51 | Q_DECLARE_METATYPE(StringStringMap) |
52 | Q_DECLARE_METATYPE(LLDateTimeMap) |
53 | |
54 | static bool compare(const QDBusUnixFileDescriptor &t1, const QDBusUnixFileDescriptor &t2) |
55 | { |
56 | int fd1 = t1.fileDescriptor(); |
57 | int fd2 = t2.fileDescriptor(); |
58 | if ((fd1 == -1 || fd2 == -1) && fd1 != fd2) { |
59 | // one is valid, the other isn't |
60 | return false; |
61 | } |
62 | |
63 | #ifdef Q_OS_UNIX |
64 | return compareFileDescriptors(fd1, fd2); |
65 | #else |
66 | return true; |
67 | #endif |
68 | } |
69 | |
70 | struct MyStruct |
71 | { |
72 | int i; |
73 | QString s; |
74 | |
75 | inline bool operator==(const MyStruct &other) const |
76 | { return i == other.i && s == other.s; } |
77 | }; |
78 | Q_DECLARE_METATYPE(MyStruct) |
79 | |
80 | QDBusArgument &operator<<(QDBusArgument &arg, const MyStruct &ms) |
81 | { |
82 | arg.beginStructure(); |
83 | arg << ms.i << ms.s; |
84 | arg.endStructure(); |
85 | return arg; |
86 | } |
87 | |
88 | const QDBusArgument &operator>>(const QDBusArgument &arg, MyStruct &ms) |
89 | { |
90 | arg.beginStructure(); |
91 | arg >> ms.i >> ms.s; |
92 | arg.endStructure(); |
93 | return arg; |
94 | } |
95 | |
96 | struct MyVariantMapStruct |
97 | { |
98 | QString s; |
99 | QVariantMap map; |
100 | |
101 | inline bool operator==(const MyVariantMapStruct &other) const |
102 | { return s == other.s && map == other.map; } |
103 | }; |
104 | Q_DECLARE_METATYPE(MyVariantMapStruct) |
105 | |
106 | QDBusArgument &operator<<(QDBusArgument &arg, const MyVariantMapStruct &ms) |
107 | { |
108 | arg.beginStructure(); |
109 | arg << ms.s << ms.map; |
110 | arg.endStructure(); |
111 | return arg; |
112 | } |
113 | |
114 | const QDBusArgument &operator>>(const QDBusArgument &arg, MyVariantMapStruct &ms) |
115 | { |
116 | arg.beginStructure(); |
117 | arg >> ms.s >> ms.map; |
118 | arg.endStructure(); |
119 | return arg; |
120 | } |
121 | |
122 | struct MyFileDescriptorStruct |
123 | { |
124 | QDBusUnixFileDescriptor fd; |
125 | |
126 | inline bool operator==(const MyFileDescriptorStruct &other) const |
127 | { return compare(t1: fd, t2: other.fd); } |
128 | }; |
129 | Q_DECLARE_METATYPE(MyFileDescriptorStruct) |
130 | |
131 | QDBusArgument &operator<<(QDBusArgument &arg, const MyFileDescriptorStruct &ms) |
132 | { |
133 | arg.beginStructure(); |
134 | arg << ms.fd; |
135 | arg.endStructure(); |
136 | return arg; |
137 | } |
138 | |
139 | const QDBusArgument &operator>>(const QDBusArgument &arg, MyFileDescriptorStruct &ms) |
140 | { |
141 | arg.beginStructure(); |
142 | arg >> ms.fd; |
143 | arg.endStructure(); |
144 | return arg; |
145 | } |
146 | |
147 | |
148 | void commonInit() |
149 | { |
150 | qDBusRegisterMetaType<QList<QDateTime> >(); |
151 | qDBusRegisterMetaType<QList<QStringList> >(); |
152 | qDBusRegisterMetaType<QList<QByteArray> >(); |
153 | qDBusRegisterMetaType<QList<QList<bool> > >(); |
154 | qDBusRegisterMetaType<QList<QList<short> > >(); |
155 | qDBusRegisterMetaType<QList<QList<ushort> > >(); |
156 | qDBusRegisterMetaType<QList<QList<int> > >(); |
157 | qDBusRegisterMetaType<QList<QList<uint> > >(); |
158 | qDBusRegisterMetaType<QList<QList<qlonglong> > >(); |
159 | qDBusRegisterMetaType<QList<QList<qulonglong> > >(); |
160 | qDBusRegisterMetaType<QList<QList<double> > >(); |
161 | qDBusRegisterMetaType<QList<QList<QDBusObjectPath> > >(); |
162 | qDBusRegisterMetaType<QList<QList<QDBusSignature> > >(); |
163 | qDBusRegisterMetaType<QList<QVariantList> >(); |
164 | |
165 | qDBusRegisterMetaType<QMap<int, QString> >(); |
166 | qDBusRegisterMetaType<QMap<QString, QString> >(); |
167 | qDBusRegisterMetaType<QMap<QDBusObjectPath, QString> >(); |
168 | qDBusRegisterMetaType<QMap<qlonglong, QDateTime> >(); |
169 | qDBusRegisterMetaType<QMap<QDBusSignature, QString> >(); |
170 | |
171 | qDBusRegisterMetaType<MyStruct>(); |
172 | qDBusRegisterMetaType<MyVariantMapStruct>(); |
173 | qDBusRegisterMetaType<QList<MyVariantMapStruct> >(); |
174 | qDBusRegisterMetaType<MyFileDescriptorStruct>(); |
175 | qDBusRegisterMetaType<QList<MyFileDescriptorStruct> >(); |
176 | } |
177 | #ifdef USE_PRIVATE_CODE |
178 | #include "private/qdbusintrospection_p.h" |
179 | |
180 | // just to make it easier: |
181 | typedef QDBusIntrospection::Interfaces InterfaceMap; |
182 | typedef QDBusIntrospection::Objects ObjectMap; |
183 | typedef QDBusIntrospection::Arguments ArgumentList; |
184 | typedef QDBusIntrospection::Annotations AnnotationsMap; |
185 | typedef QDBusIntrospection::Methods MethodMap; |
186 | typedef QDBusIntrospection::Signals SignalMap; |
187 | typedef QDBusIntrospection::Properties PropertyMap; |
188 | |
189 | Q_DECLARE_METATYPE(QDBusIntrospection::Method) |
190 | Q_DECLARE_METATYPE(QDBusIntrospection::Signal) |
191 | Q_DECLARE_METATYPE(QDBusIntrospection::Property) |
192 | Q_DECLARE_METATYPE(MethodMap) |
193 | Q_DECLARE_METATYPE(SignalMap) |
194 | Q_DECLARE_METATYPE(PropertyMap) |
195 | |
196 | inline QDBusIntrospection::Argument arg(const char* type, const char *name = 0) |
197 | { |
198 | QDBusIntrospection::Argument retval; |
199 | retval.type = QLatin1String(type); |
200 | retval.name = QLatin1String(name); |
201 | return retval; |
202 | } |
203 | |
204 | template<typename T> |
205 | inline QMap<QString, T>& operator<<(QMap<QString, T>& map, const T& m) |
206 | { map.insertMulti(m.name, m); return map; } |
207 | |
208 | inline const char* mapName(const MethodMap&) |
209 | { return "MethodMap" ; } |
210 | |
211 | inline const char* mapName(const SignalMap&) |
212 | { return "SignalMap" ; } |
213 | |
214 | inline const char* mapName(const PropertyMap&) |
215 | { return "PropertyMap" ; } |
216 | |
217 | QString printable(const QDBusIntrospection::Method& m) |
218 | { |
219 | QString result = "method " + m.name + "(" ; |
220 | foreach (QDBusIntrospection::Argument arg, m.inputArgs) |
221 | result += QString("in %1 %2, " ) |
222 | .arg(arg.type, arg.name); |
223 | foreach (QDBusIntrospection::Argument arg, m.outputArgs) |
224 | result += QString("out %1 %2, " ) |
225 | .arg(arg.type, arg.name); |
226 | AnnotationsMap::const_iterator it = m.annotations.begin(); |
227 | for ( ; it != m.annotations.end(); ++it) |
228 | result += QString("%1 \"%2\", " ).arg(it.key()).arg(it.value()); |
229 | |
230 | result += ")" ; |
231 | return result; |
232 | } |
233 | |
234 | QString printable(const QDBusIntrospection::Signal& s) |
235 | { |
236 | QString result = "signal " + s.name + "(" ; |
237 | foreach (QDBusIntrospection::Argument arg, s.outputArgs) |
238 | result += QString("out %1 %2, " ) |
239 | .arg(arg.type, arg.name); |
240 | AnnotationsMap::const_iterator it = s.annotations.begin(); |
241 | for ( ; it != s.annotations.end(); ++it) |
242 | result += QString("%1 \"%2\", " ).arg(it.key()).arg(it.value()); |
243 | |
244 | result += ")" ; |
245 | return result; |
246 | } |
247 | |
248 | QString printable(const QDBusIntrospection::Property& p) |
249 | { |
250 | QString result; |
251 | if (p.access == QDBusIntrospection::Property::Read) |
252 | result = "property read %1 %2, " ; |
253 | else if (p.access == QDBusIntrospection::Property::Write) |
254 | result = "property write %1 %2, " ; |
255 | else |
256 | result = "property readwrite %1 %2, " ; |
257 | result = result.arg(p.type, p.name); |
258 | |
259 | AnnotationsMap::const_iterator it = p.annotations.begin(); |
260 | for ( ; it != p.annotations.end(); ++it) |
261 | result += QString("%1 \"%2\", " ).arg(it.key()).arg(it.value()); |
262 | |
263 | return result; |
264 | } |
265 | |
266 | template<typename T> |
267 | char* printableMap(const QMap<QString, T>& map) |
268 | { |
269 | QString contents = "\n" ; |
270 | typename QMap<QString, T>::const_iterator it = map.begin(); |
271 | for ( ; it != map.end(); ++it) { |
272 | if (it.key() != it.value().name) |
273 | contents += it.value().name + ":" ; |
274 | contents += printable(it.value()); |
275 | contents += ";\n" ; |
276 | } |
277 | |
278 | QString result("%1(size = %2): {%3}" ); |
279 | return qstrdup(qPrintable(result |
280 | .arg(mapName(map)) |
281 | .arg(map.size()) |
282 | .arg(contents))); |
283 | } |
284 | |
285 | QT_BEGIN_NAMESPACE |
286 | namespace QTest { |
287 | template<> |
288 | inline char* toString(const MethodMap& map) |
289 | { |
290 | return printableMap(map); |
291 | } |
292 | |
293 | template<> |
294 | inline char* toString(const SignalMap& map) |
295 | { |
296 | return printableMap(map); |
297 | } |
298 | |
299 | template<> |
300 | inline char* toString(const PropertyMap& map) |
301 | { |
302 | return printableMap(map); |
303 | } |
304 | } |
305 | QT_END_NAMESPACE |
306 | |
307 | #endif |
308 | |
309 | template<typename T> |
310 | bool compare(const T &t1, const T &t2) |
311 | { return t1 == t2; } |
312 | |
313 | template<> |
314 | bool compare(const QVariant &v1, const QVariant &v2); |
315 | |
316 | bool compare(double d1, double d2) |
317 | { |
318 | if (qIsNaN(d: d1) && qIsNaN(d: d2)) |
319 | return true; |
320 | return d1 == d2; |
321 | } |
322 | |
323 | template<> |
324 | bool compare(const QString &s1, const QString &s2) |
325 | { |
326 | if (s1.isEmpty() && s2.isEmpty()) |
327 | return true; // regardless of whether one of them is null |
328 | return s1 == s2; |
329 | } |
330 | |
331 | template<> |
332 | bool compare(const QByteArray &ba1, const QByteArray &ba2) |
333 | { |
334 | if (ba1.isEmpty() && ba2.isEmpty()) |
335 | return true; // regardless of whether one of them is null |
336 | return ba1 == ba2; |
337 | } |
338 | |
339 | template<> |
340 | bool compare(const QDBusVariant &s1, const QDBusVariant &s2) |
341 | { |
342 | return compare(v1: s1.variant(), v2: s2.variant()); |
343 | } |
344 | |
345 | template<typename T> |
346 | bool compare(const QList<T> &l1, const QList<T> &l2) |
347 | { |
348 | if (l1.count() != l2.count()) |
349 | return false; |
350 | |
351 | typename QList<T>::ConstIterator it1 = l1.constBegin(); |
352 | typename QList<T>::ConstIterator it2 = l2.constBegin(); |
353 | typename QList<T>::ConstIterator end = l1.constEnd(); |
354 | for ( ; it1 != end; ++it1, ++it2) |
355 | if (!compare(*it1, *it2)) |
356 | return false; |
357 | return true; |
358 | } |
359 | |
360 | template<typename Key, typename T> |
361 | bool compare(const QMap<Key, T> &m1, const QMap<Key, T> &m2) |
362 | { |
363 | if (m1.count() != m2.size()) |
364 | return false; |
365 | typename QMap<Key, T>::ConstIterator i1 = m1.constBegin(); |
366 | typename QMap<Key, T>::ConstIterator end = m1.constEnd(); |
367 | for ( ; i1 != end; ++i1) { |
368 | typename QMap<Key, T>::ConstIterator i2 = m2.find(i1.key()); |
369 | if (i2 == m2.constEnd()) |
370 | return false; |
371 | if (!compare(*i1, *i2)) |
372 | return false; |
373 | } |
374 | return true; |
375 | } |
376 | |
377 | template<typename T> |
378 | inline bool compare(const QDBusArgument &arg, const QVariant &v2, T * = 0) |
379 | { |
380 | return compare(qdbus_cast<T>(arg), qvariant_cast<T>(v2)); |
381 | } |
382 | |
383 | bool compareToArgument(const QDBusArgument &arg, const QVariant &v2) |
384 | { |
385 | if (arg.currentSignature() != QDBusMetaType::typeToSignature(type: v2.userType())) |
386 | return false; |
387 | |
388 | // try to demarshall the arg according to v2 |
389 | switch (v2.userType()) |
390 | { |
391 | case QVariant::Bool: |
392 | return compare<bool>(arg, v2); |
393 | case QMetaType::UChar: |
394 | return compare<uchar>(arg, v2); |
395 | case QMetaType::Short: |
396 | return compare<short>(arg, v2); |
397 | case QMetaType::UShort: |
398 | return compare<ushort>(arg, v2); |
399 | case QVariant::Int: |
400 | return compare<int>(arg, v2); |
401 | case QVariant::UInt: |
402 | return compare<uint>(arg, v2); |
403 | case QVariant::LongLong: |
404 | return compare<qlonglong>(arg, v2); |
405 | case QVariant::ULongLong: |
406 | return compare<qulonglong>(arg, v2); |
407 | case QVariant::Double: |
408 | return compare<double>(arg, v2); |
409 | case QVariant::String: |
410 | return compare<QString>(arg, v2); |
411 | case QVariant::ByteArray: |
412 | return compare<QByteArray>(arg, v2); |
413 | case QVariant::List: |
414 | return compare<QVariantList>(arg, v2); |
415 | case QVariant::Map: |
416 | return compare<QVariantMap>(arg, v2); |
417 | case QVariant::Point: |
418 | return compare<QPoint>(arg, v2); |
419 | case QVariant::PointF: |
420 | return compare<QPointF>(arg, v2); |
421 | case QVariant::Size: |
422 | return compare<QSize>(arg, v2); |
423 | case QVariant::SizeF: |
424 | return compare<QSizeF>(arg, v2); |
425 | case QVariant::Line: |
426 | return compare<QLine>(arg, v2); |
427 | case QVariant::LineF: |
428 | return compare<QLineF>(arg, v2); |
429 | case QVariant::Rect: |
430 | return compare<QRect>(arg, v2); |
431 | case QVariant::RectF: |
432 | return compare<QRectF>(arg, v2); |
433 | case QVariant::Date: |
434 | return compare<QDate>(arg, v2); |
435 | case QVariant::Time: |
436 | return compare<QTime>(arg, v2); |
437 | case QVariant::DateTime: |
438 | return compare<QDateTime>(arg, v2); |
439 | default: |
440 | int id = v2.userType(); |
441 | if (id == qMetaTypeId<QDBusObjectPath>()) |
442 | return compare<QDBusObjectPath>(arg, v2); |
443 | else if (id == qMetaTypeId<QDBusSignature>()) |
444 | return compare<QDBusSignature>(arg, v2); |
445 | else if (id == qMetaTypeId<QDBusVariant>()) |
446 | return compare<QDBusVariant>(arg, v2); |
447 | else if (id == qMetaTypeId<QList<bool> >()) |
448 | return compare<QList<bool> >(arg, v2); |
449 | else if (id == qMetaTypeId<QList<short> >()) |
450 | return compare<QList<short> >(arg, v2); |
451 | else if (id == qMetaTypeId<QList<ushort> >()) |
452 | return compare<QList<ushort> >(arg, v2); |
453 | else if (id == qMetaTypeId<QList<int> >()) |
454 | return compare<QList<int> >(arg, v2); |
455 | else if (id == qMetaTypeId<QList<uint> >()) |
456 | return compare<QList<uint> >(arg, v2); |
457 | else if (id == qMetaTypeId<QList<qlonglong> >()) |
458 | return compare<QList<qlonglong> >(arg, v2); |
459 | else if (id == qMetaTypeId<QList<qulonglong> >()) |
460 | return compare<QList<qulonglong> >(arg, v2); |
461 | else if (id == qMetaTypeId<QList<double> >()) |
462 | return compare<QList<double> >(arg, v2); |
463 | else if (id == qMetaTypeId<QList<QDBusObjectPath> >()) |
464 | return compare<QList<QDBusObjectPath> >(arg, v2); |
465 | else if (id == qMetaTypeId<QList<QDBusSignature> >()) |
466 | return compare<QList<QDBusSignature> >(arg, v2); |
467 | else if (id == qMetaTypeId<QList<QDBusUnixFileDescriptor> >()) |
468 | return compare<QList<QDBusUnixFileDescriptor> >(arg, v2); |
469 | else if (id == qMetaTypeId<QList<QDateTime> >()) |
470 | return compare<QList<QDateTime> >(arg, v2); |
471 | |
472 | else if (id == qMetaTypeId<QMap<int, QString> >()) |
473 | return compare<QMap<int, QString> >(arg, v2); |
474 | else if (id == qMetaTypeId<QMap<QString, QString> >()) |
475 | return compare<QMap<QString, QString> >(arg, v2); |
476 | else if (id == qMetaTypeId<QMap<QDBusObjectPath, QString> >()) |
477 | return compare<QMap<QDBusObjectPath, QString> >(arg, v2); |
478 | else if (id == qMetaTypeId<QMap<qlonglong, QDateTime> >()) |
479 | return compare<QMap<qlonglong, QDateTime> >(arg, v2); |
480 | else if (id == qMetaTypeId<QMap<QDBusSignature, QString> >()) |
481 | return compare<QMap<QDBusSignature, QString> >(arg, v2); |
482 | |
483 | else if (id == qMetaTypeId<QList<QByteArray> >()) |
484 | return compare<QList<QByteArray> >(arg, v2); |
485 | else if (id == qMetaTypeId<QList<QList<bool> > >()) |
486 | return compare<QList<QList<bool> > >(arg, v2); |
487 | else if (id == qMetaTypeId<QList<QList<short> > >()) |
488 | return compare<QList<QList<short> > >(arg, v2); |
489 | else if (id == qMetaTypeId<QList<QList<ushort> > >()) |
490 | return compare<QList<QList<ushort> > >(arg, v2); |
491 | else if (id == qMetaTypeId<QList<QList<int> > >()) |
492 | return compare<QList<QList<int> > >(arg, v2); |
493 | else if (id == qMetaTypeId<QList<QList<uint> > >()) |
494 | return compare<QList<QList<uint> > >(arg, v2); |
495 | else if (id == qMetaTypeId<QList<QList<qlonglong> > >()) |
496 | return compare<QList<QList<qlonglong> > >(arg, v2); |
497 | else if (id == qMetaTypeId<QList<QList<qulonglong> > >()) |
498 | return compare<QList<QList<qulonglong> > >(arg, v2); |
499 | else if (id == qMetaTypeId<QList<QList<double> > >()) |
500 | return compare<QList<QList<double> > >(arg, v2); |
501 | else if (id == qMetaTypeId<QList<QStringList> >()) |
502 | return compare<QList<QStringList> >(arg, v2); |
503 | else if (id == qMetaTypeId<QList<QVariantList> >()) |
504 | return compare<QList<QVariantList> >(arg, v2); |
505 | |
506 | else if (id == qMetaTypeId<MyStruct>()) |
507 | return compare<MyStruct>(arg, v2); |
508 | |
509 | else if (id == qMetaTypeId<MyVariantMapStruct>()) |
510 | return compare<MyVariantMapStruct>(arg, v2); |
511 | else if (id == qMetaTypeId<QList<MyVariantMapStruct> >()) |
512 | return compare<QList<MyVariantMapStruct> >(arg, v2); |
513 | else if (id == qMetaTypeId<MyFileDescriptorStruct>()) |
514 | return compare<MyFileDescriptorStruct>(arg, v2); |
515 | else if (id == qMetaTypeId<QList<MyFileDescriptorStruct> >()) |
516 | return compare<QList<MyFileDescriptorStruct> >(arg, v2); |
517 | } |
518 | |
519 | qWarning() << "Unexpected QVariant type" << v2.userType() |
520 | << QByteArray(QDBusMetaType::typeToSignature(type: v2.userType())) |
521 | << QMetaType::typeName(type: v2.userType()); |
522 | return false; |
523 | } |
524 | |
525 | template<> bool compare(const QVariant &v1, const QVariant &v2) |
526 | { |
527 | // v1 is the one that came from the network |
528 | // v2 is the one that we sent |
529 | |
530 | if (v1.userType() == qMetaTypeId<QDBusArgument>()) |
531 | // this argument has been left un-demarshalled |
532 | return compareToArgument(arg: qvariant_cast<QDBusArgument>(v: v1), v2); |
533 | |
534 | if (v1.userType() != v2.userType()) |
535 | return false; |
536 | |
537 | int id = v1.userType(); |
538 | if (id == QVariant::List) |
539 | return compare(l1: v1.toList(), l2: v2.toList()); |
540 | |
541 | else if (id == QVariant::Map) |
542 | return compare(m1: v1.toMap(), m2: v2.toMap()); |
543 | |
544 | else if (id == QVariant::String) |
545 | return compare(s1: v1.toString(), s2: v2.toString()); |
546 | |
547 | else if (id == QVariant::ByteArray) |
548 | return compare(ba1: v1.toByteArray(), ba2: v2.toByteArray()); |
549 | |
550 | else if (id == QMetaType::UChar) |
551 | return qvariant_cast<uchar>(v: v1) == qvariant_cast<uchar>(v: v2); |
552 | |
553 | else if (id == QMetaType::Short) |
554 | return qvariant_cast<short>(v: v1) == qvariant_cast<short>(v: v2); |
555 | |
556 | else if (id == QMetaType::UShort) |
557 | return qvariant_cast<ushort>(v: v1) == qvariant_cast<ushort>(v: v2); |
558 | |
559 | else if (id == qMetaTypeId<QDBusObjectPath>()) |
560 | return qvariant_cast<QDBusObjectPath>(v: v1).path() == qvariant_cast<QDBusObjectPath>(v: v2).path(); |
561 | |
562 | else if (id == qMetaTypeId<QDBusSignature>()) |
563 | return qvariant_cast<QDBusSignature>(v: v1).signature() == qvariant_cast<QDBusSignature>(v: v2).signature(); |
564 | |
565 | else if (id == qMetaTypeId<QDBusUnixFileDescriptor>()) |
566 | return compare(t1: qvariant_cast<QDBusUnixFileDescriptor>(v: v1), t2: qvariant_cast<QDBusUnixFileDescriptor>(v: v2)); |
567 | |
568 | else if (id == qMetaTypeId<QDBusVariant>()) |
569 | return compare(v1: qvariant_cast<QDBusVariant>(v: v1).variant(), v2: qvariant_cast<QDBusVariant>(v: v2).variant()); |
570 | |
571 | else if (id == qMetaTypeId<QVariant>()) |
572 | return compare(v1: qvariant_cast<QVariant>(v: v1), v2: qvariant_cast<QVariant>(v: v2)); |
573 | |
574 | else if (id == qMetaTypeId<QList<bool> >()) |
575 | return qvariant_cast<QList<bool> >(v: v1) == qvariant_cast<QList<bool> >(v: v2); |
576 | |
577 | else if (id == qMetaTypeId<QList<short> >()) |
578 | return qvariant_cast<QList<short> >(v: v1) == qvariant_cast<QList<short> >(v: v2); |
579 | |
580 | else if (id == qMetaTypeId<QList<ushort> >()) |
581 | return qvariant_cast<QList<ushort> >(v: v1) == qvariant_cast<QList<ushort> >(v: v2); |
582 | |
583 | else if (id == qMetaTypeId<QList<int> >()) |
584 | return qvariant_cast<QList<int> >(v: v1) == qvariant_cast<QList<int> >(v: v2); |
585 | |
586 | else if (id == qMetaTypeId<QList<uint> >()) |
587 | return qvariant_cast<QList<uint> >(v: v1) == qvariant_cast<QList<uint> >(v: v2); |
588 | |
589 | else if (id == qMetaTypeId<QList<qlonglong> >()) |
590 | return qvariant_cast<QList<qlonglong> >(v: v1) == qvariant_cast<QList<qlonglong> >(v: v2); |
591 | |
592 | else if (id == qMetaTypeId<QList<qulonglong> >()) |
593 | return qvariant_cast<QList<qulonglong> >(v: v2) == qvariant_cast<QList<qulonglong> >(v: v2); |
594 | |
595 | else if (id == qMetaTypeId<QList<double> >()) |
596 | return compare(l1: qvariant_cast<QList<double> >(v: v1), l2: qvariant_cast<QList<double> >(v: v2)); |
597 | |
598 | else if (id == qMetaTypeId<QVariant>()) |
599 | return compare(v1: qvariant_cast<QVariant>(v: v1), v2: qvariant_cast<QVariant>(v: v2)); |
600 | |
601 | else if (id == qMetaTypeId<QList<QList<bool> > >()) |
602 | return qvariant_cast<QList<QList<bool> > >(v: v1) == qvariant_cast<QList<QList<bool> > >(v: v2); |
603 | |
604 | else if (id == qMetaTypeId<QList<QList<short> > >()) |
605 | return qvariant_cast<QList<QList<short> > >(v: v1) == qvariant_cast<QList<QList<short> > >(v: v2); |
606 | |
607 | else if (id == qMetaTypeId<QList<QList<ushort> > >()) |
608 | return qvariant_cast<QList<QList<ushort> > >(v: v1) == qvariant_cast<QList<QList<ushort> > >(v: v2); |
609 | |
610 | else if (id == qMetaTypeId<QList<QList<int> > >()) |
611 | return qvariant_cast<QList<QList<int> > >(v: v1) == qvariant_cast<QList<QList<int> > >(v: v2); |
612 | |
613 | else if (id == qMetaTypeId<QList<QList<uint> > >()) |
614 | return qvariant_cast<QList<QList<uint> > >(v: v1) == qvariant_cast<QList<QList<uint> > >(v: v2); |
615 | |
616 | else if (id == qMetaTypeId<QList<QList<qlonglong> > >()) |
617 | return qvariant_cast<QList<QList<qlonglong> > >(v: v1) == qvariant_cast<QList<QList<qlonglong> > >(v: v2); |
618 | |
619 | else if (id == qMetaTypeId<QList<QList<qulonglong> > >()) |
620 | return qvariant_cast<QList<QList<qulonglong> > >(v: v1) == qvariant_cast<QList<QList<qulonglong> > >(v: v2); |
621 | |
622 | else if (id == qMetaTypeId<QList<QList<double> > >()) |
623 | return compare(l1: qvariant_cast<QList<QList<double> > >(v: v1), l2: qvariant_cast<QList<QList<double> > >(v: v2)); |
624 | |
625 | else if (id == qMetaTypeId<QList<QStringList> >()) |
626 | return qvariant_cast<QList<QStringList> >(v: v1) == qvariant_cast<QList<QStringList> >(v: v2); |
627 | |
628 | else if (id == qMetaTypeId<QList<QByteArray> >()) |
629 | return qvariant_cast<QList<QByteArray> >(v: v1) == qvariant_cast<QList<QByteArray> >(v: v2); |
630 | |
631 | else if (id == qMetaTypeId<QList<QVariantList> >()) |
632 | return compare(l1: qvariant_cast<QList<QVariantList> >(v: v1), l2: qvariant_cast<QList<QVariantList> >(v: v2)); |
633 | |
634 | else if (id == qMetaTypeId<QMap<int, QString> >()) |
635 | return compare(m1: qvariant_cast<QMap<int, QString> >(v: v1), m2: qvariant_cast<QMap<int, QString> >(v: v2)); |
636 | |
637 | else if (id == qMetaTypeId<QMap<QString, QString> >()) // ssmap |
638 | return compare(m1: qvariant_cast<QMap<QString, QString> >(v: v1), m2: qvariant_cast<QMap<QString, QString> >(v: v2)); |
639 | |
640 | else if (id == qMetaTypeId<QMap<QDBusObjectPath, QString> >()) |
641 | return compare(m1: qvariant_cast<QMap<QDBusObjectPath, QString> >(v: v1), m2: qvariant_cast<QMap<QDBusObjectPath, QString> >(v: v2)); |
642 | |
643 | else if (id == qMetaTypeId<QMap<qlonglong, QDateTime> >()) // lldtmap |
644 | return compare(m1: qvariant_cast<QMap<qint64, QDateTime> >(v: v1), m2: qvariant_cast<QMap<qint64, QDateTime> >(v: v2)); |
645 | |
646 | else if (id == qMetaTypeId<QMap<QDBusSignature, QString> >()) |
647 | return compare(m1: qvariant_cast<QMap<QDBusSignature, QString> >(v: v1), m2: qvariant_cast<QMap<QDBusSignature, QString> >(v: v2)); |
648 | |
649 | else if (id == qMetaTypeId<MyStruct>()) // (is) |
650 | return qvariant_cast<MyStruct>(v: v1) == qvariant_cast<MyStruct>(v: v2); |
651 | |
652 | else if (id < int(QVariant::UserType)) // yes, v1.type() |
653 | // QVariant can compare |
654 | return v1 == v2; |
655 | |
656 | else { |
657 | qWarning() << "Please write a comparison case for type" << v1.typeName(); |
658 | return false; // unknown type |
659 | } |
660 | } |
661 | |