Ejemplo n.º 1
0
QDBusMessagePrivate::~QDBusMessagePrivate()
{
    if (msg)
        q_dbus_message_unref(msg);
    if (reply)
        q_dbus_message_unref(reply);
    delete localReply;
}
Ejemplo n.º 2
0
QT_BEGIN_NAMESPACE

QDBusArgumentPrivate::~QDBusArgumentPrivate()
{
    if (message)
        q_dbus_message_unref(message);
}
Ejemplo n.º 3
0
QT_BEGIN_NAMESPACE

QDBusArgumentPrivate::~QDBusArgumentPrivate()
{
#ifndef DUMMY_DBUS
    if (message)
        q_dbus_message_unref(message);
#endif
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
/*!
    \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;
}