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 bool has_next() const; 00074 00080 bool next(); 00081 00082 MessageIterator& operator ++(); 00083 00084 MessageIterator operator ++( int ); 00085 00086 bool operator==( const MessageIterator& other ); 00087 00089 Type arg_type() const; 00090 00096 Type element_type() const; 00097 00099 bool is_fixed() const; 00100 00102 bool is_container() const; 00103 00105 bool is_array() const; 00106 00108 bool is_dict() const; 00109 00115 MessageIterator recurse(); 00116 00118 std::string signature() const; 00119 00128 // void value( std::vector<std::string>& temp ); 00129 00130 // void value( std::string& temp ); 00131 00132 // void value( Variant& temp ); 00133 00134 // template <typename T0> 00135 // void value( Struct<T0>& temp ) { 00136 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00137 // MessageIterator subiter = this->recurse(); 00138 // subiter.value( boost::get<0>( temp ) ); 00139 // } 00140 00141 // template <typename T0, typename T1> 00142 // void value( Struct<T0,T1>& temp ) { 00143 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00144 // MessageIterator subiter = this->recurse(); 00145 // subiter.value( boost::get<0>( temp ) ); 00146 // subiter.value( boost::get<1>( temp ) ); 00147 // } 00148 00149 // template <typename T0, typename T1, typename T2> 00150 // void value( Struct<T0,T1,T2>& temp ) { 00151 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00152 // MessageIterator subiter = this->recurse(); 00153 // subiter.value( boost::get<0>( temp ) ); 00154 // subiter.value( boost::get<1>( temp ) ); 00155 // subiter.value( boost::get<2>( temp ) ); 00156 // } 00157 // 00158 // template <typename T0, typename T1, typename T2, typename T3> 00159 // void value( Struct<T0,T1,T2,T3>& temp ) { 00160 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00161 // MessageIterator subiter = this->recurse(); 00162 // subiter.value( boost::get<0>( temp ) ); 00163 // subiter.value( boost::get<1>( temp ) ); 00164 // subiter.value( boost::get<2>( temp ) ); 00165 // subiter.value( boost::get<3>( temp ) ); 00166 // } 00167 // 00168 // template <typename T0, typename T1, typename T2, typename T3, typename T4> 00169 // void value( Struct<T0,T1,T2,T3,T4>& temp ) { 00170 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00171 // MessageIterator subiter = this->recurse(); 00172 // subiter.value( boost::get<0>( temp ) ); 00173 // subiter.value( boost::get<1>( temp ) ); 00174 // subiter.value( boost::get<2>( temp ) ); 00175 // subiter.value( boost::get<3>( temp ) ); 00176 // subiter.value( boost::get<4>( temp ) ); 00177 // } 00178 // 00179 // template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5> 00180 // void value( Struct<T0,T1,T2,T3,T4,T5>& temp ) { 00181 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00182 // MessageIterator subiter = this->recurse(); 00183 // subiter.value( boost::get<0>( temp ) ); 00184 // subiter.value( boost::get<1>( temp ) ); 00185 // subiter.value( boost::get<2>( temp ) ); 00186 // subiter.value( boost::get<3>( temp ) ); 00187 // subiter.value( boost::get<4>( temp ) ); 00188 // subiter.value( boost::get<5>( temp ) ); 00189 // } 00190 // 00191 // template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> 00192 // void value( Struct<T0,T1,T2,T3,T4,T5,T6>& temp ) { 00193 // if ( this->element_type() != TYPE_STRUCT ) throw ErrorInvalidTypecast(); 00194 // MessageIterator subiter = this->recurse(); 00195 // subiter.value( boost::get<0>( temp ) ); 00196 // subiter.value( boost::get<1>( temp ) ); 00197 // subiter.value( boost::get<2>( temp ) ); 00198 // subiter.value( boost::get<3>( temp ) ); 00199 // subiter.value( boost::get<4>( temp ) ); 00200 // subiter.value( boost::get<5>( temp ) ); 00201 // subiter.value( boost::get<6>( temp ) ); 00202 // } 00203 00204 // template <typename Key, typename Data> 00205 // void value( std::vector<std::pair<Key,Data> >& temp ) { 00206 // if ( this->element_type() != TYPE_ARRAY ) 00207 // throw ErrorInvalidTypecast( "Extracting non-array type into dictionary" ); 00208 // 00209 // temp.clear(); 00210 // MessageIterator subiter = this->recurse(); 00211 // MessageIterator subsubiter; 00212 // Key k; 00213 // Data d; 00214 // 00215 // while ( subiter.has_next() ) { 00216 // if ( subiter.element_type() != TYPE_DICT_ENTRY ) 00217 // throw ErrorInvalidTypecast( "Extracting non-dictionary-entry type into dictionary entry" ); 00218 // subsubiter = subiter.recurse(); 00219 // subsubiter.value( k ); 00220 // ++subsubiter; 00221 // subsubiter.value( d ); 00222 // temp.push_back( std::make_pair( k,d ) ); 00223 // ++subiter; 00224 // } 00225 // } 00226 00227 // template <typename T> 00228 // void value( std::vector<T>& temp ) { 00229 // if ( this->element_type() != DBus::type( temp ) ) { 00230 // std::string s = "MessageIterator: Extracting DBus array type "; 00231 // s += type_string( temp ); 00232 // s += " into C++ vector with RTTI type "; 00233 // s += typeid( T ).name(); 00234 // throw ErrorInvalidTypecast( s.c_str() ); 00235 // } 00236 // 00237 // int elements; 00238 // T* values; 00239 // dbus_message_iter_get_fixed_array( &m_cobj, &values, &elements ); 00240 // temp.clear(); 00241 // for ( int i=0; i < elements; i++ ) 00242 // temp.push_back( *( values+elements ) ); 00243 // } 00244 00245 00246 operator bool(); 00247 operator uint8_t(); 00248 operator uint16_t(); 00249 operator int16_t(); 00250 operator uint32_t(); 00251 operator int32_t(); 00252 operator uint64_t(); 00253 operator int64_t(); 00254 operator double(); 00255 operator const char*(); 00256 00257 operator char(); 00258 operator int8_t(); 00259 operator float(); 00260 #if DBUS_CXX_SIZEOF_LONG_INT == 4 00261 operator long int(); 00262 operator unsigned long int(); 00263 #endif 00264 00265 00266 bool get_bool(); 00267 uint8_t get_uint8(); 00268 uint16_t get_uint16(); 00269 int16_t get_int16(); 00270 uint32_t get_uint32(); 00271 int32_t get_int32(); 00272 uint64_t get_uint64(); 00273 int64_t get_int64(); 00274 double get_double(); 00275 const char* get_string(); 00276 00277 template <typename T> 00278 MessageIterator& operator>>( T& v ) 00279 { 00280 v = (T)(*this); 00281 this->next(); 00282 return *this; 00283 } 00284 00285 template <typename T> 00286 void value( T& temp ) { 00287 if ( this->arg_type() != DBus::type( temp ) ) { 00288 std::string s = "MessageIterator: Extracting DBus type "; 00289 s += type_string( temp ); 00290 s += " into C++ RTTI type "; 00291 s += typeid( T ).name(); 00292 throw ErrorInvalidTypecast( s.c_str() ); 00293 } 00294 dbus_message_iter_get_basic( &m_cobj, &temp ); 00295 } 00296 00297 protected: 00298 const Message* m_message; 00299 DBusMessageIter m_cobj; 00300 00301 }; 00302 00303 } 00304 00305 #endif