Ejemplo n.º 1
0
inline bool QDBusMarshaller::append(const QDBusVariant &arg)
{
    if (ba) {
        *ba += DBUS_TYPE_VARIANT_AS_STRING;
        return true;
    }

    const QVariant &value = arg.variant();
    QVariant::Type id = QVariant::Type(value.userType());
    if (id == QVariant::Invalid) {
        qWarning("QDBusMarshaller: cannot add a null QDBusVariant");
        error();
        return false;
    }

    const char *signature = QDBusMetaType::typeToSignature(id);
    if (!signature) {
        qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. "
                 "Use qDBusRegisterMetaType to register it",
                 QVariant::typeToName( id ), id);
        error();
        return false;
    }

    QDBusMarshaller sub;
    open(sub, DBUS_TYPE_VARIANT, signature);
    bool isOk = sub.appendVariantInternal(value);
    // don't call sub.close(): it auto-closes

    return isOk;
}
Ejemplo n.º 2
0
bool QDBusMarshaller::appendCrossMarshalling(QDBusDemarshaller *demarshaller)
{
    int code = q_dbus_message_iter_get_arg_type(&demarshaller->iterator);
    if (q_dbus_type_is_basic(code)) {
        // easy: just append
        // do exactly like the D-BUS docs suggest
        // (see apidocs for q_dbus_message_iter_get_basic)

        qlonglong value;
        q_dbus_message_iter_get_basic(&demarshaller->iterator, &value);
        q_dbus_message_iter_next(&demarshaller->iterator);
        q_dbus_message_iter_append_basic(&iterator, code, &value);
        return true;
    }

    if (code == DBUS_TYPE_ARRAY) {
        int element = q_dbus_message_iter_get_element_type(&demarshaller->iterator);
        if (q_dbus_type_is_fixed(element)) {
            // another optimisation: fixed size arrays
            // code is exactly like QDBusDemarshaller::toByteArray
            DBusMessageIter sub;
            q_dbus_message_iter_recurse(&demarshaller->iterator, &sub);
            q_dbus_message_iter_next(&demarshaller->iterator);
            int len;
            void* data;
            q_dbus_message_iter_get_fixed_array(&sub,&data,&len);

            char signature[2] = { element, 0 };
            q_dbus_message_iter_open_container(&iterator, DBUS_TYPE_ARRAY, signature, &sub);
            q_dbus_message_iter_append_fixed_array(&sub, element, &data, len);
            q_dbus_message_iter_close_container(&iterator, &sub);

            return true;
        }
    }

    // We have to recurse
    QDBusDemarshaller *drecursed = demarshaller->beginCommon();

    QDBusMarshaller mrecursed;  // create on the stack makes it autoclose
    QByteArray subSignature;
    const char *sig = 0;
    if (code == DBUS_TYPE_VARIANT || code == DBUS_TYPE_ARRAY) {
        subSignature = drecursed->currentSignature().toLatin1();
        if (!subSignature.isEmpty())
            sig = subSignature.constData();
    }
    open(mrecursed, code, sig);

    while (!drecursed->atEnd()) {
        if (!mrecursed.appendCrossMarshalling(drecursed)) {
            delete drecursed;
            return false;
        }
    }

    delete drecursed;
    return true;
}
Ejemplo n.º 3
0
inline void QDBusMarshaller::append(const QStringList &arg)
{
    if (ba) {
        *ba += DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING;
        return;
    }

    QDBusMarshaller sub;
    open(sub, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING);
    QStringList::ConstIterator it = arg.constBegin();
    QStringList::ConstIterator end = arg.constEnd();
    for ( ; it != end; ++it)
        sub.append(*it);
    // don't call sub.close(): it auto-closes
}
Ejemplo n.º 4
0
inline bool QDBusMarshaller::append(const QDBusVariant &arg)
{
    if (ba) {
        *ba += DBUS_TYPE_VARIANT_AS_STRING;
        return true;
    }

    const QVariant &value = arg.variant();
    QVariant::Type id = QVariant::Type(value.userType());
    if (id == QVariant::Invalid) {
        qWarning("QDBusMarshaller: cannot add a null QDBusVariant");
        error();
        return false;
    }

    QByteArray tmpSignature;
    const char *signature = 0;
    if (int(id) == qMetaTypeId<QDBusArgument>()) {
        // take the signature from the QDBusArgument object we're marshalling
        tmpSignature =
            qvariant_cast<QDBusArgument>(value).currentSignature().toLatin1();
        signature = tmpSignature.constData();
    } else {
        // take the signatuer from the metatype we're marshalling
        signature = QDBusMetaType::typeToSignature(id);
    }
    if (!signature) {
        qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. "
                 "Use qDBusRegisterMetaType to register it",
                 QVariant::typeToName( id ), id);
        error();
        return false;
    }

    QDBusMarshaller sub;
    open(sub, DBUS_TYPE_VARIANT, signature);
    bool isOk = sub.appendVariantInternal(value);
    // don't call sub.close(): it auto-closes

    return isOk;
}
Ejemplo n.º 5
0
/*!
    \internal
    Constructs a DBusMessage object from this object. The returned value must be de-referenced
    with q_dbus_message_unref.

    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, 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;
    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;
}