QDBusMessagePrivate::~QDBusMessagePrivate() { if (msg) q_dbus_message_unref(msg); if (reply) q_dbus_message_unref(reply); delete localReply; }
QT_BEGIN_NAMESPACE QDBusArgumentPrivate::~QDBusArgumentPrivate() { if (message) q_dbus_message_unref(message); }
QT_BEGIN_NAMESPACE QDBusArgumentPrivate::~QDBusArgumentPrivate() { #ifndef DUMMY_DBUS if (message) q_dbus_message_unref(message); #endif }
QDBusMessage QDBusMessagePrivate::makeLocal(const QDBusConnectionPrivate &conn, const QDBusMessage &asSent) { // simulate the message being sent to the bus and then received back // the only field that the bus sets when delivering the message // (as opposed to the message as we send it), is the sender // so we simply set the sender to our unique name // determine if we are carrying any complex types QString computedSignature; QVariantList::ConstIterator it = asSent.d_ptr->arguments.constBegin(); QVariantList::ConstIterator end = asSent.d_ptr->arguments.constEnd(); for ( ; it != end; ++it) { int id = it->userType(); const char *signature = QDBusMetaType::typeToSignature(id); if ((id != QVariant::StringList && id != QVariant::ByteArray && qstrlen(signature) != 1) || id == qMetaTypeId<QDBusVariant>()) { // yes, we are // we must marshall and demarshall again so as to create QDBusArgument // entries for the complex types QDBusError error; DBusMessage *message = toDBusMessage(asSent, conn.capabilities, &error); if (!message) { // failed to marshall, so it's a call error return QDBusMessage::createError(error); } q_dbus_message_set_sender(message, conn.baseService.toUtf8()); QDBusMessage retval = fromDBusMessage(message, conn.capabilities); retval.d_ptr->localMessage = true; q_dbus_message_unref(message); if (retval.d_ptr->service.isEmpty()) retval.d_ptr->service = conn.baseService; return retval; } else { computedSignature += QLatin1String(signature); } } // no complex types seen // optimize by using the variant list itself QDBusMessage retval; QDBusMessagePrivate *d = retval.d_ptr; d->arguments = asSent.d_ptr->arguments; d->path = asSent.d_ptr->path; d->interface = asSent.d_ptr->interface; d->name = asSent.d_ptr->name; d->message = asSent.d_ptr->message; d->type = asSent.d_ptr->type; d->service = conn.baseService; d->signature = computedSignature; d->localMessage = true; return retval; }
/*! \internal Constructs a DBusMessage object from \a message. The returned value must be de-referenced with q_dbus_message_unref. The \a capabilities flags indicates which capabilities to use. The \a error object is set to indicate the error if anything went wrong with the marshalling. Usually, this error message will be placed in the reply, as if the call failed. The \a error pointer must not be null. */ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDBusConnection::ConnectionCapabilities capabilities, QDBusError *error) { if (!qdbus_loadLibDBus()) { *error = QDBusError(QDBusError::Failed, QLatin1String("Could not open lidbus-1 library")); return 0; } DBusMessage *msg = 0; const QDBusMessagePrivate *d_ptr = message.d_ptr; switch (d_ptr->type) { case DBUS_MESSAGE_TYPE_INVALID: //qDebug() << "QDBusMessagePrivate::toDBusMessage" << "message is invalid"; break; case DBUS_MESSAGE_TYPE_METHOD_CALL: // only service and interface can be empty -> path and name must not be empty if (!d_ptr->parametersValidated) { if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) return 0; if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) return 0; if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) return 0; if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) return 0; } msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(), data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8()); q_dbus_message_set_auto_start( msg, d_ptr->autoStartService ); break; case DBUS_MESSAGE_TYPE_METHOD_RETURN: msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); if (!d_ptr->localMessage) { q_dbus_message_set_destination(msg, q_dbus_message_get_sender(d_ptr->reply)); q_dbus_message_set_reply_serial(msg, q_dbus_message_get_serial(d_ptr->reply)); } break; case DBUS_MESSAGE_TYPE_ERROR: // error name can't be empty if (!d_ptr->parametersValidated && !QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error)) return 0; msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); q_dbus_message_set_error_name(msg, d_ptr->name.toUtf8()); if (!d_ptr->localMessage) { q_dbus_message_set_destination(msg, q_dbus_message_get_sender(d_ptr->reply)); q_dbus_message_set_reply_serial(msg, q_dbus_message_get_serial(d_ptr->reply)); } break; case DBUS_MESSAGE_TYPE_SIGNAL: // nothing can be empty here if (!d_ptr->parametersValidated) { if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) return 0; if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) return 0; if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) return 0; } msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(), d_ptr->name.toUtf8()); break; default: Q_ASSERT(false); break; } // if we got here, the parameters validated // and since the message parameters cannot be changed once the message is created // we can record this fact d_ptr->parametersValidated = true; QDBusMarshaller marshaller(capabilities); QVariantList::ConstIterator it = d_ptr->arguments.constBegin(); QVariantList::ConstIterator cend = d_ptr->arguments.constEnd(); q_dbus_message_iter_init_append(msg, &marshaller.iterator); if (!d_ptr->message.isEmpty()) // prepend the error message marshaller.append(d_ptr->message); for ( ; it != cend; ++it) marshaller.appendVariantInternal(*it); // check if everything is ok if (marshaller.ok) return msg; // not ok; q_dbus_message_unref(msg); *error = QDBusError(QDBusError::Failed, QLatin1String("Marshalling failed: ") + marshaller.errorString); return 0; }