2 * Copyright (C) 2009 Intel Corporation
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) version 3.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * This file contains everything that a D-Bus server needs to
22 * integrate a normal C++ class into D-Bus. Argument and result
23 * marshaling is done in wrapper functions which convert directly
24 * to normal C++ types (bool, integers, std::string, std::map<>, ...).
25 * See dbus_traits for the full list of supported types.
27 * Before explaining the binding, some terminology first:
28 * - A function has a return type and multiple parameters.
29 * - Input parameters are read-only arguments of the function.
30 * - The function can return values to the caller via the
31 * return type and output parameters (retvals).
33 * The C++ binding roughly looks like this:
34 * - Arguments can be passed as plain types or const references:
35 void foo(int arg); void bar(const std::string &str);
36 * - A single result can be returned as return value:
38 * - Multiple results can be copied into instances provided by
39 * the wrapper, passed by reference: void foo(std::string &res);
40 * - A return value, arguments and retvals can be combined
41 * arbitrarily. In the D-Bus reply the return code comes before
44 * Asynchronous methods are possible by declaring one parameter as a
45 * Result pointer and later calling the virtual function provided by
46 * it. Parameter passing of results is less flexible than that of
47 * method parameters: the later allows both std::string as well as
48 * const std::string &, for results only the const reference is
49 * supported. The Result instance is passed as pointer and then owned
50 * by the called method.
52 * Reference counting via boost::intrusive_ptr ensures that all
53 * D-Bus objects are handled automatically internally.
57 #ifndef INCL_GDBUS_CXX_BRIDGE
58 #define INCL_GDBUS_CXX_BRIDGE
61 #include "gdbus-cxx.h"
66 #include <boost/bind.hpp>
67 #include <boost/intrusive_ptr.hpp>
68 #include <boost/shared_ptr.hpp>
71 void intrusive_ptr_add_ref(DBusConnection *con) { dbus_connection_ref(con); }
72 void intrusive_ptr_release(DBusConnection *con) { dbus_connection_unref(con); }
73 void intrusive_ptr_add_ref(DBusMessage *msg) { dbus_message_ref(msg); }
74 void intrusive_ptr_release(DBusMessage *msg) { dbus_message_unref(msg); }
77 class DBusConnectionPtr : public boost::intrusive_ptr<DBusConnection>
80 DBusConnectionPtr() {}
81 // connections are typically created once, so increment the ref counter by default
82 DBusConnectionPtr(DBusConnection *conn, bool add_ref = true) :
83 boost::intrusive_ptr<DBusConnection>(conn, add_ref)
86 DBusConnection *reference(void) throw()
88 DBusConnection *conn = get();
89 dbus_connection_ref(conn);
94 class DBusMessagePtr : public boost::intrusive_ptr<DBusMessage>
98 // expected to be used for messages created anew,
99 // so use the reference already incremented for us
100 // and don't increment by default
101 DBusMessagePtr(DBusMessage *msg, bool add_ref = false) :
102 boost::intrusive_ptr<DBusMessage>(msg, add_ref)
105 DBusMessage *reference(void) throw()
107 DBusMessage *msg = get();
108 dbus_message_ref(msg);
114 * wrapper around DBusError which initializes
115 * the struct automatically, then can be used to
118 class DBusErrorCXX : public DBusError
121 DBusErrorCXX() { dbus_error_init(this); }
122 void throwFailure(const std::string &operation)
124 if (dbus_error_is_set(this)) {
125 throw std::runtime_error(operation + ": " + message);
127 throw std::runtime_error(operation + " failed");
133 return dbus_error_is_set(this);
138 * Special type for object paths. A string in practice.
140 class DBusObject_t : public std::string
144 template <class T> DBusObject_t(T val) : std::string(val) {}
145 template <class T> DBusObject_t &operator = (T val) { assign(val); return *this; }
149 * specializations of this must defined methods for encoding and
150 * decoding type C and declare its signature
152 template<class C> struct dbus_traits {};
154 struct dbus_traits_base
157 * A C++ method or function can handle a call asynchronously by
158 * asking to be passed a "boost::shared_ptr<Result*>" parameter.
159 * The dbus_traits for those parameters have "asynchronous" set to
160 * true, which skips all processing after calling the method.
162 static const bool asynchronous = false;
166 * Append a varying number of parameters as result to the
167 * message. Types can be anything that has a dbus_traits, including
168 * types which are normally recognized as input parameters in D-Bus
171 template <class A1, class A2, class A3, class A4, class A5,
172 class A6, class A7, class A8, class A9, class A10>
173 void append_retvals(DBusMessagePtr &msg,
185 DBusMessageIter iter;
186 dbus_message_iter_init_append(msg.get(), &iter);
187 dbus_traits<A1>::append_retval(iter, a1);
188 dbus_traits<A2>::append_retval(iter, a2);
189 dbus_traits<A3>::append_retval(iter, a3);
190 dbus_traits<A4>::append_retval(iter, a4);
191 dbus_traits<A5>::append_retval(iter, a5);
192 dbus_traits<A6>::append_retval(iter, a6);
193 dbus_traits<A7>::append_retval(iter, a7);
194 dbus_traits<A8>::append_retval(iter, a8);
195 dbus_traits<A9>::append_retval(iter, a9);
196 dbus_traits<A10>::append_retval(iter, a10);
199 template <class A1, class A2, class A3, class A4, class A5,
200 class A6, class A7, class A8, class A9>
201 void append_retvals(DBusMessagePtr &msg,
212 DBusMessageIter iter;
213 dbus_message_iter_init_append(msg.get(), &iter);
214 dbus_traits<A1>::append_retval(iter, a1);
215 dbus_traits<A2>::append_retval(iter, a2);
216 dbus_traits<A3>::append_retval(iter, a3);
217 dbus_traits<A4>::append_retval(iter, a4);
218 dbus_traits<A5>::append_retval(iter, a5);
219 dbus_traits<A6>::append_retval(iter, a6);
220 dbus_traits<A7>::append_retval(iter, a7);
221 dbus_traits<A8>::append_retval(iter, a8);
222 dbus_traits<A9>::append_retval(iter, a9);
225 template <class A1, class A2, class A3, class A4, class A5,
226 class A6, class A7, class A8>
227 void append_retvals(DBusMessagePtr &msg,
237 DBusMessageIter iter;
238 dbus_message_iter_init_append(msg.get(), &iter);
239 dbus_traits<A1>::append_retval(iter, a1);
240 dbus_traits<A2>::append_retval(iter, a2);
241 dbus_traits<A3>::append_retval(iter, a3);
242 dbus_traits<A4>::append_retval(iter, a4);
243 dbus_traits<A5>::append_retval(iter, a5);
244 dbus_traits<A6>::append_retval(iter, a6);
245 dbus_traits<A7>::append_retval(iter, a7);
246 dbus_traits<A8>::append_retval(iter, a8);
249 template <class A1, class A2, class A3, class A4, class A5,
251 void append_retvals(DBusMessagePtr &msg,
260 DBusMessageIter iter;
261 dbus_message_iter_init_append(msg.get(), &iter);
262 dbus_traits<A1>::append_retval(iter, a1);
263 dbus_traits<A2>::append_retval(iter, a2);
264 dbus_traits<A3>::append_retval(iter, a3);
265 dbus_traits<A4>::append_retval(iter, a4);
266 dbus_traits<A5>::append_retval(iter, a5);
267 dbus_traits<A6>::append_retval(iter, a6);
268 dbus_traits<A7>::append_retval(iter, a7);
271 template <class A1, class A2, class A3, class A4, class A5,
273 void append_retvals(DBusMessagePtr &msg,
281 DBusMessageIter iter;
282 dbus_message_iter_init_append(msg.get(), &iter);
283 dbus_traits<A1>::append_retval(iter, a1);
284 dbus_traits<A2>::append_retval(iter, a2);
285 dbus_traits<A3>::append_retval(iter, a3);
286 dbus_traits<A4>::append_retval(iter, a4);
287 dbus_traits<A5>::append_retval(iter, a5);
288 dbus_traits<A6>::append_retval(iter, a6);
291 template <class A1, class A2, class A3, class A4, class A5>
292 void append_retvals(DBusMessagePtr &msg,
299 DBusMessageIter iter;
300 dbus_message_iter_init_append(msg.get(), &iter);
301 dbus_traits<A1>::append_retval(iter, a1);
302 dbus_traits<A2>::append_retval(iter, a2);
303 dbus_traits<A3>::append_retval(iter, a3);
304 dbus_traits<A4>::append_retval(iter, a4);
305 dbus_traits<A5>::append_retval(iter, a5);
308 template <class A1, class A2, class A3, class A4>
309 void append_retvals(DBusMessagePtr &msg,
315 DBusMessageIter iter;
316 dbus_message_iter_init_append(msg.get(), &iter);
317 dbus_traits<A1>::append_retval(iter, a1);
318 dbus_traits<A2>::append_retval(iter, a2);
319 dbus_traits<A3>::append_retval(iter, a3);
320 dbus_traits<A4>::append_retval(iter, a4);
323 template <class A1, class A2, class A3>
324 void append_retvals(DBusMessagePtr &msg,
329 DBusMessageIter iter;
330 dbus_message_iter_init_append(msg.get(), &iter);
331 dbus_traits<A1>::append_retval(iter, a1);
332 dbus_traits<A2>::append_retval(iter, a2);
333 dbus_traits<A3>::append_retval(iter, a3);
336 template <class A1, class A2>
337 void append_retvals(DBusMessagePtr &msg,
341 DBusMessageIter iter;
342 dbus_message_iter_init_append(msg.get(), &iter);
343 dbus_traits<A1>::append_retval(iter, a1);
344 dbus_traits<A2>::append_retval(iter, a2);
348 void append_retvals(DBusMessagePtr &msg,
351 DBusMessageIter iter;
352 dbus_message_iter_init_append(msg.get(), &iter);
353 dbus_traits<A1>::append_retval(iter, a1);
357 * interface expected by EmitSignal
362 virtual ~DBusObject() {}
364 virtual DBusConnection *getConnection() const = 0;
365 virtual const char *getPath() const = 0;
366 virtual const char *getInterface() const = 0;
371 const DBusObject &m_object;
372 const std::string m_signal;
375 EmitSignal0(const DBusObject &object,
376 const std::string &signal) :
383 DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(),
384 m_object.getInterface(),
387 throw std::runtime_error("dbus_message_new_signal() failed");
390 if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) {
391 throw std::runtime_error("dbus_connection_send failed");
395 GDBusSignalTable makeSignalEntry(GDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const
397 GDBusSignalTable entry;
398 entry.name = m_signal.c_str();
400 entry.signature = strdup(buffer.c_str());
406 template <typename A1>
409 const DBusObject &m_object;
410 const std::string m_signal;
413 EmitSignal1(const DBusObject &object,
414 const std::string &signal) :
419 void operator () (A1 a1)
421 DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(),
422 m_object.getInterface(),
425 throw std::runtime_error("dbus_message_new_signal() failed");
427 append_retvals(msg, a1);
429 if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) {
430 throw std::runtime_error("dbus_connection_send failed");
434 GDBusSignalTable makeSignalEntry(GDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const
436 GDBusSignalTable entry;
437 entry.name = m_signal.c_str();
439 buffer += dbus_traits<A1>::getSignature();
440 entry.signature = strdup(buffer.c_str());
446 template <typename A1, typename A2>
449 const DBusObject &m_object;
450 const std::string m_signal;
453 EmitSignal2(const DBusObject &object,
454 const std::string &signal) :
459 void operator () (A1 a1, A2 a2)
461 DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(),
462 m_object.getInterface(),
465 throw std::runtime_error("dbus_message_new_signal() failed");
467 append_retvals(msg, a1, a2);
469 if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) {
470 throw std::runtime_error("dbus_connection_send failed");
474 GDBusSignalTable makeSignalEntry(GDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const
476 GDBusSignalTable entry;
477 entry.name = m_signal.c_str();
479 buffer += dbus_traits<A1>::getSignature();
480 buffer += dbus_traits<A2>::getSignature();
481 entry.signature = strdup(buffer.c_str());
487 template <typename A1, typename A2, typename A3>
490 const DBusObject &m_object;
491 const std::string m_signal;
494 EmitSignal3(const DBusObject &object,
495 const std::string &signal) :
500 void operator () (A1 a1, A2 a2, A3 a3)
502 DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(),
503 m_object.getInterface(),
506 throw std::runtime_error("dbus_message_new_signal() failed");
508 append_retvals(msg, a1, a2, a3);
509 if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) {
510 throw std::runtime_error("dbus_connection_send failed");
514 GDBusSignalTable makeSignalEntry(GDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const
516 GDBusSignalTable entry;
517 entry.name = m_signal.c_str();
519 buffer += dbus_traits<A1>::getSignature();
520 buffer += dbus_traits<A2>::getSignature();
521 buffer += dbus_traits<A3>::getSignature();
522 entry.signature = strdup(buffer.c_str());
528 template <typename A1, typename A2, typename A3, typename A4>
531 const DBusObject &m_object;
532 const std::string m_signal;
535 EmitSignal4(const DBusObject &object,
536 const std::string &signal) :
541 void operator () (A1 a1, A2 a2, A3 a3, A4 a4)
543 DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(),
544 m_object.getInterface(),
547 throw std::runtime_error("dbus_message_new_signal() failed");
549 append_retvals(msg, a1, a2, a3, a4);
550 if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) {
551 throw std::runtime_error("dbus_connection_send failed");
555 GDBusSignalTable makeSignalEntry(GDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const
557 GDBusSignalTable entry;
558 entry.name = m_signal.c_str();
560 buffer += dbus_traits<A1>::getSignature();
561 buffer += dbus_traits<A2>::getSignature();
562 buffer += dbus_traits<A3>::getSignature();
563 buffer += dbus_traits<A4>::getSignature();
564 entry.signature = strdup(buffer.c_str());
570 template <typename A1, typename A2, typename A3, typename A4, typename A5>
573 const DBusObject &m_object;
574 const std::string m_signal;
577 EmitSignal5(const DBusObject &object,
578 const std::string &signal) :
583 void operator () (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
585 DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(),
586 m_object.getInterface(),
589 throw std::runtime_error("dbus_message_new_signal() failed");
591 append_retvals(msg, a1, a2, a3, a4, a5);
592 if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) {
593 throw std::runtime_error("dbus_connection_send failed");
597 GDBusSignalTable makeSignalEntry(GDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const
599 GDBusSignalTable entry;
600 entry.name = m_signal.c_str();
602 buffer += dbus_traits<A1>::getSignature();
603 buffer += dbus_traits<A2>::getSignature();
604 buffer += dbus_traits<A3>::getSignature();
605 buffer += dbus_traits<A4>::getSignature();
606 buffer += dbus_traits<A5>::getSignature();
607 entry.signature = strdup(buffer.c_str());
614 struct MakeMethodEntry
616 // There is no generic implementation of this method.
617 // If you get an error about it missing, then write
618 // a specialization for your type M (the method pointer).
620 // static GDBusMethodTable make(const char *name,
621 // GDBusMethodFlags flags)
625 * Storage for method/signal/property arrays.
626 * Always contains at least one empty element
627 * at the end or is NULL.
629 template <class T> class DBusVector {
634 static void destroy(GDBusMethodTable &entry) {
635 free(const_cast<char *>(entry.name));
636 free(const_cast<char *>(entry.signature));
637 free(const_cast<char *>(entry.reply));
639 entry.destroy(&entry);
643 static void destroy(GDBusSignalTable &entry) {
644 free(const_cast<char *>(entry.signature));
645 // if (entry.destroy) {
646 // entry.destroy(&entry);
651 DBusVector() : m_entries(0), m_size(0), m_elements(NULL) {}
654 for (size_t i = 0; i < m_entries; i++) {
655 destroy(m_elements[i]);
661 T *get() { return m_elements; }
662 void push_back(const T &element) {
663 if (m_entries + 1 >= m_size) {
664 size_t newSize = m_size ? m_size * 2 : 16;
665 m_elements = static_cast<T *>(realloc(m_elements, newSize * sizeof(T)));
667 throw std::bad_alloc();
671 m_elements[m_entries] = element;
673 memset(m_elements + m_entries, 0, sizeof(T));
678 * utility class for registering an interface
680 class DBusObjectHelper : public DBusObject
682 DBusConnectionPtr m_conn;
684 std::string m_interface;
686 DBusVector<GDBusMethodTable> m_methods;
687 DBusVector<GDBusSignalTable> m_signals;
690 DBusObjectHelper(DBusConnection *conn,
691 const std::string &path,
692 const std::string &interface) :
695 m_interface(interface),
705 virtual DBusConnection *getConnection() const { return m_conn.get(); }
706 virtual const char *getPath() const { return m_path.c_str(); }
707 virtual const char *getInterface() const { return m_interface.c_str(); }
710 * binds a member to the this pointer of its instance
711 * and invokes it when the specified method is called
713 template <class A1, class C, class M> void add(A1 instance, M C::*method,
714 const char *name, GDBusMethodFlags flags = G_DBUS_METHOD_FLAG_NONE) {
715 typedef MakeMethodEntry< boost::function<M> > entry_type;
716 m_methods.push_back(entry_type::make(name, flags, entry_type::boostptr(method, instance)));
721 * binds a plain function pointer with no additional arguments and
722 * invokes it when the specified method is called
724 template <class M> void add(M *function,
725 const char *name, GDBusMethodFlags flags = G_DBUS_METHOD_FLAG_NONE) {
726 m_methods.push_back(MakeMethodEntry< boost::function<M> >::make(name, flags, function));
730 * add an existing signal entry
732 template <class S> void add(const S &s) {
733 m_signals.push_back(s.makeSignalEntry());
736 void activate(GDBusMethodTable *methods,
737 GDBusSignalTable *signals,
738 GDBusPropertyTable *properties,
740 if (!g_dbus_register_interface(getConnection(), getPath(), getInterface(),
741 methods, signals, properties, user_data, NULL)) {
742 throw std::runtime_error(std::string("g_dbus_register_interface() failed for ") + getPath() + " " + getInterface());
748 if (!g_dbus_register_interface(getConnection(), getPath(), getInterface(),
749 m_methods.get(), m_signals.get(), NULL, NULL, NULL)) {
750 throw std::runtime_error(std::string("g_dbus_register_interface() failed for ") + getPath() + " " + getInterface());
758 if (!g_dbus_unregister_interface(getConnection(),
761 throw std::runtime_error(std::string("g_dbus_unregister_interface() failed for ") + getPath() + " " + getInterface());
770 * to be used for plain parameters like int32_t:
771 * treat as arguments which have to be extracted
772 * from the D-Bus message and can be skipped when
775 template<class host, int dbus> struct basic_marshal : public dbus_traits_base
777 typedef host host_type;
778 typedef host arg_type;
779 static const int dbus_type = dbus;
782 * copy value from D-Bus iterator into variable
784 static void get(DBusConnection *conn, DBusMessage *msg,
785 DBusMessageIter &iter, host &value)
787 if (dbus_message_iter_get_arg_type(&iter) != dbus) {
788 throw std::runtime_error("invalid argument");
790 dbus_message_iter_get_basic(&iter, &value);
791 dbus_message_iter_next(&iter);
795 * copy value from return value into D-Bus iterator,
796 * empty here because plain types are no return values
798 static void append(DBusMessageIter &iter, arg_type value)
804 * utility function to be used by derived classes which
805 * need to copy a variable of this underlying type
807 static void append_retval(DBusMessageIter &iter, arg_type value)
809 if (!dbus_message_iter_append_basic(&iter, dbus, &value)) {
810 throw std::runtime_error("out of memory");
815 template<> struct dbus_traits<uint8_t> :
816 public basic_marshal< uint8_t, DBUS_TYPE_BYTE >
819 * plain type, regardless of whether used as
820 * input or output parameter
822 static std::string getType() { return "y"; }
825 * plain type => input parameter => non-empty signature
827 static std::string getSignature() {return getType(); }
830 * plain type => not returned to caller
832 static std::string getReply() { return ""; }
836 /** if the app wants to use signed char, let it and treat it like a byte */
837 template<> struct dbus_traits<int8_t> : dbus_traits<uint8_t>
839 typedef int8_t host_type;
840 typedef int8_t arg_type;
842 static void get(DBusConnection *conn, DBusMessage *msg,
843 DBusMessageIter &iter, host_type &value)
845 dbus_traits<uint8_t>::get(conn, msg, iter, reinterpret_cast<uint8_t &>(value));
849 template<> struct dbus_traits<int16_t> :
850 public basic_marshal< int16_t, DBUS_TYPE_INT16 >
852 static std::string getType() { return "n"; }
853 static std::string getSignature() {return getType(); }
854 static std::string getReply() { return ""; }
856 template<> struct dbus_traits<uint16_t> :
857 public basic_marshal< uint16_t, DBUS_TYPE_UINT16 >
859 static std::string getType() { return "q"; }
860 static std::string getSignature() {return getType(); }
861 static std::string getReply() { return ""; }
863 template<> struct dbus_traits<int32_t> :
864 public basic_marshal< int32_t, DBUS_TYPE_INT32 >
866 static std::string getType() { return "i"; }
867 static std::string getSignature() {return getType(); }
868 static std::string getReply() { return ""; }
870 template<> struct dbus_traits<uint32_t> :
871 public basic_marshal< uint32_t, DBUS_TYPE_UINT32 >
873 static std::string getType() { return "u"; }
874 static std::string getSignature() {return getType(); }
875 static std::string getReply() { return ""; }
878 template<> struct dbus_traits<bool> : public dbus_traits_base
880 static std::string getType() { return "b"; }
881 static std::string getSignature() {return getType(); }
882 static std::string getReply() { return ""; }
883 static const int dbus = DBUS_TYPE_BOOLEAN;
885 static void get(DBusConnection *conn, DBusMessage *msg,
886 DBusMessageIter &iter, bool &value)
888 if (dbus_message_iter_get_arg_type(&iter) != dbus) {
889 throw std::runtime_error("invalid argument");
891 dbus_bool_t dbus_value;
892 dbus_message_iter_get_basic(&iter, &dbus_value);
893 dbus_message_iter_next(&iter);
897 static void append(DBusMessageIter &iter, bool value) {}
899 static void append_retval(DBusMessageIter &iter, bool value)
901 dbus_bool_t dbus_value = value;
902 if (!dbus_message_iter_append_basic(&iter, dbus, &dbus_value)) {
903 throw std::runtime_error("out of memory");
907 typedef bool host_type;
908 typedef bool arg_type;
911 template<> struct dbus_traits<std::string> : public dbus_traits_base
913 static std::string getType() { return "s"; }
914 static std::string getSignature() {return getType(); }
915 static std::string getReply() { return ""; }
916 static const int dbus = DBUS_TYPE_STRING;
918 static void get(DBusConnection *conn, DBusMessage *msg,
919 DBusMessageIter &iter, std::string &value)
921 if (dbus_message_iter_get_arg_type(&iter) != dbus) {
922 throw std::runtime_error("invalid argument");
925 dbus_message_iter_get_basic(&iter, &str);
926 dbus_message_iter_next(&iter);
930 static void append(DBusMessageIter &iter, const std::string &value) {}
932 static void append_retval(DBusMessageIter &iter, const std::string &value)
934 const char *str = value.c_str();
935 if (!dbus_message_iter_append_basic(&iter, dbus, &str)) {
936 throw std::runtime_error("out of memory");
940 typedef std::string host_type;
941 typedef const std::string &arg_type;
944 template <> struct dbus_traits<DBusObject_t> : public dbus_traits_base
946 static std::string getType() { return "o"; }
947 static std::string getSignature() {return getType(); }
948 static std::string getReply() { return ""; }
949 static const int dbus = DBUS_TYPE_OBJECT_PATH;
951 static void get(DBusConnection *conn, DBusMessage *msg,
952 DBusMessageIter &iter, DBusObject_t &value)
954 if (dbus_message_iter_get_arg_type(&iter) != dbus) {
955 throw std::runtime_error("invalid argument");
958 dbus_message_iter_get_basic(&iter, &str);
959 dbus_message_iter_next(&iter);
963 static void append(DBusMessageIter &iter, const DBusObject_t &value) {}
965 static void append_retval(DBusMessageIter &iter, const DBusObject_t &value)
967 const char *str = value.c_str();
968 if (!dbus_message_iter_append_basic(&iter, dbus, &str)) {
969 throw std::runtime_error("out of memory");
973 typedef DBusObject_t host_type;
974 typedef const DBusObject_t &arg_type;
978 * pseudo-parameter: not part of D-Bus signature,
979 * but rather extracted from message attributes
981 template <> struct dbus_traits<Caller_t> : public dbus_traits_base
983 static std::string getType() { return ""; }
984 static std::string getSignature() { return ""; }
985 static std::string getReply() { return ""; }
987 static void get(DBusConnection *conn, DBusMessage *msg,
988 DBusMessageIter &iter, Caller_t &value)
990 const char *peer = dbus_message_get_sender(msg);
992 throw std::runtime_error("D-Bus method call without sender?!");
997 static void append(DBusMessageIter &iter, const DBusObject_t &value) {}
999 typedef Caller_t host_type;
1000 typedef const Caller_t &arg_type;
1004 * Pass array of basic type plus its number of entries.
1005 * Can only be used in cases where the caller owns the
1006 * memory and can discard it when the call returns, in
1007 * other words, for method calls, asynchronous replys and
1008 * signals, but not for return values.
1010 template<class V> struct dbus_traits< std::pair<size_t, const V *> > : public dbus_traits_base
1012 static std::string getContainedType()
1014 return dbus_traits<V>::getType();
1016 static std::string getType()
1018 return std::string("a") +
1019 dbus_traits<V>::getType();
1021 static std::string getSignature() {return getType(); }
1022 static std::string getReply() { return ""; }
1023 typedef std::pair<size_t, const V *> host_type;
1024 typedef const host_type &arg_type;
1026 static void get(DBusConnection *conn, DBusMessage *msg,
1027 DBusMessageIter &iter, host_type &array)
1029 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1030 throw std::runtime_error("invalid argument");
1032 DBusMessageIter sub;
1033 dbus_message_iter_recurse(&iter, &sub);
1034 int type = dbus_message_iter_get_arg_type(&sub);
1035 if (type != dbus_traits<V>::dbus_type) {
1036 throw std::runtime_error("invalid argument");
1039 typename dbus_traits<V>::host_type *data;
1040 dbus_message_iter_get_fixed_array(&sub, &data, &nelements);
1041 array.first = nelements;
1042 array.second = data;
1043 dbus_message_iter_next(&iter);
1046 static void append(DBusMessageIter &iter, arg_type array) {}
1048 static void append_retval(DBusMessageIter &iter, arg_type array)
1050 DBusMessageIter sub;
1051 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, getContainedType().c_str(), &sub) ||
1052 !dbus_message_iter_append_fixed_array(&sub, dbus_traits<V>::dbus_type, &array.second, array.first) ||
1053 !dbus_message_iter_close_container(&iter, &sub)) {
1054 throw std::runtime_error("out of memory");
1060 * a std::map - treat it like a D-Bus dict
1062 template<class K, class V> struct dbus_traits< std::map<K, V> > : public dbus_traits_base
1064 static std::string getContainedType()
1066 return std::string("{") +
1067 dbus_traits<K>::getType() +
1068 dbus_traits<V>::getType() +
1071 static std::string getType()
1073 return std::string("a") +
1076 static std::string getSignature() {return getType(); }
1077 static std::string getReply() { return ""; }
1078 typedef std::map<K, V> host_type;
1079 typedef const std::map<K, V> &arg_type;
1081 static void get(DBusConnection *conn, DBusMessage *msg,
1082 DBusMessageIter &iter, host_type &dict)
1084 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1085 throw std::runtime_error("invalid argument");
1087 DBusMessageIter sub;
1088 dbus_message_iter_recurse(&iter, &sub);
1090 while ((type = dbus_message_iter_get_arg_type(&sub)) != DBUS_TYPE_INVALID) {
1091 if (type != DBUS_TYPE_DICT_ENTRY) {
1092 throw std::runtime_error("invalid argument");
1094 DBusMessageIter entry;
1095 dbus_message_iter_recurse(&sub, &entry);
1098 dbus_traits<K>::get(conn, msg, entry, key);
1099 dbus_traits<V>::get(conn, msg, entry, value);
1100 dict.insert(std::make_pair(key, value));
1101 dbus_message_iter_next(&sub);
1103 dbus_message_iter_next(&iter);
1106 static void append(DBusMessageIter &iter, arg_type dict) {}
1108 static void append_retval(DBusMessageIter &iter, arg_type dict)
1110 DBusMessageIter sub;
1111 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, getContainedType().c_str(), &sub)) {
1112 throw std::runtime_error("out of memory");
1115 for(typename host_type::const_iterator it = dict.begin();
1118 DBusMessageIter entry;
1119 if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &entry)) {
1120 throw std::runtime_error("out of memory");
1122 dbus_traits<K>::append_retval(entry, it->first);
1123 dbus_traits<V>::append_retval(entry, it->second);
1124 if (!dbus_message_iter_close_container(&sub, &entry)) {
1125 throw std::runtime_error("out of memory");
1128 if (!dbus_message_iter_close_container(&iter, &sub)) {
1129 throw std::runtime_error("out of memory");
1135 * a std::vector - maps to D-Bus array, but with inefficient marshaling
1136 * because we cannot get a base pointer for the whole array
1138 template<class V> struct dbus_traits< std::vector<V> > : public dbus_traits_base
1140 static std::string getContainedType()
1142 return dbus_traits<V>::getType();
1144 static std::string getType()
1146 return std::string("a") +
1149 static std::string getSignature() {return getType(); }
1150 static std::string getReply() { return ""; }
1151 typedef std::vector<V> host_type;
1152 typedef const std::vector<V> &arg_type;
1154 static void get(DBusConnection *conn, DBusMessage *msg,
1155 DBusMessageIter &iter, host_type &array)
1157 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1158 throw std::runtime_error("invalid argument");
1160 DBusMessageIter sub;
1161 dbus_message_iter_recurse(&iter, &sub);
1162 while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
1164 dbus_traits<V>::get(conn, msg, sub, value);
1165 array.push_back(value);
1167 dbus_message_iter_next(&iter);
1170 static void append(DBusMessageIter &iter, arg_type array) {}
1172 static void append_retval(DBusMessageIter &iter, arg_type array)
1174 DBusMessageIter sub;
1175 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, getContainedType().c_str(), &sub)) {
1176 throw std::runtime_error("out of memory");
1179 for(typename host_type::const_iterator it = array.begin();
1182 dbus_traits<V>::append_retval(sub, *it);
1184 if (!dbus_message_iter_close_container(&iter, &sub)) {
1185 throw std::runtime_error("out of memory");
1191 * a single member m of type V in a struct K
1193 template<class K, class V, V K::*m> struct dbus_member_single
1195 static std::string getType()
1197 return dbus_traits<V>::getType();
1199 typedef V host_type;
1201 static void get(DBusConnection *conn, DBusMessage *msg,
1202 DBusMessageIter &iter, K &val)
1204 dbus_traits<V>::get(conn, msg, iter, val.*m);
1207 static void append_retval(DBusMessageIter &iter, const K &val)
1209 dbus_traits<V>::append_retval(iter, val.*m);
1214 * a member m of type V in a struct K, followed by another dbus_member
1215 * or dbus_member_single to end the chain
1217 template<class K, class V, V K::*m, class M> struct dbus_member
1219 static std::string getType()
1221 return dbus_traits<V>::getType() + M::getType();
1223 typedef V host_type;
1225 static void get(DBusConnection *conn, DBusMessage *msg,
1226 DBusMessageIter &iter, K &val)
1228 dbus_traits<V>::get(conn, msg, iter, val.*m);
1229 M::get(conn, msg, iter, val);
1232 static void append_retval(DBusMessageIter &iter, const K &val)
1234 dbus_traits<V>::append_retval(iter, val.*m);
1235 M::append_retval(iter, val);
1240 * a helper class which implements dbus_traits for
1241 * a class, use with:
1242 * struct foo { int a; std::string b; };
1243 * template<> struct dbus_traits< foo > : dbus_struct_traits< foo,
1244 * dbus_member<foo, int, &foo::a,
1245 * dbus_member_single<foo, std::string, &foo::b> > > {};
1247 template<class K, class M> struct dbus_struct_traits : public dbus_traits_base
1249 static std::string getContainedType()
1251 return M::getType();
1253 static std::string getType()
1255 return std::string("(") +
1256 getContainedType() +
1259 static std::string getSignature() {return getType(); }
1260 static std::string getReply() { return ""; }
1261 typedef K host_type;
1262 typedef const K &arg_type;
1264 static void get(DBusConnection *conn, DBusMessage *msg,
1265 DBusMessageIter &iter, host_type &val)
1268 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRUCT) {
1269 throw std::runtime_error("invalid argument");
1271 DBusMessageIter sub;
1272 dbus_message_iter_recurse(&iter, &sub);
1273 M::get(conn, msg, sub, val);
1274 dbus_message_iter_next(&iter);
1277 static void append(DBusMessageIter &iter, arg_type val) {}
1279 static void append_retval(DBusMessageIter &iter, arg_type val)
1281 DBusMessageIter sub;
1282 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &sub)) {
1283 throw std::runtime_error("out of memory");
1285 M::append_retval(sub, val);
1286 if (!dbus_message_iter_close_container(&iter, &sub)) {
1287 throw std::runtime_error("out of memory");
1293 * special case const reference parameter:
1294 * treat like pass-by-value input argument
1296 * Example: const std::string &arg
1298 template<class C> struct dbus_traits<const C &> : public dbus_traits<C> {};
1301 * special case writeable reference parameter:
1302 * must be a return value, so provide our own
1303 * get() and pack() where get() doesn't do
1304 * anything and pack() really encodes the value
1306 * Example: std::string &retval
1308 template<class C> struct dbus_traits<C &> : public dbus_traits<C>
1311 * skip when extracting input arguments
1313 static void get(DBusConnection *conn, DBusMessage *msg,
1314 DBusMessageIter &iter, C &value) {}
1315 static std::string getSignature() { return ""; }
1318 * use utility function provided by underlying trait
1320 static void append(DBusMessageIter &iter, const C &value)
1322 dbus_traits<C>::append_retval(iter, value);
1324 static std::string getReply() { return dbus_traits<C>::getType(); }
1328 * dbus-cxx base exception thrown in dbus server
1329 * org.syncevolution.gdbus-cxx.Exception
1330 * This base class only contains interfaces, no data members
1332 class DBusCXXException
1336 * get exception name, used to convert to dbus error name
1337 * subclasses should override it
1339 virtual std::string getName() const { return "org.syncevolution.gdbus-cxx.Exception"; }
1344 virtual const char* getMessage() const { return "unknown"; }
1347 static DBusMessage *handleException(DBusMessage *msg)
1350 #ifdef DBUS_CXX_EXCEPTION_HANDLER
1351 return DBUS_CXX_EXCEPTION_HANDLER(msg);
1355 } catch (const dbus_error &ex) {
1356 return g_dbus_create_error(msg, ex.dbusName().c_str(), "%s", ex.what());
1357 } catch (const DBusCXXException &ex) {
1358 return g_dbus_create_error(msg, ex.getName().c_str(), "%s", ex.getMessage());
1359 } catch (const std::runtime_error &ex) {
1360 return g_dbus_create_error(msg, "org.syncevolution.gdbus-cxx.Exception", "%s", ex.what());
1362 return g_dbus_create_error(msg, "org.syncevolution.gdbus-cxx.Exception", "unknown");
1367 * Check presence of a certain D-Bus client.
1369 class DBusWatch : public Watch
1371 DBusConnectionPtr m_conn;
1372 boost::function<void (void)> m_callback;
1376 static void disconnect(DBusConnection *connection,
1379 DBusWatch *watch = static_cast<DBusWatch *>(user_data);
1380 if (!watch->m_called) {
1381 watch->m_called = true;
1382 if (watch->m_callback) {
1383 watch->m_callback();
1389 DBusWatch(const DBusConnectionPtr &conn,
1390 const boost::function<void (void)> &callback = boost::function<void (void)>()) :
1392 m_callback(callback),
1398 virtual void setCallback(const boost::function<void (void)> &callback)
1400 m_callback = callback;
1401 if (m_called && m_callback) {
1406 void activate(const char *peer)
1409 throw std::runtime_error("DBusWatch::activate(): no peer");
1412 // Install watch first ...
1413 m_watchID = g_dbus_add_disconnect_watch(m_conn.get(),
1419 throw std::runtime_error("g_dbus_add_disconnect_watch() failed");
1422 // ... then check that the peer really exists,
1423 // otherwise we'll never notice the disconnect.
1424 // If it disconnects while we are doing this,
1425 // then disconnect() will be called twice,
1426 // but it handles that.
1428 if (!dbus_bus_name_has_owner(m_conn.get(),
1432 error.throwFailure("dbus_bus_name_has_owner()");
1434 disconnect(m_conn.get(), this);
1441 if (!g_dbus_remove_watch(m_conn.get(), m_watchID)) {
1442 // this may happen because the watch is
1443 // removed automatically when it was triggered
1451 * pseudo-parameter: not part of D-Bus signature,
1452 * but rather extracted from message attributes
1454 template <> struct dbus_traits< boost::shared_ptr<Watch> > : public dbus_traits_base
1456 static std::string getType() { return ""; }
1457 static std::string getSignature() { return ""; }
1458 static std::string getReply() { return ""; }
1460 static void get(DBusConnection *conn, DBusMessage *msg,
1461 DBusMessageIter &iter, boost::shared_ptr<Watch> &value)
1463 boost::shared_ptr<DBusWatch> watch(new DBusWatch(conn));
1464 watch->activate(dbus_message_get_sender(msg));
1468 static void append(DBusMessageIter &iter, const boost::shared_ptr<Watch> &value) {}
1470 typedef boost::shared_ptr<Watch> host_type;
1471 typedef const boost::shared_ptr<Watch> &arg_type;
1475 * base class for D-Bus results,
1476 * keeps references to required objects and provides the
1479 class DBusResult : virtual public Result
1482 DBusConnectionPtr m_conn; /**< connection via which the message was received */
1483 DBusMessagePtr m_msg; /**< the method invocation message */
1486 DBusResult(DBusConnection *conn,
1492 virtual void failed(const dbus_error &error)
1494 if (!g_dbus_send_error(m_conn.get(), m_msg.get(),
1495 error.dbusName().c_str(),
1496 "%s", error.what())) {
1497 throw std::runtime_error("g_dbus_send_error() failed");
1501 virtual Watch *createWatch(const boost::function<void (void)> &callback)
1503 std::auto_ptr<DBusWatch> watch(new DBusWatch(m_conn, callback));
1504 watch->activate(dbus_message_get_sender(m_msg.get()));
1505 return watch.release();
1514 DBusResult0(DBusConnection *conn,
1516 DBusResult(conn, msg)
1521 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1523 throw std::runtime_error("no DBusMessage");
1525 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1526 throw std::runtime_error("dbus_connection_send failed");
1530 static std::string getSignature() { return ""; }
1531 static void append(DBusMessageIter &iter) {}
1534 template <typename A1>
1540 DBusResult1(DBusConnection *conn,
1542 DBusResult(conn, msg)
1545 virtual void done(A1 a1)
1547 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1549 throw std::runtime_error("no DBusMessage");
1551 append_retvals(reply, a1);
1552 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1553 throw std::runtime_error("dbus_connection_send failed");
1557 static std::string getSignature() { return dbus_traits<A1>::getSignature(); }
1559 static const bool asynchronous =
1560 dbus_traits<A1>::asynchronous;
1563 template <typename A1, typename A2>
1565 public Result2<A1, A2>,
1569 DBusResult2(DBusConnection *conn,
1571 DBusResult(conn, msg)
1574 virtual void done(A1 a1, A2 a2)
1576 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1578 throw std::runtime_error("no DBusMessage");
1580 append_retvals(reply, a1, a2);
1581 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1582 throw std::runtime_error("dbus_connection_send failed");
1586 static std::string getSignature() {
1587 return dbus_traits<A1>::getSignature() +
1588 DBusResult1<A2>::getSignature();
1591 static const bool asynchronous =
1592 dbus_traits<A1>::asynchronous ||
1593 DBusResult1<A2>::asynchronous;
1596 template <typename A1, typename A2, typename A3>
1598 public Result3<A1, A2, A3>,
1602 DBusResult3(DBusConnection *conn,
1604 DBusResult(conn, msg)
1607 virtual void done(A1 a1, A2 a2, A3 a3)
1609 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1611 throw std::runtime_error("no DBusMessage");
1613 append_retvals(reply, a1, a2, a3);
1614 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1615 throw std::runtime_error("dbus_connection_send failed");
1619 static std::string getSignature() {
1620 return dbus_traits<A1>::getSignature() +
1621 DBusResult2<A2, A3>::getSignature();
1624 static const bool asynchronous =
1625 dbus_traits<A1>::asynchronous ||
1626 DBusResult2<A2, A3>::asynchronous;
1629 template <typename A1, typename A2, typename A3, typename A4>
1631 public Result4<A1, A2, A3, A4>,
1635 DBusResult4(DBusConnection *conn,
1637 DBusResult(conn, msg)
1640 virtual void done(A1 a1, A2 a2, A3 a3, A4 a4)
1642 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1644 throw std::runtime_error("no DBusMessage");
1646 append_retvals(reply, a1, a2, a3, a4);
1647 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1648 throw std::runtime_error("dbus_connection_send failed");
1652 static std::string getSignature() {
1653 return dbus_traits<A1>::getSignature() +
1654 DBusResult3<A2, A3, A4>::getSignature();
1657 static const bool asynchronous =
1658 dbus_traits<A1>::asynchronous ||
1659 DBusResult3<A2, A3, A4>::asynchronous;
1662 template <typename A1, typename A2, typename A3, typename A4, typename A5>
1664 public Result5<A1, A2, A3, A4, A5>,
1668 DBusResult5(DBusConnection *conn,
1670 DBusResult(conn, msg)
1673 virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
1675 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1677 throw std::runtime_error("no DBusMessage");
1679 append_retvals(reply, a1, a2, a3, a4, a5);
1680 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1681 throw std::runtime_error("dbus_connection_send failed");
1685 static std::string getSignature() {
1686 return dbus_traits<A1>::getSignature() +
1687 DBusResult4<A2, A3, A4, A5>::getSignature();
1690 static const bool asynchronous =
1691 dbus_traits<A1>::asynchronous ||
1692 DBusResult4<A2, A3, A4, A5>::asynchronous;
1695 template <typename A1, typename A2, typename A3, typename A4, typename A5,
1698 public Result6<A1, A2, A3, A4, A5, A6>,
1702 DBusResult6(DBusConnection *conn,
1704 DBusResult(conn, msg)
1707 virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
1709 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1711 throw std::runtime_error("no DBusMessage");
1713 append_retvals(reply, a1, a2, a3, a4, a5, a6);
1714 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1715 throw std::runtime_error("dbus_connection_send failed");
1719 static std::string getSignature() {
1720 return dbus_traits<A1>::getSignature() +
1721 DBusResult5<A2, A3, A4, A5, A6>::getSignature();
1724 static const bool asynchronous =
1725 dbus_traits<A1>::asynchronous ||
1726 DBusResult5<A2, A3, A4, A5, A6>::asynchronous;
1729 template <typename A1, typename A2, typename A3, typename A4, typename A5,
1730 typename A6, typename A7>
1732 public Result7<A1, A2, A3, A4, A5, A6, A7>,
1736 DBusResult7(DBusConnection *conn,
1738 DBusResult(conn, msg)
1741 virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
1743 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1745 throw std::runtime_error("no DBusMessage");
1747 append_retvals(reply, a1, a2, a3, a4, a5, a6, a7);
1748 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1749 throw std::runtime_error("dbus_connection_send failed");
1753 static std::string getSignature() {
1754 return dbus_traits<A1>::getSignature() +
1755 DBusResult6<A2, A3, A4, A5, A6, A7>::getSignature();
1758 static const bool asynchronous =
1759 dbus_traits<A1>::asynchronous ||
1760 DBusResult6<A2, A3, A4, A5, A6, A7>::asynchronous;
1763 template <typename A1, typename A2, typename A3, typename A4, typename A5,
1764 typename A6, typename A7, typename A8>
1766 public Result8<A1, A2, A3, A4, A5, A6, A7, A8>,
1770 DBusResult8(DBusConnection *conn,
1772 DBusResult(conn, msg)
1775 virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
1777 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1779 throw std::runtime_error("no DBusMessage");
1781 append_retvals(reply, a1, a2, a3, a4, a5, a6, a7, a8);
1782 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1783 throw std::runtime_error("dbus_connection_send failed");
1787 static std::string getSignature() {
1788 return dbus_traits<A1>::getSignature() +
1789 DBusResult7<A2, A3, A4, A5, A6, A7, A8>::getSignature();
1792 static const bool asynchronous =
1793 dbus_traits<A1>::asynchronous ||
1794 DBusResult7<A2, A3, A4, A5, A6, A7, A8>::asynchronous;
1797 template <typename A1, typename A2, typename A3, typename A4, typename A5,
1798 typename A6, typename A7, typename A8, typename A9>
1800 public Result9<A1, A2, A3, A4, A5, A6, A7, A8, A9>,
1804 DBusResult9(DBusConnection *conn,
1806 DBusResult(conn, msg)
1809 virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
1811 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1813 throw std::runtime_error("no DBusMessage");
1815 append_retvals(reply, a1, a2, a3, a4, a5, a6, a7, a8, a9);
1816 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1817 throw std::runtime_error("dbus_connection_send failed");
1821 static std::string getSignature() {
1822 return dbus_traits<A1>::getSignature() +
1823 DBusResult8<A2, A3, A4, A5, A6, A7, A8, A9>::getSignature();
1826 static const bool asynchronous =
1827 dbus_traits<A1>::asynchronous ||
1828 DBusResult8<A2, A3, A4, A5, A6, A7, A8, A9>::asynchronous;
1831 template <typename A1, typename A2, typename A3, typename A4, typename A5,
1832 typename A6, typename A7, typename A8, typename A9, typename A10>
1833 class DBusResult10 :
1834 public Result10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>,
1838 DBusResult10(DBusConnection *conn,
1840 DBusResult(conn, msg)
1843 virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10)
1845 DBusMessagePtr reply(g_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID));
1847 throw std::runtime_error("no DBusMessage");
1849 append_retvals(reply, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
1850 if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) {
1851 throw std::runtime_error("dbus_connection_send failed");
1855 static std::string getSignature() {
1856 return dbus_traits<A1>::getSignature() +
1857 DBusResult9<A2, A3, A4, A5, A6, A7, A8, A9, A10>::getSignature();
1860 static const bool asynchronous =
1861 dbus_traits<A1>::asynchronous ||
1862 DBusResult9<A2, A3, A4, A5, A6, A7, A8, A9, A10>::asynchronous;
1866 * A parameter which points towards one of our Result* structures.
1867 * All of the types contained in it count towards the Reply signature.
1868 * The requested Result type itself is constructed here.
1870 * @param R Result0, Result1<type>, ...
1871 * @param DBusR the class implementing R
1873 template <class R, class DBusR> struct dbus_traits_result
1875 static std::string getType() { return DBusR::getSignature(); }
1876 static std::string getSignature() { return ""; }
1877 static std::string getReply() { return getType(); }
1879 typedef boost::shared_ptr<R> host_type;
1880 typedef boost::shared_ptr<R> &arg_type;
1881 static const bool asynchronous = true;
1883 static void get(DBusConnection *conn, DBusMessage *msg,
1884 DBusMessageIter &iter, host_type &value)
1886 value.reset(new DBusR(conn, msg));
1889 static void append(DBusMessageIter &iter, const host_type &value) {}
1890 static void append_retval(DBusMessageIter &iter, const host_type &value) {}
1894 struct dbus_traits< boost::shared_ptr<Result0> > :
1895 public dbus_traits_result<Result0, DBusResult0>
1898 struct dbus_traits< boost::shared_ptr< Result1<A1> > >:
1899 public dbus_traits_result< Result1<A1>, DBusResult1<A1> >
1901 template <class A1, class A2>
1902 struct dbus_traits< boost::shared_ptr< Result2<A1, A2> > >:
1903 public dbus_traits_result< Result2<A1, A2>, DBusResult2<A1, A2> >
1905 template <class A1, class A2, class A3>
1906 struct dbus_traits< boost::shared_ptr< Result3<A1, A2, A3> > >:
1907 public dbus_traits_result< Result3<A1, A2, A3>, DBusResult3<A1, A2, A3> >
1909 template <class A1, class A2, class A3, class A4>
1910 struct dbus_traits< boost::shared_ptr< Result4<A1, A2, A3, A4> > >:
1911 public dbus_traits_result< Result4<A1, A2, A3, A4>, DBusResult4<A1, A2, A3, A4> >
1913 template <class A1, class A2, class A3, class A4, class A5>
1914 struct dbus_traits< boost::shared_ptr< Result5<A1, A2, A3, A4, A5> > >:
1915 public dbus_traits_result< Result5<A1, A2, A3, A4, A5>, DBusResult5<A1, A2, A3, A4, A5> >
1917 template <class A1, class A2, class A3, class A4, class A5, class A6>
1918 struct dbus_traits< boost::shared_ptr< Result6<A1, A2, A3, A4, A5, A6> > >:
1919 public dbus_traits_result< Result6<A1, A2, A3, A4, A5, A6>, DBusResult6<A1, A2, A3, A4, A5, A6> >
1921 template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
1922 struct dbus_traits< boost::shared_ptr< Result7<A1, A2, A3, A4, A5, A6, A7> > >:
1923 public dbus_traits_result< Result7<A1, A2, A3, A4, A5, A6, A7>, DBusResult7<A1, A2, A3, A4, A5, A6, A7> >
1925 template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
1926 struct dbus_traits< boost::shared_ptr< Result8<A1, A2, A3, A4, A5, A6, A7, A8> > >:
1927 public dbus_traits_result< Result8<A1, A2, A3, A4, A5, A6, A7, A8>, DBusResult8<A1, A2, A3, A4, A5, A6, A7, A8> >
1929 template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
1930 struct dbus_traits< boost::shared_ptr< Result9<A1, A2, A3, A4, A5, A6, A7, A8, A9> > >:
1931 public dbus_traits_result< Result9<A1, A2, A3, A4, A5, A6, A7, A8, A9>, DBusResult9<A1, A2, A3, A4, A5, A6, A7, A8, A9> >
1933 template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
1934 struct dbus_traits< boost::shared_ptr< Result10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> > >:
1935 public dbus_traits_result< Result10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>, DBusResult10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> >
1941 * Call with two parameters and one return code. All other calls are
1942 * variations of this, so this one is fully documented to explain all
1943 * tricks used in these templates. The actual code without comments is
1946 template <class R, class A1, class A2>
1947 struct MakeMethodEntry< boost::function<R (A1, A2)> >
1949 typedef boost::function<R (A1, A2)> M;
1951 // Any type a Result parameter? This can be computed at compile time.
1952 static const bool asynchronous = dbus_traits< DBusResult2<A1, A2> >::asynchronous;
1954 static DBusMessage *methodFunction(DBusConnection *conn,
1955 DBusMessage *msg, void *data)
1957 // all exceptions must be caught and translated into
1958 // a suitable D-Bus reply
1960 // Argument types might may be references or pointers.
1961 // To instantiate a variable we need the underlying
1962 // datatype, which is provided by the dbus_traits.
1963 // "typename" is necessary to tell the compiler
1964 // that host_type really is a type.
1965 typename dbus_traits<R>::host_type r;
1966 typename dbus_traits<A1>::host_type a1;
1967 typename dbus_traits<A2>::host_type a2;
1969 // Extract all parameters. Because we don't now
1970 // whether a parameter is an argument or a return
1971 // value, we call get() for each of them and let
1972 // the corresponding dbus_traits decide that. Traits
1973 // for types which are plain types or const references
1974 // have a non-empty get(), whereas references are treated
1975 // as return values and have an empty get().
1976 DBusMessageIter iter;
1977 dbus_message_iter_init(msg, &iter);
1978 dbus_traits<A1>::get(conn, msg, iter, a1);
1979 dbus_traits<A2>::get(conn, msg, iter, a2);
1981 // The data pointer is a pointer to a boost function,
1982 // as set up for us by make(). The compiler knows the
1983 // exact method prototype and thus can handle
1984 // call-by-value and call-by-reference correctly.
1985 r = (*static_cast<M *>(data))(a1, a2);
1987 // No reply necessary? If any of the types is asking for
1988 // a Result handle, then the reply will be sent later.
1993 // Now prepare the reply. As with extracting parameters,
1994 // append() is empty for those parameters where nothing
1996 DBusMessage *reply = dbus_message_new_method_return(msg);
1999 dbus_message_iter_init_append(reply, &iter);
2000 // We know that the return value has to be appended,
2001 // even though the trait would not normally do that
2002 // because it is a plain type => call utility function
2004 dbus_traits<R>::append_retval(iter, r);
2005 dbus_traits<A1>::append(iter, a1);
2006 dbus_traits<A2>::append(iter, a2);
2009 // let handleException rethrow the exception
2010 // to determine its type
2011 return handleException(msg);
2016 * The boost function doesn't have a virtual destructor.
2017 * Therefore we have to cast down to the right type M
2018 * before deleting it. The rest of the allocated data
2019 * is freed by GDBusVector.
2021 static void destroyFunction(void *user_data)
2023 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
2024 delete static_cast<M *>(entry->method_data);
2028 * Creates a GDBusMethodTable entry.
2029 * The strings inside the entry are allocated
2030 * with strdup(), to be freed by GDBusVector::destroy().
2032 GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
2034 GDBusMethodTable entry;
2035 entry.name = strdup(name);
2036 // same trick as before: only argument types
2037 // are added to the signature
2039 buffer += dbus_traits<A1>::getSignature();
2040 buffer += dbus_traits<A2>::getSignature();
2041 entry.signature = strdup(buffer.c_str());
2042 // now the same for reply types
2044 buffer += dbus_traits<R>::getReply();
2045 buffer += dbus_traits<A1>::getReply();
2046 buffer += dbus_traits<A2>::getReply();
2047 entry.reply = strdup(buffer.c_str());
2048 // these are the function templates above
2049 entry.function = methodFunction;
2050 entry.destroy = destroyFunction;
2051 // make sure that methodFunction has access to the boost function
2052 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
2053 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
2054 entry.method_data = new M(m);
2060 /** ===> 10 parameters */
2061 template <class A1, class A2, class A3, class A4, class A5,
2062 class A6, class A7, class A8, class A9, class A10>
2063 struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> >
2065 typedef void (Mptr)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
2066 typedef boost::function<Mptr> M;
2068 template <class I, class C> static M bind(Mptr C::*method, I instance) {
2069 // this fails because bind() only supports up to 9 parameters, including
2070 // the initial this pointer
2071 return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8, _9 /* _10 */);
2074 static const bool asynchronous = dbus_traits< DBusResult10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> >::asynchronous;
2076 static DBusMessage *methodFunction(DBusConnection *conn,
2077 DBusMessage *msg, void *data)
2080 typename dbus_traits<A1>::host_type a1;
2081 typename dbus_traits<A2>::host_type a2;
2082 typename dbus_traits<A3>::host_type a3;
2083 typename dbus_traits<A4>::host_type a4;
2084 typename dbus_traits<A5>::host_type a5;
2085 typename dbus_traits<A6>::host_type a6;
2086 typename dbus_traits<A7>::host_type a7;
2087 typename dbus_traits<A8>::host_type a8;
2088 typename dbus_traits<A9>::host_type a9;
2089 typename dbus_traits<A10>::host_type a10;
2091 DBusMessageIter iter;
2092 dbus_message_iter_init(msg, &iter);
2093 dbus_traits<A1>::get(conn, msg, iter, a1);
2094 dbus_traits<A2>::get(conn, msg, iter, a2);
2095 dbus_traits<A3>::get(conn, msg, iter, a3);
2096 dbus_traits<A4>::get(conn, msg, iter, a4);
2097 dbus_traits<A5>::get(conn, msg, iter, a5);
2098 dbus_traits<A6>::get(conn, msg, iter, a6);
2099 dbus_traits<A7>::get(conn, msg, iter, a7);
2100 dbus_traits<A8>::get(conn, msg, iter, a8);
2101 dbus_traits<A9>::get(conn, msg, iter, a9);
2102 dbus_traits<A10>::get(conn, msg, iter, a10);
2104 (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
2110 DBusMessage *reply = dbus_message_new_method_return(msg);
2113 dbus_message_iter_init_append(reply, &iter);
2114 dbus_traits<A1>::append(iter, a1);
2115 dbus_traits<A2>::append(iter, a2);
2116 dbus_traits<A3>::append(iter, a3);
2117 dbus_traits<A4>::append(iter, a4);
2118 dbus_traits<A5>::append(iter, a5);
2119 dbus_traits<A6>::append(iter, a6);
2120 dbus_traits<A7>::append(iter, a7);
2121 dbus_traits<A8>::append(iter, a8);
2122 dbus_traits<A9>::append(iter, a9);
2123 dbus_traits<A10>::append(iter, a10);
2126 return handleException(msg);
2130 static void destroyFunction(void *user_data)
2132 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
2133 delete static_cast<M *>(entry->method_data);
2136 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
2138 GDBusMethodTable entry;
2139 entry.name = strdup(name);
2141 buffer += dbus_traits<A1>::getSignature();
2142 buffer += dbus_traits<A2>::getSignature();
2143 buffer += dbus_traits<A3>::getSignature();
2144 buffer += dbus_traits<A4>::getSignature();
2145 buffer += dbus_traits<A5>::getSignature();
2146 buffer += dbus_traits<A6>::getSignature();
2147 buffer += dbus_traits<A7>::getSignature();
2148 buffer += dbus_traits<A8>::getSignature();
2149 buffer += dbus_traits<A9>::getSignature();
2150 buffer += dbus_traits<A10>::getSignature();
2151 entry.signature = strdup(buffer.c_str());
2153 buffer += dbus_traits<A1>::getReply();
2154 buffer += dbus_traits<A2>::getReply();
2155 buffer += dbus_traits<A3>::getReply();
2156 buffer += dbus_traits<A4>::getReply();
2157 buffer += dbus_traits<A5>::getReply();
2158 buffer += dbus_traits<A6>::getReply();
2159 buffer += dbus_traits<A7>::getReply();
2160 buffer += dbus_traits<A8>::getReply();
2161 buffer += dbus_traits<A9>::getReply();
2162 buffer += dbus_traits<A10>::getReply();
2163 entry.reply = strdup(buffer.c_str());
2164 entry.function = methodFunction;
2165 entry.destroy = destroyFunction;
2166 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
2167 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
2168 entry.method_data = new M(m);
2173 /** 9 arguments, 1 return value */
2175 class A1, class A2, class A3, class A4, class A5,
2176 class A6, class A7, class A8, class A9>
2177 struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4, A5, A6, A7, A8, A9)> >
2179 typedef R (Mptr)(A1, A2, A3, A4, A5, A6, A7, A8, A9);
2180 typedef boost::function<Mptr> M;
2182 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
2183 // this fails because bind() only supports up to 9 parameters, including
2184 // the initial this pointer
2185 return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8, _9);
2188 static const bool asynchronous = DBusResult9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::asynchronous;
2190 static DBusMessage *methodFunction(DBusConnection *conn,
2191 DBusMessage *msg, void *data)
2194 typename dbus_traits<R>::host_type r;
2195 typename dbus_traits<A1>::host_type a1;
2196 typename dbus_traits<A2>::host_type a2;
2197 typename dbus_traits<A3>::host_type a3;
2198 typename dbus_traits<A4>::host_type a4;
2199 typename dbus_traits<A5>::host_type a5;
2200 typename dbus_traits<A6>::host_type a6;
2201 typename dbus_traits<A7>::host_type a7;
2202 typename dbus_traits<A8>::host_type a8;
2203 typename dbus_traits<A9>::host_type a9;
2205 DBusMessageIter iter;
2206 dbus_message_iter_init(msg, &iter);
2207 dbus_traits<A1>::get(conn, msg, iter, a1);
2208 dbus_traits<A2>::get(conn, msg, iter, a2);
2209 dbus_traits<A3>::get(conn, msg, iter, a3);
2210 dbus_traits<A4>::get(conn, msg, iter, a4);
2211 dbus_traits<A5>::get(conn, msg, iter, a5);
2212 dbus_traits<A6>::get(conn, msg, iter, a6);
2213 dbus_traits<A7>::get(conn, msg, iter, a7);
2214 dbus_traits<A8>::get(conn, msg, iter, a8);
2215 dbus_traits<A9>::get(conn, msg, iter, a9);
2217 r = (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7, a8, a9);
2223 DBusMessage *reply = dbus_message_new_method_return(msg);
2226 dbus_message_iter_init_append(reply, &iter);
2227 dbus_traits<R>::append_retval(iter, r);
2228 dbus_traits<A1>::append(iter, a1);
2229 dbus_traits<A2>::append(iter, a2);
2230 dbus_traits<A3>::append(iter, a3);
2231 dbus_traits<A4>::append(iter, a4);
2232 dbus_traits<A5>::append(iter, a5);
2233 dbus_traits<A6>::append(iter, a6);
2234 dbus_traits<A7>::append(iter, a7);
2235 dbus_traits<A8>::append(iter, a8);
2236 dbus_traits<A9>::append(iter, a9);
2239 return handleException(msg);
2243 static void destroyFunction(void *user_data)
2245 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
2246 delete static_cast<M *>(entry->method_data);
2249 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
2251 GDBusMethodTable entry;
2252 entry.name = strdup(name);
2254 buffer += dbus_traits<A1>::getSignature();
2255 buffer += dbus_traits<A2>::getSignature();
2256 buffer += dbus_traits<A3>::getSignature();
2257 buffer += dbus_traits<A4>::getSignature();
2258 buffer += dbus_traits<A5>::getSignature();
2259 buffer += dbus_traits<A6>::getSignature();
2260 buffer += dbus_traits<A7>::getSignature();
2261 buffer += dbus_traits<A8>::getSignature();
2262 buffer += dbus_traits<A9>::getSignature();
2263 entry.signature = strdup(buffer.c_str());
2265 buffer += dbus_traits<R>::getReply();
2266 buffer += dbus_traits<A1>::getReply();
2267 buffer += dbus_traits<A2>::getReply();
2268 buffer += dbus_traits<A3>::getReply();
2269 buffer += dbus_traits<A4>::getReply();
2270 buffer += dbus_traits<A5>::getReply();
2271 buffer += dbus_traits<A6>::getReply();
2272 buffer += dbus_traits<A7>::getReply();
2273 buffer += dbus_traits<A8>::getReply();
2274 buffer += dbus_traits<A9>::getReply();
2275 entry.reply = strdup(buffer.c_str());
2276 entry.function = methodFunction;
2277 entry.destroy = destroyFunction;
2278 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
2279 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
2280 entry.method_data = new M(m);
2285 /** ===> 9 parameters */
2286 template <class A1, class A2, class A3, class A4, class A5,
2287 class A6, class A7, class A8, class A9>
2288 struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5, A6, A7, A8, A9)> >
2290 typedef void (Mptr)(A1, A2, A3, A4, A5, A6, A7, A8, A9);
2291 typedef boost::function<Mptr> M;
2293 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
2294 return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8, _9);
2297 static const bool asynchronous = DBusResult9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::asynchronous;
2299 static DBusMessage *methodFunction(DBusConnection *conn,
2300 DBusMessage *msg, void *data)
2303 typename dbus_traits<A1>::host_type a1;
2304 typename dbus_traits<A2>::host_type a2;
2305 typename dbus_traits<A3>::host_type a3;
2306 typename dbus_traits<A4>::host_type a4;
2307 typename dbus_traits<A5>::host_type a5;
2308 typename dbus_traits<A6>::host_type a6;
2309 typename dbus_traits<A7>::host_type a7;
2310 typename dbus_traits<A8>::host_type a8;
2311 typename dbus_traits<A9>::host_type a9;
2313 DBusMessageIter iter;
2314 dbus_message_iter_init(msg, &iter);
2315 dbus_traits<A1>::get(conn, msg, iter, a1);
2316 dbus_traits<A2>::get(conn, msg, iter, a2);
2317 dbus_traits<A3>::get(conn, msg, iter, a3);
2318 dbus_traits<A4>::get(conn, msg, iter, a4);
2319 dbus_traits<A5>::get(conn, msg, iter, a5);
2320 dbus_traits<A6>::get(conn, msg, iter, a6);
2321 dbus_traits<A7>::get(conn, msg, iter, a7);
2322 dbus_traits<A8>::get(conn, msg, iter, a8);
2323 dbus_traits<A9>::get(conn, msg, iter, a9);
2325 (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7, a8, a9);
2331 DBusMessage *reply = dbus_message_new_method_return(msg);
2334 dbus_message_iter_init_append(reply, &iter);
2335 dbus_traits<A1>::append(iter, a1);
2336 dbus_traits<A2>::append(iter, a2);
2337 dbus_traits<A3>::append(iter, a3);
2338 dbus_traits<A4>::append(iter, a4);
2339 dbus_traits<A5>::append(iter, a5);
2340 dbus_traits<A6>::append(iter, a6);
2341 dbus_traits<A7>::append(iter, a7);
2342 dbus_traits<A8>::append(iter, a8);
2343 dbus_traits<A9>::append(iter, a9);
2346 return handleException(msg);
2350 static void destroyFunction(void *user_data)
2352 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
2353 delete static_cast<M *>(entry->method_data);
2356 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
2358 GDBusMethodTable entry;
2359 entry.name = strdup(name);
2361 buffer += dbus_traits<A1>::getSignature();
2362 buffer += dbus_traits<A2>::getSignature();
2363 buffer += dbus_traits<A3>::getSignature();
2364 buffer += dbus_traits<A4>::getSignature();
2365 buffer += dbus_traits<A5>::getSignature();
2366 buffer += dbus_traits<A6>::getSignature();
2367 buffer += dbus_traits<A7>::getSignature();
2368 buffer += dbus_traits<A8>::getSignature();
2369 buffer += dbus_traits<A9>::getSignature();
2370 entry.signature = strdup(buffer.c_str());
2372 buffer += dbus_traits<A1>::getReply();
2373 buffer += dbus_traits<A2>::getReply();
2374 buffer += dbus_traits<A3>::getReply();
2375 buffer += dbus_traits<A4>::getReply();
2376 buffer += dbus_traits<A5>::getReply();
2377 buffer += dbus_traits<A6>::getReply();
2378 buffer += dbus_traits<A7>::getReply();
2379 buffer += dbus_traits<A8>::getReply();
2380 buffer += dbus_traits<A9>::getReply();
2381 entry.reply = strdup(buffer.c_str());
2382 entry.function = methodFunction;
2383 entry.destroy = destroyFunction;
2384 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
2385 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
2386 entry.method_data = new M(m);
2391 /** 8 arguments, 1 return value */
2393 class A1, class A2, class A3, class A4, class A5,
2394 class A6, class A7, class A8>
2395 struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4, A5, A6, A7, A8)> >
2397 typedef R (Mptr)(A1, A2, A3, A4, A5, A6, A7, A8);
2398 typedef boost::function<Mptr> M;
2400 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
2401 return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8);
2404 static const bool asynchronous = DBusResult8<A1, A2, A3, A4, A5, A6, A7, A8>::asynchronous;
2406 static DBusMessage *methodFunction(DBusConnection *conn,
2407 DBusMessage *msg, void *data)
2410 typename dbus_traits<R>::host_type r;
2411 typename dbus_traits<A1>::host_type a1;
2412 typename dbus_traits<A2>::host_type a2;
2413 typename dbus_traits<A3>::host_type a3;
2414 typename dbus_traits<A4>::host_type a4;
2415 typename dbus_traits<A5>::host_type a5;
2416 typename dbus_traits<A6>::host_type a6;
2417 typename dbus_traits<A7>::host_type a7;
2418 typename dbus_traits<A8>::host_type a8;
2420 DBusMessageIter iter;
2421 dbus_message_iter_init(msg, &iter);
2422 dbus_traits<A1>::get(conn, msg, iter, a1);
2423 dbus_traits<A2>::get(conn, msg, iter, a2);
2424 dbus_traits<A3>::get(conn, msg, iter, a3);
2425 dbus_traits<A4>::get(conn, msg, iter, a4);
2426 dbus_traits<A5>::get(conn, msg, iter, a5);
2427 dbus_traits<A6>::get(conn, msg, iter, a6);
2428 dbus_traits<A7>::get(conn, msg, iter, a7);
2429 dbus_traits<A8>::get(conn, msg, iter, a8);
2431 r = (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7, a8);
2437 DBusMessage *reply = dbus_message_new_method_return(msg);
2440 dbus_message_iter_init_append(reply, &iter);
2441 dbus_traits<R>::append_retval(iter, r);
2442 dbus_traits<A1>::append(iter, a1);
2443 dbus_traits<A2>::append(iter, a2);
2444 dbus_traits<A3>::append(iter, a3);
2445 dbus_traits<A4>::append(iter, a4);
2446 dbus_traits<A5>::append(iter, a5);
2447 dbus_traits<A6>::append(iter, a6);
2448 dbus_traits<A7>::append(iter, a7);
2449 dbus_traits<A8>::append(iter, a8);
2452 return handleException(msg);
2456 static void destroyFunction(void *user_data)
2458 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
2459 delete static_cast<M *>(entry->method_data);
2462 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
2464 GDBusMethodTable entry;
2465 entry.name = strdup(name);
2467 buffer += dbus_traits<A1>::getSignature();
2468 buffer += dbus_traits<A2>::getSignature();
2469 buffer += dbus_traits<A3>::getSignature();
2470 buffer += dbus_traits<A4>::getSignature();
2471 buffer += dbus_traits<A5>::getSignature();
2472 buffer += dbus_traits<A6>::getSignature();
2473 buffer += dbus_traits<A7>::getSignature();
2474 buffer += dbus_traits<A8>::getSignature();
2475 entry.signature = strdup(buffer.c_str());
2477 buffer += dbus_traits<R>::getReply();
2478 buffer += dbus_traits<A1>::getReply();
2479 buffer += dbus_traits<A2>::getReply();
2480 buffer += dbus_traits<A3>::getReply();
2481 buffer += dbus_traits<A4>::getReply();
2482 buffer += dbus_traits<A5>::getReply();
2483 buffer += dbus_traits<A6>::getReply();
2484 buffer += dbus_traits<A7>::getReply();
2485 buffer += dbus_traits<A8>::getReply();
2486 entry.reply = strdup(buffer.c_str());
2487 entry.function = methodFunction;
2488 entry.destroy = destroyFunction;
2489 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
2490 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
2491 entry.method_data = new M(m);
2496 /** ===> 8 parameters */
2497 template <class A1, class A2, class A3, class A4, class A5,
2498 class A6, class A7, class A8>
2499 struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5, A6, A7, A8)> >
2501 typedef void (Mptr)(A1, A2, A3, A4, A5, A6, A7, A8);
2502 typedef boost::function<Mptr> M;
2504 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
2505 return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8);
2508 static const bool asynchronous = DBusResult8<A1, A2, A3, A4, A5, A6, A7, A8>::asynchronous;
2510 static DBusMessage *methodFunction(DBusConnection *conn,
2511 DBusMessage *msg, void *data)
2514 typename dbus_traits<A1>::host_type a1;
2515 typename dbus_traits<A2>::host_type a2;
2516 typename dbus_traits<A3>::host_type a3;
2517 typename dbus_traits<A4>::host_type a4;
2518 typename dbus_traits<A5>::host_type a5;
2519 typename dbus_traits<A6>::host_type a6;
2520 typename dbus_traits<A7>::host_type a7;
2521 typename dbus_traits<A8>::host_type a8;
2523 DBusMessageIter iter;
2524 dbus_message_iter_init(msg, &iter);
2525 dbus_traits<A1>::get(conn, msg, iter, a1);
2526 dbus_traits<A2>::get(conn, msg, iter, a2);
2527 dbus_traits<A3>::get(conn, msg, iter, a3);
2528 dbus_traits<A4>::get(conn, msg, iter, a4);
2529 dbus_traits<A5>::get(conn, msg, iter, a5);
2530 dbus_traits<A6>::get(conn, msg, iter, a6);
2531 dbus_traits<A7>::get(conn, msg, iter, a7);
2532 dbus_traits<A8>::get(conn, msg, iter, a8);
2534 (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7, a8);
2540 DBusMessage *reply = dbus_message_new_method_return(msg);
2543 dbus_message_iter_init_append(reply, &iter);
2544 dbus_traits<A1>::append(iter, a1);
2545 dbus_traits<A2>::append(iter, a2);
2546 dbus_traits<A3>::append(iter, a3);
2547 dbus_traits<A4>::append(iter, a4);
2548 dbus_traits<A5>::append(iter, a5);
2549 dbus_traits<A6>::append(iter, a6);
2550 dbus_traits<A7>::append(iter, a7);
2551 dbus_traits<A8>::append(iter, a8);
2554 return handleException(msg);
2558 static void destroyFunction(void *user_data)
2560 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
2561 delete static_cast<M *>(entry->method_data);
2564 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
2566 GDBusMethodTable entry;
2567 entry.name = strdup(name);
2569 buffer += dbus_traits<A1>::getSignature();
2570 buffer += dbus_traits<A2>::getSignature();
2571 buffer += dbus_traits<A3>::getSignature();
2572 buffer += dbus_traits<A4>::getSignature();
2573 buffer += dbus_traits<A5>::getSignature();
2574 buffer += dbus_traits<A6>::getSignature();
2575 buffer += dbus_traits<A7>::getSignature();
2576 buffer += dbus_traits<A8>::getSignature();
2577 entry.signature = strdup(buffer.c_str());
2579 buffer += dbus_traits<A1>::getReply();
2580 buffer += dbus_traits<A2>::getReply();
2581 buffer += dbus_traits<A3>::getReply();
2582 buffer += dbus_traits<A4>::getReply();
2583 buffer += dbus_traits<A5>::getReply();
2584 buffer += dbus_traits<A6>::getReply();
2585 buffer += dbus_traits<A7>::getReply();
2586 buffer += dbus_traits<A8>::getReply();
2587 entry.reply = strdup(buffer.c_str());
2588 entry.function = methodFunction;
2589 entry.destroy = destroyFunction;
2590 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
2591 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
2592 entry.method_data = new M(m);
2597 /** 7 arguments, 1 return value */
2599 class A1, class A2, class A3, class A4, class A5,
2601 struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4, A5, A6, A7)> >
2603 typedef R (Mptr)(A1, A2, A3, A4, A5, A6, A7);
2604 typedef boost::function<Mptr> M;
2606 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
2607 return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7);
2610 static const bool asynchronous = DBusResult7<A1, A2, A3, A4, A5, A6, A7>::asynchronous;
2612 static DBusMessage *methodFunction(DBusConnection *conn,
2613 DBusMessage *msg, void *data)
2616 typename dbus_traits<R>::host_type r;
2617 typename dbus_traits<A1>::host_type a1;
2618 typename dbus_traits<A2>::host_type a2;
2619 typename dbus_traits<A3>::host_type a3;
2620 typename dbus_traits<A4>::host_type a4;
2621 typename dbus_traits<A5>::host_type a5;
2622 typename dbus_traits<A6>::host_type a6;
2623 typename dbus_traits<A7>::host_type a7;
2625 DBusMessageIter iter;
2626 dbus_message_iter_init(msg, &iter);
2627 dbus_traits<A1>::get(conn, msg, iter, a1);
2628 dbus_traits<A2>::get(conn, msg, iter, a2);
2629 dbus_traits<A3>::get(conn, msg, iter, a3);
2630 dbus_traits<A4>::get(conn, msg, iter, a4);
2631 dbus_traits<A5>::get(conn, msg, iter, a5);
2632 dbus_traits<A6>::get(conn, msg, iter, a6);
2633 dbus_traits<A7>::get(conn, msg, iter, a7);
2635 r = (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7);
2641 DBusMessage *reply = dbus_message_new_method_return(msg);
2644 dbus_message_iter_init_append(reply, &iter);
2645 dbus_traits<R>::append_retval(iter, r);
2646 dbus_traits<A1>::append(iter, a1);
2647 dbus_traits<A2>::append(iter, a2);
2648 dbus_traits<A3>::append(iter, a3);
2649 dbus_traits<A4>::append(iter, a4);
2650 dbus_traits<A5>::append(iter, a5);
2651 dbus_traits<A6>::append(iter, a6);
2652 dbus_traits<A7>::append(iter, a7);
2655 return handleException(msg);
2659 static void destroyFunction(void *user_data)
2661 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
2662 delete static_cast<M *>(entry->method_data);
2665 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
2667 GDBusMethodTable entry;
2668 entry.name = strdup(name);
2670 buffer += dbus_traits<A1>::getSignature();
2671 buffer += dbus_traits<A2>::getSignature();
2672 buffer += dbus_traits<A3>::getSignature();
2673 buffer += dbus_traits<A4>::getSignature();
2674 buffer += dbus_traits<A5>::getSignature();
2675 buffer += dbus_traits<A6>::getSignature();
2676 buffer += dbus_traits<A7>::getSignature();
2677 entry.signature = strdup(buffer.c_str());
2679 buffer += dbus_traits<R>::getReply();
2680 buffer += dbus_traits<A1>::getReply();
2681 buffer += dbus_traits<A2>::getReply();
2682 buffer += dbus_traits<A3>::getReply();
2683 buffer += dbus_traits<A4>::getReply();
2684 buffer += dbus_traits<A5>::getReply();
2685 buffer += dbus_traits<A6>::getReply();
2686 buffer += dbus_traits<A7>::getReply();
2687 entry.reply = strdup(buffer.c_str());
2688 entry.function = methodFunction;
2689 entry.destroy = destroyFunction;
2690 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
2691 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
2692 entry.method_data = new M(m);
2697 /** ===> 7 parameters */
2698 template <class A1, class A2, class A3, class A4, class A5,
2700 struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5, A6, A7)> >
2702 typedef void (Mptr)(A1, A2, A3, A4, A5, A6, A7);
2703 typedef boost::function<Mptr> M;
2705 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
2706 return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7);
2709 static const bool asynchronous = DBusResult7<A1, A2, A3, A4, A5, A6, A7>::asynchronous;
2711 static DBusMessage *methodFunction(DBusConnection *conn,
2712 DBusMessage *msg, void *data)
2715 typename dbus_traits<A1>::host_type a1;
2716 typename dbus_traits<A2>::host_type a2;
2717 typename dbus_traits<A3>::host_type a3;
2718 typename dbus_traits<A4>::host_type a4;
2719 typename dbus_traits<A5>::host_type a5;
2720 typename dbus_traits<A6>::host_type a6;
2721 typename dbus_traits<A7>::host_type a7;
2723 DBusMessageIter iter;
2724 dbus_message_iter_init(msg, &iter);
2725 dbus_traits<A1>::get(conn, msg, iter, a1);
2726 dbus_traits<A2>::get(conn, msg, iter, a2);
2727 dbus_traits<A3>::get(conn, msg, iter, a3);
2728 dbus_traits<A4>::get(conn, msg, iter, a4);
2729 dbus_traits<A5>::get(conn, msg, iter, a5);
2730 dbus_traits<A6>::get(conn, msg, iter, a6);
2731 dbus_traits<A7>::get(conn, msg, iter, a7);
2733 (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7);
2739 DBusMessage *reply = dbus_message_new_method_return(msg);
2742 dbus_message_iter_init_append(reply, &iter);
2743 dbus_traits<A1>::append(iter, a1);
2744 dbus_traits<A2>::append(iter, a2);
2745 dbus_traits<A3>::append(iter, a3);
2746 dbus_traits<A4>::append(iter, a4);
2747 dbus_traits<A5>::append(iter, a5);
2748 dbus_traits<A6>::append(iter, a6);
2749 dbus_traits<A7>::append(iter, a7);
2752 return handleException(msg);
2756 static void destroyFunction(void *user_data)
2758 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
2759 delete static_cast<M *>(entry->method_data);
2762 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
2764 GDBusMethodTable entry;
2765 entry.name = strdup(name);
2767 buffer += dbus_traits<A1>::getSignature();
2768 buffer += dbus_traits<A2>::getSignature();
2769 buffer += dbus_traits<A3>::getSignature();
2770 buffer += dbus_traits<A4>::getSignature();
2771 buffer += dbus_traits<A5>::getSignature();
2772 buffer += dbus_traits<A6>::getSignature();
2773 buffer += dbus_traits<A7>::getSignature();
2774 entry.signature = strdup(buffer.c_str());
2776 buffer += dbus_traits<A1>::getReply();
2777 buffer += dbus_traits<A2>::getReply();
2778 buffer += dbus_traits<A3>::getReply();
2779 buffer += dbus_traits<A4>::getReply();
2780 buffer += dbus_traits<A5>::getReply();
2781 buffer += dbus_traits<A6>::getReply();
2782 buffer += dbus_traits<A7>::getReply();
2783 entry.reply = strdup(buffer.c_str());
2784 entry.function = methodFunction;
2785 entry.destroy = destroyFunction;
2786 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
2787 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
2788 entry.method_data = new M(m);
2793 /** 6 arguments, 1 return value */
2795 class A1, class A2, class A3, class A4, class A5,
2797 struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4, A5, A6)> >
2799 typedef R (Mptr)(A1, A2, A3, A4, A5, A6);
2800 typedef boost::function<Mptr> M;
2802 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
2803 return boost::bind(method, instance, _1, _2, _3, _4, _5, _6);
2806 static const bool asynchronous = DBusResult6<A1, A2, A3, A4, A5, A6>::asynchronous;
2808 static DBusMessage *methodFunction(DBusConnection *conn,
2809 DBusMessage *msg, void *data)
2812 typename dbus_traits<R>::host_type r;
2813 typename dbus_traits<A1>::host_type a1;
2814 typename dbus_traits<A2>::host_type a2;
2815 typename dbus_traits<A3>::host_type a3;
2816 typename dbus_traits<A4>::host_type a4;
2817 typename dbus_traits<A5>::host_type a5;
2818 typename dbus_traits<A6>::host_type a6;
2820 DBusMessageIter iter;
2821 dbus_message_iter_init(msg, &iter);
2822 dbus_traits<A1>::get(conn, msg, iter, a1);
2823 dbus_traits<A2>::get(conn, msg, iter, a2);
2824 dbus_traits<A3>::get(conn, msg, iter, a3);
2825 dbus_traits<A4>::get(conn, msg, iter, a4);
2826 dbus_traits<A5>::get(conn, msg, iter, a5);
2827 dbus_traits<A6>::get(conn, msg, iter, a6);
2829 r = (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6);
2835 DBusMessage *reply = dbus_message_new_method_return(msg);
2838 dbus_message_iter_init_append(reply, &iter);
2839 dbus_traits<R>::append_retval(iter, r);
2840 dbus_traits<A1>::append(iter, a1);
2841 dbus_traits<A2>::append(iter, a2);
2842 dbus_traits<A3>::append(iter, a3);
2843 dbus_traits<A4>::append(iter, a4);
2844 dbus_traits<A5>::append(iter, a5);
2845 dbus_traits<A6>::append(iter, a6);
2848 return handleException(msg);
2852 static void destroyFunction(void *user_data)
2854 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
2855 delete static_cast<M *>(entry->method_data);
2858 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
2860 GDBusMethodTable entry;
2861 entry.name = strdup(name);
2863 buffer += dbus_traits<A1>::getSignature();
2864 buffer += dbus_traits<A2>::getSignature();
2865 buffer += dbus_traits<A3>::getSignature();
2866 buffer += dbus_traits<A4>::getSignature();
2867 buffer += dbus_traits<A5>::getSignature();
2868 buffer += dbus_traits<A6>::getSignature();
2869 entry.signature = strdup(buffer.c_str());
2871 buffer += dbus_traits<R>::getReply();
2872 buffer += dbus_traits<A1>::getReply();
2873 buffer += dbus_traits<A2>::getReply();
2874 buffer += dbus_traits<A3>::getReply();
2875 buffer += dbus_traits<A4>::getReply();
2876 buffer += dbus_traits<A5>::getReply();
2877 buffer += dbus_traits<A6>::getReply();
2878 entry.reply = strdup(buffer.c_str());
2879 entry.function = methodFunction;
2880 entry.destroy = destroyFunction;
2881 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
2882 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
2883 entry.method_data = new M(m);
2888 /** ===> 6 parameters */
2889 template <class A1, class A2, class A3, class A4, class A5,
2891 struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5, A6)> >
2893 typedef void (Mptr)(A1, A2, A3, A4, A5, A6);
2894 typedef boost::function<Mptr> M;
2896 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
2897 return boost::bind(method, instance, _1, _2, _3, _4, _5, _6);
2900 static const bool asynchronous = DBusResult6<A1, A2, A3, A4, A5, A6>::asynchronous;
2902 static DBusMessage *methodFunction(DBusConnection *conn,
2903 DBusMessage *msg, void *data)
2906 typename dbus_traits<A1>::host_type a1;
2907 typename dbus_traits<A2>::host_type a2;
2908 typename dbus_traits<A3>::host_type a3;
2909 typename dbus_traits<A4>::host_type a4;
2910 typename dbus_traits<A5>::host_type a5;
2911 typename dbus_traits<A6>::host_type a6;
2913 DBusMessageIter iter;
2914 dbus_message_iter_init(msg, &iter);
2915 dbus_traits<A1>::get(conn, msg, iter, a1);
2916 dbus_traits<A2>::get(conn, msg, iter, a2);
2917 dbus_traits<A3>::get(conn, msg, iter, a3);
2918 dbus_traits<A4>::get(conn, msg, iter, a4);
2919 dbus_traits<A5>::get(conn, msg, iter, a5);
2920 dbus_traits<A6>::get(conn, msg, iter, a6);
2922 (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6);
2928 DBusMessage *reply = dbus_message_new_method_return(msg);
2931 dbus_message_iter_init_append(reply, &iter);
2932 dbus_traits<A1>::append(iter, a1);
2933 dbus_traits<A2>::append(iter, a2);
2934 dbus_traits<A3>::append(iter, a3);
2935 dbus_traits<A4>::append(iter, a4);
2936 dbus_traits<A5>::append(iter, a5);
2937 dbus_traits<A6>::append(iter, a6);
2940 return handleException(msg);
2943 static void destroyFunction(void *user_data)
2945 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
2946 delete static_cast<M *>(entry->method_data);
2949 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
2951 GDBusMethodTable entry;
2952 entry.name = strdup(name);
2954 buffer += dbus_traits<A1>::getSignature();
2955 buffer += dbus_traits<A2>::getSignature();
2956 buffer += dbus_traits<A3>::getSignature();
2957 buffer += dbus_traits<A4>::getSignature();
2958 buffer += dbus_traits<A5>::getSignature();
2959 buffer += dbus_traits<A6>::getSignature();
2960 entry.signature = strdup(buffer.c_str());
2962 buffer += dbus_traits<A1>::getReply();
2963 buffer += dbus_traits<A2>::getReply();
2964 buffer += dbus_traits<A3>::getReply();
2965 buffer += dbus_traits<A4>::getReply();
2966 buffer += dbus_traits<A5>::getReply();
2967 buffer += dbus_traits<A6>::getReply();
2968 entry.reply = strdup(buffer.c_str());
2969 entry.function = methodFunction;
2970 entry.destroy = destroyFunction;
2971 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
2972 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
2973 entry.method_data = new M(m);
2978 /** 5 arguments, 1 return value */
2980 class A1, class A2, class A3, class A4, class A5>
2981 struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4, A5)> >
2983 typedef R (Mptr)(A1, A2, A3, A4, A5);
2984 typedef boost::function<Mptr> M;
2986 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
2987 return boost::bind(method, instance, _1, _2, _3, _4, _5);
2990 static const bool asynchronous = DBusResult5<A1, A2, A3, A4, A5>::asynchronous;
2992 static DBusMessage *methodFunction(DBusConnection *conn,
2993 DBusMessage *msg, void *data)
2996 typename dbus_traits<R>::host_type r;
2997 typename dbus_traits<A1>::host_type a1;
2998 typename dbus_traits<A2>::host_type a2;
2999 typename dbus_traits<A3>::host_type a3;
3000 typename dbus_traits<A4>::host_type a4;
3001 typename dbus_traits<A5>::host_type a5;
3003 DBusMessageIter iter;
3004 dbus_message_iter_init(msg, &iter);
3005 dbus_traits<A1>::get(conn, msg, iter, a1);
3006 dbus_traits<A2>::get(conn, msg, iter, a2);
3007 dbus_traits<A3>::get(conn, msg, iter, a3);
3008 dbus_traits<A4>::get(conn, msg, iter, a4);
3009 dbus_traits<A5>::get(conn, msg, iter, a5);
3011 r = (*static_cast<M *>(data))(a1, a2, a3, a4, a5);
3017 DBusMessage *reply = dbus_message_new_method_return(msg);
3020 dbus_message_iter_init_append(reply, &iter);
3021 dbus_traits<R>::append_retval(iter, r);
3022 dbus_traits<A1>::append(iter, a1);
3023 dbus_traits<A2>::append(iter, a2);
3024 dbus_traits<A3>::append(iter, a3);
3025 dbus_traits<A4>::append(iter, a4);
3026 dbus_traits<A5>::append(iter, a5);
3029 return handleException(msg);
3033 static void destroyFunction(void *user_data)
3035 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3036 delete static_cast<M *>(entry->method_data);
3039 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3041 GDBusMethodTable entry;
3042 entry.name = strdup(name);
3044 buffer += dbus_traits<A1>::getSignature();
3045 buffer += dbus_traits<A2>::getSignature();
3046 buffer += dbus_traits<A3>::getSignature();
3047 buffer += dbus_traits<A4>::getSignature();
3048 buffer += dbus_traits<A5>::getSignature();
3049 entry.signature = strdup(buffer.c_str());
3051 buffer += dbus_traits<R>::getReply();
3052 buffer += dbus_traits<A1>::getReply();
3053 buffer += dbus_traits<A2>::getReply();
3054 buffer += dbus_traits<A3>::getReply();
3055 buffer += dbus_traits<A4>::getReply();
3056 buffer += dbus_traits<A5>::getReply();
3057 entry.reply = strdup(buffer.c_str());
3058 entry.function = methodFunction;
3059 entry.destroy = destroyFunction;
3060 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
3061 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
3062 entry.method_data = new M(m);
3067 /** ===> 5 parameters */
3068 template <class A1, class A2, class A3, class A4, class A5>
3069 struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5)> >
3071 typedef void (Mptr)(A1, A2, A3, A4, A5);
3072 typedef boost::function<Mptr> M;
3074 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3075 return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8);
3078 static const bool asynchronous = DBusResult5<A1, A2, A3, A4, A5>::asynchronous;
3080 static DBusMessage *methodFunction(DBusConnection *conn,
3081 DBusMessage *msg, void *data)
3084 typename dbus_traits<A1>::host_type a1;
3085 typename dbus_traits<A2>::host_type a2;
3086 typename dbus_traits<A3>::host_type a3;
3087 typename dbus_traits<A4>::host_type a4;
3088 typename dbus_traits<A5>::host_type a5;
3090 DBusMessageIter iter;
3091 dbus_message_iter_init(msg, &iter);
3092 dbus_traits<A1>::get(conn, msg, iter, a1);
3093 dbus_traits<A2>::get(conn, msg, iter, a2);
3094 dbus_traits<A3>::get(conn, msg, iter, a3);
3095 dbus_traits<A4>::get(conn, msg, iter, a4);
3096 dbus_traits<A5>::get(conn, msg, iter, a5);
3098 (*static_cast<M *>(data))(a1, a2, a3, a4, a5);
3104 DBusMessage *reply = dbus_message_new_method_return(msg);
3107 dbus_message_iter_init_append(reply, &iter);
3108 dbus_traits<A1>::append(iter, a1);
3109 dbus_traits<A2>::append(iter, a2);
3110 dbus_traits<A3>::append(iter, a3);
3111 dbus_traits<A4>::append(iter, a4);
3112 dbus_traits<A5>::append(iter, a5);
3115 return handleException(msg);
3119 static void destroyFunction(void *user_data)
3121 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3122 delete static_cast<M *>(entry->method_data);
3125 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3127 GDBusMethodTable entry;
3128 entry.name = strdup(name);
3130 buffer += dbus_traits<A1>::getSignature();
3131 buffer += dbus_traits<A2>::getSignature();
3132 buffer += dbus_traits<A3>::getSignature();
3133 buffer += dbus_traits<A4>::getSignature();
3134 buffer += dbus_traits<A5>::getSignature();
3135 entry.signature = strdup(buffer.c_str());
3137 buffer += dbus_traits<A1>::getReply();
3138 buffer += dbus_traits<A2>::getReply();
3139 buffer += dbus_traits<A3>::getReply();
3140 buffer += dbus_traits<A4>::getReply();
3141 buffer += dbus_traits<A5>::getReply();
3142 entry.reply = strdup(buffer.c_str());
3143 entry.function = methodFunction;
3144 entry.destroy = destroyFunction;
3145 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
3146 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
3147 entry.method_data = new M(m);
3152 /** 4 arguments, 1 return value */
3154 class A1, class A2, class A3, class A4>
3155 struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4)> >
3157 typedef R (Mptr)(A1, A2, A3, A4);
3158 typedef boost::function<Mptr> M;
3160 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3161 return boost::bind(method, instance, _1, _2, _3, _4);
3164 static const bool asynchronous = DBusResult4<A1, A2, A3, A4>::asynchronous;
3166 static DBusMessage *methodFunction(DBusConnection *conn,
3167 DBusMessage *msg, void *data)
3170 typename dbus_traits<R>::host_type r;
3171 typename dbus_traits<A1>::host_type a1;
3172 typename dbus_traits<A2>::host_type a2;
3173 typename dbus_traits<A3>::host_type a3;
3174 typename dbus_traits<A4>::host_type a4;
3176 DBusMessageIter iter;
3177 dbus_message_iter_init(msg, &iter);
3178 dbus_traits<A1>::get(conn, msg, iter, a1);
3179 dbus_traits<A2>::get(conn, msg, iter, a2);
3180 dbus_traits<A3>::get(conn, msg, iter, a3);
3181 dbus_traits<A4>::get(conn, msg, iter, a4);
3183 r = (*static_cast<M *>(data))(a1, a2, a3, a4);
3189 DBusMessage *reply = dbus_message_new_method_return(msg);
3192 dbus_message_iter_init_append(reply, &iter);
3193 dbus_traits<R>::append_retval(iter, r);
3194 dbus_traits<A1>::append(iter, a1);
3195 dbus_traits<A2>::append(iter, a2);
3196 dbus_traits<A3>::append(iter, a3);
3197 dbus_traits<A4>::append(iter, a4);
3200 return handleException(msg);
3204 static void destroyFunction(void *user_data)
3206 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3207 delete static_cast<M *>(entry->method_data);
3210 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3212 GDBusMethodTable entry;
3213 entry.name = strdup(name);
3215 buffer += dbus_traits<A1>::getSignature();
3216 buffer += dbus_traits<A2>::getSignature();
3217 buffer += dbus_traits<A3>::getSignature();
3218 buffer += dbus_traits<A4>::getSignature();
3219 entry.signature = strdup(buffer.c_str());
3221 buffer += dbus_traits<R>::getReply();
3222 buffer += dbus_traits<A1>::getReply();
3223 buffer += dbus_traits<A2>::getReply();
3224 buffer += dbus_traits<A3>::getReply();
3225 buffer += dbus_traits<A4>::getReply();
3226 entry.reply = strdup(buffer.c_str());
3227 entry.function = methodFunction;
3228 entry.destroy = destroyFunction;
3229 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
3230 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
3231 entry.method_data = new M(m);
3236 /** ===> 4 parameters */
3237 template <class A1, class A2, class A3, class A4>
3238 struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4)> >
3240 typedef void (Mptr)(A1, A2, A3, A4);
3241 typedef boost::function<Mptr> M;
3243 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3244 return boost::bind(method, instance, _1, _2, _3, _4);
3247 static const bool asynchronous = DBusResult4<A1, A2, A3, A4>::asynchronous;
3249 static DBusMessage *methodFunction(DBusConnection *conn,
3250 DBusMessage *msg, void *data)
3253 typename dbus_traits<A1>::host_type a1;
3254 typename dbus_traits<A2>::host_type a2;
3255 typename dbus_traits<A3>::host_type a3;
3256 typename dbus_traits<A4>::host_type a4;
3258 DBusMessageIter iter;
3259 dbus_message_iter_init(msg, &iter);
3260 dbus_traits<A1>::get(conn, msg, iter, a1);
3261 dbus_traits<A2>::get(conn, msg, iter, a2);
3262 dbus_traits<A3>::get(conn, msg, iter, a3);
3263 dbus_traits<A4>::get(conn, msg, iter, a4);
3265 (*static_cast<M *>(data))(a1, a2, a3, a4);
3271 DBusMessage *reply = dbus_message_new_method_return(msg);
3274 dbus_message_iter_init_append(reply, &iter);
3275 dbus_traits<A1>::append(iter, a1);
3276 dbus_traits<A2>::append(iter, a2);
3277 dbus_traits<A3>::append(iter, a3);
3278 dbus_traits<A4>::append(iter, a4);
3281 return handleException(msg);
3285 static void destroyFunction(void *user_data)
3287 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3288 delete static_cast<M *>(entry->method_data);
3291 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3293 GDBusMethodTable entry;
3294 entry.name = strdup(name);
3296 buffer += dbus_traits<A1>::getSignature();
3297 buffer += dbus_traits<A2>::getSignature();
3298 buffer += dbus_traits<A3>::getSignature();
3299 buffer += dbus_traits<A4>::getSignature();
3300 entry.signature = strdup(buffer.c_str());
3302 buffer += dbus_traits<A1>::getReply();
3303 buffer += dbus_traits<A2>::getReply();
3304 buffer += dbus_traits<A3>::getReply();
3305 buffer += dbus_traits<A4>::getReply();
3306 entry.reply = strdup(buffer.c_str());
3307 entry.function = methodFunction;
3308 entry.destroy = destroyFunction;
3309 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
3310 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
3311 entry.method_data = new M(m);
3316 /** 3 arguments, 1 return value */
3318 class A1, class A2, class A3>
3319 struct MakeMethodEntry< boost::function<R (A1, A2, A3)> >
3321 typedef R (Mptr)(A1, A2, A3);
3322 typedef boost::function<Mptr> M;
3324 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3325 return boost::bind(method, instance, _1, _2, _3);
3328 static const bool asynchronous = DBusResult3<A1, A2, A3>::asynchronous;
3330 static DBusMessage *methodFunction(DBusConnection *conn,
3331 DBusMessage *msg, void *data)
3334 typename dbus_traits<R>::host_type r;
3335 typename dbus_traits<A1>::host_type a1;
3336 typename dbus_traits<A2>::host_type a2;
3337 typename dbus_traits<A3>::host_type a3;
3339 DBusMessageIter iter;
3340 dbus_message_iter_init(msg, &iter);
3341 dbus_traits<A1>::get(conn, msg, iter, a1);
3342 dbus_traits<A2>::get(conn, msg, iter, a2);
3343 dbus_traits<A3>::get(conn, msg, iter, a3);
3345 r = (*static_cast<M *>(data))(a1, a2, a3);
3351 DBusMessage *reply = dbus_message_new_method_return(msg);
3354 dbus_message_iter_init_append(reply, &iter);
3355 dbus_traits<R>::append_retval(iter, r);
3356 dbus_traits<A1>::append(iter, a1);
3357 dbus_traits<A2>::append(iter, a2);
3358 dbus_traits<A3>::append(iter, a3);
3361 return handleException(msg);
3365 static void destroyFunction(void *user_data)
3367 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3368 delete static_cast<M *>(entry->method_data);
3371 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3373 GDBusMethodTable entry;
3374 entry.name = strdup(name);
3376 buffer += dbus_traits<A1>::getSignature();
3377 buffer += dbus_traits<A2>::getSignature();
3378 buffer += dbus_traits<A3>::getSignature();
3379 entry.signature = strdup(buffer.c_str());
3381 buffer += dbus_traits<R>::getReply();
3382 buffer += dbus_traits<A1>::getReply();
3383 buffer += dbus_traits<A2>::getReply();
3384 buffer += dbus_traits<A3>::getReply();
3385 entry.reply = strdup(buffer.c_str());
3386 entry.function = methodFunction;
3387 entry.destroy = destroyFunction;
3388 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
3389 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
3390 entry.method_data = new M(m);
3395 /** ===> 3 parameters */
3396 template <class A1, class A2, class A3>
3397 struct MakeMethodEntry< boost::function<void (A1, A2, A3)> >
3399 typedef void (Mptr)(A1, A2, A3);
3400 typedef boost::function<Mptr> M;
3402 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3403 return boost::bind(method, instance, _1, _2, _3);
3406 static const bool asynchronous = DBusResult3<A1, A2, A3>::asynchronous;
3408 static DBusMessage *methodFunction(DBusConnection *conn,
3409 DBusMessage *msg, void *data)
3412 typename dbus_traits<A1>::host_type a1;
3413 typename dbus_traits<A2>::host_type a2;
3414 typename dbus_traits<A3>::host_type a3;
3416 DBusMessageIter iter;
3417 dbus_message_iter_init(msg, &iter);
3418 dbus_traits<A1>::get(conn, msg, iter, a1);
3419 dbus_traits<A2>::get(conn, msg, iter, a2);
3420 dbus_traits<A3>::get(conn, msg, iter, a3);
3422 (*static_cast<M *>(data))(a1, a2, a3);
3428 DBusMessage *reply = dbus_message_new_method_return(msg);
3431 dbus_message_iter_init_append(reply, &iter);
3432 dbus_traits<A1>::append(iter, a1);
3433 dbus_traits<A2>::append(iter, a2);
3434 dbus_traits<A3>::append(iter, a3);
3437 return handleException(msg);
3441 static void destroyFunction(void *user_data)
3443 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3444 delete static_cast<M *>(entry->method_data);
3447 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3449 GDBusMethodTable entry;
3450 entry.name = strdup(name);
3452 buffer += dbus_traits<A1>::getSignature();
3453 buffer += dbus_traits<A2>::getSignature();
3454 buffer += dbus_traits<A3>::getSignature();
3455 entry.signature = strdup(buffer.c_str());
3457 buffer += dbus_traits<A1>::getReply();
3458 buffer += dbus_traits<A2>::getReply();
3459 buffer += dbus_traits<A3>::getReply();
3460 entry.reply = strdup(buffer.c_str());
3461 entry.function = methodFunction;
3462 entry.destroy = destroyFunction;
3463 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
3464 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
3465 entry.method_data = new M(m);
3470 /** 2 arguments, 1 return value */
3473 struct MakeMethodEntry< boost::function<R (A1, A2)> >
3475 typedef R (Mptr)(A1, A2);
3476 typedef boost::function<Mptr> M;
3478 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3479 return boost::bind(method, instance, _1, _2);
3482 static const bool asynchronous = DBusResult2<A1, A2>::asynchronous;
3484 static DBusMessage *methodFunction(DBusConnection *conn,
3485 DBusMessage *msg, void *data)
3488 typename dbus_traits<R>::host_type r;
3489 typename dbus_traits<A1>::host_type a1;
3490 typename dbus_traits<A2>::host_type a2;
3492 DBusMessageIter iter;
3493 dbus_message_iter_init(msg, &iter);
3494 dbus_traits<A1>::get(conn, msg, iter, a1);
3495 dbus_traits<A2>::get(conn, msg, iter, a2);
3497 r = (*static_cast<M *>(data))(a1, a2);
3503 DBusMessage *reply = dbus_message_new_method_return(msg);
3506 dbus_message_iter_init_append(reply, &iter);
3507 dbus_traits<R>::append_retval(iter, r);
3508 dbus_traits<A1>::append(iter, a1);
3509 dbus_traits<A2>::append(iter, a2);
3512 return handleException(msg);
3516 static void destroyFunction(void *user_data)
3518 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3519 delete static_cast<M *>(entry->method_data);
3522 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3524 GDBusMethodTable entry;
3525 entry.name = strdup(name);
3527 buffer += dbus_traits<A1>::getSignature();
3528 buffer += dbus_traits<A2>::getSignature();
3529 entry.signature = strdup(buffer.c_str());
3531 buffer += dbus_traits<R>::getReply();
3532 buffer += dbus_traits<A1>::getReply();
3533 buffer += dbus_traits<A2>::getReply();
3534 entry.reply = strdup(buffer.c_str());
3535 entry.function = methodFunction;
3536 entry.destroy = destroyFunction;
3537 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
3538 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
3539 entry.method_data = new M(m);
3544 /** ===> 2 parameters */
3545 template <class A1, class A2>
3546 struct MakeMethodEntry< boost::function<void (A1, A2)> >
3548 typedef void (Mptr)(A1, A2);
3549 typedef boost::function<Mptr> M;
3551 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3552 return boost::bind(method, instance, _1, _2);
3555 static const bool asynchronous = DBusResult2<A1, A2>::asynchronous;
3557 static DBusMessage *methodFunction(DBusConnection *conn,
3558 DBusMessage *msg, void *data)
3561 typename dbus_traits<A1>::host_type a1;
3562 typename dbus_traits<A2>::host_type a2;
3564 DBusMessageIter iter;
3565 dbus_message_iter_init(msg, &iter);
3566 dbus_traits<A1>::get(conn, msg, iter, a1);
3567 dbus_traits<A2>::get(conn, msg, iter, a2);
3569 (*static_cast<M *>(data))(a1, a2);
3575 DBusMessage *reply = dbus_message_new_method_return(msg);
3578 dbus_message_iter_init_append(reply, &iter);
3579 dbus_traits<A1>::append(iter, a1);
3580 dbus_traits<A2>::append(iter, a2);
3583 return handleException(msg);
3587 static void destroyFunction(void *user_data)
3589 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3590 delete static_cast<M *>(entry->method_data);
3593 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3595 GDBusMethodTable entry;
3596 entry.name = strdup(name);
3598 buffer += dbus_traits<A1>::getSignature();
3599 buffer += dbus_traits<A2>::getSignature();
3600 entry.signature = strdup(buffer.c_str());
3602 buffer += dbus_traits<A1>::getReply();
3603 buffer += dbus_traits<A2>::getReply();
3604 entry.reply = strdup(buffer.c_str());
3605 entry.function = methodFunction;
3606 entry.destroy = destroyFunction;
3607 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
3608 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
3609 entry.method_data = new M(m);
3614 /** 1 argument, 1 return value */
3617 struct MakeMethodEntry< boost::function<R (A1)> >
3619 typedef R (Mptr)(A1);
3620 typedef boost::function<Mptr> M;
3622 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3623 return boost::bind(method, instance, _1);
3626 static const bool asynchronous = DBusResult1<A1>::asynchronous;
3628 static DBusMessage *methodFunction(DBusConnection *conn,
3629 DBusMessage *msg, void *data)
3632 typename dbus_traits<R>::host_type r;
3633 typename dbus_traits<A1>::host_type a1;
3635 DBusMessageIter iter;
3636 dbus_message_iter_init(msg, &iter);
3637 dbus_traits<A1>::get(conn, msg, iter, a1);
3639 r = (*static_cast<M *>(data))(a1);
3645 DBusMessage *reply = dbus_message_new_method_return(msg);
3648 dbus_message_iter_init_append(reply, &iter);
3649 dbus_traits<R>::append_retval(iter, r);
3650 dbus_traits<A1>::append(iter, a1);
3653 return handleException(msg);
3657 static void destroyFunction(void *user_data)
3659 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3660 delete static_cast<M *>(entry->method_data);
3663 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3665 GDBusMethodTable entry;
3666 entry.name = strdup(name);
3668 buffer += dbus_traits<A1>::getSignature();
3669 entry.signature = strdup(buffer.c_str());
3671 buffer += dbus_traits<R>::getReply();
3672 buffer += dbus_traits<A1>::getReply();
3673 entry.reply = strdup(buffer.c_str());
3674 entry.function = methodFunction;
3675 entry.destroy = destroyFunction;
3676 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
3677 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
3678 entry.method_data = new M(m);
3683 /** ===> 1 parameter */
3685 struct MakeMethodEntry< boost::function<void (A1)> >
3687 typedef void (Mptr)(A1);
3688 typedef boost::function<void (A1)> M;
3690 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3691 return boost::bind(method, instance, _1);
3694 static const bool asynchronous = DBusResult1<A1>::asynchronous;
3696 static DBusMessage *methodFunction(DBusConnection *conn,
3697 DBusMessage *msg, void *data)
3700 typename dbus_traits<A1>::host_type a1;
3702 DBusMessageIter iter;
3703 dbus_message_iter_init(msg, &iter);
3704 dbus_traits<A1>::get(conn, msg, iter, a1);
3706 (*static_cast<M *>(data))(a1);
3712 DBusMessage *reply = dbus_message_new_method_return(msg);
3715 dbus_message_iter_init_append(reply, &iter);
3716 dbus_traits<A1>::append(iter, a1);
3719 return handleException(msg);
3723 static void destroyFunction(void *user_data)
3725 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3726 delete static_cast<M *>(entry->method_data);
3729 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3731 GDBusMethodTable entry;
3732 entry.name = strdup(name);
3734 buffer += dbus_traits<A1>::getSignature();
3735 entry.signature = strdup(buffer.c_str());
3737 buffer += dbus_traits<A1>::getReply();
3738 entry.reply = strdup(buffer.c_str());
3739 entry.function = methodFunction;
3740 entry.destroy = destroyFunction;
3741 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA |
3742 (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0));
3743 entry.method_data = new M(m);
3748 /** 0 arguments, 1 return value */
3750 struct MakeMethodEntry< boost::function<R ()> >
3753 typedef boost::function<Mptr> M;
3755 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3756 return boost::bind(method, instance);
3759 static DBusMessage *methodFunction(DBusConnection *conn,
3760 DBusMessage *msg, void *data)
3763 typename dbus_traits<R>::host_type r;
3765 r = (*static_cast<M *>(data))();
3767 DBusMessage *reply = dbus_message_new_method_return(msg);
3770 DBusMessageIter iter;
3771 dbus_message_iter_init_append(reply, &iter);
3772 dbus_traits<R>::append_retval(iter, r);
3775 return handleException(msg);
3778 static void destroyFunction(void *user_data)
3780 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3781 delete static_cast<M *>(entry->method_data);
3784 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3786 GDBusMethodTable entry;
3787 entry.name = strdup(name);
3789 entry.signature = strdup(buffer.c_str());
3791 buffer += dbus_traits<R>::getReply();
3792 entry.reply = strdup(buffer.c_str());
3793 entry.function = methodFunction;
3794 entry.destroy = destroyFunction;
3795 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA);
3796 entry.method_data = new M(m);
3801 /** ===> 0 parameter */
3803 struct MakeMethodEntry< boost::function<void ()> >
3805 typedef void (Mptr)();
3806 typedef boost::function<Mptr> M;
3808 template <class I, class C> static M boostptr(Mptr C::*method, I instance) {
3809 return boost::bind(method, instance);
3812 static DBusMessage *methodFunction(DBusConnection *conn,
3813 DBusMessage *msg, void *data)
3816 (*static_cast<M *>(data))();
3818 DBusMessage *reply = dbus_message_new_method_return(msg);
3823 return handleException(msg);
3827 static void destroyFunction(void *user_data)
3829 GDBusMethodTable *entry = static_cast<GDBusMethodTable *>(user_data);
3830 delete static_cast<M *>(entry->method_data);
3833 static GDBusMethodTable make(const char *name, GDBusMethodFlags flags, const M &m)
3835 GDBusMethodTable entry;
3836 entry.name = strdup(name);
3838 entry.signature = strdup(buffer.c_str());
3840 entry.reply = strdup(buffer.c_str());
3841 entry.function = methodFunction;
3842 entry.destroy = destroyFunction;
3843 entry.flags = GDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA);
3844 entry.method_data = new M(m);
3849 #endif // INCL_GDBUS_CXX_BRIDGE