dbus-cxx logo

messageiterator.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007,2009,2010 by Rick L. Vinyard, Jr.                  *
00003  *   rvinyard@cs.nmsu.edu                                                  *
00004  *                                                                         *
00005  *   This file is part of the dbus-cxx library.                            *
00006  *                                                                         *
00007  *   The dbus-cxx library is free software; you can redistribute it and/or *
00008  *   modify it under the terms of the GNU General Public License           *
00009  *   version 3 as published by the Free Software Foundation.               *
00010  *                                                                         *
00011  *   The dbus-cxx library is distributed in the hope that it will be       *
00012  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty   *
00013  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   *
00014  *   General Public License for more details.                              *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU General Public License     *
00017  *   along with this software. If not see <http://www.gnu.org/licenses/>.  *
00018  ***************************************************************************/
00019 #include <dbus/dbus.h>
00020 
00021 #include <dbus-cxx/types.h>
00022 
00023 #ifndef DBUSCXX_MESSAGEITERATOR_H
00024 #define DBUSCXX_MESSAGEITERATOR_H
00025 
00026 namespace DBus
00027 {
00028 
00029   class Message;
00030 
00038   class MessageIterator
00039   {
00040     public:
00041 
00042       MessageIterator();
00043 
00044       MessageIterator( const Message& message );
00045       
00046       MessageIterator( DBusCxxPointer<Message> message );
00047 
00052       const Message* message() const;
00053 
00055       DBusMessageIter* cobj();
00056 
00058       bool init( const Message& message );
00059 
00061       void invalidate();
00062 
00064       bool is_valid() const;
00065 
00067       bool has_next() const;
00068 
00074       bool next();
00075 
00076       MessageIterator& operator ++();
00077 
00078       MessageIterator operator ++( int );
00079 
00080       bool operator==( const MessageIterator& other );
00081 
00083       Type arg_type() const;
00084 
00090       Type element_type() const;
00091 
00093       bool is_fixed() const;
00094 
00096       bool is_container() const;
00097 
00099       bool is_array() const;
00100 
00102       bool is_dict() const;
00103 
00109       MessageIterator recurse();
00110 
00112       std::string signature() const;
00113 
00122 //       void value( std::vector<std::string>& temp );
00123 
00124 //       void value( std::string& temp );
00125 
00126 //       void value( Variant& temp );
00127 
00128 //       template <typename T0>
00129 //       void value( Struct<T0>& temp ) {
00130 //         if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast();
00131 //         MessageIterator subiter = this->recurse();
00132 //         subiter.value( boost::get<0>( temp ) );
00133 //       }
00134 
00135 //       template <typename T0, typename T1>
00136 //       void value( Struct<T0,T1>& temp ) {
00137 //         if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast();
00138 //         MessageIterator subiter = this->recurse();
00139 //         subiter.value( boost::get<0>( temp ) );
00140 //         subiter.value( boost::get<1>( temp ) );
00141 //       }
00142 
00143 //       template <typename T0, typename T1, typename T2>
00144 //       void value( Struct<T0,T1,T2>& temp ) {
00145 //         if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast();
00146 //         MessageIterator subiter = this->recurse();
00147 //         subiter.value( boost::get<0>( temp ) );
00148 //         subiter.value( boost::get<1>( temp ) );
00149 //         subiter.value( boost::get<2>( temp ) );
00150 //       }
00151 // 
00152 //       template <typename T0, typename T1, typename T2, typename T3>
00153 //       void value( Struct<T0,T1,T2,T3>& temp ) {
00154 //         if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast();
00155 //         MessageIterator subiter = this->recurse();
00156 //         subiter.value( boost::get<0>( temp ) );
00157 //         subiter.value( boost::get<1>( temp ) );
00158 //         subiter.value( boost::get<2>( temp ) );
00159 //         subiter.value( boost::get<3>( temp ) );
00160 //       }
00161 // 
00162 //       template <typename T0, typename T1, typename T2, typename T3, typename T4>
00163 //       void value( Struct<T0,T1,T2,T3,T4>& temp ) {
00164 //         if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast();
00165 //         MessageIterator subiter = this->recurse();
00166 //         subiter.value( boost::get<0>( temp ) );
00167 //         subiter.value( boost::get<1>( temp ) );
00168 //         subiter.value( boost::get<2>( temp ) );
00169 //         subiter.value( boost::get<3>( temp ) );
00170 //         subiter.value( boost::get<4>( temp ) );
00171 //       }
00172 // 
00173 //       template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
00174 //       void value( Struct<T0,T1,T2,T3,T4,T5>& temp ) {
00175 //         if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast();
00176 //         MessageIterator subiter = this->recurse();
00177 //         subiter.value( boost::get<0>( temp ) );
00178 //         subiter.value( boost::get<1>( temp ) );
00179 //         subiter.value( boost::get<2>( temp ) );
00180 //         subiter.value( boost::get<3>( temp ) );
00181 //         subiter.value( boost::get<4>( temp ) );
00182 //         subiter.value( boost::get<5>( temp ) );
00183 //       }
00184 // 
00185 //       template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
00186 //       void value( Struct<T0,T1,T2,T3,T4,T5,T6>& temp ) {
00187 //         if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast();
00188 //         MessageIterator subiter = this->recurse();
00189 //         subiter.value( boost::get<0>( temp ) );
00190 //         subiter.value( boost::get<1>( temp ) );
00191 //         subiter.value( boost::get<2>( temp ) );
00192 //         subiter.value( boost::get<3>( temp ) );
00193 //         subiter.value( boost::get<4>( temp ) );
00194 //         subiter.value( boost::get<5>( temp ) );
00195 //         subiter.value( boost::get<6>( temp ) );
00196 //       }
00197 
00198 //       template <typename Key, typename Data>
00199 //       void value( std::vector<std::pair<Key,Data> >& temp ) {
00200 //         if ( this->element_type() != TYPE_ARRAY )
00201 //           throw ErrorInvalidTypecast( "Extracting non-array type into dictionary" );
00202 // 
00203 //         temp.clear();
00204 //         MessageIterator subiter = this->recurse();
00205 //         MessageIterator subsubiter;
00206 //         Key k;
00207 //         Data d;
00208 // 
00209 //         while ( subiter.has_next() ) {
00210 //           if ( subiter.element_type() != TYPE_DICT_ENTRY )
00211 //             throw ErrorInvalidTypecast( "Extracting non-dictionary-entry type into dictionary entry" );
00212 //           subsubiter = subiter.recurse();
00213 //           subsubiter.value( k );
00214 //           ++subsubiter;
00215 //           subsubiter.value( d );
00216 //           temp.push_back( std::make_pair( k,d ) );
00217 //           ++subiter;
00218 //         }
00219 //       }
00220 
00221 
00222 
00223       operator bool();
00224       operator uint8_t();
00225       operator uint16_t();
00226       operator int16_t();
00227       operator uint32_t();
00228       operator int32_t();
00229       operator uint64_t();
00230       operator int64_t();
00231       operator double();
00232       operator const char*();
00233       
00234       operator char();
00235       operator int8_t();
00236       operator float();
00237       #if DBUS_CXX_SIZEOF_LONG_INT == 4
00238         operator long int();
00239         operator unsigned long int();
00240       #endif
00241         
00242       template <typename T>
00243       operator std::vector<T>() {
00244         return get_array<T>();
00245       }
00246 
00247       bool        get_bool();
00248       uint8_t     get_uint8();
00249       uint16_t    get_uint16();
00250       int16_t     get_int16();
00251       uint32_t    get_uint32();
00252       int32_t     get_int32();
00253       uint64_t    get_uint64();
00254       int64_t     get_int64();
00255       double      get_double();
00256       const char* get_string();
00257 
00258       template <typename T>
00259       std::vector<T> get_array() {
00260         
00261         if ( not this->is_array() )
00262           throw ErrorInvalidTypecast::create( "MessageIterator: Extracting non array into std::vector" );
00263         
00264         if ( not this->is_fixed() )
00265           throw ErrorInvalidTypecast::create( "MessageIterator: Extracting non fixed array into std::vector" );
00266         
00267         if ( this->element_type() != DBus::type<T>() ) {
00268           std::string s = "MessageIterator: Extracting DBus array type ";
00269           s += type_string<T>();
00270           s += " into C++ vector with RTTI type ";
00271           s += typeid( T ).name();
00272           throw ErrorInvalidTypecast::create( s.c_str() );
00273         }
00274         
00275         std::vector<T> array;
00276         int elements;
00277         T* values;
00278         
00279         MessageIterator subiter = this->recurse();
00280         
00281         // Get the underlying array
00282         dbus_message_iter_get_fixed_array( subiter.cobj(), &values, &elements );
00283         
00284         // Iteratively add the elements to the array
00285         for ( int i=0; i < elements; i++ )
00286           array.push_back( values[i] );
00287         
00288         return array;
00289       }
00290       
00291       template <typename T>
00292       void get_array(std::vector<T>& array) {
00293         
00294         if ( not this->is_array() )
00295           throw ErrorInvalidTypecast::create( "MessageIterator: Extracting non array into std::vector" );
00296         
00297         if ( not this->is_fixed() )
00298           throw ErrorInvalidTypecast::create( "MessageIterator: Extracting non fixed array into std::vector" );
00299         
00300         if ( this->element_type() != DBus::type<T>() ) {
00301           std::string s = "MessageIterator: Extracting DBus array type ";
00302           s += type_string<T>();
00303           s += " into C++ vector with RTTI type ";
00304           s += typeid( T ).name();
00305           throw ErrorInvalidTypecast::create( s.c_str() );
00306         }
00307         
00308         int elements;
00309         T* values;
00310         
00311         MessageIterator subiter = this->recurse();
00312         
00313         // Get the underlying array
00314         dbus_message_iter_get_fixed_array( subiter.cobj(), &values, &elements );
00315         
00316         // Iteratively add the elements to the array
00317         array.clear();
00318         for ( int i=0; i < elements; i++ )
00319           array.push_back( values[i] );
00320       }
00321 
00322       template <typename T>
00323       MessageIterator& operator>>( std::vector<T>& v )
00324       {
00325         this->get_array<T>(v);
00326         return *this;
00327       }
00328 
00329       template <typename T>
00330       MessageIterator& operator>>( T& v )
00331       {
00332         v = (T)(*this);
00333         this->next();
00334         return *this;
00335       }
00336       
00337       template <typename T>
00338       void value( T& temp ) {
00339         if ( this->arg_type() != DBus::type( temp ) ) {
00340           std::string s = "MessageIterator: Extracting DBus type ";
00341           s += type_string( temp );
00342           s += " into C++ RTTI type ";
00343           s += typeid( T ).name();
00344           throw ErrorInvalidTypecast( s.c_str() );
00345         }
00346         dbus_message_iter_get_basic( &m_cobj, &temp );
00347       }
00348 
00349     protected:
00350       const Message* m_message;
00351       DBusMessageIter m_cobj;
00352 
00353   };
00354 
00355 }
00356 
00357 #endif

Generated on Thu Mar 18 09:30:54 2010 for dbus-cxx by doxygen 1.6.1