Репозитории ALT
S: | 1.14.10-alt1 |
5.1: | 1.2.16-alt2 |
4.1: | 1.2.12-alt1.M41.1 |
+updates: | 1.2.4-alt0.M41.1 |
4.0: | 1.0.3-alt1.M40.2 |
3.0: | 0.36.2-alt1 |
Другие репозитории
Upstream: | 1.1.20 |
Группа :: Система/Серверы
Пакет: dbus
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: dbus-qt.patch
Скачать
Скачать
Common subdirectories: dbus-old/qt/CVS and dbus/qt/CVS
diff -u -N dbus-old/qt/Makefile.am dbus/qt/Makefile.am
--- dbus-old/qt/Makefile.am 2005-03-07 21:10:46.000000000 +0000
+++ dbus/qt/Makefile.am 2005-06-14 19:55:25.000000000 +0100
@@ -7,7 +7,7 @@
dbusinclude_HEADERS= \
dbus-qt.h message.h connection.h \
- server.h
+ server.h argument.h object.h
libdbus_qt_1_la_SOURCES = \
dbus-qthread.cpp \
@@ -15,9 +15,13 @@
$(top_srcdir)/qt/connection.cpp \
$(top_srcdir)/qt/integrator.cpp \
$(top_srcdir)/qt/server.cpp \
+ $(top_srcdir)/qt/argument.cpp \
+ $(top_srcdir)/qt/object.cpp \
$(top_srcdir)/qt/connection.h \
$(top_srcdir)/qt/integrator.h \
- $(top_srcdir)/qt/server.h
+ $(top_srcdir)/qt/server.h \
+ $(top_srcdir)/qt/argument.h \
+ $(top_srcdir)/qt/object.h
$(top_srcdir)/qt/connection.cpp: connection.moc
diff -u -N dbus-old/qt/argument.cpp dbus/qt/argument.cpp
--- dbus-old/qt/argument.cpp 1970-01-01 01:00:00.000000000 +0100
+++ dbus/qt/argument.cpp 2005-06-14 19:55:25.000000000 +0100
@@ -0,0 +1,318 @@
+/* -*- mode: C++; c-file-style: "gnu" -*- */
+/* argument.cpp: Qt wrapper for D-BUS message arguments
+ *
+ * Copyright (C) 2005 James Thorniley <james@uncommonlygood.co.uk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "argument.h"
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+#include <assert.h>
+
+namespace DBusQt
+{
+
+ class Argument::Private{
+
+ public:
+
+ Private(){}
+ Private( Private *p );
+ ~Private();
+
+ /**Stores the type of this argument*/
+ Argument::Type argumentType;
+
+ /**If argumentType is array, this is
+ set to the type of the elements inside the argument.
+ DO NOT USE if argumentType is not array.*/
+ Argument::Type elementType;
+
+ /**The argument is stored in this union.*/
+ union
+ {
+
+ char byte;
+ dbus_bool_t boolean;
+ dbus_int16_t int16;
+ dbus_uint16_t uint16;
+ dbus_int32_t int32;
+ dbus_uint32_t uint32;
+ dbus_int64_t int64;
+ dbus_uint64_t uint64;
+ double ieeeFloat;
+ void * ptr;
+
+ } value;
+
+ };
+
+ Argument::Private::Private( Private *p )
+ {
+ //qDebug( "DBusQt: Argument::Private::Private( Private *p )" );
+
+ switch( p->argumentType )
+ {
+ case Argument::Int32:
+ value.int32 = p->value.int32;
+ break;
+
+ case Argument::String:
+ //qDebug( "DBusQt: Copying string" );
+ value.ptr = new QString( *(QString*)(p->value.ptr) );
+ break;
+
+ case Argument::Struct:
+ value.ptr = new QValueList<Argument>( *(QValueList<Argument>*)(p->value.ptr) );
+ break;
+
+ case Argument::Array:
+ //qDebug( "DBusQt: Copying array" );
+ switch( p->elementType )
+ {
+ case Argument::String:
+ //qDebug( "DBusQt: Copying string array" );
+ value.ptr = new QStringList( *(QStringList*)(p->value.ptr) );
+ break;
+
+ case Argument::Array:
+ //qDebug( "DBusQt: Copying array array" );
+ value.ptr = new QValueList<Argument>( *(QValueList<Argument>*)(p->value.ptr) );
+ break;
+ }
+
+ elementType = p->elementType;
+ break;
+ }
+
+ argumentType = p->argumentType ;
+ if( argumentType != Argument::Array )
+ elementType = Argument::Invalid;
+
+ }
+
+ Argument::Private::~Private()
+ {
+ switch( argumentType )
+ {
+ case Argument::String:
+ delete (QString*)(value.ptr);
+ break;
+
+ case Argument::Struct:
+ delete (QValueList<Argument>*)(value.ptr);
+ break;
+
+ case Argument::Array:
+ switch( elementType )
+ {
+ case Argument::String:
+ delete (QStringList*)(value.ptr);
+ break;
+ case Argument::Array:
+ delete (QValueList<Argument>*)(value.ptr);
+ break;
+ }
+ break;
+ }
+ }
+
+ Argument::Argument()
+ {
+ //qDebug( "DBusQt: Argument::Argument( )" );
+ d = new Private;
+
+ d->argumentType = Argument::Invalid;
+ d->elementType = Argument::Invalid;
+ d->value.ptr = 0;
+ }
+
+ Argument::Argument( Q_INT32 integer )
+ {
+ d = new Private;
+
+ d->argumentType = Argument::Int32;
+ d->elementType = Argument::Invalid;
+ d->value.int32 = integer;
+ }
+
+ Argument::Argument( const QString &string )
+ {
+ //qDebug( "DBusQt: Argument::Argument( const QString &string )" );
+ d = new Private;
+
+ d->argumentType = Argument::String;
+ d->elementType = Argument::Invalid;
+
+ d->value.ptr = new QString(string);
+ }
+
+ Argument::Argument( const QStringList &stringList )
+ {
+ //qDebug( "DBusQt: Argument::Argument( const QStringList &stringList )" );
+
+ d = new Private;
+
+ d->argumentType = Argument::Array;
+ d->elementType = Argument::String;
+
+ d->value.ptr = new QStringList( stringList );
+ }
+
+ Argument::Argument( const QValueList<Argument> &nested, NestedType type )
+ {
+
+ d = new Private;
+
+ if( type == Structure )
+ {
+
+ d->argumentType = Argument::Struct;
+ d->elementType = Argument::Invalid;
+
+ d->value.ptr = new QValueList<Argument>(nested);
+ }
+ else
+ {
+
+ d->argumentType = Argument::Array;
+ d->elementType = Argument::Array;
+
+ d->value.ptr = new QValueList<Argument>(nested);
+
+ ///@todo Test array-array validity checking works
+ int i = 0, c = nested.count();
+ Type lastElementType = nested[0].d->elementType;
+
+ while( i < c )
+ {
+
+ if( nested[i].d->argumentType != Argument::Array )
+ {
+ qDebug( "DBusQt: ERROR: Tried to create array of arrays but some elements were not arrays" );
+ d->value.ptr = 0;
+ break;
+ }
+
+ if( ( ++i != c ) && ( lastElementType != (lastElementType = nested[i].d->elementType) ) )
+ {
+ qDebug( "DBusQt: ERROR: Tried to create array of arrays with varying element types" );
+ d->value.ptr = 0;
+ break;
+ }
+ }
+
+ assert( d->value.ptr );
+
+ }
+
+ }
+
+ Argument::Argument( const Argument &arg )
+ {
+ d = new Private( arg.d );
+ }
+
+ Argument &Argument::operator=( const Argument &arg )
+ {
+ Private *tmp = new Private( arg.d );
+
+ delete d; d = tmp;
+
+ return *this;
+ }
+
+ Argument::~Argument()
+ {
+ delete d;
+ }
+
+ Q_INT32 Argument::toInt32() const
+ {
+ if( d->argumentType == Argument::Int32 )
+ {
+ return d->value.int32;
+ }else
+ {
+ return 0;
+ }
+ }
+ const QString Argument::toString() const
+ {
+ if( d->argumentType == Argument::String )
+ return *((QString*)d->value.ptr);
+ else
+ return QString::null;
+ }
+
+ const QStringList Argument::toStringList() const
+ {
+ //qDebug( "DBusQt: QStringList Argument::toStringList() const" );
+
+ if( (d->argumentType == Argument::Array) &&
+ (d->elementType == Argument::String) )
+ {
+ return *((QStringList*)d->value.ptr);
+ }
+ else
+ {
+ return *((QStringList*)0);
+ }
+
+ }
+
+ const QValueList<Argument> &Argument::toStruct() const
+ {
+ if( d->argumentType == Argument::Struct )
+ {
+ return *((QValueList<Argument>*)d->value.ptr);
+ }
+ else
+ {
+ return *((QValueList<Argument>*)0);
+ }
+ }
+
+ const QValueList<Argument> &Argument::toArrayArray() const
+ {
+ if( d->argumentType == Argument::Array &&
+ d->elementType == Argument::Array )
+ {
+ return *((QValueList<Argument>*)d->value.ptr);
+ }
+ else
+ {
+ return *((QValueList<Argument>*)0);
+ }
+ }
+
+ Argument::Type Argument::argumentType() const
+ {
+ return d->argumentType;
+ }
+
+ Argument::Type Argument::elementType() const
+ {
+ return d->elementType;
+ }
+
+}
diff -u -N dbus-old/qt/argument.h dbus/qt/argument.h
--- dbus-old/qt/argument.h 1970-01-01 01:00:00.000000000 +0100
+++ dbus/qt/argument.h 2005-06-14 19:55:25.000000000 +0100
@@ -0,0 +1,400 @@
+/* -*- mode: C++; c-file-style: "gnu" -*- */
+/* argument.h: Qt wrapper for D-BUS message arguments
+ *
+ * Copyright (C) 2005 James Thorniley <james@uncommonlygood.co.uk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#ifndef DBUS_QT_ARGUMENT_H
+#define DBUS_QT_ARGUMENT_H
+
+#include "dbus/dbus.h"
+#include <qglobal.h>
+
+#ifdef __cplusplus //prevents Doxygen from deciding that Argument is a template class
+template <class T> class QValueList;
+#endif
+
+class QStringList;
+class QString;
+
+namespace DBusQt
+{
+
+ /**
+
+ @short A class for wrapping C++/Qt types for use with D-BUS
+
+ <p>Each Argument object represents a <em>single complete type</em> as it is
+ defined in the D-BUS protocol. That is, an argument can
+ be a byte, boolean, integer, string etc. Or it could be a
+ complex type such as an array or struct.
+
+ <p>To attach data to messages, it must first be turned into Argument objects.
+ Use one of the supplied constructors to do that. Add it to a message by getting
+ hold of the message's argument list (see: {@link Message::arguments()}), and using
+ QValueList methods to add your argument to the list.
+
+ <p>For example to add a QString to a message, you might use:
+
+ @code
+ Message myMessage(...); //fill in arguments with destination, object etc...
+
+ Argument stringArg( QString( "Hello world" ) );
+
+ myMessage.arguments()->append( stringArg );
+
+ @endcode
+
+ <p>To get data out of a message, once again use the {@link Message::arguments() arguments} method to retreive
+ a QValueList of arguments and retrieve an argument from the list. To convert this argument
+ back to a C++ / Qt type, use the relevant toXXX() method. You can check which type
+ this argument represents with the {@link #argumentType()} method.
+
+ <p>For example to receive a reply containing a QString:
+
+ @code
+ Message reply = connection.sendWidthReplyAndBlock( myMessage );
+
+ Argument replyArg = reply.arguments()->first();
+
+ QString replyString = replyArg.toString();
+ @endcode
+
+ <p>You may wish to use the QValueList::Iterator class to iterate over multiple arguments.
+ See the Qt documentation for more help.
+
+ @todo Implement Dicts.
+
+ @author James Thorniley
+ */
+ class Argument
+ {
+
+
+ public:
+
+ /**
+ The possible types that can be contained
+ in an argument object.
+
+ <p>The following table describes all the types you may
+ use for D-BUS arguments.
+
+ <table>
+ <tr><td>Type</td><td>D-BUS format</td><td>C++/QT format</td></tr>
+
+ <tr><td>Byte</td><td>Single byte</td><td>char</td></tr>
+ <tr><td>Boolean</td><td>32 bit integer, 1 = true, 0 = false, other values invalid </td><td>bool</td></tr>
+ <tr><td>Int16</td><td>16 bit signed integer</td><td>Q_INT16</td></tr>
+ <tr><td>Uint16</td><td>16 bit unsigned integer</td><td>Q_UINT16</td></tr>
+ <tr><td>Int32</td><td>32 bit signed integer</td><td>Q_INT32</td></tr>
+ <tr><td>Uint32</td><td>32 bit unsigned integer</td><td>Q_UINT32</td></tr>
+ <tr><td>Int64</td><td>64 bit signed integer</td><td>Q_LONG</td></tr>
+ <tr><td>Uint64</td><td>64 bit unsigned integer</td><td>Q_ULONG</td></tr>
+ <tr><td>IEEEFloat</td><td>IEEE 754 double precision float</td><td>double</td></tr>
+ <tr><td>String</td><td>UTF-8 encoded null terminated byte array</td><td>QString</td></tr>
+ <tr><td>Struct</td><td>Struct</td><td>QValueList<Argument></tr>
+ <tr><td>Invalid</td><td colspan="2">Arguments that do not represent any real type are of type Invalid.</td></tr>
+
+
+ </table>
+ */
+ enum Type
+ {
+ Byte = (int)'y',
+ Boolean = (int)'b',
+ Int16 = (int)'n',
+ Uint16 = (int)'q',
+ Int32 = (int)'i',
+ Uint32 = (int)'u',
+ Int64 = (int)'x',
+ Uint64 = (int)'t',
+ IEEEFloat = (int)'d',
+ String = (int)'s',
+ Struct = (int)'r',
+ Array = (int)'a',
+ Invalid = 0 /**
+ <p>Does not represent a real type. Probably the {@link #argumentType()} of a
+ object created with {@link #Argument() }, or the {@link #elementType()} of an
+ Argument that is not an array.
+ */
+ };
+
+ /**
+ The possible types that may be nested.
+
+ @see Argument( const QValueList<Argument>&, NestedType )
+ */
+ enum NestedType
+ {
+ ///An array of arrays.
+ ArrayArray,
+ ///A struct.
+ Structure
+ };
+
+ /**
+ Create an empty argument.
+
+ <p>The new object represents a placeholder for an
+ unknown / unsupported type.
+ */
+ Argument( );
+
+ /**
+ Create a new argument representing a
+ single byte.
+
+ <p>This is equivalent to a DBUS_TYPE_BYTE (code 'y')
+ on the wire.
+
+ @param byte The byte to use in the argument
+ @todo Implement Argument( char byte );
+ */
+ Argument( char byte );
+
+ /**
+ Create a new argument representing a
+ boolean value.
+
+ <p>This is equivalent to a DBUS_TYPE_BOOLEAN (code 'b')
+ on the wire.
+
+ @param boolean The boolean to use in the argument
+ @todo Implement Argument( bool boolean );
+ */
+ Argument( bool boolean );
+
+ /**
+ Create a new argument representing a
+ 16 bit signed integer.
+
+ <p>This is equivalent to a DBUS_TYPE_INT16 (code 'n')
+ on the wire.
+
+ @param integer The integer to use in the argument
+ @todo Implement Argument( Q_INT16 integer );
+ */
+ Argument( Q_INT16 integer );
+
+ /**
+ Create a new argument representing an
+ unsigned 16 bit integer.
+
+ <p>This is equivalent to a DBUS_TYPE_UINT16 (code 'q')
+ on the wire.
+
+ @param integer The integer to use in the argument
+ @todo Implement Argument( Q_UINT16 integer );
+ */
+ Argument( Q_UINT16 integer );
+
+ /**
+ Create a new argument representing a
+ signed 32 bit integer.
+
+ <p>This is equivalent to a DBUS_TYPE_INT32 (code 'i')
+ on the wire.
+
+ @param integer The integer to use in the argument
+ */
+ Argument( Q_INT32 integer );
+
+ /**
+ Create a new argument representing an
+ unsigned 32 bit integer.
+
+ <p>This is equivalent to a DBUS_TYPE_UINT32 (code 'u')
+ on the wire.
+
+ @param integer The integer to use in the argument
+ @todo Implement Argument( Q_UINT32 integer );
+
+ */
+ Argument( Q_UINT32 integer );
+
+ /**
+ Create a new argument representing a
+ signed 64 bit integer.
+
+ <p>This is equivalent to a DBUS_TYPE_INT64 (code 'x')
+ on the wire.
+
+ @param integer The integer to use in the argument
+ @todo Implement Argument( Q_LONG integer );
+ */
+ Argument( Q_LONG integer );
+
+ /**
+ @brief Create a new argument representing an unsigned 64 bit integer.
+
+ <p>This is equivalent to a DBUS_TYPE_UINT64 (code 't')
+ on the wire.
+
+ @param integer The integer to use in the argument
+ @todo Implement Argument( Q_ULONG integer );
+ */
+ Argument( Q_ULONG integer );
+
+ /**
+ @brief Create a new argument representing a IEEE-754 floating point number.
+
+ <p>This is equivalent to a DBUS_TYPE_DOUBLE (code 'd')
+ on the wire
+
+ @param ieeeFloat The double to use in the argument
+ @todo Implement Argument( doubel ieeeFloat );
+ */
+ Argument( double ieeeFloat );
+
+ /**
+ Create a new argument representing a UTF-8 string.
+
+ <p>This is equivalent to a DBUS_TYPE_STRING (code 's')
+ on the wire
+
+ @param string The string to use in the argument
+ */
+ Argument( const QString& string );
+
+ /*!
+ @brief Create a new argument representing a nested type.
+ This means either a struct or an array of arrays at the moment.
+
+ <p>A struct, in D-BUS terms, may contain any number of
+ single complete types, including other structs. This class
+ models a struct as a QValueList of Argument objects.
+
+ <p>To create an array of arrays,
+ all the arguments in the given QValueList must be
+ arrays (i.e. argumentType() == Array). The elementType of
+ each of the arrays must be equal to the supplied element type.
+ This element type can be Array as well, if you want to make
+ and array of arrays of arrays.
+
+ @param nested A QValueList of Argument objects, representing
+ a struct or array array.
+ @param type Either @arg @c Argument::ArrayArray for an array of arrays;
+ or @arg @c Argument::Structure for a struct.
+
+ @see #NestedType
+ */
+ Argument( const QValueList<Argument>& nested, NestedType type );
+
+ /**
+ Create a new argument representing an array of strings.
+
+ @param stringList The array of strings to use.
+ */
+ Argument( const QStringList& stringList );
+
+ /**
+ Deep copy an Argument object.
+
+ @param arg The Argument to copy.
+ */
+ Argument( const Argument &arg );
+
+ /**
+ Deep copy an Argument object.
+
+ @param arg The Argument to copy.
+ @return A copy of the supplied Argument.
+ */
+ Argument &operator=( const Argument &arg );
+
+ /**
+ Destructor.
+ */
+ ~Argument();
+
+ /**
+ Gets the type of this argument.
+
+ @return The type of this argument.
+
+ @see #Type
+ */
+ Type argumentType() const ;
+
+ /**
+ Gets the type of the elements of this array
+ (if this argument is an array)
+
+ @return The type of this array
+
+ @see #Type
+ */
+ Type elementType() const;
+
+ /**
+ Converts the argument to a QString. If the argument
+ is not a string, returns QString::null
+
+ @return The QString held in this argument, or QString::null
+ if this argument is not a string
+ */
+ const QString toString() const;
+
+ /**
+ Converts the argument to a QStringList, assuming the
+ argument is an array of strigs.
+
+ @return The QStringList held in this argument, or an
+ invalid QStringList if this argument is not a string array.
+ */
+ const QStringList toStringList() const;
+
+ /**
+ Converts this argument into a QValueList of arguments
+ representing a struct object, assuming this argument
+ is actually a struct.
+
+ @return The QValueList held in this argument, or an
+ invalid QValueList<Argument> if this argument
+ is not a struct.
+ */
+ const QValueList<Argument> &toStruct() const;
+
+ /**
+ Converts this argument into a QValueList of arguments
+ representing an array or arrays. Each argument in the
+ list will be themselves arrays, and they will all have
+ the same element type.
+
+ @return The QValueList held in this argument, or
+ an invalid QValueList<Argument> if this argument
+ is not an array of arrays.
+ */
+ const QValueList<Argument> &toArrayArray() const;
+
+ Q_INT32 toInt32() const;
+
+ private:
+
+ class Private;
+ Private *d;
+
+ };
+
+}
+
+#endif
diff -u -N dbus-old/qt/connection.cpp dbus/qt/connection.cpp
--- dbus-old/qt/connection.cpp 2004-09-04 16:09:48.000000000 +0100
+++ dbus/qt/connection.cpp 2005-06-15 12:24:57.000000000 +0100
@@ -2,6 +2,7 @@
/* connection.cpp: Qt wrapper for DBusConnection
*
* Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ * 2005 James Thorniley <james@uncommonlygood.co.uk>
*
* Licensed under the Academic Free License version 2.0
*
@@ -21,35 +22,77 @@
*
*/
#include "connection.h"
+#include "integrator.h"
+#include "message.h"
+#include "argument.h"
+#include "object.h"
+#include "dbus-qt.h"
-using namespace DBusQt;
+#include <qmap.h>
+#include <qvaluelist.h>
+
+namespace DBusQt{
-#include "integrator.h"
using Internal::Integrator;
-struct Connection::Private
+
+class Connection::Private
{
- Private( Connection *qq );
- void setConnection( DBusConnection *c );
- DBusConnection *connection;
- int connectionSlot;
- DBusError error;
- Integrator *integrator;
- int timeout;
- Connection *q;
+ public:
+ Private( Connection *qq );
+ ~Private();
+ void setConnection( DBusConnection *c );
+ DBusConnection *connection;
+ int connectionSlot;
+ DBusError error;
+ Integrator *integrator;
+ int timeout;
+ Connection *q;
+
+ /**
+ Stores object paths and references to the Object
+ instances they refer to.
+ */
+ QMap<QString,Object*> *pathMap;
+
+ DBusObjectPathVTable *vtable;
+
+ /**@internal
+
+ Passed to pendingCallNotify in for use in dealing with async
+ message replies.
+ */
+ typedef struct
+ {
+ Connection *connection;
+ const Message *message;
+ }SentMessage;
+
};
Connection::Private::Private( Connection *qq )
: connection( 0 ), connectionSlot( 0 ), integrator( 0 ),
- timeout( -1 ), q( qq )
+ timeout( -1 ), q( qq ), vtable( new DBusObjectPathVTable ),
+ pathMap( new QMap<QString, Object*>() )
{
dbus_error_init( &error );
+
+ vtable->unregister_function = Connection::unregisterHandler;
+ vtable->message_function = Connection::messageHandler;
+
+}
+
+Connection::Private::~Private()
+{
+ delete vtable;
+ delete pathMap;
}
void Connection::Private::setConnection( DBusConnection *c )
{
if (!c) {
- qDebug( "error: %s, %s", error.name, error.message );
+ qDebug( "DBusQt: Did not get connection: %s, %s", error.name, error.message );
+ dbusErrorMemCheck( &error );
dbus_error_free( &error );
return;
}
@@ -80,6 +123,11 @@
d->setConnection( dbus_bus_get(type, &d->error) );
}
+Connection::~Connection()
+{
+ delete d;
+}
+
void Connection::init( const QString& host )
{
d->setConnection( dbus_connection_open( host.ascii(), &d->error) );
@@ -132,26 +180,181 @@
d->setConnection(connection);
}
-void Connection::send( const Message &m )
+bool Connection::registerObject( Object *object, const QString &path, const QString &name )
{
- dbus_connection_send(d->connection, m.message(), 0);
-}
-void Connection::sendWithReply( const Message& )
+ QString completePath = (path + name);
+
+ if( d->pathMap->contains( completePath ) )
+ {
+ qDebug( "DBusQt: Could not register %s: object path already exists", completePath.latin1() );
+ return false;
+ }
+
+ d->pathMap->insert( completePath, object );
+
+ dbusMemFunction(
+ dbus_connection_register_object_path( d->connection, completePath.latin1(), d->vtable, this )
+ );
+ return true;
+}
+
+///@todo Provide this method with a DBusQT::Object * as the argument
+bool Connection::unregisterObject( const QString &path, const QString &name )
+{
+
+ QString completePath = (path + name);
+
+ if( d->pathMap->contains( completePath ) )
+ {
+ dbusMemFunction(
+ dbus_connection_unregister_object_path( d->connection, completePath.latin1() )
+ );
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+
+}
+bool Connection::requestName( const QString &name )
+{
+ int i;
+ if( (i =dbus_bus_request_name( d->connection,
+ name.latin1(),
+ 0,
+ &d->error ))
+ == -1 )
+ {
+ qDebug( "DBusQt: Could not get name, %s, %s", d->error.name, d->error.message );
+ dbusErrorMemCheck( &d->error );
+ dbus_error_free( &d->error );
+ return false;
+ }
+
+ if( i == DBUS_REQUEST_NAME_REPLY_EXISTS )
+ {
+ qDebug( "DBusQt: Could not register as %s, name in use", name.ascii() );
+ return false;
+ }
+ else if( (i == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) || (i == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) )
+ {
+ return true;
+ }
+ return false;
+
+}
+void Connection::send( const Message &m )
{
+ DBusMessage *message = m.message();
+ dbusMemFunction( dbus_connection_send(d->connection, message, 0) );
+ dbus_message_unref( message );
+}
+
+void Connection::sendWithReply( const Message& m )
+{
+ //qDebug( "DBusQt: void Connection::sendWithReply( const Message& m )" );
+
+ DBusPendingCall *pending;
+ DBusMessage *message = m.message();
+
+ dbusMemFunction(
+ dbus_connection_send_with_reply( d->connection,
+ message,
+ &pending,
+ -1 )
+ );
+
+ dbus_message_unref( message );
+
+ Private::SentMessage *sentMessage = new Private::SentMessage;
+ sentMessage->connection = this;
+ sentMessage->message = &m;
+
+ dbus_pending_call_set_notify( pending,
+ &pendingCallNotify,
+ sentMessage,
+ &deleteSentMessage );
}
Message Connection::sendWithReplyAndBlock( const Message &m )
{
DBusMessage *reply;
- reply = dbus_connection_send_with_reply_and_block( d->connection, m.message(), d->timeout, &d->error );
+ DBusMessage *message = m.message();
+ dbusMemFunction(
+ (reply = dbus_connection_send_with_reply_and_block( d->connection, message, d->timeout, &d->error ) )
+ != 0 );
+
+ dbus_message_unref( message );
if (dbus_error_is_set(&d->error)) {
- qDebug("error: %s, %s", d->error.name, d->error.message);
+ qDebug("DBusQt: Error sending message: %s, %s", d->error.name, d->error.message);
+ Message ret(Message::MethodReturn);
+ ret.arguments()->append( (Argument)QString( d->error.message ) );
dbus_error_free(&d->error);
+ return ret;
}
return Message( reply );
}
+void Connection::pendingCallNotify( DBusPendingCall *pending, void *data )
+{
+
+ //qDebug( "DBusQt: void Connection::pendingCallNotify( DBusPendingCall *pending, void *data ) " );
+ Connection *connection = static_cast<Private::SentMessage*>(data)->connection;
+ const Message *message = static_cast<Private::SentMessage*>(data)->message;
+
+ DBusMessage *replyMsg = dbus_pending_call_steal_reply( pending );
+ if( replyMsg == NULL )
+ {
+ qDebug( "DBusQt: Async method invocation got NULL reply" );
+ return;
+ }
+
+ Message reply( replyMsg );
+
+ connection->emitReplyReceived( *message, reply );
+
+ //we're not going to be using this pending call again
+ dbus_pending_call_unref( pending );
+
+}
+
+void Connection::deleteSentMessage( void *message )
+{
+ //qDebug( "DBusQt: void Connection::deleteSentMessage( void *message )" );
+ delete (Private::SentMessage*)message;
+}
+
+void Connection::emitReplyReceived(const Message &message, const Message &reply)
+{
+ //qDebug( "DBusQt: emitted replyReceived" );
+ emit replyReceived( message, reply );
+}
+
+DBusHandlerResult Connection::messageHandler( DBusConnection *connection, DBusMessage *message, void *user_data )
+{
+
+ Connection *conn = (Connection *)user_data;
+ const QString &path = ( dbus_message_get_path( message ) );
+
+ if( conn->d->pathMap->contains( path ) )
+ {
+ Object *o = (*conn->d->pathMap)[path];
+ return o->process( *conn, Message( message ) );
+ }
+ else
+ {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+}
+
+void Connection::unregisterHandler( DBusConnection *connection, void *user_data )
+{
+
+}
+
void* Connection::virtual_hook( int, void* )
{
}
@@ -161,7 +364,7 @@
d->setConnection( connection );
}
-
+}
/////////////////////////////////////////////////////////
diff -u -N dbus-old/qt/connection.h dbus/qt/connection.h
--- dbus-old/qt/connection.h 2004-09-04 16:09:48.000000000 +0100
+++ dbus/qt/connection.h 2005-06-15 12:38:16.000000000 +0100
@@ -2,6 +2,7 @@
/* connection.h: Qt wrapper for DBusConnection
*
* Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ * 2005 James Thorniley <james@uncommonlygood.co.uk>
*
* Licensed under the Academic Free License version 2.1
*
@@ -23,7 +24,6 @@
#ifndef DBUS_QT_CONNECTION_H
#define DBUS_QT_CONNECTION_H
-#include "message.h"
#include <qobject.h>
#include <qstring.h>
@@ -35,15 +35,39 @@
class Integrator;
}
+ class Message;
+ class Object;
+
+ /**
+ @brief Provides a connection to a D-BUS message bus.
+
+ A connection must be acquired before an app can communicate
+ over D-BUS. The easiest way to get a connection is to
+ use the {@link Connection( DBusBusType, QObject* ) bus type based constructor}.
+ You can then use send and friends
+ to send {@link Message messages} over D-BUS, or you can register
+ a new {@link Object object} with registerObject.
+ */
class Connection : public QObject
{
Q_OBJECT
+
public:
+
Connection( QObject *parent =0 );
Connection( const QString& host,
QObject *parent = 0 );
+
+ /**
+ @brief Opens a connection to the main session or system message bus.
+
+ @param type The message bus to connect to, either @arg @c DBUS_BUS_SESSION for the
+ session bus; or @arg @c DBUS_BUS_SYSTEM for the system bus.
+ @param parent The QObject parent for this QObject.
+ */
Connection( DBusBusType type, QObject* parent = 0 );
-
+ ~Connection();
+
bool isConnected() const;
bool isAuthenticated() const;
@@ -52,12 +76,71 @@
void stealBorrowMessage( const Message& );
void dbus_connection_setup_with_qt_main (DBusConnection *connection);
+ /**
+ @brief Registers an object on the message bus.
+
+ The object will be called when messages are sent to the path specified by
+ @c path and @c name.
+
+ @param object A pointer to the object to register. This pointer must not be
+ deleted without first unregistering it from the bus with unregisterObject()
+ @param path The path to the object, e.g. "/org/freedesktop/"
+ @param name The name of the object, e.g. "DBus"
+ @returns False if the object could not be registered.
+ @todo You can only register one object on any particular path,
+ is this the right behaviour?
+ @todo Deal with badly formed names / paths*/
+ bool registerObject( Object *object, const QString &path, const QString &name );
+
+ /**
+ @brief Unregisters an object so it will no longer recieve messages
+
+ The object with @c name at the given @c path will no longer receive
+ messages from this connection.
+
+ @param path The path of the object to unregister
+ @param name The name of the object to unregister
+ @returns false if no object is registered at the given path / name
+ */
+ bool unregisterObject( const QString &path, const QString &name );
+
+ /**
+ @brief Request a commonly known name to use on the bus.
+
+ All connections automatically register with a unique name on the D-BUS, but you
+ can also request a commonly known name, normally in the form of a reverse
+ domain name style name, e.g. "org.freedesktop.DBus". If some object already has this
+ name, it will not be moved.
+
+ @param name The commonly known name to request
+ @returns false if the name was not successfully acquired.
+ @todo FIXME: Does not support RequestName flags
+ */
+ bool requestName( const QString & name );
+
+ signals:
+ /**
+ Emitted when a reply is received from a message sent using sendWithReply().
+
+ @param message The original message
+ @param reply The reply
+ */
+ void replyReceived( const DBusQt::Message& message, const DBusQt::Message& reply );
+
public slots:
void open( const QString& );
void close();
void flush();
void send( const Message& );
- void sendWithReply( const Message& );
+ /**
+ Sends a method call asynchronously.
+
+ The message will be sent over this connection. If and when a reply is
+ received, replyReceived() will be emitted with the reply message.
+
+ @param message The message to send
+ */
+ void sendWithReply( const Message& message );
Message sendWithReplyAndBlock( const Message& );
protected slots:
@@ -71,10 +154,18 @@
friend class Internal::Integrator;
DBusConnection *connection() const;
Connection( DBusConnection *connection, QObject *parent );
-
+
+ void emitReplyReceived( const Message &message, const Message &reply );
+ static void pendingCallNotify( DBusPendingCall *pending, void/*SentMessage*/ *data );
+ static void deleteSentMessage( void/*SentMessage*/ *message );
+
+ static DBusHandlerResult messageHandler( DBusConnection *connection, DBusMessage *message, void *user_data );
+ static void unregisterHandler( DBusConnection *connection, void *user_data );
private:
- struct Private;
+ class Private;
Private *d;
+
+
};
}
diff -u -N dbus-old/qt/dbus-qt.h dbus/qt/dbus-qt.h
--- dbus-old/qt/dbus-qt.h 2004-08-10 04:07:01.000000000 +0100
+++ dbus/qt/dbus-qt.h 2005-06-14 19:58:46.000000000 +0100
@@ -22,10 +22,81 @@
* 02111-1307 USA
*
*/
+
#ifndef DBUS_QT_H
#define DBUS_QT_H
+/**
+@mainpage The D-BUS Qt bindings
+@todo write a main page for these bindings.
+*/
+
#include <dbus/dbus.h>
+#include <new>
+
+namespace DBusQt
+{
+
+ /**
+ @brief An exception to notify when a D-BUS library function runs out of memory.
+
+ This class inherits std::bad_alloc, so you can catch that if
+ you want to get all out of memory errors, not just dbus related ones.
+
+ @todo Clean up out of memory handling. Check it works properly
+ */
+ class OutOfMemory : public std::bad_alloc
+ {
+ public:
+ OutOfMemory() {}
+ };
+
+
+ /**
+ @internal
+
+ @brief Used to test for out of memory errors in dbus library functions.
+
+ Many dbus library functions return false or a null pointer if
+ they fail due to lack of memory. This function tests the return
+ value of such functions and throws an OutOfMemory exception if
+ appropriate.
+
+ @param result The result of a function that returns false
+ on out of memory errors.
+ @throws OutOfMemory If the expression result is false
+ */
+ inline void dbusMemFunction(bool result)
+ {
+ if( !result )
+ {
+ throw OutOfMemory();
+ }
+ }
+
+ /**
+ @internal
+
+ @brief Checks a DBusError object to see if it is an out of memory error.
+
+ Some dbus library functions will provide a DBusError object to
+ inform us when there is an out of memory error. This function checks
+ throws an OutOfMemory exception if @c error is an out of memory
+ error.
+
+ @param error The DBusError to check
+ @throws DBusQt::OutOfMemory If the error is an out of memory error.
+ */
+ inline void dbusErrorMemCheck(DBusError *error)
+ {
+ if( dbus_error_has_name( error, "org.freedesktop.DBus.Error.NoMemory" ) )
+ {
+ dbusMemFunction( false );
+ }
+ }
+
+}
+
/*
* Two approaches - one presented below a DBusQtConnection
* object which is a Qt wrapper around DBusConnection
diff -u -N dbus-old/qt/integrator.cpp dbus/qt/integrator.cpp
--- dbus-old/qt/integrator.cpp 2004-09-04 16:09:48.000000000 +0100
+++ dbus/qt/integrator.cpp 2005-06-14 19:59:51.000000000 +0100
@@ -22,6 +22,7 @@
*/
#include "integrator.h"
#include "connection.h"
+#include "dbus-qt.h"
#include <qtimer.h>
#include <qsocketnotifier.h>
@@ -124,19 +125,22 @@
{
m_timeouts.setAutoDelete( true );
+ dbusMemFunction(
dbus_connection_set_watch_functions( m_connection,
dbusAddWatch,
dbusRemoveWatch,
dbusToggleWatch,
- this, 0 );
+ this, 0 ));
+ dbusMemFunction(
dbus_connection_set_timeout_functions( m_connection,
dbusAddTimeout,
dbusRemoveTimeout,
dbusToggleTimeout,
- this, 0 );
+ this, 0 ));
+
dbus_connection_set_wakeup_main_function( m_connection,
- dbusWakeupMain,
- this, 0 );
+ dbusWakeupMain,
+ this, 0 );
}
Integrator::Integrator( DBusServer *server, QObject *parent )
@@ -145,16 +149,19 @@
m_connection = reinterpret_cast<DBusConnection*>( m_server );
m_timeouts.setAutoDelete( true );
+ dbusMemFunction(
dbus_server_set_watch_functions( m_server,
dbusAddWatch,
dbusRemoveWatch,
dbusToggleWatch,
- this, 0 );
+ this, 0 ));
+ dbusMemFunction(
dbus_server_set_timeout_functions( m_server,
dbusAddTimeout,
dbusRemoveTimeout,
dbusToggleTimeout,
- this, 0 );
+ this, 0 ));
+
dbus_server_set_new_connection_function( m_server,
dbusNewConnection,
this, 0 );
@@ -164,7 +171,7 @@
{
QIntDictIterator<Watch> it( m_watches );
for ( ; it.current(); ++it )
- dbus_watch_handle ( it.current()->watch, DBUS_WATCH_READABLE );
+ dbusMemFunction(dbus_watch_handle ( it.current()->watch, DBUS_WATCH_READABLE ));
emit readReady();
}
@@ -173,12 +180,12 @@
{
QIntDictIterator<Watch> it( m_watches );
for ( ; it.current(); ++it )
- dbus_watch_handle ( it.current()->watch, DBUS_WATCH_WRITABLE );
+ dbusMemFunction(dbus_watch_handle ( it.current()->watch, DBUS_WATCH_WRITABLE ));
}
void Integrator::slotTimeout( DBusTimeout *timeout )
{
- dbus_timeout_handle( timeout );
+ dbusMemFunction(dbus_timeout_handle( timeout ));
}
void Integrator::addWatch( DBusWatch *watch )
diff -u -N dbus-old/qt/message.cpp dbus/qt/message.cpp
--- dbus-old/qt/message.cpp 2005-01-17 19:49:52.000000000 +0000
+++ dbus/qt/message.cpp 2005-06-14 20:07:10.000000000 +0100
@@ -2,6 +2,7 @@
/* message.cpp: Qt wrapper for DBusMessage
*
* Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ * 2005 James Thorniley <james@uncommonlygood.co.uk>
*
* Licensed under the Academic Free License version 2.0
*
@@ -21,303 +22,377 @@
*
*/
#include "message.h"
+#include "argument.h"
+#include "dbus-qt.h"
+#include <stdlib.h>
#include <qmap.h>
+#include <qstring.h>
+#include <qstringlist.h>
-#include <cstdlib>
+#include <dbus/dbus.h>
namespace DBusQt {
-struct Message::iterator::IteratorData {
- DBusMessageIter *iter;
- QVariant var;
- bool end;
- DBusMessage *mesg;
+class Message::Private {
+ public:
+ DBusMessage *msg;
+ QValueList<Argument> *arguments;
+
+ Private();
+ ~Private();
+ /**
+ Fill this message with arguments from the DBusMessage
+ */
+ void fillListFromMessage();
+
+
+ /**
+ Append the arguments contained in the argument list to msg.
+
+ @return The message, identical to msg, but with arguments appended.
+ */
+ DBusMessage *fillMessageFromList() const;
+
+ private:
+ /**
+ Iterates through all available arguments using the given iterator.
+ creates Argument objects from the objects referenced by the iterator,
+ and adds them to the given list.
+ */
+ void readArguments( QValueList<Argument> *list, DBusMessageIter *iter );
+
+ /**
+ For the special case of reading in a string array. Creates a QStringList
+ representing the array and adds it to the given list.
+ */
+ void readStringList( QValueList<Argument> *list, DBusMessageIter *subIter );
+
+ /**
+ Reads in an array from arrayIter. I.e. it is assumed that arrayIter must have
+ argument type == DBUS_TYPE_ARRAY.
+ */
+ void arrayRecurse( QValueList<Argument> *list, DBusMessageIter *arrayIter );
+
+ void writeArguments( const QValueList<Argument> &list, DBusMessageIter *iter ) const;
+
+ void writeArray( const Argument &argument, DBusMessageIter *arrayIter, int recurseLevel = 0 ) const;
+
+ void writeStringList( const QStringList &stringList, DBusMessageIter *iter ) const;
};
-/**
- * Iterator.
- */
-Message::iterator::iterator()
+Message::Private::Private()
+ : arguments( new QValueList<Argument>() )
{
- d = new IteratorData;
- d->iter = 0; d->end = true;
}
-/**
- * Constructs iterator for the message.
- * @param msg message whose fields we want to iterate
- */
-Message::iterator::iterator( DBusMessage* msg )
+Message::Private::~Private()
{
- d = new IteratorData;
- d->mesg = msg;
- d->iter = static_cast<DBusMessageIter *>( malloc( sizeof(DBusMessageIter) ) );
- dbus_message_iter_init( d->mesg, d->iter );
- if ( !d->iter ) {
- qDebug("No iterator??");
+ delete arguments;
+ dbus_message_unref( msg );
+}
+void Message::Private::fillListFromMessage( )
+{
+ //qDebug( "void ArgumentList::fillListFromMessage( DBusMessage *message )" );
+
+ if( msg == 0 )
+ return; //nothing to do
+
+ DBusMessageIter iter;
+
+ if( !dbus_message_iter_init( msg, &iter ) )
+ //message has no arguments
+ return;
+
+ readArguments( arguments, &iter );
+
+}
+
+void Message::Private::readArguments( QValueList<Argument> *list, DBusMessageIter *iter )
+{
+ //qDebug( "void ArgumentList::readArguments( DBusMessageIter *iter )" );
+ int type;
+ DBusMessageIter *sub = 0; //sub iterator that will be needed for recursing into structs
+ QValueList<Argument> *structure = 0; //need somewhere to store structs when we recurse
+
+ while( (type = dbus_message_iter_get_arg_type(iter) ) != DBUS_TYPE_INVALID )
+ {
+
+ //qDebug( QString( QChar((char)type) ) );
+
+ if( type == DBUS_TYPE_INT32 )
+ {
+ dbus_int32_t i;
+ dbus_message_iter_get_basic( iter, &i );
+ list->append( Argument( (Q_INT32)i ) );
+ }
+ else if( type == DBUS_TYPE_STRING )
+ {
+ const char *str;
+ dbus_message_iter_get_basic( iter, &str );
+ list->append( Argument( QString::fromUtf8( str ) ) );
+ }
+ else if( type == DBUS_TYPE_STRUCT )
+ {
+ sub = new DBusMessageIter;
+ structure = new QValueList<Argument>();
+ dbus_message_iter_recurse( iter, sub );
+ readArguments( structure, sub );
+ list->append( Argument( *structure, Argument::Structure ) );
+
+ delete sub;
+ delete structure;
+ }
+ else if( type == DBUS_TYPE_ARRAY )
+ {
+ arrayRecurse( list, iter );
+ }
+ else
+ {
+ list->append( Argument() );
+ }
+
+ dbus_message_iter_next( iter );
+
}
- fillVar();
- d->end = false;
-}
-
-/**
- * Copy constructor for the iterator.
- * @param itr iterator
- */
-Message::iterator::iterator( const iterator& itr )
-{
- d = new IteratorData;
- d->iter = itr.d->iter;
- d->var = itr.d->var;
- d->end = itr.d->end;
-}
-
-/**
- * Destructor.
- */
-Message::iterator::~iterator()
-{
- free( d->iter );
- delete d; d=0;
-}
-
-/**
- * Creates an iterator equal to the @p itr iterator
- * @param itr other iterator
- * @return
- */
-Message::iterator&
-Message::iterator::operator=( const iterator& itr )
-{
- IteratorData *tmp = new IteratorData;
- tmp->iter = itr.d->iter;
- tmp->var = itr.d->var;
- tmp->end = itr.d->end;
- delete d; d=tmp;
- return *this;
+
+ //qDebug( QString( "Added %1 elements to message" ).arg( arguments->size() ) );
}
-/**
- * Returns the constant QVariant held by the iterator.
- * @return the constant reference to QVariant held by this iterator
- */
-const QVariant&
-Message::iterator::operator*() const
+void Message::Private::arrayRecurse( QValueList<Argument> *list, DBusMessageIter *arrayIter )
{
- return d->var;
-}
-/**
- * Returns the QVariant held by the iterator.
- * @return reference to QVariant held by this iterator
- */
-QVariant&
-Message::iterator::operator*()
-{
- return d->var;
-}
-
-/**
- * Moves to the next field and return a reference to itself after
- * incrementing.
- * @return reference to self after incrementing
- */
-Message::iterator&
-Message::iterator::operator++()
-{
- if ( d->end )
- return *this;
-
- if ( dbus_message_iter_next( d->iter ) ) {
- fillVar();
- } else {
- d->end = true;
- d->var = QVariant();
+ //qDebug( "DBusQt: Argument::Type Message::Private::arrayRecurse( QValueList<Argument> *list, DBusMessageIter *arrayIter )" );
+ DBusMessageIter subIter;
+ QValueList<Argument> *subArray; //for creating arrays of arrays
+ int argType;
+ int elementType = dbus_message_iter_get_element_type( arrayIter );
+
+ if( elementType == DBUS_TYPE_INVALID ) //array is empty
+ return;
+
+ dbus_message_iter_recurse( arrayIter, &subIter );
+
+
+ switch( elementType )
+ {
+ case DBUS_TYPE_ARRAY:
+ //qDebug( "DBusQt: Array containing arrays" );
+ subArray = new QValueList<Argument>;
+
+ while( ( argType = dbus_message_iter_get_arg_type( &subIter ) != DBUS_TYPE_INVALID ) )
+ {
+ arrayRecurse( subArray, &subIter );
+ dbus_message_iter_next( &subIter );
+ }
+ list->append( Argument( *subArray, Argument::ArrayArray ) );
+ delete subArray;
+ break;
+
+ case DBUS_TYPE_STRING:
+ //qDebug( "DBusQt: Array containing strings" );
+ readStringList( list, &subIter );
+ break;
+
}
- return *this;
+
}
-/**
- * Moves to the next field and returns self before incrementing.
- * @return self before incrementing
- */
-Message::iterator
-Message::iterator::operator++(int)
+void Message::Private::readStringList( QValueList<Argument> *list, DBusMessageIter *subIter )
{
- iterator itr( *this );
- operator++();
- return itr;
-}
-
-/**
- * Compares this iterator to @p it iterator.
- * @param it the iterator to which we're comparing this one to
- * @return true if they're equal, false otherwise
- */
-bool
-Message::iterator::operator==( const iterator& it )
-{
- if ( d->end == it.d->end ) {
- if ( d->end == true ) {
- return true;
- } else {
- return d->var == it.d->var;
- }
- } else
- return false;
-}
-
-/**
- * Compares two iterators.
- * @param it The other iterator.
- * @return true if two iterators are not equal, false
- * otherwise
- */
-bool
-Message::iterator::operator!=( const iterator& it )
-{
- return !operator==( it );
+ //qDebug( "void Message::Private::readStringList( QValueList<Argument> *list, DBusMessageIter *subIter )" );
+
+ //subIter should refer to an array of strings
+ //iterate through, extracting strings into tempList
+ //then add tempList to the supplied QValueList *list
+
+ QStringList tempList;
+
+ while( dbus_message_iter_get_arg_type(subIter) != DBUS_TYPE_INVALID )
+ {
+ const char *str;
+ dbus_message_iter_get_basic (subIter, &str);
+ tempList.append( QString::fromUtf8( str ) );
+ dbus_message_iter_next (subIter);
+ }
+
+ list->append( Argument( tempList ) );
+
+}
+
+DBusMessage *Message::Private::fillMessageFromList( ) const
+{
+
+ if( msg == 0 )
+ return 0;
+
+ DBusMessage *ret;
+ ret = dbus_message_copy( msg );
+ dbusMemFunction( ret );
+
+ DBusMessageIter iter;
+ dbus_message_iter_init_append( ret, &iter);
+
+ writeArguments( *arguments, &iter );
+
+ return ret;
}
-QVariant Message::iterator::marshallBaseType( DBusMessageIter* i )
+void Message::Private::writeArguments( const QValueList<Argument> &list, DBusMessageIter *iter ) const
{
- QVariant ret;
- switch (dbus_message_iter_get_arg_type(i)) {
- case DBUS_TYPE_INT32:
+
+ QCString strbuf;
+ char *buf;
+ DBusMessageIter subIter;
+ int i, buflen;
+
+ for( i = 0; i < list.count(); i++ )
+ {
+
+ const Argument& arg = list[i];
+
+ if( arg.argumentType() == Argument::Int32 )
{
- dbus_int32_t v;
- dbus_message_iter_get_basic (i, &v);
- ret = QVariant( v );
- }
- break;
- case DBUS_TYPE_UINT32:
+ dbus_int32_t i;
+ i = (dbus_int32_t)arg.toInt32();
+ dbusMemFunction( dbus_message_iter_append_basic( iter, DBUS_TYPE_INT32, &i ) );
+ }
+ else if( arg.argumentType() == Argument::String )
{
- dbus_uint32_t v;
- dbus_message_iter_get_basic (i, &v);
- ret = QVariant( v );
- }
- break;
- case DBUS_TYPE_DOUBLE:
+ //qDebug( "DBusQt: Appending string..." );
+ strbuf = arg.toString().utf8();
+ buflen = strbuf.size();
+ buf = new char[buflen+1];
+ qstrncpy( buf, strbuf.data(), buflen );
+ dbusMemFunction( dbus_message_iter_append_basic( iter, DBUS_TYPE_STRING, &buf ) );
+ delete buf;
+ }
+ else if( arg.argumentType() == Argument::Struct )
{
- double v;
- dbus_message_iter_get_basic (i, &v);
- ret = QVariant( v );
+ //qDebug( "DBusQt: Appending struct..." );
+ dbusMemFunction( dbus_message_iter_open_container( iter, DBUS_TYPE_STRUCT, NULL, &subIter ) );
+ writeArguments( arg.toStruct(), &subIter );
+ dbusMemFunction( dbus_message_iter_close_container( iter, &subIter ) );
}
- break;
- case DBUS_TYPE_STRING:
+
+ else if( arg.argumentType() == Argument::Array )
{
- const char *v;
- dbus_message_iter_get_basic (i, &v);
- ret = QVariant( v );
+ writeArray( arg, iter );
}
- break;
- default:
- ret = QVariant();
- break;
+
}
- return ret;
+
}
-/**
- * Fills QVariant based on what current DBusMessageIter helds.
- */
-void
-Message::iterator::fillVar()
+void Message::Private::writeArray( const Argument &arg, DBusMessageIter *arrayIter, int recurseLevel ) const
{
- switch ( dbus_message_iter_get_arg_type( d->iter ) ) {
- case DBUS_TYPE_INT32:
- case DBUS_TYPE_UINT32:
- case DBUS_TYPE_DOUBLE:
- case DBUS_TYPE_STRING:
- d->var = marshallBaseType( d->iter );
- break;
- case DBUS_TYPE_ARRAY: {
- switch ( dbus_message_iter_get_element_type( d->iter ) ) {
- case DBUS_TYPE_STRING: {
- QStringList tempList;
- DBusMessageIter sub;
- dbus_message_iter_recurse (d->iter, &sub);
- while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
- {
- const char *v;
- dbus_message_iter_get_basic (&sub, &v);
- tempList.append( QString( v ) );
- dbus_message_iter_next (&sub);
- }
- d->var = QVariant( tempList );
- break;
+ //qDebug( "DBusQt: void Message::Private::writeArray( const Argument &arg, DBusMessageIter *arrayIter, int recurseLevel ) const" );
+ DBusMessageIter subIter;
+ char *sig;
+
+ if( arg.elementType() == Argument::Array )
+ {
+ //qDebug( "DBusQt: Sending array of arrays...");
+ const QValueList<Argument> *subArray = &(arg.toArrayArray());
+
+ //now we have to work out the signature for this array
+ //this is a bit of a mess, but it works, i think
+ int nestLevel = 1;
+ const QValueList<Argument> *pArray = subArray; //work out how deeply nested the arrays are
+ while( (*pArray)[0].elementType() == Argument::Array )
+ {
+ pArray = &((*pArray)[0].toArrayArray());
+ nestLevel++;
}
- default:
- qDebug( "Array of type not implemented" );
- d->var = QVariant();
- break;
+ QCString s;
+ dbusMemFunction( s.fill( 'a', nestLevel ) );
+ //for ai, nestLevel = 1, aai nestLevel = 2 etc
+ //note that the sig only requires the types that are inside this array
+ sig = new char[s.size()+2]; // + 1 for the type + 1 for \0
+ qstrncpy( sig, s.data(), s.size() );
+ sig[nestLevel] = (char)(*pArray)[0].elementType();
+ sig[nestLevel+1] = '\0';
+
+ dbusMemFunction(
+ dbus_message_iter_open_container( arrayIter, DBUS_TYPE_ARRAY, sig, &subIter ) );
+
+ int count = subArray->count();
+ int i;
+ for( i = 0; i < count; i++ )
+ {
+ writeArray( (*subArray)[i], &subIter, ++recurseLevel );
}
- break;
- }
-#if 0
- /* DICT is gone for now, but expected to be reintroduced, or else
- * reintroduced as a flag on the introspection data that can
- * apply to array of struct of two fields
- */
- case DBUS_TYPE_DICT: {
- qDebug( "Got a hash!" );
- QMap<QString, QVariant> tempMap;
- DBusMessageIter dictIter;
- dbus_message_iter_init_dict_iterator( d->iter, &dictIter );
- do {
- char *key = dbus_message_iter_get_dict_key( &dictIter );
- tempMap[key] = marshallBaseType( &dictIter );
- dbus_free( key );
- dbus_message_iter_next( &dictIter );
- } while( dbus_message_iter_has_next( &dictIter ) );
- d->var = QVariant( tempMap );
- break;
- qDebug( "Hash/Dict type not implemented" );
- d->var = QVariant();
- break;
+ dbusMemFunction(
+ dbus_message_iter_close_container( arrayIter, &subIter ) );
+
+ delete sig;
}
-#endif
- default:
- qDebug( "not implemented" );
- d->var = QVariant();
- break;
+ else
+ {
+
+ sig = new char[2];
+ sig[1] = '\0';
+
+ switch( arg.elementType() )
+ {
+ case Argument::String:
+ //qDebug( "DBusQt: Array containing strings" );
+ sig[0] = 's';
+ dbusMemFunction(
+ dbus_message_iter_open_container( arrayIter, DBUS_TYPE_ARRAY, sig, &subIter ) );
+ writeStringList( arg.toStringList(), &subIter );
+ dbusMemFunction(
+ dbus_message_iter_close_container( arrayIter, &subIter ) );
+
+ break;
+
+ }
+
+ delete sig;
}
+
}
-/**
- * Returns a QVariant help by this iterator.
- * @return QVariant held by this iterator
- */
-QVariant
-Message::iterator::var() const
+void Message::Private::writeStringList( const QStringList &stringList, DBusMessageIter *iter ) const
{
- return d->var;
+ QCString strbuf;
+ char *buf;
+ int i = 0;
+ int buflen;
+ while( i < stringList.count() )
+ {
+ strbuf = stringList[i].utf8();
+ buflen = strbuf.size();
+ buf = new char[buflen+1];
+ qstrncpy( buf, strbuf.data(), buflen );
+ dbusMemFunction(
+ dbus_message_iter_append_basic( iter, DBUS_TYPE_STRING, &buf ) );
+ delete[] buf;
+ i++;
+ }
+
}
-struct Message::Private {
- DBusMessage *msg;
-};
-
Message::Message( DBusMessage *m )
{
+
+ //qDebug( "DBusQt: Message::Message( DBusMessage *m )" );
d = new Private;
d->msg = m;
+ dbus_message_ref( m );
+ d->fillListFromMessage();
}
-/**
- *
- */
-Message::Message( int messageType )
+Message::Message( MessageType type )
{
d = new Private;
- d->msg = dbus_message_new( messageType );
+ d->msg = dbus_message_new( type );
+ dbusMemFunction(d->msg!=0);
}
/**
* Constructs a new Message with the given service and name.
* @param service service service that the message should be sent to
- * @param name name of the message
*/
Message::Message( const QString& service, const QString& path,
const QString& interface, const QString& method )
@@ -325,12 +400,12 @@
d = new Private;
d->msg = dbus_message_new_method_call( service.latin1(), path.latin1(),
interface.latin1(), method.latin1() );
+ dbusMemFunction(d->msg!=0);
}
/**
* Constructs a message that is a reply to some other
* message.
- * @param name the name of the message
* @param replayingTo original_message the message which the created
* message is a reply to.
*/
@@ -338,14 +413,16 @@
{
d = new Private;
d->msg = dbus_message_new_method_return( replayingTo.d->msg );
+ dbusMemFunction(d->msg!=0);
}
-Message:: Message( const QString& path, const QString& interface,
+Message::Message( const QString& path, const QString& interface,
const QString& name )
{
d = new Private;
d->msg = dbus_message_new_signal( path.ascii(), interface.ascii(),
name.ascii() );
+ dbusMemFunction(d->msg!=0);
}
Message::Message( const Message& replayingTo, const QString& errorName,
@@ -354,31 +431,25 @@
d = new Private;
d->msg = dbus_message_new_error( replayingTo.d->msg, errorName.utf8(),
errorMessage.utf8() );
+ dbusMemFunction(d->msg!=0);
}
-Message Message::operator=( const Message& other )
-{
- //FIXME: ref the other.d->msg instead of copying it?
-}
/**
* Destructs message.
*/
Message::~Message()
{
- if ( d->msg ) {
- dbus_message_unref( d->msg );
- }
delete d; d=0;
}
-int Message::type() const
+Message::MessageType Message::type() const
{
- return dbus_message_get_type( d->msg );
+ return (MessageType)dbus_message_get_type( d->msg );
}
void Message::setPath( const QString& path )
{
- dbus_message_set_path( d->msg, path.ascii() );
+ dbusMemFunction(dbus_message_set_path( d->msg, path.ascii() ));
}
QString Message::path() const
@@ -388,7 +459,7 @@
void Message::setInterface( const QString& iface )
{
- dbus_message_set_interface( d->msg, iface.ascii() );
+ dbusMemFunction(dbus_message_set_interface( d->msg, iface.ascii() ));
}
QString Message::interface() const
@@ -398,7 +469,7 @@
void Message::setMember( const QString& member )
{
- dbus_message_set_member( d->msg, member.ascii() );
+ dbusMemFunction(dbus_message_set_member( d->msg, member.ascii() ));
}
QString Message::member() const
@@ -408,7 +479,7 @@
void Message::setErrorName( const QString& err )
{
- dbus_message_set_error_name( d->msg, err );
+ dbusMemFunction(dbus_message_set_error_name( d->msg, err ));
}
QString Message::errorName() const
@@ -418,7 +489,7 @@
void Message::setDestination( const QString& dest )
{
- dbus_message_set_destination( d->msg, dest );
+ dbusMemFunction(dbus_message_set_destination( d->msg, dest ));
}
QString Message::destination() const
@@ -452,45 +523,16 @@
return dbus_message_get_signature( d->msg );
}
-
-/**
- * Returns the starting iterator for the fields of this
- * message.
- * @return starting iterator
- */
-Message::iterator
-Message::begin() const
+QValueList<Argument> *Message::arguments() const
{
- return iterator( d->msg );
+ return d->arguments;
}
-/**
- * Returns the ending iterator for the fields of this
- * message.
- * @return ending iterator
- */
-Message::iterator
-Message::end() const
+bool Message::operator==( const Message& msg ) const
{
- return iterator();
-}
-/**
- * Returns the field at position @p i
- * @param i position of the wanted field
- * @return QVariant at position @p i or an empty QVariant
- */
-QVariant
-Message::at( int i )
-{
- iterator itr( d->msg );
-
- while ( i-- ) {
- if ( itr == end() )
- return QVariant();//nothing there
- ++itr;
- }
- return *itr;
+ return (d == msg.d);
+
}
/**
@@ -500,62 +542,7 @@
DBusMessage*
Message::message() const
{
- return d->msg;
-}
-
-Message& Message::operator<<( bool b )
-{
- const dbus_bool_t right_size_bool = b;
- dbus_message_append_args( d->msg, DBUS_TYPE_BOOLEAN, &right_size_bool,
- DBUS_TYPE_INVALID );
-}
-
-Message& Message::operator<<( Q_INT8 byte )
-{
- dbus_message_append_args( d->msg, DBUS_TYPE_BYTE, &byte,
- DBUS_TYPE_INVALID );
-}
-
-Message& Message::operator<<( Q_INT32 num )
-{
- dbus_message_append_args( d->msg, DBUS_TYPE_INT32, &num,
- DBUS_TYPE_INVALID );
-}
-
-Message& Message::operator<<( Q_UINT32 num )
-{
- dbus_message_append_args( d->msg, DBUS_TYPE_UINT32, &num,
- DBUS_TYPE_INVALID );
-}
-
-Message& Message::operator<<( Q_INT64 num )
-{
- dbus_message_append_args( d->msg, DBUS_TYPE_INT64, &num,
- DBUS_TYPE_INVALID );
-}
-
-Message& Message::operator<<( Q_UINT64 num )
-{
- dbus_message_append_args( d->msg, DBUS_TYPE_UINT64, &num,
- DBUS_TYPE_INVALID );
-}
-
-Message& Message::operator<<( double num )
-{
- dbus_message_append_args( d->msg, DBUS_TYPE_DOUBLE, &num,
- DBUS_TYPE_INVALID );
-}
-
-Message& Message::operator<<( const QString& str )
-{
- const char *u = str.utf8();
- dbus_message_append_args( d->msg, DBUS_TYPE_STRING, &u,
- DBUS_TYPE_INVALID );
-}
-
-Message& Message::operator<<( const QVariant& custom )
-{
- //FIXME: imeplement
+ return d->fillMessageFromList();
}
}
diff -u -N dbus-old/qt/message.h dbus/qt/message.h
--- dbus-old/qt/message.h 2004-08-10 04:07:01.000000000 +0100
+++ dbus/qt/message.h 2005-06-14 19:55:25.000000000 +0100
@@ -2,6 +2,7 @@
/* message.h: Qt wrapper for DBusMessage
*
* Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ * 2005 James Thorniley <james@uncommonlygood.co.uk>
*
* Licensed under the Academic Free License version 2.1
*
@@ -23,42 +24,50 @@
#ifndef DBUS_QT_MESSAGE_H
#define DBUS_QT_MESSAGE_H
-#include <qvariant.h>
-#include <qstring.h>
-#include <qstringlist.h>
-
#include "dbus/dbus.h"
+#ifdef __cplusplus //prevents Doxygen from deciding that Message is a template class
+template <class T> class QValueList;
+#endif
+class QString;
+
namespace DBusQt {
+ class Argument;
+
+ /**
+ A message that can be sent over the D-BUS protocol.
+
+ <p>Messages must be one of the four types described by {@link #MessageType}.
+ Once a message has been created, it should be sent using a Connection object.
+
+ */
class Message
{
public:
- class iterator {
- public:
- iterator();
- iterator( const iterator& );
- iterator( DBusMessage* msg );
- ~iterator();
-
- iterator& operator=( const iterator& );
- const QVariant& operator*() const;
- QVariant& operator*();
- iterator& operator++();
- iterator operator++(int);
- bool operator==( const iterator& it );
- bool operator!=( const iterator& it );
-
- QVariant var() const;
- protected:
- QVariant marshallBaseType( DBusMessageIter* i );
- void fillVar();
- struct IteratorData;
- IteratorData *d;
- };
- Message( int messageType );
- Message( DBusMessage * );//hide this one from the public implementation
+ /**
+ Types a D-BUS message can take.
+ */
+ enum MessageType {
+ Invalid = DBUS_MESSAGE_TYPE_INVALID,
+ ///A message to invoke a method on a remote object
+ MethodCall = DBUS_MESSAGE_TYPE_METHOD_CALL,
+ ///A message containing a reply from a remote method invocation
+ MethodReturn = DBUS_MESSAGE_TYPE_METHOD_RETURN,
+ ///A message containing an error message
+ Error = DBUS_MESSAGE_TYPE_ERROR,
+ ///A message containing an emitted signal
+ Signal = DBUS_MESSAGE_TYPE_SIGNAL
+ };
+
+
+ /**
+ Construct a generic message of the given type.
+
+ @param type The MessageType for the new message
+ */
+ Message( MessageType type );
Message( const QString& service, const QString& path,
const QString& interface, const QString& method );
Message( const Message& replayingTo );
@@ -66,16 +75,13 @@
const QString& name );
Message( const Message& replayingTo, const QString& errorName,
const QString& errorMessage );
-
- Message operator=( const Message& other );
-
- virtual ~Message();
-
- int type() const;
+ ~Message();
+
+ MessageType type() const;
void setPath( const QString& );
QString path() const;
-
+
void setInterface( const QString& );
QString interface() const;
@@ -93,36 +99,17 @@
QString signature() const;
- iterator begin() const;
- iterator end() const;
-
- QVariant at( int i );
-
-
- public:
- Message& operator<<( bool );
- Message& operator<<( Q_INT8 );
- Message& operator<<( Q_INT32 );
- Message& operator<<( Q_UINT32 );
- Message& operator<<( Q_INT64 );
- Message& operator<<( Q_UINT64 );
- Message& operator<<( double );
- Message& operator<<( const QString& );
- Message& operator<<( const QVariant& );
- //Message& operator<<();
- //Message& operator<<();
- //Message& operator<<();
- //Message& operator<<();
- //Message& operator<<();
- //Message& operator<<();
- //Message& operator<<();
-
+ QValueList<Argument> *arguments() const;
+
+ bool operator==( const Message &msg ) const;
+
protected:
- friend class Connection;
+ friend class Connection;
DBusMessage* message() const;
+ Message( DBusMessage * ); //hide this one from the public implementation
private:
- struct Private;
+ class Private;
Private *d;
};
diff -u -N dbus-old/qt/object.cpp dbus/qt/object.cpp
--- dbus-old/qt/object.cpp 1970-01-01 01:00:00.000000000 +0100
+++ dbus/qt/object.cpp 2005-06-14 19:55:25.000000000 +0100
@@ -0,0 +1,55 @@
+/* -*- mode: C++; c-file-style: "gnu" -*- */
+/* object.cpp: D-BUS / Qt object base class
+ *
+ * Copyright (C) 2005 James Thorniley <james@uncommonlygood.co.uk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "object.h"
+#include "message.h"
+
+namespace DBusQt
+{
+
+
+ class Object::Private
+ {
+ public:
+ Private(){}
+ ~Private() {}
+
+ };
+
+ Object::Object()
+ {
+ d = new Private;
+ }
+
+ Object::~Object()
+ {
+ delete d;
+ }
+
+ DBusHandlerResult Object::process( Connection &connection, const Message &message )
+ {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+
+}
diff -u -N dbus-old/qt/object.h dbus/qt/object.h
--- dbus-old/qt/object.h 1970-01-01 01:00:00.000000000 +0100
+++ dbus/qt/object.h 2005-06-14 19:55:25.000000000 +0100
@@ -0,0 +1,82 @@
+/* -*- mode: C++; c-file-style: "gnu" -*- */
+/* object.h: D-BUS / Qt object base class
+ *
+ * Copyright (C) 2005 James Thorniley <james@uncommonlygood.co.uk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef DBUS_QT_OBJECT_H
+#define DBUS_QT_OBJECT_H
+
+#include <dbus/dbus.h>
+
+class QString;
+
+namespace DBusQt
+{
+
+ class Message;
+ class Connection;
+
+ /**
+ @brief An object capable of receiving D-BUS method invocations and emitting D-BUS signals.
+
+ <p>Hopefully, in the future, subclasses will be created from some kind of IDL compiler.
+ For now, the way to implement an object is to inherit from this class, working out some
+ way to provide a path and name to identify this object on the bus. Register this object
+ on a bus using Connection::registerObject(). Reimplement process()
+ to receive object messages.
+ */
+ class Object
+ {
+ public:
+
+ /**
+ Create a new Object.
+
+ @todo Automatically attach to a D-BUS connection if possible
+ */
+ Object( );
+
+ ~Object();
+
+ /**
+ Receives incoming messages. Subclasses should reimplement this
+ to invoke object methods and send a reply if
+ appropriate.
+
+ @param message The D-BUS message that has been received.
+ @return A DBusHandlerResult. This should be one of
+ @arg @c DBUS_HANDLER_RESULT_HANDLED If this method requested was invoked;
+ @arg @c DBUS_HANDLER_RESULT_NOT_YET_HANDLED If the method requested
+ could not be invoked; or
+ @arg @c DBUS_HANDLER_RESULT_NEED_MEMORY If the method could not be
+ completed because of a lack of memory.
+ */
+ virtual DBusHandlerResult process( Connection &connection, const Message &message );
+
+ private:
+ class Private;
+ Private *d;
+
+ };
+
+}
+
+#endif