dbus-cxx
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 ***************************************************************************/
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_OBJECT_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager"
33#define DBUS_CXX_PROPERTY_EMITS_CHANGE_SIGNAL_ANNOTATION "org.freedesktop.DBus.Property.EmitsChangedSignal"
34
61#define DBUS_CXX_ITERATOR_SUPPORT( CppType, DBusType ) \
62 inline \
63 DBus::MessageIterator& operator>>(DBus::MessageIterator& __msgiter, CppType& __cpptype) \
64 { \
65 DBusType __dbustype; \
66 __msgiter >> __dbustype; \
67 __cpptype = static_cast< CppType >( __dbustype ); \
68 return __msgiter; \
69 } \
70 \
71 inline \
72 DBus::MessageAppendIterator& operator<<(DBus::MessageAppendIterator& __msgiter, CppType& __cpptype) \
73 { \
74 __msgiter << static_cast< DBusType >( __cpptype ); \
75 return __msgiter; \
76 } \
77 \
78 namespace DBus { \
79 inline std::string signature( CppType ) { DBusType d; return signature( d ); } \
80 }
81
82
83namespace DBus {
84
90
96void log_std_err( const char* logger_name, const struct ::SL_LogLocation* location,
97 const enum ::SL_LogLevel level,
98 const char* log_string );
99
105
112void hexdump( const std::vector<uint8_t>* vec, std::ostream* stream );
113
121void hexdump( const uint8_t* vec, const uint32_t len, std::ostream* stream );
122
133
135
136namespace priv {
137/*
138 * method_signature class - like dbus_signature, but outputs the args of the signature
139 * in a C++-like manner
140 */
141template<typename... argn>
143
144template<> class method_signature<> {
145public:
146 std::string method_sig() const {
147 return "";
148 }
149
150 std::string introspect( const std::vector<std::string>&, int, const std::string& ) const {
151 return "";
152 }
153};
154
155template<typename arg1, typename... argn>
156class method_signature<arg1, argn...> : public method_signature<argn...> {
157public:
158 std::string method_sig() const {
159 std::string arg1_name = demangle<arg1>();
160 std::string remaining_args = method_signature<argn...>::method_sig();
161
162 if( remaining_args.size() > 1 ) {
163 arg1_name += ",";
164 }
165
166 return arg1_name + remaining_args;
167 }
168
169 std::string introspect( const std::vector<std::string>& names, int idx, const std::string& spaces ) const {
170 arg1 arg {};
171 std::ostringstream output;
172 std::string name = names.size() > idx ? names[idx] : "";
173 output << spaces;
174 output << "<arg ";
175
176 if( name.size() > 0 ) { output << "name=\"" << name << "\" "; }
177
178 output << "type=\"" << signature( arg ) << "\" ";
179 output << "direction=\"in\"/>\n";
180 output << method_signature<argn...>().introspect( names, idx + 1, spaces );
181 return output.str();
182 }
183};
184
185template<typename... argn>
187
188template<> class multireturn_signature<> {
189public:
190 std::string multireturn_sig() const {
191 return "";
192 }
193
194 std::string introspect( const std::vector<std::string>&, int, const std::string& ) const {
195 return "";
196 }
197};
198
199template<typename arg1, typename... argn>
200class multireturn_signature<arg1, argn...> : public multireturn_signature<argn...> {
201public:
202 std::string multireturn_sig() const {
203 std::string arg1_name = demangle<arg1>();
204 std::string remaining_args = multireturn_signature<argn...>::multireturn_sig();
205
206 if( remaining_args.size() > 1 ) {
207 arg1_name += ",";
208 }
209
210 return arg1_name + remaining_args;
211 }
212
213 std::string introspect( const std::vector<std::string>& names, int& idx, const std::string& spaces ) const {
214 arg1 arg {};
215 std::ostringstream output;
216 std::string name = names.size() > idx ? names[idx] : "";
217 output << spaces;
218 output << "<arg ";
219
220 if( name.size() > 0 ) { output << "name=\"" << name << "\" "; }
221
222 output << "type=\"" << signature( arg ) << "\" ";
223 output << "direction=\"out\"/>\n";
224 idx++;
225 output << multireturn_signature<argn...>().introspect( names, idx, spaces );
226 return output.str();
227 }
228};
229
230
231/*
232 * dbus_function_traits - given a function, get information about it needed for dbus operations.
233 */
234template<typename T>
236
237template<typename ...Args>
238struct dbus_function_traits<std::function<void( Args... )>> {
239 std::string dbus_sig() const {
240 return dbus_signature<Args...>().dbus_sig();
241 }
242
243 std::string debug_string() const {
244 return "void (" + method_signature<Args...>().method_sig() + ")";
245 }
246
247 std::string introspect( const std::vector<std::string>& names, int idx, const std::string& spaces ) const {
248 std::ostringstream sout;
249 sout << method_signature<Args...>().introspect( names, idx + 1, spaces );
250 return sout.str();
251 }
252
253 void extractAndCall( std::shared_ptr<const CallMessage> callmsg, std::shared_ptr<ReturnMessage>, sigc::slot<void( Args... )> slot ) {
254 MessageIterator i = callmsg->begin();
255 std::tuple<Args...> tup_args;
256 std::apply( [i]( auto&& ...arg ) mutable {
257 ( void )( i >> ... >> arg );
258 },
259 tup_args );
260
261 std::apply( slot, tup_args );
262 }
263};
264
265template<typename T_ret, typename ...Args>
266struct dbus_function_traits<std::function<T_ret( Args... )>> {
267 std::string dbus_sig() const {
268 return dbus_signature<Args...>().dbus_sig();
269 }
270
271 std::string debug_string() const {
272 std::ostringstream ret;
273 ret << demangle<T_ret>();
274 ret << "(";
275 ret << method_signature<Args...>().method_sig();
276 ret << ")";
277 return ret.str();
278 }
279
280 std::string introspect( const std::vector<std::string>& names, int idx, const std::string& spaces ) const {
281 std::ostringstream sout;
282 T_ret ret_type {};
283 std::string name = "";
284
285 if( names.size() > 0 ) {
286 name = names[0];
287 }
288
289 sout << spaces << "<arg ";
290
291 if( name.size() > 0 ) { sout << "name=\"" << name << "\" "; }
292
293 sout << "type=\"" << signature( ret_type ) << "\" "
294 << "direction=\"out\"/>\n";
295 sout << method_signature<Args...>().introspect( names, idx + 1, spaces );
296 return sout.str();
297 }
298
299 /*
300 std::tuple<Args...> extract(Message::iterator i){
301 std::tuple<Args...> tup_args;
302 std::apply( [i](auto ...arg){
303 (i >> ... >> arg);
304 },
305 tup_args );
306 return tup_args;
307 }
308 */
309 void extractAndCall( std::shared_ptr<const CallMessage> callmsg, std::shared_ptr<ReturnMessage> retmsg, sigc::slot<T_ret( Args... )> slot ) {
310 MessageIterator i = callmsg->begin();
311 std::tuple<Args...> tup_args;
312 std::apply( [i]( auto&& ...arg ) mutable {
313 ( void )( i >> ... >> arg );
314 },
315 tup_args );
316 T_ret retval {};
317
318 retval = std::apply( slot, tup_args );
319 retmsg << retval;
320 }
321};
322
323
324template<typename... T_ret,typename ...Args>
325struct dbus_function_traits<std::function<DBus::MultipleReturn<T_ret...>( Args... )>> {
326 std::string dbus_sig() const {
327 return dbus_signature<Args...>().dbus_sig();
328 }
329
330 std::string debug_string() const {
331 std::ostringstream ret;
332 ret << "DBus::MultipleReturn<" << multireturn_signature<T_ret...>().multireturn_sig() << ">";
333 ret << "(";
334 ret << method_signature<Args...>().method_sig();
335 ret << ")";
336 return ret.str();
337 }
338
339 std::string introspect( const std::vector<std::string>& names, int idx, const std::string& spaces ) const {
340 std::ostringstream sout;
341 sout << multireturn_signature<T_ret...>().introspect( names, idx, spaces );
342 sout << method_signature<Args...>().introspect( names, idx + 1, spaces );
343 return sout.str();
344 }
345
346 void extractAndCall( std::shared_ptr<const CallMessage> callmsg, std::shared_ptr<ReturnMessage> retmsg, sigc::slot<DBus::MultipleReturn<T_ret...>( Args... )> slot ) {
347 MessageIterator i = callmsg->begin();
348 std::tuple<Args...> tup_args;
349 std::apply( [i]( auto&& ...arg ) mutable {
350 ( void )( i >> ... >> arg );
351 },
352 tup_args );
354
355 retval = std::apply( slot, tup_args );
356 retmsg << retval;
357 }
358};
359
372std::tuple<bool, int, std::vector<int>, std::chrono::milliseconds> wait_for_fd_activity( std::vector<int> fds, int timeout_ms );
373
374} /* namespace priv */
375
376} /* namespace DBus */
377
378#endif
Extraction iterator allowing values to be retrieved from a message.
Definition: messageiterator.h:56
Definition: multiplereturn.h:29
Definition: signature.h:210
std::string method_sig() const
Definition: utility.h:158
std::string introspect(const std::vector< std::string > &names, int idx, const std::string &spaces) const
Definition: utility.h:169
std::string introspect(const std::vector< std::string > &, int, const std::string &) const
Definition: utility.h:150
std::string method_sig() const
Definition: utility.h:146
Definition: utility.h:142
std::string multireturn_sig() const
Definition: utility.h:202
std::string introspect(const std::vector< std::string > &names, int &idx, const std::string &spaces) const
Definition: utility.h:213
std::string multireturn_sig() const
Definition: utility.h:190
std::string introspect(const std::vector< std::string > &, int, const std::string &) const
Definition: utility.h:194
Definition: utility.h:186
static int retval
Definition: glib-caller.cpp:7
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:115
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:160
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:76
DBus::Endianess default_endianess()
Definition: utility.cpp:164
void set_logging_function(simplelogger_log_function function)
Definition: utility.cpp:50
void set_log_level(const enum SL_LogLevel level)
Definition: utility.cpp:72
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:346
std::string introspect(const std::vector< std::string > &names, int idx, const std::string &spaces) const
Definition: utility.h:339
std::string dbus_sig() const
Definition: utility.h:267
void extractAndCall(std::shared_ptr< const CallMessage > callmsg, std::shared_ptr< ReturnMessage > retmsg, sigc::slot< T_ret(Args...)> slot)
Definition: utility.h:309
std::string introspect(const std::vector< std::string > &names, int idx, const std::string &spaces) const
Definition: utility.h:280
std::string debug_string() const
Definition: utility.h:271
std::string debug_string() const
Definition: utility.h:243
void extractAndCall(std::shared_ptr< const CallMessage > callmsg, std::shared_ptr< ReturnMessage >, sigc::slot< void(Args...)> slot)
Definition: utility.h:253
std::string introspect(const std::vector< std::string > &names, int idx, const std::string &spaces) const
Definition: utility.h:247
std::string dbus_sig() const
Definition: utility.h:239
Definition: utility.h:235