00001 /*************************************************************************** 00002 * Copyright (C) 2007,2009 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 #ifndef DBUSCXXMESSAGEITERATOR_H 00020 #define DBUSCXXMESSAGEITERATOR_H 00021 00022 #include <string> 00023 #include <vector> 00024 00025 #include <dbus/dbus.h> 00026 00027 #include <dbus-cxx/utility.h> 00028 #include <dbus-cxx/error.h> 00029 #include <dbus-cxx/pointer.h> 00030 #include <dbus-cxx/signature.h> 00031 00032 namespace DBus 00033 { 00034 00035 class Message; 00036 00044 class MessageIterator 00045 { 00046 public: 00047 00048 MessageIterator(); 00049 00050 MessageIterator( const Message& message ); 00051 00052 MessageIterator( DBusCxxPointer<Message> message ); 00053 00058 const Message* message() const; 00059 00061 DBusMessageIter* cobj(); 00062 00064 bool init( const Message& message ); 00065 00067 void invalidate(); 00068 00070 bool is_valid() const; 00071 00073 operator bool() const; 00074 00076 bool has_next() const; 00077 00083 bool next(); 00084 00085 MessageIterator& operator ++(); 00086 00087 MessageIterator operator ++( int ); 00088 00089 bool operator==( const MessageIterator& other ); 00090 00092 Type arg_type() const; 00093 00099 Type element_type() const; 00100 00102 bool is_fixed() const; 00103 00105 bool is_container() const; 00106 00108 bool is_array() const; 00109 00111 bool is_dict() const; 00112 00118 MessageIterator recurse(); 00119 00121 std::string signature() const; 00122 00131 // void value( std::vector<std::string>& temp ); 00132 00133 // void value( std::string& temp ); 00134 00135 // void value( Variant& temp ); 00136 00137 // template <typename T0> 00138 // void value( Struct<T0>& temp ) { 00139 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00140 // MessageIterator subiter = this->recurse(); 00141 // subiter.value( boost::get<0>( temp ) ); 00142 // } 00143 00144 // template <typename T0, typename T1> 00145 // void value( Struct<T0,T1>& temp ) { 00146 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00147 // MessageIterator subiter = this->recurse(); 00148 // subiter.value( boost::get<0>( temp ) ); 00149 // subiter.value( boost::get<1>( temp ) ); 00150 // } 00151 00152 // template <typename T0, typename T1, typename T2> 00153 // void value( Struct<T0,T1,T2>& 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 // } 00160 // 00161 // template <typename T0, typename T1, typename T2, typename T3> 00162 // void value( Struct<T0,T1,T2,T3>& temp ) { 00163 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00164 // MessageIterator subiter = this->recurse(); 00165 // subiter.value( boost::get<0>( temp ) ); 00166 // subiter.value( boost::get<1>( temp ) ); 00167 // subiter.value( boost::get<2>( temp ) ); 00168 // subiter.value( boost::get<3>( temp ) ); 00169 // } 00170 // 00171 // template <typename T0, typename T1, typename T2, typename T3, typename T4> 00172 // void value( Struct<T0,T1,T2,T3,T4>& temp ) { 00173 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00174 // MessageIterator subiter = this->recurse(); 00175 // subiter.value( boost::get<0>( temp ) ); 00176 // subiter.value( boost::get<1>( temp ) ); 00177 // subiter.value( boost::get<2>( temp ) ); 00178 // subiter.value( boost::get<3>( temp ) ); 00179 // subiter.value( boost::get<4>( temp ) ); 00180 // } 00181 // 00182 // template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5> 00183 // void value( Struct<T0,T1,T2,T3,T4,T5>& temp ) { 00184 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00185 // MessageIterator subiter = this->recurse(); 00186 // subiter.value( boost::get<0>( temp ) ); 00187 // subiter.value( boost::get<1>( temp ) ); 00188 // subiter.value( boost::get<2>( temp ) ); 00189 // subiter.value( boost::get<3>( temp ) ); 00190 // subiter.value( boost::get<4>( temp ) ); 00191 // subiter.value( boost::get<5>( temp ) ); 00192 // } 00193 // 00194 // template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> 00195 // void value( Struct<T0,T1,T2,T3,T4,T5,T6>& temp ) { 00196 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00197 // MessageIterator subiter = this->recurse(); 00198 // subiter.value( boost::get<0>( temp ) ); 00199 // subiter.value( boost::get<1>( temp ) ); 00200 // subiter.value( boost::get<2>( temp ) ); 00201 // subiter.value( boost::get<3>( temp ) ); 00202 // subiter.value( boost::get<4>( temp ) ); 00203 // subiter.value( boost::get<5>( temp ) ); 00204 // subiter.value( boost::get<6>( temp ) ); 00205 // } 00206 00207 // template <typename Key, typename Data> 00208 // void value( std::vector<std::pair<Key,Data> >& temp ) { 00209 // if ( this->element_type() != TYPE_ARRAY ) 00210 // throw ErrorInvalidTypecast( "Extracting non-array type into dictionary" ); 00211 // 00212 // temp.clear(); 00213 // MessageIterator subiter = this->recurse(); 00214 // MessageIterator subsubiter; 00215 // Key k; 00216 // Data d; 00217 // 00218 // while ( subiter.has_next() ) { 00219 // if ( subiter.element_type() != TYPE_DICT_ENTRY ) 00220 // throw ErrorInvalidTypecast( "Extracting non-dictionary-entry type into dictionary entry" ); 00221 // subsubiter = subiter.recurse(); 00222 // subsubiter.value( k ); 00223 // ++subsubiter; 00224 // subsubiter.value( d ); 00225 // temp.push_back( std::make_pair( k,d ) ); 00226 // ++subiter; 00227 // } 00228 // } 00229 00230 // template <typename T> 00231 // void value( std::vector<T>& temp ) { 00232 // if ( this->element_type() != DBus::type( temp ) ) { 00233 // std::string s = "MessageIterator: Extracting DBus array type "; 00234 // s += type_string( temp ); 00235 // s += " into C++ vector with RTTI type "; 00236 // s += typeid( T ).name(); 00237 // throw ErrorInvalidTypecast( s.c_str() ); 00238 // } 00239 // 00240 // int elements; 00241 // T* values; 00242 // dbus_message_iter_get_fixed_array( &m_cobj, &values, &elements ); 00243 // temp.clear(); 00244 // for ( int i=0; i < elements; i++ ) 00245 // temp.push_back( *( values+elements ) ); 00246 // } 00247 00248 00249 operator bool(); 00250 operator uint8_t(); 00251 operator uint16_t(); 00252 operator int16_t(); 00253 operator uint32_t(); 00254 operator int32_t(); 00255 operator uint64_t(); 00256 operator int64_t(); 00257 operator double(); 00258 operator const char*(); 00259 00260 bool get_bool(); 00261 uint8_t get_uint8(); 00262 uint16_t get_uint16(); 00263 int16_t get_int16(); 00264 uint32_t get_uint32(); 00265 int32_t get_int32(); 00266 uint64_t get_uint64(); 00267 int64_t get_int64(); 00268 double get_double(); 00269 const char* get_string(); 00270 00271 MessageIterator& operator>>( bool& v ); 00272 MessageIterator& operator>>( uint8_t& v ); 00273 MessageIterator& operator>>( int16_t& v ); 00274 MessageIterator& operator>>( uint16_t& v ); 00275 MessageIterator& operator>>( int32_t& v ); 00276 MessageIterator& operator>>( uint32_t& v ); 00277 MessageIterator& operator>>( int64_t& v ); 00278 MessageIterator& operator>>( uint64_t& v ); 00279 MessageIterator& operator>>( double& v ); 00280 MessageIterator& operator>>( const char*& v ); 00281 MessageIterator& operator>>( std::string& v ); 00282 MessageIterator& operator>>( Signature& v ); 00283 00284 template <typename T> 00285 void value( T& temp ) { 00286 if ( this->arg_type() != DBus::type( temp ) ) { 00287 std::string s = "MessageIterator: Extracting DBus type "; 00288 s += type_string( temp ); 00289 s += " into C++ RTTI type "; 00290 s += typeid( T ).name(); 00291 throw ErrorInvalidTypecast( s.c_str() ); 00292 } 00293 dbus_message_iter_get_basic( &m_cobj, &temp ); 00294 } 00295 00296 protected: 00297 const Message* m_message; 00298 DBusMessageIter m_cobj; 00299 00300 template <typename T> MessageIterator& protected_extract( T& v ); 00301 00302 }; 00303 00304 } 00305 00306 #endif