Exemplo n.º 1
0
bool QDBusMarshaller::appendCrossMarshalling(QDBusDemarshaller *demarshaller)
{
    int code = q_dbus_message_iter_get_arg_type(&demarshaller->iterator);
    if (QDBusUtil::isValidBasicType(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 (QDBusUtil::isValidFixedType(element) && element != DBUS_TYPE_UNIX_FD) {
            // another optimization: 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] = { char(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(capabilities);  // 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;
}
Exemplo n.º 2
0
static inline T qIterGet(DBusMessageIter *it)
{
    T t;
    q_dbus_message_iter_get_basic(it, &t);
    q_dbus_message_iter_next(it);
    return t;
}
Exemplo n.º 3
0
static inline T qIterGet(DBusMessageIter *it)
{
    // Use a union of expected and largest type q_dbus_message_iter_get_basic
    // will return to ensure reading the wrong basic type does not result in
    // stack overwrite
    union {
        // The value to be extracted
        T t;
        // Largest type that q_dbus_message_iter_get_basic will return
        // according to dbus_message_iter_get_basic API documentation
        dbus_uint64_t maxValue;
        // A pointer to ensure no stack overwrite in case there is a platform
        // where sizeof(void*) > sizeof(dbus_uint64_t)
        void* ptr;
    } value;

    // Initialize the value in case a narrower type is extracted to it.
    // Note that the result of extracting a narrower type in place of a wider
    // one and vice-versa will be platform-dependent.
    value.t = T();

    q_dbus_message_iter_get_basic(it, &value);
    q_dbus_message_iter_next(it);
    return value.t;
}
Exemplo n.º 4
0
QDBusArgument QDBusDemarshaller::duplicate()
{
    QDBusDemarshaller *d = new QDBusDemarshaller;
    d->iterator = iterator;
    d->message = q_dbus_message_ref(message);

    q_dbus_message_iter_next(&iterator);
    return QDBusArgumentPrivate::create(d);
}
Exemplo n.º 5
0
inline QDBusVariant QDBusDemarshaller::toVariant()
{
    QDBusDemarshaller sub;
    sub.message = q_dbus_message_ref(message);
    q_dbus_message_iter_recurse(&iterator, &sub.iterator);
    q_dbus_message_iter_next(&iterator);

    return QDBusVariant( sub.toVariantInternal() );
}
Exemplo n.º 6
0
QByteArray QDBusDemarshaller::toByteArray()
{
    DBusMessageIter sub;
    q_dbus_message_iter_recurse(&iterator, &sub);
    q_dbus_message_iter_next(&iterator);
    int len;
    char* data;
    q_dbus_message_iter_get_fixed_array(&sub,&data,&len);
    return QByteArray(data,len);
}
Exemplo n.º 7
0
QDBusDemarshaller *QDBusDemarshaller::beginCommon()
{
    QDBusDemarshaller *d = new QDBusDemarshaller;
    d->parent = this;
    d->message = q_dbus_message_ref(message);

    // recurse
    q_dbus_message_iter_recurse(&iterator, &d->iterator);
    q_dbus_message_iter_next(&iterator);
    return d;
}
Exemplo n.º 8
0
QStringList QDBusDemarshaller::toStringList()
{
    QStringList list;

    QDBusDemarshaller sub;
    q_dbus_message_iter_recurse(&iterator, &sub.iterator);
    q_dbus_message_iter_next(&iterator);
    while (!sub.atEnd())
        list.append(sub.toString());

    return list;
}
Exemplo n.º 9
0
QVariant QDBusDemarshaller::toVariantInternal()
{
    switch (q_dbus_message_iter_get_arg_type(&iterator)) {
    case DBUS_TYPE_BYTE:
        return QVariant::fromValue(toByte());
    case DBUS_TYPE_INT16:
	return QVariant::fromValue(toShort());
    case DBUS_TYPE_UINT16:
	return QVariant::fromValue(toUShort());
    case DBUS_TYPE_INT32:
        return toInt();
    case DBUS_TYPE_UINT32:
        return toUInt();
    case DBUS_TYPE_DOUBLE:
        return toDouble();
    case DBUS_TYPE_BOOLEAN:
        return toBool();
    case DBUS_TYPE_INT64:
        return toLongLong();
    case DBUS_TYPE_UINT64:
        return toULongLong();
    case DBUS_TYPE_STRING:
        return toStringUnchecked();
    case DBUS_TYPE_OBJECT_PATH:
        return QVariant::fromValue(toObjectPathUnchecked());
    case DBUS_TYPE_SIGNATURE:
        return QVariant::fromValue(toSignatureUnchecked());
    case DBUS_TYPE_VARIANT:
        return QVariant::fromValue(toVariant());

    case DBUS_TYPE_ARRAY:
        switch (q_dbus_message_iter_get_element_type(&iterator)) {
        case DBUS_TYPE_BYTE:
            // QByteArray
            return toByteArrayUnchecked();
        case DBUS_TYPE_STRING:
            return toStringListUnchecked();
        case DBUS_TYPE_DICT_ENTRY:
            return QVariant::fromValue(duplicate());

        default:
            return QVariant::fromValue(duplicate());
        }

    case DBUS_TYPE_STRUCT:
        return QVariant::fromValue(duplicate());

    case DBUS_TYPE_UNIX_FD:
        if (capabilities & QDBusConnection::UnixFileDescriptorPassing)
            return QVariant::fromValue(toUnixFileDescriptor());
        // fall through

    default:
//        qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
//                 q_dbus_message_iter_get_arg_type(&iterator),
//                 q_dbus_message_iter_get_arg_type(&iterator));
        char *ptr = 0;
        ptr += q_dbus_message_iter_get_arg_type(&iterator);
        q_dbus_message_iter_next(&iterator);

        // I hope you never dereference this pointer!
        return QVariant::fromValue<void *>(ptr);
    };
}