qdbusargument.cpp

来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 1,339 行 · 第 1/3 页

CPP
1,339
字号
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the tools applications of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qdbusargument.h"#include <qatomic.h>#include <qbytearray.h>#include <qlist.h>#include <qmap.h>#include <qstring.h>#include <qstringlist.h>#include <qvariant.h>#include <qdatetime.h>#include <qrect.h>#include <qline.h>#include "qdbusargument_p.h"#include "qdbusmetatype_p.h"QDBusArgumentPrivate::~QDBusArgumentPrivate(){    if (message)        dbus_message_unref(message);}QByteArray QDBusArgumentPrivate::createSignature(int id){    QByteArray signature;    QDBusMarshaller *marshaller = new QDBusMarshaller;    marshaller->ba = &signature;    // run it    void *null = 0;    QVariant v(id, null);    QDBusArgument arg(marshaller);    QDBusMetaType::marshall(arg, v.userType(), v.constData());    arg.d = 0;    // delete it    bool ok = marshaller->ok;    delete marshaller;    if (signature.isEmpty() || !ok || !dbus_signature_validate_single(signature, 0)) {        qWarning("QDBusMarshaller: type `%s' produces invalid D-BUS signature `%s' "                 "(Did you forget to call beginStructure() ?)",                 QVariant::typeToName( QVariant::Type(id) ),                 signature.isEmpty() ? "<empty>" : signature.constData());        return "";    } else if (signature.at(0) != DBUS_TYPE_ARRAY && signature.at(0) != DBUS_STRUCT_BEGIN_CHAR ||               (signature.at(0) == DBUS_TYPE_ARRAY && (signature.at(1) == DBUS_TYPE_BYTE ||                                                       signature.at(1) == DBUS_TYPE_STRING))) {        qWarning("QDBusMarshaller: type `%s' attempts to redefine basic D-BUS type '%s' (%s) "                 "(Did you forget to call beginStructure() ?)",                 QVariant::typeToName( QVariant::Type(id) ),                 signature.constData(),                 QVariant::typeToName( QVariant::Type(QDBusMetaType::signatureToType(signature))) );        return "";    }    return signature;}bool QDBusArgumentPrivate::checkWrite(QDBusArgumentPrivate *&d){    if (!d)        return false;    if (d->direction == Marshalling) {        if (!d->marshaller()->ok)            return false;        if (d->message && d->ref != 1) {            QDBusMarshaller *dd = new QDBusMarshaller;            dd->message = dbus_message_copy(d->message);            dbus_message_iter_init_append(dd->message, &dd->iterator);            QDBusArgumentPrivate *old =                qAtomicSetPtr(&d, static_cast<QDBusArgumentPrivate *>(dd));            if (!old->ref.deref())                delete old;        }        return true;    }#ifdef QT_DEBUG    qFatal("QDBusArgument: write from a read-only object");#else    qWarning("QDBusArgument: write from a read-only object");#endif    return false;}bool QDBusArgumentPrivate::checkRead(QDBusArgumentPrivate *d){    if (!d)        return false;    if (d->direction == Demarshalling)        return true;#ifdef QT_DEBUG    qFatal("QDBusArgument: read from a write-only object");#else    qWarning("QDBusArgument: read from a write-only object");#endif    return false;}bool QDBusArgumentPrivate::checkReadAndDetach(QDBusArgumentPrivate *&d){    if (!checkRead(d))        return false;           //  don't bother    if (d->ref == 1)        return true;            // no need to detach    QDBusDemarshaller *dd = new QDBusDemarshaller;    dd->message = dbus_message_ref(d->message);    dd->iterator = static_cast<QDBusDemarshaller*>(d)->iterator;    QDBusArgumentPrivate *old =        qAtomicSetPtr(&d, static_cast<QDBusArgumentPrivate *>(dd));    if (!old->ref.deref())        delete old;    return true;}/*!    \class QDBusArgument    \inmodule QtDBus    \since 4.2    \brief The QDBusArgument class is used to marshall and demarshall D-BUS arguments.    The class is used to send arguments over D-BUS to remote    applications and to receive them back. D-BUS offers an extensible    type system, based on a few primitive types and associations of    them. See the \l {qdbustypesystem.html}{QtDBus type system} page    for more information on the type system.    QDBusArgument is the central class in the QtDBus type system,    providing functions to marshall and demarshall the primitive    types. The compound types are then created by association of one    or more of the primitive types in arrays, dictionaries or    structures.    The following example illustrates how a structure containing an    integer and a string can be constructed using the \l    {qdbustypesystem.html}{QtDBus type system}:    \code        struct MyStructure        {            int count;            QString name;        };        QT_DECLARE_METATYPE(MyStructure)        // Marshall the MyStructure data into a D-BUS argument        QDBusArgument &operator<<(QDBusArgument &argument, const MyStructure &mystruct)        {            argument.beginStructure();            argument << mystruct.count << mystruct.name;            argument.endStructure();            return argument;        }        // Retrieve the MyStructure data from the D-BUS argument        const QDBusArgument &operator>>(const QDBusArgument &argument, MyStructure &mystruct)        {            argument.beginStructure();            argument >> mystruct.count >> mystruct.name;            argument.endStructure();            return argument;        }    \endcode    The type has to be registered with qDBusRegisterMetaType() before    it can be used with QDBusArgument. Therefore, somewhere in your    program, you should add the following code:    \code        qDBusRegisterMetaType<MyStructure>();    \endcode    Once registered, a type can be used in outgoing method calls    (placed with QDBusAbstractInterface::call()), signal emissions    from registered objects or in incoming calls from remote    applications.    It is important to note that the \c{operator<<} and \c{operator>>}    streaming functions must always produce the same number of entries    in case of structures, both in reading and in writing (marshalling    and demarshalling), otherwise calls and signals may start to    silently fail.    The following example illustrates this wrong usage    in context of a class that may contain invalid data:    \badcode        // Wrongly marshall the MyTime data into a D-BUS argument        QDBusArgument &operator<<(QDBusArgument &argument, const MyTime &mytime)        {            argument.beginStructure();            if (mytime.isValid)                argument << true << mytime.hour                         << mytime.minute << mytime.second;            else                argument << false;            argument.endStructure();            return argument;        }    \endcode    In this example, both the \c{operator<<} and the \c{operator>>}    functions may produce a different number of reads/writes. This can    confuse the QtDBus type system and should be avoided.    \sa QDBusAbstractInterface, {qdbustypesystem.html}{The QtDBus type    system}, {usingadaptors.html}{Using Adaptors}, qdbus_cast()*//*!    \fn qdbus_cast(const QDBusArgument &argument)    \relates QDBusArgument    \since 4.2    Attempts to demarshall the contents of \a argument into the type    \c{T}. For example:    \code        MyType item = qdbus_cast<Type>(argument);    \endcode    Note that it is equivalent to the following:    \code        MyType item;        argument >> item;    \endcode*//*!    Constructs an empty QDBusArgument argument.    An empty QDBusArgument object does not allow either reading or    writing to be performed.*/QDBusArgument::QDBusArgument(){    QDBusMarshaller *dd = new QDBusMarshaller;    d = dd;    // create a new message with any type, we won't sent it anyways    dd->message = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);    dbus_message_iter_init_append(dd->message, &dd->iterator);}/*!    Constructs a copy of the \a other QDBusArgument object.    Both objects will therefore contain the same state from this point    forward. QDBusArguments are explicitly shared and, therefore, any    modification to either copy will affect the other one too.*/QDBusArgument::QDBusArgument(const QDBusArgument &other)    : d(other.d){    if (d)        d->ref.ref();}/*!    \internal*/QDBusArgument::QDBusArgument(QDBusArgumentPrivate *dd)    : d(dd){}/*!    Copies the \a other QDBusArgument object into this one.    Both objects will therefore contain the same state from this point    forward. QDBusArguments are explicitly shared and, therefore, any    modification to either copy will affect the other one too.*/QDBusArgument &QDBusArgument::operator=(const QDBusArgument &other){    qAtomicAssign(d, other.d);    return *this;}/*!    Disposes of the resources associated with this QDBusArgument    object.*/QDBusArgument::~QDBusArgument(){    if (d && !d->ref.deref())        delete d;}/*!    Appends the primitive value \a arg of type \c{BYTE} to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(uchar arg){    if (QDBusArgumentPrivate::checkWrite(d))        d->marshaller()->append(arg);    return *this;}/*!    \overload    Appends the primitive value \a arg of type \c{BOOLEAN} to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(bool arg){    if (QDBusArgumentPrivate::checkWrite(d))        d->marshaller()->append(arg);    return *this;}/*!    \overload    Appends the primitive value \a arg of type \c{INT16} to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(short arg){    if (QDBusArgumentPrivate::checkWrite(d))        d->marshaller()->append(arg);    return *this;}/*!    \overload    Appends the primitive value \a arg of type \c{UINT16} to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(ushort arg){    if (QDBusArgumentPrivate::checkWrite(d))        d->marshaller()->append(arg);    return *this;}/*!    \overload    Appends the primitive value \a arg of type \c{INT32} to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(int arg){    if (QDBusArgumentPrivate::checkWrite(d))        d->marshaller()->append(arg);    return *this;}/*!    \overload    Appends the primitive value \a arg of type \c{UINT32} to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(uint arg){    if (QDBusArgumentPrivate::checkWrite(d))        d->marshaller()->append(arg);    return *this;}/*!    \overload    Appends the primitive value \a arg of type \c{INT64} to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(qlonglong arg){    if (QDBusArgumentPrivate::checkWrite(d))        d->marshaller()->append(arg);    return *this;}/*!    \overload    Appends the primitive value \a arg of type \c{UINT64} to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(qulonglong arg){    if (QDBusArgumentPrivate::checkWrite(d))        d->marshaller()->append(arg);    return *this;}/*!    \overload    Appends the primitive value \a arg of type \c{DOUBLE} (double-precision    floating-point) to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(double arg){    if (QDBusArgumentPrivate::checkWrite(d))        d->marshaller()->append(arg);    return *this;}/*!    \overload    Appends the primitive value \a arg of type \c{STRING} (Unicode character    string) to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(const QString &arg){    if (QDBusArgumentPrivate::checkWrite(d))        d->marshaller()->append(arg);    return *this;}/*!    \overload

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?