📄 qdbusargument.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 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://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** 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"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; arg.d = 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(){ if (direction == Marshalling) return marshaller()->ok;#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(){ if (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;}/*! \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() : d(0){}/*! 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();}/*! 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){ if (other.d) other.d->ref.ref(); QDBusArgumentPrivate *old = qAtomicSetPtr(&d, other.d); if (old && !old->ref.deref()) delete old; 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 (d && d->checkWrite()) 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 (d && d->checkWrite()) 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 (d && d->checkWrite()) 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 (d && d->checkWrite()) 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 (d && d->checkWrite()) 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 (d && d->checkWrite()) 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 (d && d->checkWrite()) 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 (d && d->checkWrite()) 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 (d && d->checkWrite()) 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 (d && d->checkWrite()) d->marshaller()->append(arg); return *this;}/*! \overload \internal Appends the primitive value \a arg of type \c{OBJECT_PATH} (path to a D-BUS object) to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(const QDBusObjectPath &arg){ if (d && d->checkWrite()) d->marshaller()->append(arg); return *this;}/*! \overload \internal Appends the primitive value \a arg of type \c{SIGNATURE} (D-BUS type signature) to the D-BUS stream.*/QDBusArgument &QDBusArgument::operator<<(const QDBusSignature &arg){ if (d && d->checkWrite()) d->marshaller()->append(arg); return *this;}/*! \overload Appends the primitive value \a arg of type \c{VARIANT} to the D-BUS stream. A D-BUS variant type can contain any type, including other variants. It is similar to the Qt QVariant type.*/QDBusArgument &QDBusArgument::operator<<(const QDBusVariant &arg){ if (d && d->checkWrite()) d->marshaller()->append(arg); return *this;}/*! \overload
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -