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 + -
显示快捷键?