/src/qtbase/src/dbus/qdbusmarshaller.cpp
Line | Count | Source |
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 | | // Qt-Security score:critical reason:data-parser |
4 | | |
5 | | #include "qdbusargument_p.h" |
6 | | #include "qdbusconnection.h" |
7 | | #include "qdbusmetatype_p.h" |
8 | | #include "qdbusutil_p.h" |
9 | | |
10 | | #ifndef QT_NO_DBUS |
11 | | |
12 | | QT_BEGIN_NAMESPACE |
13 | | |
14 | | using namespace Qt::StringLiterals; |
15 | | |
16 | | static void qIterAppend(DBusMessageIter *it, QByteArray *ba, int type, const void *arg) |
17 | 0 | { |
18 | 0 | if (ba) |
19 | 0 | *ba += char(type); |
20 | 0 | else |
21 | 0 | q_dbus_message_iter_append_basic(it, type, arg); |
22 | 0 | } |
23 | | |
24 | | QDBusMarshaller::~QDBusMarshaller() |
25 | 0 | { |
26 | 0 | close(); |
27 | 0 | } |
28 | | |
29 | | void QDBusMarshaller::unregisteredTypeError(QMetaType id) |
30 | 0 | { |
31 | 0 | const char *name = id.name(); |
32 | 0 | qWarning("QDBusMarshaller: type '%s' (%d) is not registered with D-Bus. " |
33 | 0 | "Use qDBusRegisterMetaType to register it", |
34 | 0 | name ? name : "", id.id()); |
35 | 0 | error("Unregistered type %1 passed in arguments"_L1 |
36 | 0 | .arg(QLatin1StringView(id.name()))); |
37 | 0 | } |
38 | | |
39 | | inline QString QDBusMarshaller::currentSignature() |
40 | 0 | { |
41 | 0 | if (message) |
42 | 0 | return QString::fromUtf8(q_dbus_message_get_signature(message)); |
43 | 0 | return QString(); |
44 | 0 | } |
45 | | |
46 | | inline void QDBusMarshaller::append(uchar arg) |
47 | 0 | { |
48 | 0 | if (!skipSignature) |
49 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_BYTE, &arg); |
50 | 0 | } |
51 | | |
52 | | inline void QDBusMarshaller::append(bool arg) |
53 | 0 | { |
54 | 0 | dbus_bool_t cast = arg; |
55 | 0 | if (!skipSignature) |
56 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_BOOLEAN, &cast); |
57 | 0 | } |
58 | | |
59 | | inline void QDBusMarshaller::append(short arg) |
60 | 0 | { |
61 | 0 | if (!skipSignature) |
62 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_INT16, &arg); |
63 | 0 | } |
64 | | |
65 | | inline void QDBusMarshaller::append(ushort arg) |
66 | 0 | { |
67 | 0 | if (!skipSignature) |
68 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_UINT16, &arg); |
69 | 0 | } |
70 | | |
71 | | inline void QDBusMarshaller::append(int arg) |
72 | 0 | { |
73 | 0 | if (!skipSignature) |
74 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_INT32, &arg); |
75 | 0 | } |
76 | | |
77 | | inline void QDBusMarshaller::append(uint arg) |
78 | 0 | { |
79 | 0 | if (!skipSignature) |
80 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_UINT32, &arg); |
81 | 0 | } |
82 | | |
83 | | inline void QDBusMarshaller::append(qlonglong arg) |
84 | 0 | { |
85 | 0 | if (!skipSignature) |
86 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_INT64, &arg); |
87 | 0 | } |
88 | | |
89 | | inline void QDBusMarshaller::append(qulonglong arg) |
90 | 0 | { |
91 | 0 | if (!skipSignature) |
92 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_UINT64, &arg); |
93 | 0 | } |
94 | | |
95 | | inline void QDBusMarshaller::append(double arg) |
96 | 0 | { |
97 | 0 | if (!skipSignature) |
98 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_DOUBLE, &arg); |
99 | 0 | } |
100 | | |
101 | | void QDBusMarshaller::append(const QString &arg) |
102 | 0 | { |
103 | 0 | QByteArray data = arg.toUtf8(); |
104 | 0 | const char *cdata = data.constData(); |
105 | 0 | if (!skipSignature) |
106 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_STRING, &cdata); |
107 | 0 | } |
108 | | |
109 | | inline void QDBusMarshaller::append(const QDBusObjectPath &arg) |
110 | 0 | { |
111 | 0 | QByteArray data = arg.path().toUtf8(); |
112 | 0 | if (!ba && data.isEmpty()) { |
113 | 0 | error("Invalid object path passed in arguments"_L1); |
114 | 0 | } else { |
115 | 0 | const char *cdata = data.constData(); |
116 | 0 | if (!skipSignature) |
117 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_OBJECT_PATH, &cdata); |
118 | 0 | } |
119 | 0 | } |
120 | | |
121 | | inline void QDBusMarshaller::append(const QDBusSignature &arg) |
122 | 0 | { |
123 | 0 | QByteArray data = arg.signature().toUtf8(); |
124 | 0 | if (!ba && data.isNull()) { |
125 | 0 | error("Invalid signature passed in arguments"_L1); |
126 | 0 | } else { |
127 | 0 | const char *cdata = data.constData(); |
128 | 0 | if (!skipSignature) |
129 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_SIGNATURE, &cdata); |
130 | 0 | } |
131 | 0 | } |
132 | | |
133 | | inline void QDBusMarshaller::append(const QDBusUnixFileDescriptor &arg) |
134 | 0 | { |
135 | 0 | int fd = arg.fileDescriptor(); |
136 | 0 | if (!ba && fd == -1) { |
137 | 0 | error("Invalid file descriptor passed in arguments"_L1); |
138 | 0 | } else { |
139 | 0 | if (!skipSignature) |
140 | 0 | qIterAppend(&iterator, ba, DBUS_TYPE_UNIX_FD, &fd); |
141 | 0 | } |
142 | 0 | } |
143 | | |
144 | | inline void QDBusMarshaller::append(const QByteArray &arg) |
145 | 0 | { |
146 | 0 | if (ba) { |
147 | 0 | if (!skipSignature) |
148 | 0 | *ba += DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING; |
149 | 0 | return; |
150 | 0 | } |
151 | | |
152 | 0 | const char* cdata = arg.constData(); |
153 | 0 | DBusMessageIter subiterator; |
154 | 0 | q_dbus_message_iter_open_container(&iterator, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, |
155 | 0 | &subiterator); |
156 | 0 | q_dbus_message_iter_append_fixed_array(&subiterator, DBUS_TYPE_BYTE, &cdata, arg.size()); |
157 | 0 | q_dbus_message_iter_close_container(&iterator, &subiterator); |
158 | 0 | } |
159 | | |
160 | | inline bool QDBusMarshaller::append(const QDBusVariant &arg) |
161 | 0 | { |
162 | 0 | if (ba) { |
163 | 0 | if (!skipSignature) |
164 | 0 | *ba += DBUS_TYPE_VARIANT_AS_STRING; |
165 | 0 | return true; |
166 | 0 | } |
167 | | |
168 | 0 | const QVariant &value = arg.variant(); |
169 | 0 | QMetaType id = value.metaType(); |
170 | 0 | if (!id.isValid()) { |
171 | 0 | qWarning("QDBusMarshaller: cannot add a null QDBusVariant"); |
172 | 0 | error("Invalid QVariant passed in arguments"_L1); |
173 | 0 | return false; |
174 | 0 | } |
175 | | |
176 | 0 | QByteArray tmpSignature; |
177 | 0 | const char *signature = nullptr; |
178 | 0 | if (id == QDBusMetaTypeId::argument()) { |
179 | | // take the signature from the QDBusArgument object we're marshalling |
180 | 0 | tmpSignature = |
181 | 0 | qvariant_cast<QDBusArgument>(value).currentSignature().toLatin1(); |
182 | 0 | signature = tmpSignature.constData(); |
183 | 0 | } else { |
184 | | // take the signatuer from the metatype we're marshalling |
185 | 0 | signature = QDBusMetaType::typeToSignature(id); |
186 | 0 | } |
187 | 0 | if (!signature) { |
188 | 0 | unregisteredTypeError(id); |
189 | 0 | return false; |
190 | 0 | } |
191 | | |
192 | 0 | QDBusMarshaller sub(capabilities); |
193 | 0 | open(sub, DBUS_TYPE_VARIANT, signature); |
194 | 0 | bool isOk = sub.appendVariantInternal(value); |
195 | | // don't call sub.close(): it auto-closes |
196 | |
|
197 | 0 | return isOk; |
198 | 0 | } |
199 | | |
200 | | inline void QDBusMarshaller::append(const QStringList &arg) |
201 | 0 | { |
202 | 0 | if (ba) { |
203 | 0 | if (!skipSignature) |
204 | 0 | *ba += DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING; |
205 | 0 | return; |
206 | 0 | } |
207 | | |
208 | 0 | QDBusMarshaller sub(capabilities); |
209 | 0 | open(sub, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING); |
210 | 0 | for (const QString &s : arg) |
211 | 0 | sub.append(s); |
212 | | // don't call sub.close(): it auto-closes |
213 | 0 | } |
214 | | |
215 | | inline QDBusMarshaller *QDBusMarshaller::beginStructure() |
216 | 0 | { |
217 | 0 | return beginCommon(DBUS_TYPE_STRUCT, nullptr); |
218 | 0 | } |
219 | | |
220 | | inline QDBusMarshaller *QDBusMarshaller::beginArray(QMetaType id) |
221 | 0 | { |
222 | 0 | const char *signature = QDBusMetaType::typeToSignature(id); |
223 | 0 | if (!signature) { |
224 | 0 | unregisteredTypeError(id); |
225 | 0 | return this; |
226 | 0 | } |
227 | | |
228 | 0 | return beginCommon(DBUS_TYPE_ARRAY, signature); |
229 | 0 | } |
230 | | |
231 | | inline QDBusMarshaller *QDBusMarshaller::beginMap(QMetaType kid, QMetaType vid) |
232 | 0 | { |
233 | 0 | const char *ksignature = QDBusMetaType::typeToSignature(kid); |
234 | 0 | if (!ksignature) { |
235 | 0 | unregisteredTypeError(kid); |
236 | 0 | return this; |
237 | 0 | } |
238 | 0 | if (ksignature[1] != 0 || !QDBusUtil::isValidBasicType(*ksignature)) { |
239 | 0 | QT_WARNING_PUSH |
240 | 0 | QT_WARNING_DISABLE_GCC("-Wformat-overflow") |
241 | 0 | qWarning("QDBusMarshaller: type '%s' (%d) cannot be used as the key type in a D-Bus map.", |
242 | 0 | kid.name(), kid.id()); |
243 | 0 | QT_WARNING_POP |
244 | 0 | error("Type %1 passed in arguments cannot be used as a key in a map"_L1 |
245 | 0 | .arg(QLatin1StringView(kid.name()))); |
246 | 0 | return this; |
247 | 0 | } |
248 | | |
249 | 0 | const char *vsignature = QDBusMetaType::typeToSignature(vid); |
250 | 0 | if (!vsignature) { |
251 | 0 | unregisteredTypeError(vid); |
252 | 0 | return this; |
253 | 0 | } |
254 | | |
255 | 0 | QByteArray signature; |
256 | 0 | signature = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING; |
257 | 0 | signature += ksignature; |
258 | 0 | signature += vsignature; |
259 | 0 | signature += DBUS_DICT_ENTRY_END_CHAR_AS_STRING; |
260 | 0 | return beginCommon(DBUS_TYPE_ARRAY, signature); |
261 | 0 | } |
262 | | |
263 | | inline QDBusMarshaller *QDBusMarshaller::beginMapEntry() |
264 | 0 | { |
265 | 0 | return beginCommon(DBUS_TYPE_DICT_ENTRY, nullptr); |
266 | 0 | } |
267 | | |
268 | | void QDBusMarshaller::open(QDBusMarshaller &sub, int code, const char *signature) |
269 | 0 | { |
270 | 0 | sub.parent = this; |
271 | 0 | sub.ba = ba; |
272 | 0 | sub.ok = true; |
273 | 0 | sub.capabilities = capabilities; |
274 | 0 | sub.skipSignature = skipSignature; |
275 | |
|
276 | 0 | if (ba) { |
277 | 0 | if (!skipSignature) { |
278 | 0 | switch (code) { |
279 | 0 | case DBUS_TYPE_ARRAY: |
280 | 0 | *ba += char(code); |
281 | 0 | *ba += signature; |
282 | 0 | Q_FALLTHROUGH(); |
283 | |
|
284 | 0 | case DBUS_TYPE_DICT_ENTRY: |
285 | 0 | sub.closeCode = 0; |
286 | 0 | sub.skipSignature = true; |
287 | 0 | break; |
288 | | |
289 | 0 | case DBUS_TYPE_STRUCT: |
290 | 0 | *ba += DBUS_STRUCT_BEGIN_CHAR; |
291 | 0 | sub.closeCode = DBUS_STRUCT_END_CHAR; |
292 | 0 | break; |
293 | 0 | } |
294 | 0 | } |
295 | 0 | } else { |
296 | 0 | q_dbus_message_iter_open_container(&iterator, code, signature, &sub.iterator); |
297 | 0 | } |
298 | 0 | } |
299 | | |
300 | | QDBusMarshaller *QDBusMarshaller::beginCommon(int code, const char *signature) |
301 | 0 | { |
302 | 0 | QDBusMarshaller *d = new QDBusMarshaller(capabilities); |
303 | 0 | open(*d, code, signature); |
304 | 0 | return d; |
305 | 0 | } |
306 | | |
307 | | inline QDBusMarshaller *QDBusMarshaller::endStructure() |
308 | 0 | { return endCommon(); } |
309 | | |
310 | | inline QDBusMarshaller *QDBusMarshaller::endArray() |
311 | 0 | { return endCommon(); } |
312 | | |
313 | | inline QDBusMarshaller *QDBusMarshaller::endMap() |
314 | 0 | { return endCommon(); } |
315 | | |
316 | | inline QDBusMarshaller *QDBusMarshaller::endMapEntry() |
317 | 0 | { return endCommon(); } |
318 | | |
319 | | QDBusMarshaller *QDBusMarshaller::endCommon() |
320 | 0 | { |
321 | 0 | QDBusMarshaller *retval = parent; |
322 | 0 | delete this; |
323 | 0 | return retval; |
324 | 0 | } |
325 | | |
326 | | void QDBusMarshaller::close() |
327 | 0 | { |
328 | 0 | if (ba) { |
329 | 0 | if (!skipSignature && closeCode) |
330 | 0 | *ba += closeCode; |
331 | 0 | } else if (parent) { |
332 | 0 | q_dbus_message_iter_close_container(&parent->iterator, &iterator); |
333 | 0 | } |
334 | 0 | } |
335 | | |
336 | | void QDBusMarshaller::error(const QString &msg) |
337 | 0 | { |
338 | 0 | ok = false; |
339 | 0 | if (parent) |
340 | 0 | parent->error(msg); |
341 | 0 | else |
342 | 0 | errorString = msg; |
343 | 0 | } |
344 | | |
345 | | bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) |
346 | 0 | { |
347 | 0 | QMetaType id = arg.metaType(); |
348 | 0 | if (!id.isValid()) { |
349 | 0 | qWarning("QDBusMarshaller: cannot add an invalid QVariant"); |
350 | 0 | error("Invalid QVariant passed in arguments"_L1); |
351 | 0 | return false; |
352 | 0 | } |
353 | | |
354 | | // intercept QDBusArgument parameters here |
355 | 0 | if (id == QDBusMetaTypeId::argument()) { |
356 | 0 | QDBusArgument dbusargument = qvariant_cast<QDBusArgument>(arg); |
357 | 0 | QDBusArgumentPrivate *d = QDBusArgumentPrivate::d(dbusargument); |
358 | 0 | if (!d->message) |
359 | 0 | return false; // can't append this one... |
360 | | |
361 | 0 | QDBusDemarshaller demarshaller(capabilities); |
362 | 0 | demarshaller.message = q_dbus_message_ref(d->message); |
363 | |
|
364 | 0 | if (d->direction == Direction::Demarshalling) { |
365 | | // it's demarshalling; just copy |
366 | 0 | demarshaller.iterator = static_cast<QDBusDemarshaller *>(d)->iterator; |
367 | 0 | } else { |
368 | | // it's marshalling; start over |
369 | 0 | if (!q_dbus_message_iter_init(demarshaller.message, &demarshaller.iterator)) |
370 | 0 | return false; // error! |
371 | 0 | } |
372 | | |
373 | 0 | return appendCrossMarshalling(&demarshaller); |
374 | 0 | } |
375 | | |
376 | 0 | const char *signature = QDBusMetaType::typeToSignature(id); |
377 | 0 | if (!signature) { |
378 | 0 | unregisteredTypeError(id); |
379 | 0 | return false; |
380 | 0 | } |
381 | | |
382 | 0 | switch (*signature) { |
383 | 0 | #ifdef __OPTIMIZE__ |
384 | 0 | case DBUS_TYPE_BYTE: |
385 | 0 | case DBUS_TYPE_INT16: |
386 | 0 | case DBUS_TYPE_UINT16: |
387 | 0 | case DBUS_TYPE_INT32: |
388 | 0 | case DBUS_TYPE_UINT32: |
389 | 0 | case DBUS_TYPE_INT64: |
390 | 0 | case DBUS_TYPE_UINT64: |
391 | 0 | case DBUS_TYPE_DOUBLE: |
392 | 0 | qIterAppend(&iterator, ba, *signature, arg.constData()); |
393 | 0 | return true; |
394 | 0 | case DBUS_TYPE_BOOLEAN: |
395 | 0 | append( arg.toBool() ); |
396 | 0 | return true; |
397 | | #else |
398 | | case DBUS_TYPE_BYTE: |
399 | | append( qvariant_cast<uchar>(arg) ); |
400 | | return true; |
401 | | case DBUS_TYPE_BOOLEAN: |
402 | | append( arg.toBool() ); |
403 | | return true; |
404 | | case DBUS_TYPE_INT16: |
405 | | append( qvariant_cast<short>(arg) ); |
406 | | return true; |
407 | | case DBUS_TYPE_UINT16: |
408 | | append( qvariant_cast<ushort>(arg) ); |
409 | | return true; |
410 | | case DBUS_TYPE_INT32: |
411 | | append( static_cast<dbus_int32_t>(arg.toInt()) ); |
412 | | return true; |
413 | | case DBUS_TYPE_UINT32: |
414 | | append( static_cast<dbus_uint32_t>(arg.toUInt()) ); |
415 | | return true; |
416 | | case DBUS_TYPE_INT64: |
417 | | append( arg.toLongLong() ); |
418 | | return true; |
419 | | case DBUS_TYPE_UINT64: |
420 | | append( arg.toULongLong() ); |
421 | | return true; |
422 | | case DBUS_TYPE_DOUBLE: |
423 | | append( arg.toDouble() ); |
424 | | return true; |
425 | | #endif |
426 | | |
427 | 0 | case DBUS_TYPE_STRING: |
428 | 0 | append( arg.toString() ); |
429 | 0 | return true; |
430 | 0 | case DBUS_TYPE_OBJECT_PATH: |
431 | 0 | append( qvariant_cast<QDBusObjectPath>(arg) ); |
432 | 0 | return true; |
433 | 0 | case DBUS_TYPE_SIGNATURE: |
434 | 0 | append( qvariant_cast<QDBusSignature>(arg) ); |
435 | 0 | return true; |
436 | | |
437 | | // compound types: |
438 | 0 | case DBUS_TYPE_VARIANT: |
439 | | // nested QVariant |
440 | 0 | return append( qvariant_cast<QDBusVariant>(arg) ); |
441 | | |
442 | 0 | case DBUS_TYPE_ARRAY: |
443 | | // could be many things |
444 | | // find out what kind of array it is |
445 | 0 | switch (arg.metaType().id()) { |
446 | 0 | case QMetaType::QStringList: |
447 | 0 | append( arg.toStringList() ); |
448 | 0 | return true; |
449 | | |
450 | 0 | case QMetaType::QByteArray: |
451 | 0 | append( arg.toByteArray() ); |
452 | 0 | return true; |
453 | | |
454 | 0 | default: |
455 | 0 | ; |
456 | 0 | } |
457 | 0 | Q_FALLTHROUGH(); |
458 | |
|
459 | 0 | case DBUS_TYPE_STRUCT: |
460 | 0 | case DBUS_STRUCT_BEGIN_CHAR: |
461 | 0 | return appendRegisteredType( arg ); |
462 | | |
463 | 0 | case DBUS_TYPE_DICT_ENTRY: |
464 | 0 | case DBUS_DICT_ENTRY_BEGIN_CHAR: |
465 | 0 | qFatal("QDBusMarshaller::appendVariantInternal got a DICT_ENTRY!"); |
466 | 0 | return false; |
467 | | |
468 | 0 | case DBUS_TYPE_UNIX_FD: |
469 | 0 | if (capabilities & QDBusConnection::UnixFileDescriptorPassing || ba) { |
470 | 0 | append(qvariant_cast<QDBusUnixFileDescriptor>(arg)); |
471 | 0 | return true; |
472 | 0 | } |
473 | 0 | Q_FALLTHROUGH(); |
474 | |
|
475 | 0 | default: |
476 | 0 | qWarning("QDBusMarshaller::appendVariantInternal: Found unknown D-Bus type '%s'", |
477 | 0 | signature); |
478 | 0 | return false; |
479 | 0 | } |
480 | | |
481 | 0 | return true; |
482 | 0 | } |
483 | | |
484 | | bool QDBusMarshaller::appendRegisteredType(const QVariant &arg) |
485 | 0 | { |
486 | 0 | ref.ref(); // reference up |
487 | 0 | QDBusArgument self(QDBusArgumentPrivate::create(this)); |
488 | 0 | return QDBusMetaType::marshall(self, arg.metaType(), arg.constData()); |
489 | 0 | } |
490 | | |
491 | | bool QDBusMarshaller::appendCrossMarshalling(QDBusDemarshaller *demarshaller) |
492 | 0 | { |
493 | 0 | int code = q_dbus_message_iter_get_arg_type(&demarshaller->iterator); |
494 | 0 | if (QDBusUtil::isValidBasicType(code)) { |
495 | | // easy: just append |
496 | | // do exactly like the D-Bus docs suggest |
497 | | // (see apidocs for q_dbus_message_iter_get_basic) |
498 | |
|
499 | 0 | qlonglong value; |
500 | 0 | q_dbus_message_iter_get_basic(&demarshaller->iterator, &value); |
501 | 0 | q_dbus_message_iter_next(&demarshaller->iterator); |
502 | 0 | q_dbus_message_iter_append_basic(&iterator, code, &value); |
503 | 0 | return true; |
504 | 0 | } |
505 | | |
506 | 0 | if (code == DBUS_TYPE_ARRAY) { |
507 | 0 | int element = q_dbus_message_iter_get_element_type(&demarshaller->iterator); |
508 | 0 | if (QDBusUtil::isValidFixedType(element) && element != DBUS_TYPE_UNIX_FD) { |
509 | | // another optimization: fixed size arrays |
510 | | // code is exactly like QDBusDemarshaller::toByteArray |
511 | 0 | DBusMessageIter sub; |
512 | 0 | q_dbus_message_iter_recurse(&demarshaller->iterator, &sub); |
513 | 0 | q_dbus_message_iter_next(&demarshaller->iterator); |
514 | 0 | int len; |
515 | 0 | void* data; |
516 | 0 | q_dbus_message_iter_get_fixed_array(&sub,&data,&len); |
517 | |
|
518 | 0 | char signature[2] = { char(element), 0 }; |
519 | 0 | q_dbus_message_iter_open_container(&iterator, DBUS_TYPE_ARRAY, signature, &sub); |
520 | 0 | q_dbus_message_iter_append_fixed_array(&sub, element, &data, len); |
521 | 0 | q_dbus_message_iter_close_container(&iterator, &sub); |
522 | |
|
523 | 0 | return true; |
524 | 0 | } |
525 | 0 | } |
526 | | |
527 | | // We have to recurse |
528 | 0 | QDBusDemarshaller *drecursed = demarshaller->beginCommon(); |
529 | |
|
530 | 0 | QDBusMarshaller mrecursed(capabilities); // create on the stack makes it autoclose |
531 | 0 | QByteArray subSignature; |
532 | 0 | const char *sig = nullptr; |
533 | 0 | if (code == DBUS_TYPE_VARIANT || code == DBUS_TYPE_ARRAY) { |
534 | 0 | subSignature = drecursed->currentSignature().toLatin1(); |
535 | 0 | if (!subSignature.isEmpty()) |
536 | 0 | sig = subSignature.constData(); |
537 | 0 | } |
538 | 0 | open(mrecursed, code, sig); |
539 | |
|
540 | 0 | while (!drecursed->atEnd()) { |
541 | 0 | if (!mrecursed.appendCrossMarshalling(drecursed)) { |
542 | 0 | delete drecursed; |
543 | 0 | return false; |
544 | 0 | } |
545 | 0 | } |
546 | | |
547 | 0 | delete drecursed; |
548 | 0 | return true; |
549 | 0 | } |
550 | | |
551 | | QT_END_NAMESPACE |
552 | | |
553 | | #endif // QT_NO_DBUS |