1 /* -*- mode: C++; c-file-style: "gnu" -*- */
2 /* message.cpp: Qt wrapper for DBusMessage
4 * Copyright (C) 2003 Zack Rusin <zack@kde.org>
6 * Licensed under the Academic Free License version 2.0
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 struct Message::iterator::IteratorData {
32 DBusMessageIter *iter;
41 Message::iterator::iterator()
44 d->iter = 0; d->end = true;
48 * Constructs iterator for the message.
49 * @param msg message whose fields we want to iterate
51 Message::iterator::iterator( DBusMessage* msg )
55 d->iter = static_cast<DBusMessageIter *>( malloc( sizeof(DBusMessageIter) ) );
56 dbus_message_iter_init( d->mesg, d->iter );
58 qDebug("No iterator??");
65 * Copy constructor for the iterator.
68 Message::iterator::iterator( const iterator& itr )
71 d->iter = itr.d->iter;
79 Message::iterator::~iterator()
86 * Creates an iterator equal to the @p itr iterator
87 * @param itr other iterator
91 Message::iterator::operator=( const iterator& itr )
93 IteratorData *tmp = new IteratorData;
94 tmp->iter = itr.d->iter;
95 tmp->var = itr.d->var;
96 tmp->end = itr.d->end;
102 * Returns the constant QVariant held by the iterator.
103 * @return the constant reference to QVariant held by this iterator
106 Message::iterator::operator*() const
112 * Returns the QVariant held by the iterator.
113 * @return reference to QVariant held by this iterator
116 Message::iterator::operator*()
122 * Moves to the next field and return a reference to itself after
124 * @return reference to self after incrementing
127 Message::iterator::operator++()
132 if ( dbus_message_iter_next( d->iter ) ) {
142 * Moves to the next field and returns self before incrementing.
143 * @return self before incrementing
146 Message::iterator::operator++(int)
148 iterator itr( *this );
154 * Compares this iterator to @p it iterator.
155 * @param it the iterator to which we're comparing this one to
156 * @return true if they're equal, false otherwise
159 Message::iterator::operator==( const iterator& it )
161 if ( d->end == it.d->end ) {
162 if ( d->end == true ) {
165 return d->var == it.d->var;
172 * Compares two iterators.
173 * @param it The other iterator.
174 * @return true if two iterators are not equal, false
178 Message::iterator::operator!=( const iterator& it )
180 return !operator==( it );
183 QVariant Message::iterator::marshallBaseType( DBusMessageIter* i )
186 switch (dbus_message_iter_get_arg_type(i)) {
187 case DBUS_TYPE_INT32:
190 dbus_message_iter_get_basic (i, &v);
194 case DBUS_TYPE_UINT32:
197 dbus_message_iter_get_basic (i, &v);
201 case DBUS_TYPE_DOUBLE:
204 dbus_message_iter_get_basic (i, &v);
208 case DBUS_TYPE_STRING:
211 dbus_message_iter_get_basic (i, &v);
223 * Fills QVariant based on what current DBusMessageIter helds.
226 Message::iterator::fillVar()
228 switch ( dbus_message_iter_get_arg_type( d->iter ) ) {
229 case DBUS_TYPE_INT32:
230 case DBUS_TYPE_UINT32:
231 case DBUS_TYPE_DOUBLE:
232 case DBUS_TYPE_STRING:
233 d->var = marshallBaseType( d->iter );
235 case DBUS_TYPE_ARRAY: {
236 switch ( dbus_message_iter_get_element_type( d->iter ) ) {
237 case DBUS_TYPE_STRING: {
238 QStringList tempList;
240 dbus_message_iter_recurse (d->iter, &sub);
241 while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
244 dbus_message_iter_get_basic (&sub, &v);
245 tempList.append( QString( v ) );
246 dbus_message_iter_next (&sub);
248 d->var = QVariant( tempList );
252 qDebug( "Array of type not implemented" );
259 /* DICT is gone for now, but expected to be reintroduced, or else
260 * reintroduced as a flag on the introspection data that can
261 * apply to array of struct of two fields
263 case DBUS_TYPE_DICT: {
264 qDebug( "Got a hash!" );
265 QMap<QString, QVariant> tempMap;
266 DBusMessageIter dictIter;
267 dbus_message_iter_init_dict_iterator( d->iter, &dictIter );
269 char *key = dbus_message_iter_get_dict_key( &dictIter );
270 tempMap[key] = marshallBaseType( &dictIter );
272 dbus_message_iter_next( &dictIter );
273 } while( dbus_message_iter_has_next( &dictIter ) );
274 d->var = QVariant( tempMap );
276 qDebug( "Hash/Dict type not implemented" );
282 qDebug( "not implemented" );
289 * Returns a QVariant help by this iterator.
290 * @return QVariant held by this iterator
293 Message::iterator::var() const
298 struct Message::Private {
302 Message::Message( DBusMessage *m )
311 Message::Message( int messageType )
314 d->msg = dbus_message_new( messageType );
318 * Constructs a new Message with the given service and name.
319 * @param service service service that the message should be sent to
320 * @param name name of the message
322 Message::Message( const QString& service, const QString& path,
323 const QString& interface, const QString& method )
326 d->msg = dbus_message_new_method_call( service.latin1(), path.latin1(),
327 interface.latin1(), method.latin1() );
331 * Constructs a message that is a reply to some other
333 * @param name the name of the message
334 * @param replayingTo original_message the message which the created
335 * message is a reply to.
337 Message::Message( const Message& replayingTo )
340 d->msg = dbus_message_new_method_return( replayingTo.d->msg );
343 Message:: Message( const QString& path, const QString& interface,
344 const QString& name )
347 d->msg = dbus_message_new_signal( path.ascii(), interface.ascii(),
351 Message::Message( const Message& replayingTo, const QString& errorName,
352 const QString& errorMessage )
355 d->msg = dbus_message_new_error( replayingTo.d->msg, errorName.utf8(),
356 errorMessage.utf8() );
359 Message Message::operator=( const Message& other )
361 //FIXME: ref the other.d->msg instead of copying it?
369 dbus_message_unref( d->msg );
374 int Message::type() const
376 return dbus_message_get_type( d->msg );
379 void Message::setPath( const QString& path )
381 dbus_message_set_path( d->msg, path.ascii() );
384 QString Message::path() const
386 return dbus_message_get_path( d->msg );
389 void Message::setInterface( const QString& iface )
391 dbus_message_set_interface( d->msg, iface.ascii() );
394 QString Message::interface() const
396 return dbus_message_get_interface( d->msg );
399 void Message::setMember( const QString& member )
401 dbus_message_set_member( d->msg, member.ascii() );
404 QString Message::member() const
406 return dbus_message_get_member( d->msg );
409 void Message::setErrorName( const QString& err )
411 dbus_message_set_error_name( d->msg, err );
414 QString Message::errorName() const
416 return dbus_message_get_error_name( d->msg );
419 void Message::setDestination( const QString& dest )
421 dbus_message_set_destination( d->msg, dest );
424 QString Message::destination() const
426 return dbus_message_get_destination( d->msg );
430 * Sets the message sender.
431 * @param sender the sender
432 * @return false if unsuccessful
435 Message::setSender( const QString& sender )
437 return dbus_message_set_sender( d->msg, sender.latin1() );
441 * Returns sender of this message.
445 Message::sender() const
447 return dbus_message_get_sender( d->msg );
450 QString Message::signature() const
452 return dbus_message_get_signature( d->msg );
457 * Returns the starting iterator for the fields of this
459 * @return starting iterator
462 Message::begin() const
464 return iterator( d->msg );
468 * Returns the ending iterator for the fields of this
470 * @return ending iterator
479 * Returns the field at position @p i
480 * @param i position of the wanted field
481 * @return QVariant at position @p i or an empty QVariant
486 iterator itr( d->msg );
490 return QVariant();//nothing there
497 * The underlying DBusMessage of this class.
498 * @return DBusMessage pointer.
501 Message::message() const
506 Message& Message::operator<<( bool b )
508 const dbus_bool_t right_size_bool = b;
509 dbus_message_append_args( d->msg, DBUS_TYPE_BOOLEAN, &right_size_bool,
513 Message& Message::operator<<( Q_INT8 byte )
515 dbus_message_append_args( d->msg, DBUS_TYPE_BYTE, &byte,
519 Message& Message::operator<<( Q_INT32 num )
521 dbus_message_append_args( d->msg, DBUS_TYPE_INT32, &num,
525 Message& Message::operator<<( Q_UINT32 num )
527 dbus_message_append_args( d->msg, DBUS_TYPE_UINT32, &num,
531 Message& Message::operator<<( Q_INT64 num )
533 dbus_message_append_args( d->msg, DBUS_TYPE_INT64, &num,
537 Message& Message::operator<<( Q_UINT64 num )
539 dbus_message_append_args( d->msg, DBUS_TYPE_UINT64, &num,
543 Message& Message::operator<<( double num )
545 dbus_message_append_args( d->msg, DBUS_TYPE_DOUBLE, &num,
549 Message& Message::operator<<( const QString& str )
551 const char *u = str.utf8();
552 dbus_message_append_args( d->msg, DBUS_TYPE_STRING, &u,
556 Message& Message::operator<<( const QVariant& custom )