utility.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-or-later OR BSD-3-Clause
2 /***************************************************************************
3  * Copyright (C) 2007,2008,2009,2010 by Rick L. Vinyard, Jr. *
4  * rvinyard@cs.nmsu.edu *
5  * *
6  * This file is part of the dbus-cxx library. *
7  ***************************************************************************/
8 #include <dbus-cxx/callmessage.h>
10 #include <dbus-cxx/demangle.h>
12 #include <dbus-cxx/signature.h>
14 #include <functional>
15 #include <memory>
16 #include <sstream>
17 #include <string>
18 #include <tuple>
19 #include <typeinfo>
20 #include <vector>
21 #include <sigc++/sigc++.h>
22 #include <chrono>
23 #include <dbus-cxx/demangle.h>
25 
26 #ifndef DBUSCXX_UTILITY_H
27 #define DBUSCXX_UTILITY_H
28 
29 #define DBUS_CXX_INTROSPECTABLE_INTERFACE "org.freedesktop.DBus.Introspectable"
30 #define DBUS_CXX_PEER_INTERFACE "org.freedesktop.DBus.Peer"
31 #define DBUS_CXX_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
32 #define DBUS_CXX_PROPERTY_EMITS_CHANGE_SIGNAL_ANNOTATION "org.freedesktop.DBus.Property.EmitsChangedSignal"
33 
60 #define DBUS_CXX_ITERATOR_SUPPORT( CppType, DBusType ) \
61  inline \
62  DBus::MessageIterator& operator>>(DBus::MessageIterator& __msgiter, CppType& __cpptype) \
63  { \
64  DBusType __dbustype; \
65  __msgiter >> __dbustype; \
66  __cpptype = static_cast< CppType >( __dbustype ); \
67  return __msgiter; \
68  } \
69  \
70  inline \
71  DBus::MessageAppendIterator& operator<<(DBus::MessageAppendIterator& __msgiter, CppType& __cpptype) \
72  { \
73  __msgiter << static_cast< DBusType >( __cpptype ); \
74  return __msgiter; \
75  } \
76  \
77  namespace DBus { \
78  inline std::string signature( CppType ) { DBusType d; return signature( d ); } \
79  }
80 
81 
82 namespace DBus {
83 
89 
95 void log_std_err( const char* logger_name, const struct ::SL_LogLocation* location,
96  const enum ::SL_LogLevel level,
97  const char* log_string );
98 
103 void set_log_level( const enum ::SL_LogLevel level );
104 
111 void hexdump( const std::vector<uint8_t>* vec, std::ostream* stream );
112 
120 void hexdump( const uint8_t* vec, const uint32_t len, std::ostream* stream );
121 
131 void set_default_endianess(DBus::Endianess endianess);
132 
134 
135 namespace priv {
136 /*
137  * method_signature class - like dbus_signature, but outputs the args of the signature
138  * in a C++-like manner
139  */
140 template<typename... argn>
142 
143 template<> class method_signature<> {
144 public:
145  std::string method_sig() const {
146  return "";
147  }
148 
149  std::string introspect( const std::vector<std::string>&, int, const std::string& ) const {
150  return "";
151  }
152 };
153 
154 template<typename arg1, typename... argn>
155 class method_signature<arg1, argn...> : public method_signature<argn...> {
156 public:
157  std::string method_sig() const {
158  std::string arg1_name = demangle<arg1>();
159  std::string remaining_args = method_signature<argn...>::method_sig();
160 
161  if( remaining_args.size() > 1 ) {
162  arg1_name += ",";
163  }
164 
165  return arg1_name + remaining_args;
166  }
167 
168  std::string introspect( const std::vector<std::string>& names, int idx, const std::string& spaces ) const {
169  arg1 arg;
170  std::ostringstream output;
171  std::string name = names.size() > idx ? names[idx] : "";
172  output << spaces;
173  output << "<arg ";
174 
175  if( name.size() > 0 ) { output << "name=\"" << name << "\" "; }
176 
177  output << "type=\"" << signature( arg ) << "\" ";
178  output << "direction=\"in\"/>\n";
179  output << method_signature<argn...>().introspect( names, idx + 1, spaces );
180  return output.str();
181  }
182 };
183 
184 template<typename... argn>
186 
187 template<> class multireturn_signature<> {
188 public:
189  std::string multireturn_sig() const {
190  return "";
191  }
192 
193  std::string introspect( const std::vector<std::string>&, int, const std::string& ) const {
194  return "";
195  }
196 };
197 
198 template<typename arg1, typename... argn>
199 class multireturn_signature<arg1, argn...> : public multireturn_signature<argn...> {
200 public:
201  std::string multireturn_sig() const {
202  std::string arg1_name = demangle<arg1>();
203  std::string remaining_args = multireturn_signature<argn...>::multireturn_sig();
204 
205  if( remaining_args.size() > 1 ) {
206  arg1_name += ",";
207  }
208 
209  return arg1_name + remaining_args;
210  }
211 
212  std::string introspect( const std::vector<std::string>& names, int& idx, const std::string& spaces ) const {
213  arg1 arg;
214  std::ostringstream output;
215  std::string name = names.size() > idx ? names[idx] : "";
216  output << spaces;
217  output << "<arg ";
218 
219  if( name.size() > 0 ) { output << "name=\"" << name << "\" "; }
220 
221  output << "type=\"" << signature( arg ) << "\" ";
222  output << "direction=\"out\"/>\n";
223  idx++;
224  output << multireturn_signature<argn...>().introspect( names, idx, spaces );
225  return output.str();
226  }
227 };
228 
229 
230 /*
231  * dbus_function_traits - given a function, get information about it needed for dbus operations.
232  */
233 template<typename T>
235 
236 template<typename ...Args>
237 struct dbus_function_traits<std::function<void( Args... )>> {
238  std::string dbus_sig() const {
239  return dbus_signature<Args...>().dbus_sig();
240  }
241 
242  std::string debug_string() const {
243  return "void (" + method_signature<Args...>().method_sig() + ")";
244  }
245 
246  std::string introspect( const std::vector<std::string>& names, int idx, const std::string& spaces ) const {
247  std::ostringstream sout;
248  sout << method_signature<Args...>().introspect( names, idx + 1, spaces );
249  return sout.str();
250  }
251 
252  void extractAndCall( std::shared_ptr<const CallMessage> callmsg, std::shared_ptr<ReturnMessage>, sigc::slot<void( Args... )> slot ) {
253  MessageIterator i = callmsg->begin();
254  std::tuple<Args...> tup_args;
255  std::apply( [i]( auto&& ...arg ) mutable {
256  ( void )( i >> ... >> arg );
257  },
258  tup_args );
259 
260  std::apply( slot, tup_args );
261  }
262 };
263 
264 template<typename T_ret, typename ...Args>
265 struct dbus_function_traits<std::function<T_ret( Args... )>> {
266  std::string dbus_sig() const {
267  return dbus_signature<Args...>().dbus_sig();
268  }
269 
270  std::string debug_string() const {
271  std::ostringstream ret;
272  ret << demangle<T_ret>();
273  ret << "(";
274  ret << method_signature<Args...>().method_sig();
275  ret << ")";
276  return ret.str();
277  }
278 
279  std::string introspect( const std::vector<std::string>& names, int idx, const std::string& spaces ) const {
280  std::ostringstream sout;
281  T_ret ret_type;
282  std::string name = "";
283 
284  if( names.size() > 0 ) {
285  name = names[0];
286  }
287 
288  sout << spaces << "<arg ";
289 
290  if( name.size() > 0 ) { sout << "name=\"" << name << "\" "; }
291 
292  sout << "type=\"" << signature( ret_type ) << "\" "
293  << "direction=\"out\"/>\n";
294  sout << method_signature<Args...>().introspect( names, idx + 1, spaces );
295  return sout.str();
296  }
297 
298  /*
299  std::tuple<Args...> extract(Message::iterator i){
300  std::tuple<Args...> tup_args;
301  std::apply( [i](auto ...arg){
302  (i >> ... >> arg);
303  },
304  tup_args );
305  return tup_args;
306  }
307  */
308  void extractAndCall( std::shared_ptr<const CallMessage> callmsg, std::shared_ptr<ReturnMessage> retmsg, sigc::slot<T_ret( Args... )> slot ) {
309  MessageIterator i = callmsg->begin();
310  std::tuple<Args...> tup_args;
311  std::apply( [i]( auto&& ...arg ) mutable {
312  ( void )( i >> ... >> arg );
313  },
314  tup_args );
315  T_ret retval;
316 
317  retval = std::apply( slot, tup_args );
318  retmsg << retval;
319  }
320 };
321 
322 
323 template<typename... T_ret,typename ...Args>
324 struct dbus_function_traits<std::function<DBus::MultipleReturn<T_ret...>( Args... )>> {
325  std::string dbus_sig() const {
326  return dbus_signature<Args...>().dbus_sig();
327  }
328 
329  std::string debug_string() const {
330  std::ostringstream ret;
331  ret << "DBus::MultipleReturn<" << multireturn_signature<T_ret...>().multireturn_sig() << ">";
332  ret << "(";
333  ret << method_signature<Args...>().method_sig();
334  ret << ")";
335  return ret.str();
336  }
337 
338  std::string introspect( const std::vector<std::string>& names, int idx, const std::string& spaces ) const {
339  std::ostringstream sout;
340  sout << multireturn_signature<T_ret...>().introspect( names, idx, spaces );
341  sout << method_signature<Args...>().introspect( names, idx + 1, spaces );
342  return sout.str();
343  }
344 
345  void extractAndCall( std::shared_ptr<const CallMessage> callmsg, std::shared_ptr<ReturnMessage> retmsg, sigc::slot<DBus::MultipleReturn<T_ret...>( Args... )> slot ) {
346  MessageIterator i = callmsg->begin();
347  std::tuple<Args...> tup_args;
348  std::apply( [i]( auto&& ...arg ) mutable {
349  ( void )( i >> ... >> arg );
350  },
351  tup_args );
352  DBus::MultipleReturn<T_ret...> retval;
353 
354  retval = std::apply( slot, tup_args );
355  retmsg << retval;
356  }
357 };
358 
371 std::tuple<bool, int, std::vector<int>, std::chrono::milliseconds> wait_for_fd_activity( std::vector<int> fds, int timeout_ms );
372 
373 } /* namespace priv */
374 
375 } /* namespace DBus */
376 
377 #endif
Extraction iterator allowing values to be retrieved from a message.
Definition: messageiterator.h:56
Definition: multiplereturn.h:29
Definition: signature.h:200
std::string method_sig() const
Definition: utility.h:157
std::string introspect(const std::vector< std::string > &names, int idx, const std::string &spaces) const
Definition: utility.h:168
std::string introspect(const std::vector< std::string > &, int, const std::string &) const
Definition: utility.h:149
std::string method_sig() const
Definition: utility.h:145
Definition: utility.h:141
std::string multireturn_sig() const
Definition: utility.h:201
std::string introspect(const std::vector< std::string > &names, int &idx, const std::string &spaces) const
Definition: utility.h:212
std::string multireturn_sig() const
Definition: utility.h:189
std::string introspect(const std::vector< std::string > &, int, const std::string &) const
Definition: utility.h:193
Definition: utility.h:185
std::tuple< bool, int, std::vector< int >, std::chrono::milliseconds > wait_for_fd_activity(std::vector< int > fds, int timeout_ms)
Wait for activity on any of the given FDs.
Definition: utility.cpp:114
Global DBus namespace, where everything happens.
Definition: callmessage.cpp:18
void log_std_err(const char *logger_name, const struct SL_LogLocation *location, const enum SL_LogLevel level, const char *log_string)
Definition: utility.cpp:54
void set_default_endianess(DBus::Endianess endianess)
Set the default endianess that the library uses in order to send messages.
Definition: utility.cpp:159
void hexdump(const std::vector< uint8_t > *vec, std::ostream *stream)
Print the vector as a hexdump output to the given output stream.
Definition: utility.cpp:75
DBus::Endianess default_endianess()
Definition: utility.cpp:163
void set_logging_function(simplelogger_log_function function)
Definition: utility.cpp:50
void set_log_level(const enum SL_LogLevel level)
Definition: utility.cpp:71
std::string signature(const std::tuple< T... > &)
Endianess
Definition: enums.h:114
void(* simplelogger_log_function)(const char *logger_name, const struct SL_LogLocation *location, const enum SL_LogLevel level, const char *log_string)
Pointer to a function that does the actual log operation.
Definition: simplelogger_defs.h:38
SL_LogLevel
Level of the log message.
Definition: simplelogger_defs.h:26
void extractAndCall(std::shared_ptr< const CallMessage > callmsg, std::shared_ptr< ReturnMessage > retmsg, sigc::slot< DBus::MultipleReturn< T_ret... >(Args...)> slot)
Definition: utility.h:345
std::string introspect(const std::vector< std::string > &names, int idx, const std::string &spaces) const
Definition: utility.h:338
std::string dbus_sig() const
Definition: utility.h:266
void extractAndCall(std::shared_ptr< const CallMessage > callmsg, std::shared_ptr< ReturnMessage > retmsg, sigc::slot< T_ret(Args...)> slot)
Definition: utility.h:308
std::string introspect(const std::vector< std::string > &names, int idx, const std::string &spaces) const
Definition: utility.h:279
std::string debug_string() const
Definition: utility.h:270
std::string debug_string() const
Definition: utility.h:242
void extractAndCall(std::shared_ptr< const CallMessage > callmsg, std::shared_ptr< ReturnMessage >, sigc::slot< void(Args...)> slot)
Definition: utility.h:252
std::string introspect(const std::vector< std::string > &names, int idx, const std::string &spaces) const
Definition: utility.h:246
std::string dbus_sig() const
Definition: utility.h:238
Definition: utility.h:234