Main Page | Modules | Namespace List | Class Hierarchy | Data Structures | Directories | File List | Namespace Members | Data Fields | Related Pages

message.cpp

00001 /* -*- mode: C++; c-file-style: "gnu" -*- */
00002 /* message.cpp: Qt wrapper for DBusMessage
00003  *
00004  * Copyright (C) 2003  Zack Rusin <zack@kde.org>
00005  *
00006  * Licensed under the Academic Free License version 2.0
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 #include "message.h"
00024 
00025 #include <qmap.h>
00026 
00027 #include <cstdlib>
00028 
00029 namespace DBusQt {
00030 
00031 struct Message::iterator::IteratorData {
00032   DBusMessageIter *iter;
00033   QVariant         var;
00034   bool             end;
00035   DBusMessage     *mesg;
00036 };
00037 
00041 Message::iterator::iterator()
00042 {
00043   d = new IteratorData;
00044   d->iter = 0; d->end = true;
00045 }
00046 
00051 Message::iterator::iterator( DBusMessage* msg )
00052 {
00053   d = new IteratorData;
00054   d->mesg = msg;
00055   d->iter = static_cast<DBusMessageIter *>( malloc( sizeof(DBusMessageIter) ) );
00056   dbus_message_iter_init( d->mesg, d->iter );
00057   if ( !d->iter ) {
00058     qDebug("No iterator??");
00059   }
00060   fillVar();
00061   d->end = false;
00062 }
00063 
00068 Message::iterator::iterator( const iterator& itr )
00069 {
00070   d = new IteratorData;
00071   d->iter = itr.d->iter;
00072   d->var  = itr.d->var;
00073   d->end  = itr.d->end;
00074 }
00075 
00079 Message::iterator::~iterator()
00080 {
00081   free( d->iter );
00082   delete d; d=0;
00083 }
00084 
00090 Message::iterator&
00091 Message::iterator::operator=( const iterator& itr )
00092 {
00093   IteratorData *tmp = new IteratorData;
00094   tmp->iter = itr.d->iter;
00095   tmp->var  = itr.d->var;
00096   tmp->end  = itr.d->end;
00097   delete d; d=tmp;
00098   return *this;
00099 }
00100 
00105 const QVariant&
00106 Message::iterator::operator*() const
00107 {
00108   return d->var;
00109 }
00110 
00115 QVariant&
00116 Message::iterator::operator*()
00117 {
00118   return d->var;
00119 }
00120 
00126 Message::iterator&
00127 Message::iterator::operator++()
00128 {
00129   if ( d->end )
00130     return *this;
00131 
00132   if (  dbus_message_iter_next( d->iter ) ) {
00133     fillVar();
00134   } else {
00135     d->end = true;
00136     d->var = QVariant();
00137   }
00138   return *this;
00139 }
00140 
00145 Message::iterator
00146 Message::iterator::operator++(int)
00147 {
00148   iterator itr( *this );
00149   operator++();
00150   return itr;
00151 }
00152 
00158 bool
00159 Message::iterator::operator==( const iterator& it )
00160 {
00161   if ( d->end == it.d->end ) {
00162     if ( d->end == true ) {
00163       return true;
00164     } else {
00165       return d->var == it.d->var;
00166     }
00167   } else
00168     return false;
00169 }
00170 
00177 bool
00178 Message::iterator::operator!=( const iterator& it )
00179 {
00180   return !operator==( it );
00181 }
00182 
00183 QVariant Message::iterator::marshallBaseType( DBusMessageIter* i )
00184 {
00185   QVariant ret;
00186   switch (dbus_message_iter_get_arg_type(i)) {
00187   case DBUS_TYPE_INT32:
00188     {
00189       dbus_int32_t v;
00190       dbus_message_iter_get_basic (i, &v);
00191       ret = QVariant( v );
00192     }
00193     break;
00194   case DBUS_TYPE_UINT32:
00195     {
00196       dbus_uint32_t v;
00197       dbus_message_iter_get_basic (i, &v);
00198       ret = QVariant( v );
00199     }
00200     break;
00201   case DBUS_TYPE_DOUBLE:
00202     {
00203       double v;
00204       dbus_message_iter_get_basic (i, &v);
00205       ret = QVariant( v );
00206     }
00207     break;
00208   case DBUS_TYPE_STRING:
00209     {
00210       const char *v;
00211       dbus_message_iter_get_basic (i, &v);
00212       ret = QVariant( v );
00213     }
00214     break;
00215   default:
00216     ret = QVariant();
00217     break;
00218   }
00219   return ret;
00220 }
00221 
00225 void
00226 Message::iterator::fillVar()
00227 {
00228   switch ( dbus_message_iter_get_arg_type( d->iter ) ) {
00229   case DBUS_TYPE_INT32:
00230   case DBUS_TYPE_UINT32:
00231   case DBUS_TYPE_DOUBLE:
00232   case DBUS_TYPE_STRING:
00233     d->var = marshallBaseType( d->iter );
00234     break;
00235   case DBUS_TYPE_ARRAY: {
00236     switch ( dbus_message_iter_get_element_type( d->iter ) ) {
00237     case DBUS_TYPE_STRING: {
00238       QStringList tempList;
00239       DBusMessageIter sub;
00240       dbus_message_iter_recurse (d->iter, &sub);
00241       while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
00242         {
00243           const char *v;
00244           dbus_message_iter_get_basic (&sub, &v);
00245           tempList.append( QString( v ) );
00246           dbus_message_iter_next (&sub);
00247         }
00248       d->var = QVariant( tempList );
00249       break;
00250     }
00251     default:
00252       qDebug( "Array of type not implemented" );
00253       d->var = QVariant();
00254       break;
00255     }
00256     break;
00257   }
00258 #if 0
00259   /* DICT is gone for now, but expected to be reintroduced, or else
00260    * reintroduced as a flag on the introspection data that can
00261    * apply to array of struct of two fields
00262    */
00263   case DBUS_TYPE_DICT: {
00264     qDebug( "Got a hash!" );
00265     QMap<QString, QVariant> tempMap;
00266     DBusMessageIter dictIter;
00267     dbus_message_iter_init_dict_iterator( d->iter, &dictIter );
00268     do {
00269       char *key = dbus_message_iter_get_dict_key( &dictIter );
00270       tempMap[key] = marshallBaseType( &dictIter );
00271       dbus_free( key );
00272       dbus_message_iter_next( &dictIter );
00273     } while( dbus_message_iter_has_next( &dictIter ) );
00274     d->var = QVariant( tempMap );
00275     break;
00276     qDebug( "Hash/Dict type not implemented" );
00277     d->var = QVariant();
00278     break;
00279   }
00280 #endif
00281   default:
00282     qDebug( "not implemented" );
00283     d->var = QVariant();
00284     break;
00285   }
00286 }
00287 
00292 QVariant
00293 Message::iterator::var() const
00294 {
00295   return d->var;
00296 }
00297 
00298 struct Message::Private {
00299   DBusMessage *msg;
00300 };
00301 
00302 Message::Message( DBusMessage *m )
00303 {
00304   d = new Private;
00305   d->msg = m;
00306 }
00307 
00311 Message::Message( int messageType )
00312 {
00313   d = new Private;
00314   d->msg = dbus_message_new( messageType );
00315 }
00316 
00322 Message::Message( const QString& service, const QString& path,
00323                   const QString& interface, const QString& method )
00324 {
00325   d = new Private;
00326   d->msg = dbus_message_new_method_call( service.latin1(), path.latin1(),
00327                                          interface.latin1(), method.latin1() );
00328 }
00329 
00337 Message::Message( const Message& replayingTo )
00338 {
00339   d = new Private;
00340   d->msg = dbus_message_new_method_return( replayingTo.d->msg );
00341 }
00342 
00343 Message:: Message( const QString& path, const QString& interface,
00344                    const QString& name )
00345 {
00346   d = new Private;
00347   d->msg = dbus_message_new_signal( path.ascii(), interface.ascii(),
00348                                     name.ascii() );
00349 }
00350 
00351 Message::Message( const Message& replayingTo, const QString& errorName,
00352                   const QString& errorMessage )
00353 {
00354   d = new Private;
00355   d->msg = dbus_message_new_error( replayingTo.d->msg, errorName.utf8(),
00356                                    errorMessage.utf8() );
00357 }
00358 
00359 Message Message::operator=( const Message& other )
00360 {
00361   //FIXME: ref the other.d->msg instead of copying it?
00362   return (Message &)(d->msg);
00363 }
00367 Message::~Message()
00368 {
00369   if ( d->msg ) {
00370     dbus_message_unref( d->msg );
00371   }
00372   delete d; d=0;
00373 }
00374 
00375 int Message::type() const
00376 {
00377   return dbus_message_get_type( d->msg );
00378 }
00379 
00380 void Message::setPath( const QString& path )
00381 {
00382   dbus_message_set_path( d->msg, path.ascii() );
00383 }
00384 
00385 QString Message::path() const
00386 {
00387   return dbus_message_get_path( d->msg );
00388 }
00389 
00390 void Message::setInterface( const QString& iface )
00391 {
00392   dbus_message_set_interface( d->msg, iface.ascii() );
00393 }
00394 
00395 QString Message::interface() const
00396 {
00397   return dbus_message_get_interface( d->msg );
00398 }
00399 
00400 void Message::setMember( const QString& member )
00401 {
00402   dbus_message_set_member( d->msg, member.ascii() );
00403 }
00404 
00405 QString Message::member() const
00406 {
00407   return dbus_message_get_member( d->msg );
00408 }
00409 
00410 void Message::setErrorName( const QString& err )
00411 {
00412   dbus_message_set_error_name( d->msg, err );
00413 }
00414 
00415 QString Message::errorName() const
00416 {
00417   return dbus_message_get_error_name( d->msg );
00418 }
00419 
00420 void Message::setDestination( const QString& dest )
00421 {
00422   dbus_message_set_destination( d->msg, dest );
00423 }
00424 
00425 QString Message::destination() const
00426 {
00427   return dbus_message_get_destination( d->msg );
00428 }
00429 
00435 bool
00436 Message::setSender( const QString& sender )
00437 {
00438   return dbus_message_set_sender( d->msg, sender.latin1() );
00439 }
00440 
00445 QString
00446 Message::sender() const
00447 {
00448   return dbus_message_get_sender( d->msg );
00449 }
00450 
00451 QString Message::signature() const
00452 {
00453   return dbus_message_get_signature( d->msg );
00454 }
00455 
00456 
00462 Message::iterator
00463 Message::begin() const
00464 {
00465   return iterator( d->msg );
00466 }
00467 
00473 Message::iterator
00474 Message::end() const
00475 {
00476   return iterator();
00477 }
00478 
00484 QVariant
00485 Message::at( int i )
00486 {
00487   iterator itr( d->msg );
00488 
00489   while ( i-- ) {
00490     if ( itr == end() )
00491       return QVariant();//nothing there
00492     ++itr;
00493   }
00494   return *itr;
00495 }
00496 
00501 DBusMessage*
00502 Message::message() const
00503 {
00504   return d->msg;
00505 }
00506 
00507 Message& Message::operator<<( bool b )
00508 {
00509   const dbus_bool_t right_size_bool = b;
00510   dbus_message_append_args( d->msg, DBUS_TYPE_BOOLEAN, &right_size_bool,
00511                             DBUS_TYPE_INVALID );
00512   return (Message &)(d->msg);
00513 }
00514 
00515 Message& Message::operator<<( Q_INT8 byte )
00516 {
00517   dbus_message_append_args( d->msg, DBUS_TYPE_BYTE, &byte,
00518                             DBUS_TYPE_INVALID );
00519   return (Message &)(d->msg);
00520 }
00521 
00522 Message& Message::operator<<( Q_INT32 num )
00523 {
00524   dbus_message_append_args( d->msg, DBUS_TYPE_INT32, &num,
00525                             DBUS_TYPE_INVALID );
00526   return (Message &)(d->msg);
00527 }
00528 
00529 Message& Message::operator<<( Q_UINT32 num )
00530 {
00531   dbus_message_append_args( d->msg, DBUS_TYPE_UINT32, &num,
00532                             DBUS_TYPE_INVALID );
00533   return (Message &)(d->msg);
00534 }
00535 
00536 Message& Message::operator<<( Q_INT64 num )
00537 {
00538   dbus_message_append_args( d->msg, DBUS_TYPE_INT64, &num,
00539                             DBUS_TYPE_INVALID );
00540   return (Message &)(d->msg);
00541 }
00542 
00543 Message& Message::operator<<( Q_UINT64 num )
00544 {
00545   dbus_message_append_args( d->msg, DBUS_TYPE_UINT64, &num,
00546                             DBUS_TYPE_INVALID );
00547   return (Message &)(d->msg);
00548 }
00549 
00550 Message& Message::operator<<( double num )
00551 {
00552   dbus_message_append_args( d->msg, DBUS_TYPE_DOUBLE, &num,
00553                             DBUS_TYPE_INVALID );
00554   return (Message &)(d->msg);
00555 }
00556 
00557 Message& Message::operator<<( const QString& str )
00558 {
00559   const char *u = str.utf8();
00560   dbus_message_append_args( d->msg, DBUS_TYPE_STRING, &u,
00561                             DBUS_TYPE_INVALID );
00562   return (Message &)(d->msg);
00563 }
00564 
00565 Message& Message::operator<<( const QVariant& custom )
00566 {
00567   //FIXME: imeplement
00568   return (Message &)(d->msg);
00569 }
00570 
00571 }

Generated on Tue Sep 13 01:28:08 2005 for D-BUS by  doxygen 1.4.4