diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2018-01-10 17:24:17 +0100 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2020-12-05 21:28:08 +0100 |
commit | 04f8ac0454d53c6fbd92036a93b5f0146c636997 (patch) | |
tree | 38dfec697503e7a448b1688eab5c9e8706e0f11d /src | |
parent | 2705d06fa6f9a708fb734b3f31f105ab2e888fbc (diff) |
gdbus: remove old libdbus-based implementation
GIO D-Bus is a more modern and capable implementation. The older one
was only needed on certain old Linux distros (Maemo) which did not
have a recent enough glib.
The reason for removing the old one is that it allows making API
incompatible changes for the C++ D-Bus binding without having to do
that in two places.
Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/dbus/server/exceptions.h | 8 | ||||
-rw-r--r-- | src/gdbus/README | 32 | ||||
-rw-r--r-- | src/gdbus/debug.c | 36 | ||||
-rw-r--r-- | src/gdbus/debug.h | 25 | ||||
-rw-r--r-- | src/gdbus/gdbus-cxx-bridge.cpp | 157 | ||||
-rw-r--r-- | src/gdbus/gdbus-cxx-bridge.h | 4936 | ||||
-rw-r--r-- | src/gdbus/gdbus-cxx.h | 173 | ||||
-rw-r--r-- | src/gdbus/gdbus.am | 34 | ||||
-rw-r--r-- | src/gdbus/gdbus.h | 298 | ||||
-rw-r--r-- | src/gdbus/mainloop.c | 685 | ||||
-rw-r--r-- | src/gdbus/object.c | 1440 | ||||
-rw-r--r-- | src/gdbus/test/example.cpp | 286 | ||||
-rwxr-xr-x | src/gdbus/test/test-example | 50 | ||||
-rw-r--r-- | src/gdbus/watch.c | 532 | ||||
-rw-r--r-- | src/src.am | 5 | ||||
-rw-r--r-- | src/syncevo/syncevo.am | 2 |
16 files changed, 0 insertions, 8699 deletions
diff --git a/src/dbus/server/exceptions.h b/src/dbus/server/exceptions.h index 8784c384..b8ca8686 100644 --- a/src/dbus/server/exceptions.h +++ b/src/dbus/server/exceptions.h @@ -25,19 +25,11 @@ // Can't use the GDBusCXX::message_type typedef here because it's not // defined till we include gdbus-cxx-bridge.h below. -#ifdef WITH_GIO_GDBUS // Forward decleration can't be used here due to later typedef _GDBusMessage GDBusMessage. #include <gio/gio.h> -#else -struct DBusMessage; -#endif SE_BEGIN_CXX -#ifdef WITH_GIO_GDBUS GDBusMessage *SyncEvoHandleException(GDBusMessage *msg); -#else -DBusMessage *SyncEvoHandleException(DBusMessage *msg); -#endif SE_END_CXX // This needs to be defined before including gdbus-cxx-bridge.h! #define DBUS_CXX_EXCEPTION_HANDLER SyncEvo::SyncEvoHandleException diff --git a/src/gdbus/README b/src/gdbus/README deleted file mode 100644 index d506307e..00000000 --- a/src/gdbus/README +++ /dev/null @@ -1,32 +0,0 @@ -This is a copy of the libgdbus source code: -http://git.kernel.org/?p=bluetooth/libgdbus.git;a=summary - -It is licensed under LGPL v2.1, see upstream COPYING. - -The source is included here because there is no stable -upstream release. Patches added here need to be submitted -upstream. Likewise, patches applied upstream must be imported. -The build/import-gdbus.sh and build/export-gdbus.sh scripts -automate that process. - -To import fixes from upstream: -- checkout out libgdbus and syncevolution -- enter syncevolution directory -- if not done before, create local "gdbus" branch: - git branch gdbus origin/gdbus -- run build/import-gdbus.sh -- "gdbus" branch is now checked out and updated -- verify changes, merge into master, etc. -- push into remote syncevolution repo - -To export fixes to upstream: -- check out relevant branch in syncevolution - which has our local changes (typically "master") -- run build/export-gdbus.sh -- send 0*.patch files to upstream - -Caveats: -- only files explicitly mentioned in the two scripts - are imported/exports -- Makefile changes are only imported, but not exported - (local changes not relevant upstream) diff --git a/src/gdbus/debug.c b/src/gdbus/debug.c deleted file mode 100644 index 680370e9..00000000 --- a/src/gdbus/debug.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * Library for simple D-Bus integration with GLib - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "debug.h" - -static void __attribute__ ((constructor)) __init(void) -{ - DBG(""); -} - -static void __attribute__ ((destructor)) __cleanup(void) -{ - DBG(""); -} diff --git a/src/gdbus/debug.h b/src/gdbus/debug.h deleted file mode 100644 index 5b15c05b..00000000 --- a/src/gdbus/debug.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * - * Library for simple D-Bus integration with GLib - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include <glib.h> - -//#define DBG(fmt, arg...) g_debug("%s: " fmt, __FUNCTION__ , ## arg) -#define DBG(fmt, arg...) diff --git a/src/gdbus/gdbus-cxx-bridge.cpp b/src/gdbus/gdbus-cxx-bridge.cpp deleted file mode 100644 index fdfeb803..00000000 --- a/src/gdbus/gdbus-cxx-bridge.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2011 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include "gdbus-cxx-bridge.h" -#include <boost/algorithm/string/predicate.hpp> - -#include <stdio.h> - -void intrusive_ptr_add_ref(DBusConnection *con) { dbus_connection_ref(con); } -void intrusive_ptr_release(DBusConnection *con) { dbus_connection_unref(con); } -void intrusive_ptr_add_ref(DBusMessage *msg) { dbus_message_ref(msg); } -void intrusive_ptr_release(DBusMessage *msg) { dbus_message_unref(msg); } -void intrusive_ptr_add_ref(DBusPendingCall *call) { dbus_pending_call_ref (call); } -void intrusive_ptr_release(DBusPendingCall *call) { dbus_pending_call_unref (call); } - -namespace GDBusCXX { - -DBusConnectionPtr dbus_get_bus_connection(const char *busType, - const char *name, - bool unshared, - DBusErrorCXX *err) -{ - return DBusConnectionPtr(b_dbus_setup_bus(boost::iequals(busType, "SYSTEM") ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, - name, unshared, err), - false); -} - -static void ConnectionLost(DBusConnection *connection, - void *user_data) -{ - DBusConnectionPtr::Disconnect_t *cb = static_cast<DBusConnectionPtr::Disconnect_t *>(user_data); - (*cb)(); -} - -static void DestroyDisconnect(void *user_data) -{ - DBusConnectionPtr::Disconnect_t *cb = static_cast<DBusConnectionPtr::Disconnect_t *>(user_data); - delete cb; -} - -void DBusConnectionPtr::setDisconnect(const Disconnect_t &func) -{ - b_dbus_set_disconnect_function(get(), - ConnectionLost, - new Disconnect_t(func), - DestroyDisconnect); -} - -DBusConnectionPtr dbus_get_bus_connection(const std::string &address, - DBusErrorCXX *err) -{ - DBusConnectionPtr conn(dbus_connection_open_private(address.c_str(), err), false); - if (conn) { - b_dbus_setup_connection(conn.get(), TRUE, NULL); - dbus_connection_set_exit_on_disconnect(conn.get(), FALSE); - } - return conn; -} - -void dbus_bus_connection_undelay(const DBusConnectionPtr &/*ptr*/) -{ - // no op -} - -boost::shared_ptr<DBusServerCXX> DBusServerCXX::listen(const NewConnection_t &newConnection, DBusErrorCXX *err) -{ - DBusServer *server = NULL; - char address[80]; - - address[0] = 0; - for (int counter = 1; counter < 100 && !server; counter++) { - if (*err) { - g_debug("dbus_server_listen(%s) failed, trying next candidate: %s", - address, err->message); - dbus_error_init(err); - } - sprintf(address, "unix:abstract=gdbuscxx-%d", counter); - server = dbus_server_listen(address, err); - } - - if (!server) { - return boost::shared_ptr<DBusServerCXX>(); - } - - b_dbus_setup_server(server); - boost::shared_ptr<DBusServerCXX> res(new DBusServerCXX(server, address)); - res->m_newConnection = newConnection; - dbus_server_set_new_connection_function(server, DBusServerCXX::newConnection, res.get(), NULL); - return res; -} - -void DBusServerCXX::newConnection(DBusServer *server, DBusConnection *newConn, void *data) throw() -{ - DBusServerCXX *me = static_cast<DBusServerCXX *>(data); - if (me->m_newConnection) { - try { - b_dbus_setup_connection(newConn, FALSE, NULL); - dbus_connection_set_exit_on_disconnect(newConn, FALSE); - DBusConnectionPtr conn(newConn); - me->m_newConnection(*me, conn); - } catch (...) { - g_error("handling new D-Bus connection failed with C++ exception"); - } - } -} - -DBusServerCXX::DBusServerCXX(DBusServer *server, const std::string &address) : - m_server(server), - m_address(address) -{ -} - -DBusServerCXX::~DBusServerCXX() -{ - if (m_server) { - dbus_server_disconnect(m_server.get()); - } -} - -bool CheckError(const DBusMessagePtr &reply, - std::string &buffer) -{ - const char* errname = dbus_message_get_error_name (reply.get()); - if (errname) { - buffer = errname; - DBusMessageIter iter; - if (dbus_message_iter_init(reply.get(), &iter)) { - if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) { - buffer += ": "; - const char *str; - dbus_message_iter_get_basic(&iter, &str); - buffer += str; - } - } - return true; - } else { - return false; - } -} - -} diff --git a/src/gdbus/gdbus-cxx-bridge.h b/src/gdbus/gdbus-cxx-bridge.h deleted file mode 100644 index 82fbdf9f..00000000 --- a/src/gdbus/gdbus-cxx-bridge.h +++ /dev/null @@ -1,4936 +0,0 @@ -/* - * Copyright (C) 2009 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -/** - * This file contains everything that a D-Bus server needs to - * integrate a normal C++ class into D-Bus. Argument and result - * marshaling is done in wrapper functions which convert directly - * to normal C++ types (bool, integers, std::string, std::map<>, ...). - * See dbus_traits for the full list of supported types. - * - * Before explaining the binding, some terminology first: - * - A function has a return type and multiple parameters. - * - Input parameters are read-only arguments of the function. - * - The function can return values to the caller via the - * return type and output parameters (retvals). - * - * The C++ binding roughly looks like this: - * - Arguments can be passed as plain types or const references: - void foo(int arg); void bar(const std::string &str); - * - A single result can be returned as return value: - * int foo(); - * - Multiple results can be copied into instances provided by - * the wrapper, passed by reference: void foo(std::string &res); - * - A return value, arguments and retvals can be combined - * arbitrarily. In the D-Bus reply the return code comes before - * all return values. - * - * Asynchronous methods are possible by declaring one parameter as a - * Result pointer and later calling the virtual function provided by - * it. Parameter passing of results is less flexible than that of - * method parameters: the later allows both std::string as well as - * const std::string &, for results only the const reference is - * supported. The Result instance is passed as pointer and then owned - * by the called method. - * - * Reference counting via boost::intrusive_ptr ensures that all - * D-Bus objects are handled automatically internally. - */ - - -#ifndef INCL_BDBUS_CXX_BRIDGE -#define INCL_BDBUS_CXX_BRIDGE - -#include "gdbus.h" -#include "gdbus-cxx.h" - -// Not defined by 1.4.x in Maemo Harmattan; INT_MAX has the same -// value and effect there. In older libdbus, it is the same as -// a very long timeout (2147483s), which is good enough. -#include <stdint.h> -#ifndef DBUS_TIMEOUT_INFINITE -# define DBUS_TIMEOUT_INFINITE INT_MAX -#endif - -#include <map> -#include <vector> -#include <utility> - -// Boost docs want this in the boost:: namespace, but -// that fails with clang 2.9 depending on the inclusion order of -// header files. Global namespace works in all cases. -void intrusive_ptr_add_ref(DBusConnection *con); -void intrusive_ptr_release(DBusConnection *con); -void intrusive_ptr_add_ref(DBusMessage *msg); -void intrusive_ptr_release(DBusMessage *msg); -void intrusive_ptr_add_ref(DBusPendingCall *call); -void intrusive_ptr_release(DBusPendingCall *call); -static inline void intrusive_ptr_add_ref(DBusServer *server) { dbus_server_ref(server); } -static inline void intrusive_ptr_release(DBusServer *server) { dbus_server_unref(server); } - -#include <boost/bind.hpp> -#include <boost/intrusive_ptr.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/variant.hpp> -#include <boost/variant/get.hpp> -#include <boost/utility.hpp> -#include <boost/tuple/tuple.hpp> - -#ifdef HAVE_GLIB -# include <glib.h> -#endif - -/* The connection is the only client-exposed type from the C API. To - * keep changes to a minimum while supporting both dbus - * implementations, this is made to be a define. The intention is to - * remove the define once the in-tree gdbus is dropped. */ -#define DBUS_NEW_ERROR_MSG b_dbus_create_error - -namespace GDBusCXX { - -// GDBusCXX aliases for the underlying types. -// Useful for some external dbus_traits which -// need to pass pointers to these types in their -// append()/get() methods without depending on GIO or -// libdbus types. -typedef DBusConnection connection_type; -typedef DBusMessage message_type; -typedef DBusMessageIter builder_type; -typedef DBusMessageIter reader_type; - -class DBusMessagePtr; - -class DBusConnectionPtr : public boost::intrusive_ptr<DBusConnection> -{ - public: - DBusConnectionPtr() {} - // connections are typically created once, so increment the ref counter by default - DBusConnectionPtr(DBusConnection *conn, bool add_ref = true) : - boost::intrusive_ptr<DBusConnection>(conn, add_ref) - {} - - DBusConnection *reference(void) throw() - { - DBusConnection *conn = get(); - dbus_connection_ref(conn); - return conn; - } - - /** empty stub: flushing only necessary with GIO D-Bus */ - void flush() {} - - /** GDBus GIO specific: disconnect callback */ - typedef boost::function<void ()> Disconnect_t; - void setDisconnect(const Disconnect_t &func); -#define GDBUS_CXX_HAVE_DISCONNECT 1 -}; - -class DBusMessagePtr : public boost::intrusive_ptr<DBusMessage> -{ - public: - DBusMessagePtr() {} - // expected to be used for messages created anew, - // so use the reference already incremented for us - // and don't increment by default - DBusMessagePtr(DBusMessage *msg, bool add_ref = false) : - boost::intrusive_ptr<DBusMessage>(msg, add_ref) - {} - - DBusMessage *reference(void) throw() - { - DBusMessage *msg = get(); - dbus_message_ref(msg); - return msg; - } -}; - -class DBusPendingCallPtr : public boost::intrusive_ptr<DBusPendingCall> -{ -public: - DBusPendingCallPtr(DBusPendingCall *call, bool add_ref = false) : - boost::intrusive_ptr<DBusPendingCall>(call, add_ref) - {} - - DBusPendingCall *reference(void) throw() - { - DBusPendingCall *call = get(); - dbus_pending_call_ref(call); - return call; - } -}; - -/** - * wrapper around DBusError which initializes - * the struct automatically, then can be used to - * throw an exception - */ -class DBusErrorCXX : public DBusError -{ - public: - DBusErrorCXX() { dbus_error_init(this); } - void throwFailure(const std::string &operation, const std::string &explanation = " failed") - { - if (dbus_error_is_set(this)) { - throw std::runtime_error(operation + ": " + message); - } else { - throw std::runtime_error(operation + explanation); - } - } - - operator bool () - { - return dbus_error_is_set(this); - } -}; - -DBusConnectionPtr dbus_get_bus_connection(const char *busType, - const char *name, - bool unshared, - DBusErrorCXX *err); - -DBusConnectionPtr dbus_get_bus_connection(const std::string &address, - DBusErrorCXX *err); - -void dbus_bus_connection_undelay(const DBusConnectionPtr &conn); - -/** - * Wrapper around DBusServer. Does intentionally not expose - * any of the underlying methods so that the public API - * can be implemented differently for GIO GDBus. - */ -class DBusServerCXX : private boost::noncopyable -{ - public: - ~DBusServerCXX(); - - /** - * Called for each new connection. Callback must store the DBusConnectionPtr, - * otherwise it will be unref'ed after the callback returns. - * If the new connection is not wanted, then it is good style to close it - * explicitly in the callback. - */ - typedef boost::function<void (DBusServerCXX &, DBusConnectionPtr &)> NewConnection_t; - - /** - * Start listening for new connections on an unused address. - */ - static boost::shared_ptr<DBusServerCXX> listen(const NewConnection_t &newConnection, DBusErrorCXX *err); - - /** - * address used by the server - */ - std::string getAddress() const { return m_address; } - - private: - DBusServerCXX(DBusServer *server, const std::string &address); - static void newConnection(DBusServer *server, DBusConnection *newConn, void *data) throw(); - - NewConnection_t m_newConnection; - boost::intrusive_ptr<DBusServer> m_server; - std::string m_address; -}; - - -/** - * Special type for object paths. A string in practice. - */ -class DBusObject_t : public std::string -{ - public: - DBusObject_t() {} - template <class T> DBusObject_t(T val) : std::string(val) {} - template <class T> DBusObject_t &operator = (T val) { assign(val); return *this; } -}; - -/** - * specializations of this must defined methods for encoding and - * decoding type C and declare its signature - */ -template<class C> struct dbus_traits {}; - -struct dbus_traits_base -{ - /** - * A C++ method or function can handle a call asynchronously by - * asking to be passed a "boost::shared_ptr<Result*>" parameter. - * The dbus_traits for those parameters have "asynchronous" set to - * true, which skips all processing after calling the method. - */ - static const bool asynchronous = false; -}; - -/** - * Append a varying number of parameters as result to the - * message, using AppendRetvals(msg) << res1 << res2 << ...; - * - * Types can be anything that has a dbus_traits, including - * types which are normally recognized as input parameters in D-Bus - * method calls. - */ -class AppendRetvals { - DBusMessageIter m_iter; - - public: - AppendRetvals(DBusMessagePtr &msg) { - dbus_message_iter_init_append(msg.get(), &m_iter); - } - - template<class A> AppendRetvals & operator << (const A &a) { - dbus_traits<A>::append(m_iter, a); - return *this; - } -}; - -/** - * Append a varying number of method parameters as result to the reply - * message, using AppendArgs(msg) << Set<A1>(res1) << Set<A2>(res2) << ...; - */ -struct AppendArgs { - DBusMessageIter m_iter; - - AppendArgs(DBusMessage *msg) { - dbus_message_iter_init_append(msg, &m_iter); - } - - /** syntactic sugar: redirect << into Set instance */ - template<class A> AppendArgs & operator << (const A &a) { - return a.set(*this); - } - - /** - * Always append argument, including those types which - * would be recognized by << as parameters and thus get - * skipped. - */ - template<class A> AppendArgs & operator + (const A &a) { - dbus_traits<A>::append(m_iter, a); - return *this; - } -}; - -/** default: skip it, not a result of the method */ -template<class A> struct Set -{ - // cppcheck-suppress uninitMemberVar - Set(A &a) {} - AppendArgs &set(AppendArgs &context) const { - return context; - } -}; - -/** same for const reference */ -template<class A> struct Set <const A &> -{ - // cppcheck-suppress uninitMemberVar - Set(A &a) {} - AppendArgs &set(AppendArgs &context) const { - return context; - } -}; - -/** specialization for reference: marshal result */ -template<class A> struct Set <A &> -{ - A &m_a; - Set(A &a) : m_a(a) {} - AppendArgs &set(AppendArgs &context) const { - dbus_traits<A>::append(context.m_iter, m_a); - return context; - } -}; - -/** - * Extract values from a message, using ExtractArgs(conn, msg) >> Get<A1>(val1) >> Get<A2>(val2) >> ...; - * - * This complements AppendArgs: it skips over those method arguments - * which are results of the method. Which values are skipped and - * which are marshalled depends on the specialization of Get and thus - * ultimately on the prototype of the method. - */ -struct ExtractArgs { - DBusConnection *m_conn; - DBusMessage *m_msg; - DBusMessageIter m_iter; - - public: - ExtractArgs(DBusConnection *conn, DBusMessage *msg) { - m_conn = conn; - m_msg = msg; - dbus_message_iter_init(msg, &m_iter); - } - - /** syntactic sugar: redirect >> into Get instance */ - template<class A> ExtractArgs & operator >> (const A &a) { - return a.get(*this); - } -}; - -/** default: extract data from message */ -template<class A> struct Get -{ - A &m_a; - Get(A &a) : m_a(a) {} - ExtractArgs &get(ExtractArgs &context) const { - dbus_traits<A>::get(context.m_conn, context.m_msg, context.m_iter, m_a); - return context; - } -}; - -/** same for const reference */ -template<class A> struct Get <const A &> -{ - A &m_a; - Get(A &a) : m_a(a) {} - ExtractArgs &get(ExtractArgs &context) const { - dbus_traits<A>::get(context.m_conn, context.m_msg, context.m_iter, m_a); - return context; - } -}; - -/** specialization for reference: skip it, not an input parameter */ -template<class A> struct Get <A &> -{ - Get(A &a) {} - ExtractArgs &get(ExtractArgs &context) const { - return context; - } -}; - -/** - * combines D-Bus connection, path and interface - */ -class DBusObject -{ - DBusConnectionPtr m_conn; - std::string m_path; - std::string m_interface; - bool m_closeConnection; - - public: - /** - * @param closeConnection set to true if the connection - * is private and this instance of - * DBusObject is meant to be the - * last user of the connection; - * when this DBusObject deconstructs, - * it'll close the connection - * (required by libdbus for private - * connections; the mechanism in GDBus for - * this didn't work) - */ - DBusObject(const DBusConnectionPtr &conn, - const std::string &path, - const std::string &interface, - bool closeConnection = false) : - m_conn(conn), - m_path(path), - m_interface(interface), - m_closeConnection(closeConnection) - {} - virtual ~DBusObject() { - if (m_closeConnection && - m_conn) { - dbus_connection_close(m_conn.get()); - } - } - - DBusConnection *getConnection() const { return m_conn.get(); } - const char *getPath() const { return m_path.c_str(); } - const char *getInterface() const { return m_interface.c_str(); } -}; - -/** - * adds destination to D-Bus connection, path and interface - */ -class DBusRemoteObject : public DBusObject -{ - std::string m_destination; -public: - DBusRemoteObject(const DBusConnectionPtr &conn, - const std::string &path, - const std::string &interface, - const std::string &destination, - bool closeConnection = false) : - DBusObject(conn, path, interface, closeConnection), - m_destination(destination) - {} - - const char *getDestination() const { return m_destination.c_str(); } -}; - -template<bool optional = false> class EmitSignal0Template -{ - const DBusObject &m_object; - const std::string m_signal; - - public: - EmitSignal0Template(const DBusObject &object, - const std::string &signal) : - m_object(object), - m_signal(signal) - {} - - typedef void result_type; - - void operator () () - { - DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(), - m_object.getInterface(), - m_signal.c_str())); - if (!msg) { - if (optional) { - return; - } - throw std::runtime_error("dbus_message_new_signal() failed"); - } - - if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) { - if (optional) { - return; - } - throw std::runtime_error("dbus_connection_send failed"); - } - } - - BDBusSignalTable makeSignalEntry(BDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const - { - BDBusSignalTable entry; - entry.name = m_signal.c_str(); - std::string buffer; - entry.signature = strdup(buffer.c_str()); - entry.flags = flags; - return entry; - } -}; - -typedef EmitSignal0Template<false> EmitSignal0; - -template <typename A1, bool optional = false> -class EmitSignal1 -{ - const DBusObject &m_object; - const std::string m_signal; - - public: - EmitSignal1(const DBusObject &object, - const std::string &signal) : - m_object(object), - m_signal(signal) - {} - - typedef void result_type; - - void operator () (A1 a1) - { - DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(), - m_object.getInterface(), - m_signal.c_str())); - if (!msg) { - if (optional) { - return; - } - throw std::runtime_error("dbus_message_new_signal() failed"); - } - AppendRetvals(msg) << a1; - - if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) { - if (optional) { - return; - } - throw std::runtime_error("dbus_connection_send failed"); - } - } - - BDBusSignalTable makeSignalEntry(BDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const - { - BDBusSignalTable entry; - entry.name = m_signal.c_str(); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - entry.signature = strdup(buffer.c_str()); - entry.flags = flags; - return entry; - } -}; - -template <typename A1, typename A2, bool optional = false> -class EmitSignal2 -{ - const DBusObject &m_object; - const std::string m_signal; - - public: - EmitSignal2(const DBusObject &object, - const std::string &signal) : - m_object(object), - m_signal(signal) - {} - - typedef void result_type; - - void operator () (A1 a1, A2 a2) - { - DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(), - m_object.getInterface(), - m_signal.c_str())); - if (!msg) { - if (optional) { - return; - } - throw std::runtime_error("dbus_message_new_signal() failed"); - } - AppendRetvals(msg) << a1 << a2; - - if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) { - if (optional) { - return; - } - throw std::runtime_error("dbus_connection_send failed"); - } - } - - BDBusSignalTable makeSignalEntry(BDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const - { - BDBusSignalTable entry; - entry.name = m_signal.c_str(); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - entry.signature = strdup(buffer.c_str()); - entry.flags = flags; - return entry; - } -}; - -template <typename A1, typename A2, typename A3, bool optional = false> -class EmitSignal3 -{ - const DBusObject &m_object; - const std::string m_signal; - - public: - EmitSignal3(const DBusObject &object, - const std::string &signal) : - m_object(object), - m_signal(signal) - {} - - typedef void result_type; - - void operator () (A1 a1, A2 a2, A3 a3) - { - DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(), - m_object.getInterface(), - m_signal.c_str())); - if (!msg) { - if (optional) { - return; - } - throw std::runtime_error("dbus_message_new_signal() failed"); - } - AppendRetvals(msg) << a1 << a2 << a3; - if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) { - if (optional) { - return; - } - throw std::runtime_error("dbus_connection_send failed"); - } - } - - BDBusSignalTable makeSignalEntry(BDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const - { - BDBusSignalTable entry; - entry.name = m_signal.c_str(); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - entry.signature = strdup(buffer.c_str()); - entry.flags = flags; - return entry; - } -}; - -template <typename A1, typename A2, typename A3, typename A4, bool optional = false> -class EmitSignal4 -{ - const DBusObject &m_object; - const std::string m_signal; - - public: - EmitSignal4(const DBusObject &object, - const std::string &signal) : - m_object(object), - m_signal(signal) - {} - - typedef void result_type; - - void operator () (A1 a1, A2 a2, A3 a3, A4 a4) - { - DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(), - m_object.getInterface(), - m_signal.c_str())); - if (!msg) { - if (optional) { - return; - } - throw std::runtime_error("dbus_message_new_signal() failed"); - } - AppendRetvals(msg) << a1 << a2 << a3 << a4; - if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) { - if (optional) { - return; - } - throw std::runtime_error("dbus_connection_send failed"); - } - } - - BDBusSignalTable makeSignalEntry(BDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const - { - BDBusSignalTable entry; - entry.name = m_signal.c_str(); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - entry.signature = strdup(buffer.c_str()); - entry.flags = flags; - return entry; - } -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, bool optional = false> -class EmitSignal5 -{ - const DBusObject &m_object; - const std::string m_signal; - - public: - EmitSignal5(const DBusObject &object, - const std::string &signal) : - m_object(object), - m_signal(signal) - {} - - typedef void result_type; - - void operator () (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - { - DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(), - m_object.getInterface(), - m_signal.c_str())); - if (!msg) { - if (optional) { - return; - } - throw std::runtime_error("dbus_message_new_signal() failed"); - } - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5; - if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) { - if (optional) { - return; - } - throw std::runtime_error("dbus_connection_send failed"); - } - } - - BDBusSignalTable makeSignalEntry(BDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const - { - BDBusSignalTable entry; - entry.name = m_signal.c_str(); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - entry.signature = strdup(buffer.c_str()); - entry.flags = flags; - return entry; - } -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, bool optional = false> -class EmitSignal6 -{ - const DBusObject &m_object; - const std::string m_signal; - - public: - EmitSignal6(const DBusObject &object, - const std::string &signal) : - m_object(object), - m_signal(signal) - {} - - typedef void result_type; - - void operator () (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - { - DBusMessagePtr msg(dbus_message_new_signal(m_object.getPath(), - m_object.getInterface(), - m_signal.c_str())); - if (!msg) { - if (optional) { - return; - } - throw std::runtime_error("dbus_message_new_signal() failed"); - } - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6; - if (!dbus_connection_send(m_object.getConnection(), msg.get(), NULL)) { - if (optional) { - return; - } - throw std::runtime_error("dbus_connection_send failed"); - } - } - - BDBusSignalTable makeSignalEntry(BDBusSignalFlags flags = G_DBUS_SIGNAL_FLAG_NONE) const - { - BDBusSignalTable entry; - entry.name = m_signal.c_str(); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - buffer += dbus_traits<A6>::getSignature(); - entry.signature = strdup(buffer.c_str()); - entry.flags = flags; - return entry; - } -}; - -template <class M> -struct MakeMethodEntry -{ - // There is no generic implementation of this method. - // If you get an error about it missing, then write - // a specialization for your type M (the method pointer). - // - // static BDBusMethodTable make(const char *name, - // BDBusMethodFlags flags) -}; - -/** - * Storage for method/signal/property arrays. - * Always contains at least one empty element - * at the end or is NULL. - */ -template <class T> class DBusVector { - size_t m_entries; - size_t m_size; - T *m_elements; - - static void destroy(BDBusMethodTable &entry) { - free(const_cast<char *>(entry.name)); - free(const_cast<char *>(entry.signature)); - free(const_cast<char *>(entry.reply)); - if (entry.destroy) { - entry.destroy(&entry); - } - } - - static void destroy(BDBusSignalTable &entry) { - free(const_cast<char *>(entry.signature)); - // if (entry.destroy) { - // entry.destroy(&entry); - // } - } - - public: - DBusVector() : m_entries(0), m_size(0), m_elements(NULL) {} - ~DBusVector() { - if (m_elements) { - for (size_t i = 0; i < m_entries; i++) { - destroy(m_elements[i]); - } - free(m_elements); - } - } - - T *get() { return m_elements; } - void push_back(const T &element) { - if (m_entries + 1 >= m_size) { - size_t newSize = m_size ? m_size * 2 : 16; - T *elements = static_cast<T *>(realloc(m_elements, newSize * sizeof(T))); - if (!elements) { - throw std::bad_alloc(); - } - m_elements = elements; - m_size = newSize; - } - m_elements[m_entries] = element; - m_entries++; - memset(m_elements + m_entries, 0, sizeof(T)); - } -}; - -/** - * utility class for registering an interface - */ -class DBusObjectHelper : public DBusObject -{ - boost::function<void (void)> m_callback; - bool m_activated; - DBusVector<BDBusMethodTable> m_methods; - DBusVector<BDBusSignalTable> m_signals; - - public: - typedef boost::function<void (void)> Callback_t; - - DBusObjectHelper(const DBusConnectionPtr &conn, - const std::string &path, - const std::string &interface, - const Callback_t &callback = Callback_t(), - bool closeConnection = false) : - DBusObject(conn, path, interface, closeConnection), - m_callback(callback), - m_activated(false) - { - } - - ~DBusObjectHelper() - { - deactivate(); - } - - /** - * binds a member to the this pointer of its instance - * and invokes it when the specified method is called - */ - template <class A1, class C, class M> void add(A1 instance, M C::*method, - const char *name, BDBusMethodFlags flags = G_DBUS_METHOD_FLAG_NONE) { - typedef MakeMethodEntry< boost::function<M> > entry_type; - m_methods.push_back(entry_type::make(name, flags, entry_type::boostptr(method, instance))); - } - - - /** - * binds a plain function pointer with no additional arguments and - * invokes it when the specified method is called - */ - template <class M> void add(M *function, - const char *name, BDBusMethodFlags flags = G_DBUS_METHOD_FLAG_NONE) { - m_methods.push_back(MakeMethodEntry< boost::function<M> >::make(name, flags, function)); - } - - /** - * add an existing signal entry - */ - template <class S> void add(const S &s) { - m_signals.push_back(s.makeSignalEntry()); - } - - void activate(BDBusMethodTable *methods, - BDBusSignalTable *signals, - BDBusPropertyTable *properties, - const Callback_t &callback) { - if (!b_dbus_register_interface_with_callback(getConnection(), getPath(), getInterface(), - methods, signals, properties, this, NULL, interfaceCallback)) { - throw std::runtime_error(std::string("b_dbus_register_interface() failed for ") + getPath() + " " + getInterface()); - } - m_callback = callback; - m_activated = true; - } - - void activate() { - if (!b_dbus_register_interface_with_callback(getConnection(), getPath(), getInterface(), - m_methods.get(), m_signals.get(), NULL, this, NULL, interfaceCallback)) { - throw std::runtime_error(std::string("b_dbus_register_interface() failed for ") + getPath() + " " + getInterface()); - } - m_activated = true; - } - - void deactivate() - { - if (m_activated) { - if (!b_dbus_unregister_interface(getConnection(), - getPath(), - getInterface())) { - throw std::runtime_error(std::string("b_dbus_unregister_interface() failed for ") + getPath() + " " + getInterface()); - } - m_activated = false; - } - } - static void interfaceCallback(void *userData) { - DBusObjectHelper* helper = static_cast<DBusObjectHelper*>(userData); - if (helper->m_callback) { - helper->m_callback(); - } - } -}; - - -/** - * to be used for plain parameters like int32_t: - * treat as arguments which have to be extracted - * from the D-Bus message and can be skipped when - * encoding the reply - */ -template<class host, int dbus> struct basic_marshal : public dbus_traits_base -{ - typedef host host_type; - typedef host arg_type; - static const int dbus_type = dbus; - - /** - * copy value from D-Bus iterator into variable - */ - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, host &value) - { - if (dbus_message_iter_get_arg_type(&iter) != dbus) { - throw std::runtime_error("invalid argument"); - } - dbus_message_iter_get_basic(&iter, &value); - dbus_message_iter_next(&iter); - } - - /** - * copy value into D-Bus iterator - */ - static void append(DBusMessageIter &iter, arg_type value) - { - if (!dbus_message_iter_append_basic(&iter, dbus, &value)) { - throw std::runtime_error("out of memory"); - } - } -}; - -template<> struct dbus_traits<uint8_t> : - public basic_marshal< uint8_t, DBUS_TYPE_BYTE > -{ - /** - * plain type, regardless of whether used as - * input or output parameter - */ - static std::string getType() { return "y"; } - - /** - * plain type => input parameter => non-empty signature - */ - static std::string getSignature() {return getType(); } - - /** - * plain type => not returned to caller - */ - static std::string getReply() { return ""; } - -}; - -/** if the app wants to use signed char, let it and treat it like a byte */ -template<> struct dbus_traits<int8_t> : dbus_traits<uint8_t> -{ - typedef int8_t host_type; - typedef int8_t arg_type; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, host_type &value) - { - dbus_traits<uint8_t>::get(conn, msg, iter, reinterpret_cast<uint8_t &>(value)); - } -}; - -template<> struct dbus_traits<int16_t> : - public basic_marshal< int16_t, DBUS_TYPE_INT16 > -{ - static std::string getType() { return "n"; } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } -}; -template<> struct dbus_traits<uint16_t> : - public basic_marshal< uint16_t, DBUS_TYPE_UINT16 > -{ - static std::string getType() { return "q"; } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } -}; -template<> struct dbus_traits<int32_t> : - public basic_marshal< int32_t, DBUS_TYPE_INT32 > -{ - static std::string getType() { return "i"; } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } -}; -template<> struct dbus_traits<uint32_t> : - public basic_marshal< uint32_t, DBUS_TYPE_UINT32 > -{ - static std::string getType() { return "u"; } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } -}; -template<> struct dbus_traits<int64_t> : - public basic_marshal< int64_t, DBUS_TYPE_INT64 > -{ - static std::string getType() { return "x"; } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } -}; -template<> struct dbus_traits<uint64_t> : - public basic_marshal< uint64_t, DBUS_TYPE_UINT64 > -{ - static std::string getType() { return "t"; } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } -}; -template<> struct dbus_traits<double> : - public basic_marshal< double, DBUS_TYPE_DOUBLE > -{ - static std::string getType() { return "d"; } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } -}; - -template<> struct dbus_traits<bool> : public dbus_traits_base -{ - static std::string getType() { return "b"; } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } - static const int dbus = DBUS_TYPE_BOOLEAN; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, bool &value) - { - if (dbus_message_iter_get_arg_type(&iter) != dbus) { - throw std::runtime_error("invalid argument"); - } - dbus_bool_t dbus_value; - dbus_message_iter_get_basic(&iter, &dbus_value); - dbus_message_iter_next(&iter); - value = dbus_value; - } - - static void append(DBusMessageIter &iter, bool value) - { - dbus_bool_t dbus_value = value; - if (!dbus_message_iter_append_basic(&iter, dbus, &dbus_value)) { - throw std::runtime_error("out of memory"); - } - } - - typedef bool host_type; - typedef bool arg_type; -}; - -template<> struct dbus_traits<std::string> : public dbus_traits_base -{ - static std::string getType() { return "s"; } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } - static const int dbus = DBUS_TYPE_STRING; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, std::string &value) - { - if (dbus_message_iter_get_arg_type(&iter) != dbus) { - throw std::runtime_error("invalid argument"); - } - const char *str; - dbus_message_iter_get_basic(&iter, &str); - dbus_message_iter_next(&iter); - value = str; - } - - static void append(DBusMessageIter &iter, const std::string &value) - { - const char *str = value.c_str(); -#ifdef HAVE_GLIB - // dbus_message_iter_append_basic() will log an assertion and - // return NULL (similar to GIO dbus in FDO #90118) when the - // string contains non-UTF-8 content. We must check in - // advance to avoid the assertion, even if that means - // duplicating the check (once here and once inside - // dbus_message_iter_append_basic()). - // - // Strictly speaking, this is something that the caller should - // have checked for, but as this should only happen for - // invalid external data (like broken iCalendar 2.0 events, - // see FDO #90118) and the only reasonable error handling in - // SyncEvolution would consist of filtering the data, so it is - // less intrusive overall to do that here: a question mark - // substitutes all invalid bytes. - const char *start = value.c_str(), - *end = value.c_str() + value.size(); - const gchar *invalid; - bool valid = g_utf8_validate(start, end - start, &invalid); - std::string buffer; - if (!valid) { - buffer.reserve(value.size()); - while (true) { - // "Opposite conditions in nested 'if' blocks lead to a dead code block." is not true: - // The check is necessary for the following loop iterations. - // cppcheck-suppress oppositeInnerCondition - if (valid) { - buffer.append(start, end - start); - // Empty string is valid, so we end up here in all cases. - break; - } else { - buffer.append(start, invalid - start); - buffer.append("?"); - start = invalid + 1; - } - valid = g_utf8_validate(start, end - start, &invalid); - } - str = buffer.c_str(); - } -#endif - if (!dbus_message_iter_append_basic(&iter, dbus, &str)) { - throw std::runtime_error("out of memory"); - } - } - - typedef std::string host_type; - typedef const std::string &arg_type; -}; - -template <> struct dbus_traits<DBusObject_t> : public dbus_traits_base -{ - static std::string getType() { return "o"; } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } - static const int dbus = DBUS_TYPE_OBJECT_PATH; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, DBusObject_t &value) - { - if (dbus_message_iter_get_arg_type(&iter) != dbus) { - throw std::runtime_error("invalid argument"); - } - const char *str; - dbus_message_iter_get_basic(&iter, &str); - dbus_message_iter_next(&iter); - value = str; - } - - static void append(DBusMessageIter &iter, const DBusObject_t &value) - { - const char *str = value.c_str(); - if (!dbus_message_iter_append_basic(&iter, dbus, &str)) { - throw std::runtime_error("out of memory"); - } - } - - typedef DBusObject_t host_type; - typedef const DBusObject_t &arg_type; -}; - -/** - * pseudo-parameter: not part of D-Bus signature, - * but rather extracted from message attributes - */ -template <> struct dbus_traits<Caller_t> : public dbus_traits_base -{ - static std::string getType() { return ""; } - static std::string getSignature() { return ""; } - static std::string getReply() { return ""; } - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, Caller_t &value) - { - const char *peer = dbus_message_get_sender(msg); - if (!peer) { - throw std::runtime_error("D-Bus method call without sender?!"); - } - value = peer; - } - - typedef Caller_t host_type; - typedef const Caller_t &arg_type; -}; - -/** - * a std::pair - maps to D-Bus struct - */ -template<class A, class B> struct dbus_traits< std::pair<A,B> > : public dbus_traits_base -{ - static std::string getContainedType() - { - return dbus_traits<A>::getType() + dbus_traits<B>::getType(); - } - static std::string getType() - { - return "(" + getContainedType() + ")"; - } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } - typedef std::pair<A,B> host_type; - typedef const std::pair<A,B> &arg_type; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, host_type &pair) - { - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRUCT) { - throw std::runtime_error("invalid argument"); - } - DBusMessageIter sub; - dbus_message_iter_recurse(&iter, &sub); - if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { - dbus_traits<A>::get(conn, msg, sub, pair.first); - } - if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { - dbus_traits<B>::get(conn, msg, sub, pair.second); - } - dbus_message_iter_next(&iter); - } - - static void append(DBusMessageIter &iter, arg_type pair) - { - DBusMessageIter sub; - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &sub)) { - throw std::runtime_error("out of memory"); - } - - dbus_traits<A>::append(sub, pair.first); - dbus_traits<B>::append(sub, pair.second); - - if (!dbus_message_iter_close_container(&iter, &sub)) { - throw std::runtime_error("out of memory"); - } - } -}; - -/** - * dedicated type for chunk of data, to distinguish this case from - * a normal std::pair of two values - */ -template<class V> class DBusArray : public std::pair<size_t, const V *> -{ - public: - DBusArray() : - std::pair<size_t, const V *>(0, NULL) - {} - DBusArray(size_t len, const V *data) : - std::pair<size_t, const V *>(len, data) - {} -}; -template<class V> class DBusArray<V> makeDBusArray(size_t len, const V *data) { return DBusArray<V>(len, data); } - -/** - * Pass array of basic type plus its number of entries. - * Can only be used in cases where the caller owns the - * memory and can discard it when the call returns, in - * other words, for method calls, asynchronous replys and - * signals, but not for return values. - */ -template<class V> struct dbus_traits< DBusArray<V> > : public dbus_traits_base -{ - static std::string getContainedType() - { - return dbus_traits<V>::getType(); - } - static std::string getType() - { - return std::string("a") + - dbus_traits<V>::getType(); - } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } - typedef DBusArray<V> host_type; - typedef const host_type &arg_type; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, host_type &array) - { - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { - throw std::runtime_error("invalid argument"); - } - DBusMessageIter sub; - dbus_message_iter_recurse(&iter, &sub); - int type = dbus_message_iter_get_arg_type(&sub); - // type is zero for empty arrays?! - if (type && - type != dbus_traits<V>::dbus_type) { - throw std::runtime_error("invalid argument"); - } - int nelements; - typename dbus_traits<V>::host_type *data; - dbus_message_iter_get_fixed_array(&sub, &data, &nelements); - array.first = nelements; - array.second = data; - dbus_message_iter_next(&iter); - if (!type && nelements) { - // non-empty array of invalid type?! - throw std::runtime_error("could not decode DBusArray: type is zero, but array isn't empty"); - } - } - - static void append(DBusMessageIter &iter, arg_type array) - { - DBusMessageIter sub; - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, getContainedType().c_str(), &sub) || - !dbus_message_iter_append_fixed_array(&sub, dbus_traits<V>::dbus_type, &array.second, array.first) || - !dbus_message_iter_close_container(&iter, &sub)) { - throw std::runtime_error("out of memory"); - } - } -}; - -/** - * a std::map - treat it like a D-Bus dict - */ -template<class K, class V, class C> struct dbus_traits< std::map<K, V, C> > : public dbus_traits_base -{ - static std::string getContainedType() - { - return std::string("{") + - dbus_traits<K>::getType() + - dbus_traits<V>::getType() + - "}"; - } - static std::string getType() - { - return std::string("a") + - getContainedType(); - } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } - typedef std::map<K, V, C> host_type; - typedef const host_type &arg_type; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, host_type &dict) - { - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { - throw std::runtime_error("invalid argument"); - } - DBusMessageIter sub; - dbus_message_iter_recurse(&iter, &sub); - int type; - while ((type = dbus_message_iter_get_arg_type(&sub)) != DBUS_TYPE_INVALID) { - if (type != DBUS_TYPE_DICT_ENTRY) { - throw std::runtime_error("invalid argument"); - } - DBusMessageIter entry; - dbus_message_iter_recurse(&sub, &entry); - K key; - V value; - dbus_traits<K>::get(conn, msg, entry, key); - dbus_traits<V>::get(conn, msg, entry, value); - dict.insert(std::make_pair(key, value)); - dbus_message_iter_next(&sub); - } - dbus_message_iter_next(&iter); - } - - static void append(DBusMessageIter &iter, arg_type dict) - { - DBusMessageIter sub; - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, getContainedType().c_str(), &sub)) { - throw std::runtime_error("out of memory"); - } - - for(typename host_type::const_iterator it = dict.begin(); - it != dict.end(); - ++it) { - DBusMessageIter entry; - if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &entry)) { - throw std::runtime_error("out of memory"); - } - dbus_traits<K>::append(entry, it->first); - dbus_traits<V>::append(entry, it->second); - if (!dbus_message_iter_close_container(&sub, &entry)) { - throw std::runtime_error("out of memory"); - } - } - if (!dbus_message_iter_close_container(&iter, &sub)) { - throw std::runtime_error("out of memory"); - } - } -}; - -/** - * a std::vector - maps to D-Bus array, but with inefficient marshaling - * because we cannot get a base pointer for the whole array - */ -template<class V> struct dbus_traits< std::vector<V> > : public dbus_traits_base -{ - static std::string getContainedType() - { - return dbus_traits<V>::getType(); - } - static std::string getType() - { - return std::string("a") + - getContainedType(); - } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } - typedef std::vector<V> host_type; - typedef const std::vector<V> &arg_type; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, host_type &array) - { - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { - throw std::runtime_error("invalid argument"); - } - DBusMessageIter sub; - dbus_message_iter_recurse(&iter, &sub); - while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { - V value; - dbus_traits<V>::get(conn, msg, sub, value); - array.push_back(value); - } - dbus_message_iter_next(&iter); - } - - static void append(DBusMessageIter &iter, arg_type array) - { - DBusMessageIter sub; - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, getContainedType().c_str(), &sub)) { - throw std::runtime_error("out of memory"); - } - - for(typename host_type::const_iterator it = array.begin(); - it != array.end(); - ++it) { - dbus_traits<V>::append(sub, *it); - } - if (!dbus_message_iter_close_container(&iter, &sub)) { - throw std::runtime_error("out of memory"); - } - } -}; - -/** simple smart pointer which takes memory allocated by libdbus and frees it with dbus_free() */ -template <class T> class DBusMem : private boost::noncopyable -{ - T *m_pointer; - - public: - DBusMem(T *pointer) : m_pointer(pointer) {} - ~DBusMem() { if (m_pointer) dbus_free(m_pointer); } - operator T * () { return m_pointer; } - T * get() { return m_pointer; } - operator bool () { return m_pointer != 0; } -}; - - /** - * Helper class to append variant values into an iterator - */ -class append_visitor_dummy_type {}; - -struct append_visitor : public boost::static_visitor<> -{ - DBusMessageIter &iter; - append_visitor(DBusMessageIter &i) : iter(i) {} - template <class V> void operator()(const V &v) const - { - DBusMessageIter sub; - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, - dbus_traits<V>::getType().c_str(), &sub)) { - throw std::runtime_error("out of memory"); - } - dbus_traits<V>::append(sub, v); - if (!dbus_message_iter_close_container(&iter, &sub)) { - throw std::runtime_error("out of memory"); - } - } -}; - -/** - * A boost::variant <V> maps to a dbus variant, only care about values of - * type V but will not throw error if type is not matched, this is useful if - * application is interested on only a sub set of possible value types - * in variant. - */ -template <class V> struct dbus_traits <boost::variant <V> > : public dbus_traits_base -{ - static std::string getType() { return "v"; } - static std::string getSignature() { return getType(); } - static std::string getReply() { return ""; } - static const int dbus = DBUS_TYPE_VARIANT; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, boost::variant <V> &value) - { - if (dbus_message_iter_get_arg_type(&iter) != dbus) { - throw std::runtime_error("invalid argument"); - return; - } - DBusMessageIter sub; - dbus_message_iter_recurse(&iter, &sub); - DBusMem<char> sig(dbus_message_iter_get_signature(&sub)); - if (dbus_traits<V>::getSignature() != sig.get()) { - //ignore unrecognized sub type in variant - return; - } - V val; - dbus_traits<V>::get (conn, msg, sub, val); - value = val; - } - - static void append(DBusMessageIter &iter, const boost::variant<V> &value) - { - boost::apply_visitor(append_visitor(iter), value); - } - - typedef boost::variant<V> host_type; - typedef const boost::variant<V> &arg_type; -}; - -/** - * A boost::variant <V1, V2> maps to a dbus variant, only care about values of - * type V1, V2 but will not throw error if type is not matched, this is useful if - * application is interested on only a sub set of possible value types - * in variant. - */ -template <class V1, class V2> struct dbus_traits <boost::variant <V1, V2> > : public dbus_traits_base -{ - static std::string getType() { return "v"; } - static std::string getSignature() { return getType(); } - static std::string getReply() { return ""; } - static const int dbus = DBUS_TYPE_VARIANT; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, boost::variant <V1, V2> &value) - { - if (dbus_message_iter_get_arg_type(&iter) != dbus) { - throw std::runtime_error("invalid argument"); - return; - } - DBusMessageIter sub; - dbus_message_iter_recurse(&iter, &sub); - DBusMem<char> sig(dbus_message_iter_get_signature(&sub)); - if (dbus_traits<V1>::getSignature() == sig.get()) { - V1 val; - dbus_traits<V1>::get (conn, msg, sub, val); - value = val; - } else if (dbus_traits<V2>::getSignature() == sig.get()) { - V2 val; - dbus_traits<V2>::get (conn, msg, sub, val); - value = val; - } else { - //ignore unrecognized sub type in variant - } - } - - static void append(DBusMessageIter &iter, const boost::variant<V1, V2> &value) - { - boost::apply_visitor(append_visitor(iter), value); - } - - typedef boost::variant<V1, V2> host_type; - typedef const boost::variant<V1, V2> &arg_type; -}; - -/** - * a single member m of type V in a struct K - */ -template<class K, class V, V K::*m> struct dbus_member_single -{ - static std::string getType() - { - return dbus_traits<V>::getType(); - } - typedef V host_type; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, K &val) - { - dbus_traits<V>::get(conn, msg, iter, val.*m); - } - - static void append(DBusMessageIter &iter, const K &val) - { - dbus_traits<V>::append(iter, val.*m); - } -}; - -/** - * a member m of type V in a struct K, followed by another dbus_member - * or dbus_member_single to end the chain - */ -template<class K, class V, V K::*m, class M> struct dbus_member -{ - static std::string getType() - { - return dbus_traits<V>::getType() + M::getType(); - } - typedef V host_type; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, K &val) - { - dbus_traits<V>::get(conn, msg, iter, val.*m); - M::get(conn, msg, iter, val); - } - - static void append(DBusMessageIter &iter, const K &val) - { - dbus_traits<V>::append(iter, val.*m); - M::append(iter, val); - } -}; - -/** - * The base class of type V of a struct K, followed by another dbus_member - * or dbus_member_single to end the chain - */ -template<class K, class V, class M> struct dbus_base -{ - static std::string getType() - { - return dbus_traits<V>::getType() + M::getType(); - } - typedef V host_type; - - static void get(ExtractArgs &context, - GVariantIter &iter, K &val) - { - dbus_traits<V>::get(context, iter, val); - M::get(context, iter, val); - } - - static void append(GVariantBuilder &builder, const K &val) - { - dbus_traits<V>::append(builder, val); - M::append(builder, val); - } -}; - -/** - * a helper class which implements dbus_traits for - * a class, use with: - * struct foo { int a; std::string b; }; - * template<> struct dbus_traits< foo > : dbus_struct_traits< foo, - * dbus_member<foo, int, &foo::a, - * dbus_member_single<foo, std::string, &foo::b> > > {}; - */ -template<class K, class M> struct dbus_struct_traits : public dbus_traits_base -{ - static std::string getContainedType() - { - return M::getType(); - } - static std::string getType() - { - return std::string("(") + - getContainedType() + - ")"; - } - static std::string getSignature() {return getType(); } - static std::string getReply() { return ""; } - typedef K host_type; - typedef const K &arg_type; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, host_type &val) - { - - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRUCT) { - throw std::runtime_error("invalid argument"); - } - DBusMessageIter sub; - dbus_message_iter_recurse(&iter, &sub); - M::get(conn, msg, sub, val); - dbus_message_iter_next(&iter); - } - - static void append(DBusMessageIter &iter, arg_type val) - { - DBusMessageIter sub; - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &sub)) { - throw std::runtime_error("out of memory"); - } - M::append(sub, val); - if (!dbus_message_iter_close_container(&iter, &sub)) { - throw std::runtime_error("out of memory"); - } - } -}; - -/** - * a helper class which implements dbus_traits for an enum, - * parameterize it with the enum type and an integer type - * large enough to hold all valid enum values - */ -template<class E, class I> struct dbus_enum_traits : public dbus_traits<I> -{ - typedef E host_type; - typedef E arg_type; - - // cast from enum to int in append() is implicit; in - // get() we have to make it explicit - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, host_type &val) - { - I ival; - dbus_traits<I>::get(conn, msg, iter, ival); - val = static_cast<E>(ival); - } -}; - -/** - * special case const reference parameter: - * treat like pass-by-value input argument - * - * Example: const std::string &arg - */ -template<class C> struct dbus_traits<const C &> : public dbus_traits<C> {}; - -/** - * special case writeable reference parameter: - * must be a return value - * - * Example: std::string &retval - */ -template<class C> struct dbus_traits<C &> : public dbus_traits<C> -{ - static std::string getSignature() { return ""; } - static std::string getReply() { return dbus_traits<C>::getType(); } -}; - -/** - * dbus-cxx base exception thrown in dbus server - * org.syncevolution.gdbuscxx.Exception - * This base class only contains interfaces, no data members - */ -class DBusCXXException -{ - public: - /** - * get exception name, used to convert to dbus error name - * subclasses should override it - */ - virtual std::string getName() const { return "org.syncevolution.gdbuscxx.Exception"; } - - /** - * get error message - */ - virtual const char* getMessage() const { return "unknown"; } -}; - -static DBusMessage *handleException(DBusMessage *msg) -{ - try { -#ifdef DBUS_CXX_EXCEPTION_HANDLER - return DBUS_CXX_EXCEPTION_HANDLER(msg); -#else - throw; -#endif - } catch (const dbus_error &ex) { - return b_dbus_create_error(msg, ex.dbusName().c_str(), "%s", ex.what()); - } catch (const DBusCXXException &ex) { - return b_dbus_create_error(msg, ex.getName().c_str(), "%s", ex.getMessage()); - } catch (const std::runtime_error &ex) { - return b_dbus_create_error(msg, "org.syncevolution.gdbuscxx.Exception", "%s", ex.what()); - } catch (...) { - return b_dbus_create_error(msg, "org.syncevolution.gdbuscxx.Exception", "unknown"); - } -} - -/** - * Check presence of a certain D-Bus client. - */ -class Watch : private boost::noncopyable -{ - DBusConnectionPtr m_conn; - boost::function<void (void)> m_callback; - bool m_called; - guint m_watchID; - - static void disconnect(DBusConnection *connection, - void *user_data) - { - Watch *watch = static_cast<Watch *>(user_data); - if (!watch->m_called) { - watch->m_called = true; - if (watch->m_callback) { - watch->m_callback(); - } - } - } - - public: - Watch(const DBusConnectionPtr &conn, - const boost::function<void (void)> &callback = boost::function<void (void)>()) : - m_conn(conn), - m_callback(callback), - m_called(false), - m_watchID(0) - { - } - - void setCallback(const boost::function<void (void)> &callback) - { - m_callback = callback; - if (m_called && m_callback) { - m_callback(); - } - } - - void activate(const char *peer) - { - if (!peer) { - throw std::runtime_error("Watch::activate(): no peer"); - } - - // Install watch first ... - m_watchID = b_dbus_add_disconnect_watch(m_conn.get(), - peer, - disconnect, - this, - NULL); - if (!m_watchID) { - throw std::runtime_error("b_dbus_add_disconnect_watch() failed"); - } - - // ... then check that the peer really exists, - // otherwise we'll never notice the disconnect. - // If it disconnects while we are doing this, - // then disconnect() will be called twice, - // but it handles that. - DBusErrorCXX error; - if (!dbus_bus_name_has_owner(m_conn.get(), - peer, - &error)) { - if (error) { - error.throwFailure("dbus_bus_name_has_owner()"); - } - disconnect(m_conn.get(), this); - } - } - - ~Watch() - { - if (m_watchID) { - if (!b_dbus_remove_watch(m_conn.get(), m_watchID)) { - // this may happen because the watch is - // removed automatically when it was triggered - } - m_watchID = 0; - } - } -}; - -/** - * pseudo-parameter: not part of D-Bus signature, - * but rather extracted from message attributes - */ -template <> struct dbus_traits< boost::shared_ptr<Watch> > : public dbus_traits_base -{ - static std::string getType() { return ""; } - static std::string getSignature() { return ""; } - static std::string getReply() { return ""; } - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, boost::shared_ptr<Watch> &value) - { - boost::shared_ptr<Watch> watch(new Watch(conn)); - watch->activate(dbus_message_get_sender(msg)); - value = watch; - } - - static void append(DBusMessageIter &iter, const boost::shared_ptr<Watch> &value) {} - - typedef boost::shared_ptr<Watch> host_type; - typedef const boost::shared_ptr<Watch> &arg_type; -}; - -/** - * base class for D-Bus results, - * keeps references to required objects and provides the - * failed() method - */ -class DBusResult : virtual public Result -{ - protected: - DBusConnectionPtr m_conn; /**< connection via which the message was received */ - DBusMessagePtr m_msg; /**< the method invocation message */ - - public: - DBusResult(DBusConnection *conn, - DBusMessage *msg) : - m_conn(conn, true), - m_msg(msg, true) - {} - - virtual void failed(const dbus_error &error) - { - if (!b_dbus_send_error(m_conn.get(), m_msg.get(), - error.dbusName().c_str(), - "%s", error.what())) { - throw std::runtime_error("b_dbus_send_error() failed"); - } - } - - virtual Watch *createWatch(const boost::function<void (void)> &callback) - { - std::unique_ptr<Watch> watch(new Watch(m_conn, callback)); - watch->activate(dbus_message_get_sender(m_msg.get())); - return watch.release(); - } -}; - -class DBusResult0 : - public Result0, - public DBusResult -{ - public: - DBusResult0(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done() - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { return ""; } -}; - -template <typename A1> -class DBusResult1 : - public Result1<A1>, - public DBusResult -{ - public: - DBusResult1(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done(A1 a1) - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - AppendRetvals(reply) << a1; - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { return dbus_traits<A1>::getSignature(); } - - static const bool asynchronous = - dbus_traits<A1>::asynchronous; -}; - -template <typename A1, typename A2> -class DBusResult2 : - public Result2<A1, A2>, - public DBusResult -{ - public: - DBusResult2(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done(A1 a1, A2 a2) - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - AppendRetvals(reply) << a1 << a2; - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { - return dbus_traits<A1>::getSignature() + - DBusResult1<A2>::getSignature(); - } - - static const bool asynchronous = - dbus_traits<A1>::asynchronous || - DBusResult1<A2>::asynchronous; -}; - -template <typename A1, typename A2, typename A3> -class DBusResult3 : - public Result3<A1, A2, A3>, - public DBusResult -{ - public: - DBusResult3(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done(A1 a1, A2 a2, A3 a3) - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - AppendRetvals(reply) << a1 << a2 << a3; - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { - return dbus_traits<A1>::getSignature() + - DBusResult2<A2, A3>::getSignature(); - } - - static const bool asynchronous = - dbus_traits<A1>::asynchronous || - DBusResult2<A2, A3>::asynchronous; -}; - -template <typename A1, typename A2, typename A3, typename A4> -class DBusResult4 : - public Result4<A1, A2, A3, A4>, - public DBusResult -{ - public: - DBusResult4(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4) - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - AppendRetvals(reply) << a1 << a2 << a3 << a4; - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { - return dbus_traits<A1>::getSignature() + - DBusResult3<A2, A3, A4>::getSignature(); - } - - static const bool asynchronous = - dbus_traits<A1>::asynchronous || - DBusResult3<A2, A3, A4>::asynchronous; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5> -class DBusResult5 : - public Result5<A1, A2, A3, A4, A5>, - public DBusResult -{ - public: - DBusResult5(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - AppendRetvals(reply) << a1 << a2 << a3 << a4 << a5; - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { - return dbus_traits<A1>::getSignature() + - DBusResult4<A2, A3, A4, A5>::getSignature(); - } - - static const bool asynchronous = - dbus_traits<A1>::asynchronous || - DBusResult4<A2, A3, A4, A5>::asynchronous; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6> -class DBusResult6 : - public Result6<A1, A2, A3, A4, A5, A6>, - public DBusResult -{ - public: - DBusResult6(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - AppendRetvals(reply) << a1 << a2 << a3 << a4 << a5 << a6; - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { - return dbus_traits<A1>::getSignature() + - DBusResult5<A2, A3, A4, A5, A6>::getSignature(); - } - - static const bool asynchronous = - dbus_traits<A1>::asynchronous || - DBusResult5<A2, A3, A4, A5, A6>::asynchronous; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7> -class DBusResult7 : - public Result7<A1, A2, A3, A4, A5, A6, A7>, - public DBusResult -{ - public: - DBusResult7(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - AppendRetvals(reply) << a1 << a2 << a3 << a4 << a5 << a6 << a7; - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { - return dbus_traits<A1>::getSignature() + - DBusResult6<A2, A3, A4, A5, A6, A7>::getSignature(); - } - - static const bool asynchronous = - dbus_traits<A1>::asynchronous || - DBusResult6<A2, A3, A4, A5, A6, A7>::asynchronous; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8> -class DBusResult8 : - public Result8<A1, A2, A3, A4, A5, A6, A7, A8>, - public DBusResult -{ - public: - DBusResult8(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - AppendRetvals(reply) << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { - return dbus_traits<A1>::getSignature() + - DBusResult7<A2, A3, A4, A5, A6, A7, A8>::getSignature(); - } - - static const bool asynchronous = - dbus_traits<A1>::asynchronous || - DBusResult7<A2, A3, A4, A5, A6, A7, A8>::asynchronous; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9> -class DBusResult9 : - public Result9<A1, A2, A3, A4, A5, A6, A7, A8, A9>, - public DBusResult -{ - public: - DBusResult9(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - AppendRetvals(reply) << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { - return dbus_traits<A1>::getSignature() + - DBusResult8<A2, A3, A4, A5, A6, A7, A8, A9>::getSignature(); - } - - static const bool asynchronous = - dbus_traits<A1>::asynchronous || - DBusResult8<A2, A3, A4, A5, A6, A7, A8, A9>::asynchronous; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9, typename A10> -class DBusResult10 : - public Result10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>, - public DBusResult -{ - public: - DBusResult10(DBusConnection *conn, - DBusMessage *msg) : - DBusResult(conn, msg) - {} - - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - { - DBusMessagePtr reply(b_dbus_create_reply(m_msg.get(), DBUS_TYPE_INVALID)); - if (!reply) { - throw std::runtime_error("no DBusMessage"); - } - AppendRetvals(reply) << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9 << a10; - if (!dbus_connection_send(m_conn.get(), reply.get(), NULL)) { - throw std::runtime_error("dbus_connection_send failed"); - } - } - - static std::string getSignature() { - return dbus_traits<A1>::getSignature() + - DBusResult9<A2, A3, A4, A5, A6, A7, A8, A9, A10>::getSignature(); - } - - static const bool asynchronous = - dbus_traits<A1>::asynchronous || - DBusResult9<A2, A3, A4, A5, A6, A7, A8, A9, A10>::asynchronous; -}; - -/** - * A parameter which points towards one of our Result* structures. - * All of the types contained in it count towards the Reply signature. - * The requested Result type itself is constructed here. - * - * @param R Result0, Result1<type>, ... - * @param DBusR the class implementing R - */ -template <class R, class DBusR> struct dbus_traits_result -{ - static std::string getType() { return DBusR::getSignature(); } - static std::string getSignature() { return ""; } - static std::string getReply() { return getType(); } - - typedef boost::shared_ptr<R> host_type; - typedef boost::shared_ptr<R> &arg_type; - static const bool asynchronous = true; - - static void get(DBusConnection *conn, DBusMessage *msg, - DBusMessageIter &iter, host_type &value) - { - value.reset(new DBusR(conn, msg)); - } -}; - -template <> -struct dbus_traits< boost::shared_ptr<Result0> > : - public dbus_traits_result<Result0, DBusResult0> -{}; -template <class A1> -struct dbus_traits< boost::shared_ptr< Result1<A1> > >: - public dbus_traits_result< Result1<A1>, DBusResult1<A1> > -{}; -template <class A1, class A2> -struct dbus_traits< boost::shared_ptr< Result2<A1, A2> > >: - public dbus_traits_result< Result2<A1, A2>, DBusResult2<A1, A2> > -{}; -template <class A1, class A2, class A3> - struct dbus_traits< boost::shared_ptr< Result3<A1, A2, A3> > >: - public dbus_traits_result< Result3<A1, A2, A3>, DBusResult3<A1, A2, A3> > -{}; -template <class A1, class A2, class A3, class A4> - struct dbus_traits< boost::shared_ptr< Result4<A1, A2, A3, A4> > >: - public dbus_traits_result< Result4<A1, A2, A3, A4>, DBusResult4<A1, A2, A3, A4> > -{}; -template <class A1, class A2, class A3, class A4, class A5> - struct dbus_traits< boost::shared_ptr< Result5<A1, A2, A3, A4, A5> > >: - public dbus_traits_result< Result5<A1, A2, A3, A4, A5>, DBusResult5<A1, A2, A3, A4, A5> > -{}; -template <class A1, class A2, class A3, class A4, class A5, class A6> - struct dbus_traits< boost::shared_ptr< Result6<A1, A2, A3, A4, A5, A6> > >: - public dbus_traits_result< Result6<A1, A2, A3, A4, A5, A6>, DBusResult6<A1, A2, A3, A4, A5, A6> > -{}; -template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> - struct dbus_traits< boost::shared_ptr< Result7<A1, A2, A3, A4, A5, A6, A7> > >: - public dbus_traits_result< Result7<A1, A2, A3, A4, A5, A6, A7>, DBusResult7<A1, A2, A3, A4, A5, A6, A7> > -{}; -template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> - struct dbus_traits< boost::shared_ptr< Result8<A1, A2, A3, A4, A5, A6, A7, A8> > >: - public dbus_traits_result< Result8<A1, A2, A3, A4, A5, A6, A7, A8>, DBusResult8<A1, A2, A3, A4, A5, A6, A7, A8> > -{}; -template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> - struct dbus_traits< boost::shared_ptr< Result9<A1, A2, A3, A4, A5, A6, A7, A8, A9> > >: - public dbus_traits_result< Result9<A1, A2, A3, A4, A5, A6, A7, A8, A9>, DBusResult9<A1, A2, A3, A4, A5, A6, A7, A8, A9> > -{}; -template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> - struct dbus_traits< boost::shared_ptr< Result10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> > >: - 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> > -{}; - - -#if 0 -/** - * Call with two parameters and one return code. All other calls are - * variations of this, so this one is fully documented to explain all - * tricks used in these templates. The actual code without comments is - * below. - */ -template <class R, class A1, class A2> -struct MakeMethodEntry< boost::function<R (A1, A2)> > -{ - typedef boost::function<R (A1, A2)> M; - - // Any type a Result parameter? This can be computed at compile time. - static const bool asynchronous = dbus_traits< DBusResult2<A1, A2> >::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - // all exceptions must be caught and translated into - // a suitable D-Bus reply - try { - // Argument types might may be references or pointers. - // To instantiate a variable we need the underlying - // datatype, which is provided by the dbus_traits. - // "typename" is necessary to tell the compiler - // that host_type really is a type. - typename dbus_traits<R>::host_type r; - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - - // Extract all parameters. Because we don't now - // whether a parameter is an argument or a return - // value, we call get() for each of them and let - // the corresponding dbus_traits decide that. Traits - // for types which are plain types or const references - // have a non-empty get(), whereas references are treated - // as return values and have an empty get(). - DBusMessageIter iter; - dbus_message_iter_init(msg, &iter); - dbus_traits<A1>::get(conn, msg, iter, a1); - dbus_traits<A2>::get(conn, msg, iter, a2); - - // The data pointer is a pointer to a boost function, - // as set up for us by make(). The compiler knows the - // exact method prototype and thus can handle - // call-by-value and call-by-reference correctly. - r = (*static_cast<M *>(data))(a1, a2); - - // No reply necessary? If any of the types is asking for - // a Result handle, then the reply will be sent later. - if (asynchronous) { - return NULL; - } - - // Now prepare the reply. As with extracting parameters, - // append() is empty for those parameters where nothing - // has to be done. - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - dbus_message_iter_init_append(reply, &iter); - // We know that the return value has to be appended, - // even though the trait would not normally do that - // because it is a plain type => call utility function - // directly. - dbus_traits<R>::append(iter, r); - dbus_traits<A1>::append(iter, a1); - dbus_traits<A2>::append(iter, a2); - return reply; - } catch (...) { - // let handleException rethrow the exception - // to determine its type - return handleException(msg); - } - } - - /** - * The boost function doesn't have a virtual destructor. - * Therefore we have to cast down to the right type M - * before deleting it. The rest of the allocated data - * is freed by BDBusVector. - */ - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - /** - * Creates a BDBusMethodTable entry. - * The strings inside the entry are allocated - * with strdup(), to be freed by BDBusVector::destroy(). - */ - BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - // same trick as before: only argument types - // are added to the signature - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - entry.signature = strdup(buffer.c_str()); - // now the same for reply types - buffer.clear(); - buffer += dbus_traits<R>::getType(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - entry.reply = strdup(buffer.c_str()); - // these are the function templates above - entry.function = methodFunction; - entry.destroy = destroyFunction; - // make sure that methodFunction has access to the boost function - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; -#endif // 0 - -/** ===> 10 parameters */ -template <class A1, class A2, class A3, class A4, class A5, - class A6, class A7, class A8, class A9, class A10> -struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> > -{ - typedef void (Mptr)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); - typedef boost::function<Mptr> M; - - template <class I, class C> static M bind(Mptr C::*method, I instance) { - // this fails because bind() only supports up to 9 parameters, including - // the initial this pointer - return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8, _9 /* _10 */); - } - - static const bool asynchronous = dbus_traits< DBusResult10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> >::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - typename dbus_traits<A6>::host_type a6; - typename dbus_traits<A7>::host_type a7; - typename dbus_traits<A8>::host_type a8; - typename dbus_traits<A9>::host_type a9; - typename dbus_traits<A10>::host_type a10; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5) >> Get<A6>(a6) >> Get<A7>(a7) >> Get<A8>(a8) >> Get<A9>(a9) >> Get<A10>(a10); - - (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5) << Set<A6>(a6) << Set<A7>(a7) << Set<A8>(a8) << Set<A9>(a9) << Set<A10>(a10); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - buffer += dbus_traits<A6>::getSignature(); - buffer += dbus_traits<A7>::getSignature(); - buffer += dbus_traits<A8>::getSignature(); - buffer += dbus_traits<A9>::getSignature(); - buffer += dbus_traits<A10>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - buffer += dbus_traits<A6>::getReply(); - buffer += dbus_traits<A7>::getReply(); - buffer += dbus_traits<A8>::getReply(); - buffer += dbus_traits<A9>::getReply(); - buffer += dbus_traits<A10>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** 9 arguments, 1 return value */ -template <class R, - class A1, class A2, class A3, class A4, class A5, - class A6, class A7, class A8, class A9> -struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4, A5, A6, A7, A8, A9)> > -{ - typedef R (Mptr)(A1, A2, A3, A4, A5, A6, A7, A8, A9); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - // this fails because bind() only supports up to 9 parameters, including - // the initial this pointer - return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8, _9); - } - - static const bool asynchronous = DBusResult9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<R>::host_type r; - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - typename dbus_traits<A6>::host_type a6; - typename dbus_traits<A7>::host_type a7; - typename dbus_traits<A8>::host_type a8; - typename dbus_traits<A9>::host_type a9; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5) >> Get<A6>(a6) >> Get<A7>(a7) >> Get<A8>(a8) >> Get<A9>(a9); - - r = (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7, a8, a9); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) + r << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5) << Set<A6>(a6) << Set<A7>(a7) << Set<A8>(a8) << Set<A9>(a9); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - buffer += dbus_traits<A6>::getSignature(); - buffer += dbus_traits<A7>::getSignature(); - buffer += dbus_traits<A8>::getSignature(); - buffer += dbus_traits<A9>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<R>::getType(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - buffer += dbus_traits<A6>::getReply(); - buffer += dbus_traits<A7>::getReply(); - buffer += dbus_traits<A8>::getReply(); - buffer += dbus_traits<A9>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** ===> 9 parameters */ -template <class A1, class A2, class A3, class A4, class A5, - class A6, class A7, class A8, class A9> -struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5, A6, A7, A8, A9)> > -{ - typedef void (Mptr)(A1, A2, A3, A4, A5, A6, A7, A8, A9); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8, _9); - } - - static const bool asynchronous = DBusResult9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - typename dbus_traits<A6>::host_type a6; - typename dbus_traits<A7>::host_type a7; - typename dbus_traits<A8>::host_type a8; - typename dbus_traits<A9>::host_type a9; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5) >> Get<A6>(a6) >> Get<A7>(a7) >> Get<A8>(a8) >> Get<A9>(a9); - - (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7, a8, a9); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5) << Set<A6>(a6) << Set<A7>(a7) << Set<A8>(a8) << Set<A9>(a9); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - buffer += dbus_traits<A6>::getSignature(); - buffer += dbus_traits<A7>::getSignature(); - buffer += dbus_traits<A8>::getSignature(); - buffer += dbus_traits<A9>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - buffer += dbus_traits<A6>::getReply(); - buffer += dbus_traits<A7>::getReply(); - buffer += dbus_traits<A8>::getReply(); - buffer += dbus_traits<A9>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** 8 arguments, 1 return value */ -template <class R, - class A1, class A2, class A3, class A4, class A5, - class A6, class A7, class A8> -struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4, A5, A6, A7, A8)> > -{ - typedef R (Mptr)(A1, A2, A3, A4, A5, A6, A7, A8); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8); - } - - static const bool asynchronous = DBusResult8<A1, A2, A3, A4, A5, A6, A7, A8>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<R>::host_type r; - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - typename dbus_traits<A6>::host_type a6; - typename dbus_traits<A7>::host_type a7; - typename dbus_traits<A8>::host_type a8; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5) >> Get<A6>(a6) >> Get<A7>(a7) >> Get<A8>(a8); - - r = (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7, a8); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) + r << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5) << Set<A6>(a6) << Set<A7>(a7) << Set<A8>(a8); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - buffer += dbus_traits<A6>::getSignature(); - buffer += dbus_traits<A7>::getSignature(); - buffer += dbus_traits<A8>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<R>::getType(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - buffer += dbus_traits<A6>::getReply(); - buffer += dbus_traits<A7>::getReply(); - buffer += dbus_traits<A8>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** ===> 8 parameters */ -template <class A1, class A2, class A3, class A4, class A5, - class A6, class A7, class A8> -struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5, A6, A7, A8)> > -{ - typedef void (Mptr)(A1, A2, A3, A4, A5, A6, A7, A8); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7, _8); - } - - static const bool asynchronous = DBusResult8<A1, A2, A3, A4, A5, A6, A7, A8>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - typename dbus_traits<A6>::host_type a6; - typename dbus_traits<A7>::host_type a7; - typename dbus_traits<A8>::host_type a8; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5) >> Get<A6>(a6) >> Get<A7>(a7) >> Get<A8>(a8); - - (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7, a8); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5) << Set<A6>(a6) << Set<A7>(a7) << Set<A8>(a8); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - buffer += dbus_traits<A6>::getSignature(); - buffer += dbus_traits<A7>::getSignature(); - buffer += dbus_traits<A8>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - buffer += dbus_traits<A6>::getReply(); - buffer += dbus_traits<A7>::getReply(); - buffer += dbus_traits<A8>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** 7 arguments, 1 return value */ -template <class R, - class A1, class A2, class A3, class A4, class A5, - class A6, class A7> -struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4, A5, A6, A7)> > -{ - typedef R (Mptr)(A1, A2, A3, A4, A5, A6, A7); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7); - } - - static const bool asynchronous = DBusResult7<A1, A2, A3, A4, A5, A6, A7>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<R>::host_type r; - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - typename dbus_traits<A6>::host_type a6; - typename dbus_traits<A7>::host_type a7; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5) >> Get<A6>(a6) >> Get<A7>(a7); - - r = (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) + r << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5) << Set<A6>(a6) << Set<A7>(a7); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - buffer += dbus_traits<A6>::getSignature(); - buffer += dbus_traits<A7>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<R>::getType(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - buffer += dbus_traits<A6>::getReply(); - buffer += dbus_traits<A7>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** ===> 7 parameters */ -template <class A1, class A2, class A3, class A4, class A5, - class A6, class A7> -struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5, A6, A7)> > -{ - typedef void (Mptr)(A1, A2, A3, A4, A5, A6, A7); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4, _5, _6, _7); - } - - static const bool asynchronous = DBusResult7<A1, A2, A3, A4, A5, A6, A7>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - typename dbus_traits<A6>::host_type a6; - typename dbus_traits<A7>::host_type a7; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5) >> Get<A6>(a6) >> Get<A7>(a7); - - (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6, a7); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5) << Set<A6>(a6) << Set<A7>(a7); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - buffer += dbus_traits<A6>::getSignature(); - buffer += dbus_traits<A7>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - buffer += dbus_traits<A6>::getReply(); - buffer += dbus_traits<A7>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** 6 arguments, 1 return value */ -template <class R, - class A1, class A2, class A3, class A4, class A5, - class A6> -struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4, A5, A6)> > -{ - typedef R (Mptr)(A1, A2, A3, A4, A5, A6); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4, _5, _6); - } - - static const bool asynchronous = DBusResult6<A1, A2, A3, A4, A5, A6>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<R>::host_type r; - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - typename dbus_traits<A6>::host_type a6; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5) >> Get<A6>(a6); - - r = (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) + r << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5) << Set<A6>(a6); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - buffer += dbus_traits<A6>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<R>::getType(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - buffer += dbus_traits<A6>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** ===> 6 parameters */ -template <class A1, class A2, class A3, class A4, class A5, - class A6> -struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5, A6)> > -{ - typedef void (Mptr)(A1, A2, A3, A4, A5, A6); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4, _5, _6); - } - - static const bool asynchronous = DBusResult6<A1, A2, A3, A4, A5, A6>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - typename dbus_traits<A6>::host_type a6; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5) >> Get<A6>(a6); - - (*static_cast<M *>(data))(a1, a2, a3, a4, a5, a6); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5) << Set<A6>(a6); - - return reply; - } catch (...) { - return handleException(msg); - } - } - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - buffer += dbus_traits<A6>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - buffer += dbus_traits<A6>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** 5 arguments, 1 return value */ -template <class R, - class A1, class A2, class A3, class A4, class A5> -struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4, A5)> > -{ - typedef R (Mptr)(A1, A2, A3, A4, A5); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4, _5); - } - - static const bool asynchronous = DBusResult5<A1, A2, A3, A4, A5>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<R>::host_type r; - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5); - - r = (*static_cast<M *>(data))(a1, a2, a3, a4, a5); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) + r << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<R>::getType(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** ===> 5 parameters */ -template <class A1, class A2, class A3, class A4, class A5> -struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4, A5)> > -{ - typedef void (Mptr)(A1, A2, A3, A4, A5); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4, _5); - } - - static const bool asynchronous = DBusResult5<A1, A2, A3, A4, A5>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4) >> Get<A5>(a5); - - (*static_cast<M *>(data))(a1, a2, a3, a4, a5); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4) << Set<A5>(a5); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - buffer += dbus_traits<A5>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - buffer += dbus_traits<A5>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** 4 arguments, 1 return value */ -template <class R, - class A1, class A2, class A3, class A4> -struct MakeMethodEntry< boost::function<R (A1, A2, A3, A4)> > -{ - typedef R (Mptr)(A1, A2, A3, A4); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4); - } - - static const bool asynchronous = DBusResult4<A1, A2, A3, A4>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<R>::host_type r; - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4); - - r = (*static_cast<M *>(data))(a1, a2, a3, a4); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) + r << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<R>::getType(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** ===> 4 parameters */ -template <class A1, class A2, class A3, class A4> -struct MakeMethodEntry< boost::function<void (A1, A2, A3, A4)> > -{ - typedef void (Mptr)(A1, A2, A3, A4); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3, _4); - } - - static const bool asynchronous = DBusResult4<A1, A2, A3, A4>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3) >> Get<A4>(a4); - - (*static_cast<M *>(data))(a1, a2, a3, a4); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3) << Set<A4>(a4); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - buffer += dbus_traits<A4>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - buffer += dbus_traits<A4>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** 3 arguments, 1 return value */ -template <class R, - class A1, class A2, class A3> -struct MakeMethodEntry< boost::function<R (A1, A2, A3)> > -{ - typedef R (Mptr)(A1, A2, A3); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3); - } - - static const bool asynchronous = DBusResult3<A1, A2, A3>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<R>::host_type r; - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3); - - r = (*static_cast<M *>(data))(a1, a2, a3); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) + r << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<R>::getType(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** ===> 3 parameters */ -template <class A1, class A2, class A3> -struct MakeMethodEntry< boost::function<void (A1, A2, A3)> > -{ - typedef void (Mptr)(A1, A2, A3); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2, _3); - } - - static const bool asynchronous = DBusResult3<A1, A2, A3>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2) >> Get<A3>(a3); - - (*static_cast<M *>(data))(a1, a2, a3); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) << Set<A1>(a1) << Set<A2>(a2) << Set<A3>(a3); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - buffer += dbus_traits<A3>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - buffer += dbus_traits<A3>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** 2 arguments, 1 return value */ -template <class R, - class A1, class A2> -struct MakeMethodEntry< boost::function<R (A1, A2)> > -{ - typedef R (Mptr)(A1, A2); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2); - } - - static const bool asynchronous = DBusResult2<A1, A2>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<R>::host_type r; - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2); - - r = (*static_cast<M *>(data))(a1, a2); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) + r << Set<A1>(a1) << Set<A2>(a2); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<R>::getType(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** ===> 2 parameters */ -template <class A1, class A2> -struct MakeMethodEntry< boost::function<void (A1, A2)> > -{ - typedef void (Mptr)(A1, A2); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1, _2); - } - - static const bool asynchronous = DBusResult2<A1, A2>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - - ExtractArgs(conn, msg) >> Get<A1>(a1) >> Get<A2>(a2); - - (*static_cast<M *>(data))(a1, a2); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) << Set<A1>(a1) << Set<A2>(a2); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - buffer += dbus_traits<A2>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<A1>::getReply(); - buffer += dbus_traits<A2>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** 1 argument, 1 return value */ -template <class R, - class A1> -struct MakeMethodEntry< boost::function<R (A1)> > -{ - typedef R (Mptr)(A1); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1); - } - - static const bool asynchronous = DBusResult1<A1>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<R>::host_type r; - typename dbus_traits<A1>::host_type a1; - - ExtractArgs(conn, msg) >> Get<A1>(a1); - - r = (*static_cast<M *>(data))(a1); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) + r << Set<A1>(a1); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<R>::getType(); - buffer += dbus_traits<A1>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** ===> 1 parameter */ -template <class A1> -struct MakeMethodEntry< boost::function<void (A1)> > -{ - typedef void (Mptr)(A1); - typedef boost::function<void (A1)> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance, _1); - } - - static const bool asynchronous = DBusResult1<A1>::asynchronous; - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<A1>::host_type a1; - - ExtractArgs(conn, msg) >> Get<A1>(a1); - - (*static_cast<M *>(data))(a1); - - if (asynchronous) { - return NULL; - } - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) << Set<A1>(a1); - - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - buffer += dbus_traits<A1>::getSignature(); - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<A1>::getReply(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA | - (asynchronous ? G_DBUS_METHOD_FLAG_ASYNC : 0)); - entry.method_data = new M(m); - return entry; - } -}; - -/** 0 arguments, 1 return value */ -template <class R> -struct MakeMethodEntry< boost::function<R ()> > -{ - typedef R (Mptr)(); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance); - } - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - typename dbus_traits<R>::host_type r; - - r = (*static_cast<M *>(data))(); - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - - AppendArgs(reply) + r; - - return reply; - } catch (...) { - return handleException(msg); - } - } - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - buffer += dbus_traits<R>::getType(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA); - entry.method_data = new M(m); - return entry; - } -}; - -/** ===> 0 parameter */ -template <> -struct MakeMethodEntry< boost::function<void ()> > -{ - typedef void (Mptr)(); - typedef boost::function<Mptr> M; - - template <class I, class C> static M boostptr(Mptr C::*method, I instance) { - return boost::bind(method, instance); - } - - static DBusMessage *methodFunction(DBusConnection *conn, - DBusMessage *msg, void *data) - { - try { - (*static_cast<M *>(data))(); - - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - return reply; - } catch (...) { - return handleException(msg); - } - } - - static void destroyFunction(void *user_data) - { - BDBusMethodTable *entry = static_cast<BDBusMethodTable *>(user_data); - delete static_cast<M *>(entry->method_data); - } - - static BDBusMethodTable make(const char *name, BDBusMethodFlags flags, const M &m) - { - BDBusMethodTable entry; - entry.name = strdup(name); - std::string buffer; - entry.signature = strdup(buffer.c_str()); - buffer.clear(); - entry.reply = strdup(buffer.c_str()); - entry.function = methodFunction; - entry.destroy = destroyFunction; - entry.flags = BDBusMethodFlags(flags | G_DBUS_METHOD_FLAG_METHOD_DATA); - entry.method_data = new M(m); - return entry; - } -}; - -template <class Cb, class Ret> -struct TraitsBase -{ - typedef Cb Callback_t; - typedef Ret Return_t; - - struct CallbackData - { - //only keep connection, for DBusClientCall instance is absent when 'dbus client call' returns - //suppose connection is available in the callback handler - const DBusConnectionPtr m_conn; - Callback_t m_callback; - CallbackData(const DBusConnectionPtr &conn, const Callback_t &callback) - : m_conn(conn), m_callback(callback) - {} - }; -}; - -struct VoidReturn {}; - -struct VoidTraits : public TraitsBase<boost::function<void (const std::string &)>, VoidReturn> -{ - typedef TraitsBase<boost::function<void (const std::string &)>, VoidReturn> base; - typedef base::Callback_t Callback_t; - typedef base::Return_t Return_t; - - static Return_t demarshal(DBusMessagePtr &/*reply*/, const DBusConnectionPtr &/*conn*/) - { - return Return_t(); - } - - static void handleMessage(DBusMessagePtr &/*reply*/, base::CallbackData *data, const std::string &error) - { - //unmarshal the return results and call user callback - if (data->m_callback) { - data->m_callback(error); - } - } -}; - -template <class R1> -struct Ret1Traits : public TraitsBase<boost::function<void (const R1 &, const std::string &)>, R1> -{ - typedef TraitsBase<boost::function<void (const R1 &, const std::string &)>, R1> base; - typedef typename base::Callback_t Callback_t; - typedef typename base::Return_t Return_t; - - static Return_t demarshal(DBusMessagePtr &reply, const DBusConnectionPtr &conn) - { - typename dbus_traits<R1>::host_type r; - - ExtractArgs(conn.get(), reply.get()) >> Get<R1>(r); - return r; - } - - static void handleMessage(DBusMessagePtr &reply, typename base::CallbackData *data, const std::string &error) - { - typename dbus_traits<R1>::host_type r; - if (error.empty()) { - ExtractArgs(data->m_conn.get(), reply.get()) >> Get<R1>(r); - } - - //unmarshal the return results and call user callback - if (data->m_callback) { - data->m_callback(r, error); - } - } -}; - -template <class R1, class R2> -struct Ret2Traits : public TraitsBase<boost::function<void (const R1 &, const R2 &, const std::string &)>, std::pair<R1, R2> > -{ - typedef TraitsBase<boost::function<void (const R1 &, const R2 &, const std::string &)>, std::pair<R1, R2> > base; - typedef typename base::Callback_t Callback_t; - typedef typename base::Return_t Return_t; - - static Return_t demarshal(DBusMessagePtr &reply, const DBusConnectionPtr &conn) - { - Return_t r; - - ExtractArgs(conn.get(), reply.get()) >> Get<R1>(r.first) >> Get<R2>(r.second); - return r; - } - - static void handleMessage(DBusMessagePtr &reply, typename base::CallbackData *data, const std::string &error) - { - typename dbus_traits<R1>::host_type r1; - typename dbus_traits<R2>::host_type r2; - if (error.empty()) { - ExtractArgs(data->m_conn.get(), reply.get()) >> Get<R1>(r1) >> Get<R2>(r2); - } - - //unmarshal the return results and call user callback - if (data->m_callback) { - data->m_callback(r1, r2, error); - } - } -}; - -template <class R1, class R2, class R3> -struct Ret3Traits : public TraitsBase<boost::function<void (const R1 &, const R2 &, const R3 &, const std::string &)>, boost::tuple<R1, R2, R3> > -{ - typedef TraitsBase<boost::function<void (const R1 &, const R2 &, const R3 &, const std::string &)>, boost::tuple<R1, R2, R3> > base; - typedef typename base::Callback_t Callback_t; - typedef typename base::Return_t Return_t; - - static Return_t demarshal(DBusMessagePtr &reply, const DBusConnectionPtr &conn) - { - Return_t r; - - ExtractArgs(conn.get(), reply.get()) >> Get<R1>(boost::get<0>(r)) >> Get<R2>(boost::get<1>(r)) >> Get<R3>(boost::get<2>(r)); - return r; - } - - static void handleMessage(DBusMessagePtr &reply, typename base::CallbackData *data, const std::string &error) - { - typename dbus_traits<R1>::host_type r1; - typename dbus_traits<R2>::host_type r2; - typename dbus_traits<R3>::host_type r3; - if (error.empty()) { - ExtractArgs(data->m_conn.get(), reply.get()) >> Get<R1>(r1) >> Get<R2>(r2) >> Get<R3>(r3); - } - - //unmarshal the return results and call user callback - if (data->m_callback) { - data->m_callback(r1, r2, r3, error); - } - } -}; - -/** fill buffer with error name and description (if available), return true if error found */ -bool CheckError(const DBusMessagePtr &reply, - std::string &buffer); - -template <class CallTraits> -class DBusClientCall -{ -public: - typedef typename CallTraits::Callback_t Callback_t; - typedef typename CallTraits::Return_t Return_t; - typedef typename CallTraits::base::CallbackData CallbackData; - -protected: - const std::string m_destination; - const std::string m_path; - const std::string m_interface; - const std::string m_method; - const DBusConnectionPtr m_conn; - - static void dbusCallback (DBusPendingCall *call, void *user_data) - { - CallbackData *data = static_cast<CallbackData *>(user_data); - DBusMessagePtr reply = dbus_pending_call_steal_reply (call); - std::string error; - - CheckError(reply, error); - CallTraits::handleMessage(reply, data, error); - } - - /** - * called by libdbus to free the user_data pointer set in - * dbus_pending_call_set_notify() - */ - static void callDataUnref(void *user_data) { - delete static_cast<CallbackData *>(user_data); - } - - void prepare(DBusMessagePtr &msg) - { - // Constructor steals reference, reset() doesn't! - // Therefore use constructor+copy instead of reset(). - msg = - DBusMessagePtr(dbus_message_new_method_call(m_destination.c_str(), - m_path.c_str(), - m_interface.c_str(), - m_method.c_str())); - if (!msg) { - throw std::runtime_error("dbus_message_new_method_call() failed"); - } - } - - void send(DBusMessagePtr &msg, const Callback_t &callback) - { - DBusPendingCall *call; - if (!dbus_connection_send_with_reply(m_conn.get(), msg.get(), &call, DBUS_TIMEOUT_INFINITE)) { - throw std::runtime_error("dbus_connection_send failed"); - } else if (call == NULL) { - throw std::runtime_error("received pending call is NULL"); - } - - - DBusPendingCallPtr mCall (call); - CallbackData *data = new CallbackData(m_conn, callback); - dbus_pending_call_set_notify(mCall.get(), - dbusCallback, - data, - callDataUnref); - } - - Return_t sendAndReturn(DBusMessagePtr &msg) - { - DBusErrorCXX error; - // Constructor steals reference, reset() doesn't! - // Therefore use constructor+copy instead of reset(). - DBusMessagePtr reply = DBusMessagePtr(dbus_connection_send_with_reply_and_block(m_conn.get(), msg.get(), DBUS_TIMEOUT_INFINITE, &error)); - if (!reply) { - error.throwFailure(m_method); - } - return CallTraits::demarshal(reply, m_conn); - } - - -public: - DBusClientCall(const DBusRemoteObject &object, const std::string &method) - :m_destination (object.getDestination()), - m_path (object.getPath()), - m_interface (object.getInterface()), - m_method (method), - m_conn (object.getConnection()) - { - } - - DBusConnection *getConnection() { return m_conn.get(); } - std::string getMethod() const { return m_method; } - - Return_t operator () () - { - DBusMessagePtr msg; - prepare(msg); - return sendAndReturn(msg); - } - - void start(const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - send(msg, callback); - } - - template <class A1> - Return_t operator () (const A1 &a1) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1; - return sendAndReturn(msg); - } - - template <class A1> - void start(const A1 &a1, const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1; - send(msg, callback); - } - - template <class A1, class A2> - Return_t operator () (const A1 &a1, const A2 &a2) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2; - return sendAndReturn(msg); - } - - template <class A1, class A2> - void start(const A1 &a1, const A2 &a2, const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2; - send(msg, callback); - } - - template <class A1, class A2, class A3> - void operator ()(const A1 &a1, const A2 &a2, const A3 &a3) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3; - sendAndReturn(msg); - } - - template <class A1, class A2, class A3> - void start(const A1 &a1, const A2 &a2, const A3 &a3, const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3; - send(msg, callback); - } - - template <class A1, class A2, class A3, class A4> - void operator () (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4; - sendAndReturn(msg); - } - - template <class A1, class A2, class A3, class A4> - void start(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4; - send(msg, callback); - } - - template <class A1, class A2, class A3, class A4, class A5> - void operator () (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5; - sendAndReturn(msg); - } - - template <class A1, class A2, class A3, class A4, class A5> - void start(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5; - send(msg, callback); - } - - template <class A1, class A2, class A3, class A4, class A5, class A6> - void operator () (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, - const A6 &a6) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6; - sendAndReturn(msg); - } - - template <class A1, class A2, class A3, class A4, class A5, class A6> - void start(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, - const A6 &a6, - const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6; - send(msg, callback); - } - - template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> - void operator () (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, - const A6 &a6, const A7 &a7) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6 << a7; - sendAndReturn(msg); - } - - template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> - void start(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, - const A6 &a6, const A7 &a7, - const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6 << a7; - send(msg, callback); - } - - template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> - void operator () (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, - const A6 &a6, const A7 &a7, const A8 &a8) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; - sendAndReturn(msg); - } - - template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> - void start(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, - const A6 &a6, const A7 &a7, const A8 &a8, - const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; - send(msg, callback); - } - - template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> - void operator () (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, - const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; - sendAndReturn(msg); - } - - template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> - void start(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, - const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, - const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; - send(msg, callback); - } - - template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> - void operator () (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, - const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, const A10 &a10) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9 << a10; - sendAndReturn(msg); - } - - template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> - void start(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, - const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, const A10 &a10, - const Callback_t &callback) - { - DBusMessagePtr msg; - prepare(msg); - AppendRetvals(msg) << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9 << a10; - send(msg, callback); - } -}; - -/* - * A DBus Client Call object handling zero or more parameter and - * zero return value. - */ -class DBusClientCall0 : public DBusClientCall<VoidTraits> -{ -public: - DBusClientCall0 (const DBusRemoteObject &object, const std::string &method) - : DBusClientCall<VoidTraits>(object, method) - { - } -}; - -/** 1 return value and 0 or more parameters */ -template <class R1> -class DBusClientCall1 : public DBusClientCall<Ret1Traits<R1> > -{ -public: - DBusClientCall1 (const DBusRemoteObject &object, const std::string &method) - : DBusClientCall<Ret1Traits<R1> >(object, method) - { - } -}; - -/** 2 return value and 0 or more parameters */ -template <class R1, class R2> -class DBusClientCall2 : public DBusClientCall<Ret2Traits<R1, R2> > -{ -public: - DBusClientCall2 (const DBusRemoteObject &object, const std::string &method) - : DBusClientCall<Ret2Traits<R1, R2> >(object, method) - { - } -}; - -/** 3 return value and 0 or more parameters */ -template <class R1, class R2, class R3> -class DBusClientCall3 : public DBusClientCall<Ret3Traits<R1, R2, R3> > -{ -public: - DBusClientCall3 (const DBusRemoteObject &object, const std::string &method) - : DBusClientCall<Ret3Traits<R1, R2, R3> >(object, method) - { - } -}; - -/** - * Common functionality of all SignalWatch* classes. - * @param T boost::function with the right signature - */ -template <class T> class SignalWatch -{ - public: - SignalWatch(const DBusRemoteObject &object, - const std::string &signal, bool is_bus_conn = true) - : m_object(object), m_signal(signal), m_tag(0), m_is_bus_conn(is_bus_conn) - { - } - - ~SignalWatch() - { - if (m_tag) { - DBusConnection *connection = m_object.getConnection(); - if (connection) { - b_dbus_remove_watch(connection, m_tag); - } - } - } - - typedef T Callback_t; - const Callback_t &getCallback() const{ return m_callback; } - - protected: - const DBusRemoteObject &m_object; - std::string m_signal; - guint m_tag; - T m_callback; - bool m_is_bus_conn; - - std::string makeSignalRule() { - std::string rule; - rule = "type='signal',path='"; - rule += m_object.getPath(); - rule += "',interface='"; - rule += m_object.getInterface(); - rule += "',member='"; - rule += m_signal; - rule += "'"; - return rule; - } - - static gboolean isMatched(DBusMessage *msg, void *data) { - SignalWatch *watch = static_cast<SignalWatch*>(data); - return dbus_message_has_path(msg, watch->m_object.getPath()) && - dbus_message_is_signal(msg, watch->m_object.getInterface(), watch->m_signal.c_str()); - } - - void activateInternal(const Callback_t &callback, - gboolean (*cb)(DBusConnection *, DBusMessage *, void *)) - { - m_callback = callback; - - std::string rule = makeSignalRule(); - m_tag = b_dbus_add_signal_watch(m_object.getConnection(), - rule.c_str(), - cb, - this, - NULL, - m_is_bus_conn); - - if (!m_tag) { - throw std::runtime_error(std::string("activating signal failed: ") + - "path " + m_object.getPath() + - " interface " + m_object.getInterface() + - " member " + m_signal); - } - } -}; - -class SignalWatch0 : public SignalWatch< boost::function<void (void)> > -{ - typedef boost::function<void (void)> Callback_t; - - public: - SignalWatch0(const DBusRemoteObject &object, - const std::string &signal, bool is_bus_conn = true) - : SignalWatch<Callback_t>(object, signal, is_bus_conn) - { - } - - static gboolean internalCallback(DBusConnection *conn, DBusMessage *msg, void *data) - { - if(isMatched(msg, data) == FALSE) { - return TRUE; - } - const Callback_t &cb = static_cast< SignalWatch<Callback_t> *>(data)->getCallback(); - cb(); - - return TRUE; - } - - void activate(const Callback_t &callback) { SignalWatch< boost::function<void (void)> >::activateInternal(callback, internalCallback); } -}; - -template <typename A1> -class SignalWatch1 : public SignalWatch< boost::function<void (const A1 &)> > -{ - typedef boost::function<void (const A1 &)> Callback_t; - - public: - SignalWatch1(const DBusRemoteObject &object, - const std::string &signal, bool is_bus_conn = true) - : SignalWatch<Callback_t>(object, signal, is_bus_conn) - { - } - - static gboolean internalCallback(DBusConnection *conn, DBusMessage *msg, void *data) - { - if (SignalWatch<Callback_t>::isMatched(msg, data) == FALSE) { - return TRUE; - } - const Callback_t &cb =static_cast< SignalWatch<Callback_t> *>(data)->getCallback(); - - typename dbus_traits<A1>::host_type a1; - - DBusMessageIter iter; - dbus_message_iter_init(msg, &iter); - dbus_traits<A1>::get(conn, msg, iter, a1); - cb(a1); - - return TRUE; - } - - void activate(const Callback_t &callback) { SignalWatch< boost::function<void (const A1 &)> >::activateInternal(callback, internalCallback); } -}; - -template <typename A1, typename A2> -class SignalWatch2 : public SignalWatch< boost::function<void (const A1 &, const A2 &)> > -{ - typedef boost::function<void (const A1 &, const A2 &)> Callback_t; - - public: - SignalWatch2(const DBusRemoteObject &object, - const std::string &signal, bool is_bus_conn = true) - : SignalWatch<Callback_t>(object, signal, is_bus_conn) - { - } - - static gboolean internalCallback(DBusConnection *conn, DBusMessage *msg, void *data) - { - if (SignalWatch<Callback_t>::isMatched(msg, data) == FALSE) { - return TRUE; - } - const Callback_t &cb = static_cast< SignalWatch<Callback_t> *>(data)->getCallback(); - - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - - DBusMessageIter iter; - dbus_message_iter_init(msg, &iter); - dbus_traits<A1>::get(conn, msg, iter, a1); - dbus_traits<A2>::get(conn, msg, iter, a2); - cb(a1, a2); - - return TRUE; - } - - void activate(const Callback_t &callback) { SignalWatch< boost::function<void (const A1 &, const A2 &)> >::activateInternal(callback, internalCallback); } -}; - -template <typename A1, typename A2, typename A3> -class SignalWatch3 : public SignalWatch< boost::function<void (const A1 &, const A2 &, const A3 &)> > -{ - typedef boost::function<void (const A1 &, const A2 &, const A3 &)> Callback_t; - - public: - SignalWatch3(const DBusRemoteObject &object, - const std::string &signal, bool is_bus_conn = true) - : SignalWatch<Callback_t>(object, signal, is_bus_conn) - { - } - - static gboolean internalCallback(DBusConnection *conn, DBusMessage *msg, void *data) - { - if (SignalWatch<Callback_t>::isMatched(msg, data) == FALSE) { - return TRUE; - } - const Callback_t &cb =static_cast< SignalWatch<Callback_t> *>(data)->getCallback(); - - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - - DBusMessageIter iter; - dbus_message_iter_init(msg, &iter); - dbus_traits<A1>::get(conn, msg, iter, a1); - dbus_traits<A2>::get(conn, msg, iter, a2); - dbus_traits<A3>::get(conn, msg, iter, a3); - cb(a1, a2, a3); - - return TRUE; - } - - void activate(const Callback_t &callback) { SignalWatch< boost::function<void (const A1 &, const A2 &, const A3 &)> >::activateInternal(callback, internalCallback); } -}; - -template <typename A1, typename A2, typename A3, typename A4> -class SignalWatch4 : public SignalWatch< boost::function<void (const A1 &, const A2 &, const A3 &, const A4 &)> > -{ - typedef boost::function<void (const A1 &, const A2 &, const A3 &, const A4 &)> Callback_t; - - public: - SignalWatch4(const DBusRemoteObject &object, - const std::string &signal, bool is_bus_conn = true) - : SignalWatch<Callback_t>(object, signal, is_bus_conn) - { - } - - static gboolean internalCallback(DBusConnection *conn, DBusMessage *msg, void *data) - { - if (SignalWatch<Callback_t>::isMatched(msg, data) == FALSE) { - return TRUE; - } - const Callback_t &cb = static_cast< SignalWatch<Callback_t> *>(data)->getCallback(); - - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - - DBusMessageIter iter; - dbus_message_iter_init(msg, &iter); - dbus_traits<A1>::get(conn, msg, iter, a1); - dbus_traits<A2>::get(conn, msg, iter, a2); - dbus_traits<A3>::get(conn, msg, iter, a3); - dbus_traits<A4>::get(conn, msg, iter, a4); - cb(a1, a2, a3, a4); - - return TRUE; - } - - void activate(const Callback_t &callback) { SignalWatch< boost::function<void (const A1 &, const A2 &, const A3 &, const A4 &)> >::activateInternal(callback, internalCallback); } -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5> -class SignalWatch5 : public SignalWatch< boost::function<void (const A1 &, const A2 &, const A3 &, const A4 &, const A5 &)> > -{ - typedef boost::function<void (const A1 &, const A2 &, const A3 &, const A4 &, const A5 &)> Callback_t; - - public: - SignalWatch5(const DBusRemoteObject &object, - const std::string &signal, bool is_bus_conn = true) - : SignalWatch<Callback_t>(object, signal, is_bus_conn) - { - } - - static gboolean internalCallback(DBusConnection *conn, DBusMessage *msg, void *data) - { - if (SignalWatch<Callback_t>::isMatched(msg, data) == FALSE) { - return TRUE; - } - const Callback_t &cb = static_cast< SignalWatch<Callback_t> *>(data)->getCallback(); - - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - - DBusMessageIter iter; - dbus_message_iter_init(msg, &iter); - dbus_traits<A1>::get(conn, msg, iter, a1); - dbus_traits<A2>::get(conn, msg, iter, a2); - dbus_traits<A3>::get(conn, msg, iter, a3); - dbus_traits<A4>::get(conn, msg, iter, a4); - dbus_traits<A5>::get(conn, msg, iter, a5); - cb(a1, a2, a3, a4, a5); - - return TRUE; - } - - void activate(const Callback_t &callback) { SignalWatch< boost::function<void (const A1 &, const A2 &, const A3 &, const A4 &, const A5 &)> >::activateInternal(callback, internalCallback); } -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> -class SignalWatch6 : public SignalWatch< boost::function<void (const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &)> > -{ - typedef boost::function<void (const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &)> Callback_t; - - - public: - SignalWatch6(const DBusRemoteObject &object, - const std::string &signal, bool is_bus_conn = true) - : SignalWatch<Callback_t>(object, signal, is_bus_conn) - { - } - - static gboolean internalCallback(DBusConnection *conn, DBusMessage *msg, void *data) - { - if (SignalWatch<Callback_t>::isMatched(msg, data) == FALSE) { - return TRUE; - } - const Callback_t &cb = static_cast< SignalWatch<Callback_t> *>(data)->getCallback(); - - typename dbus_traits<A1>::host_type a1; - typename dbus_traits<A2>::host_type a2; - typename dbus_traits<A3>::host_type a3; - typename dbus_traits<A4>::host_type a4; - typename dbus_traits<A5>::host_type a5; - typename dbus_traits<A6>::host_type a6; - - DBusMessageIter iter; - dbus_message_iter_init(msg, &iter); - dbus_traits<A1>::get(conn, msg, iter, a1); - dbus_traits<A2>::get(conn, msg, iter, a2); - dbus_traits<A3>::get(conn, msg, iter, a3); - dbus_traits<A4>::get(conn, msg, iter, a4); - dbus_traits<A5>::get(conn, msg, iter, a5); - dbus_traits<A6>::get(conn, msg, iter, a6); - cb(a1, a2, a3, a4, a5, a6); - - return TRUE; - } - - void activate(const Callback_t &callback) { SignalWatch< boost::function<void (const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &)> >::activateInternal(callback, internalCallback); } -}; - -} // namespace GDBusCXX - -#endif // INCL_BDBUS_CXX_BRIDGE diff --git a/src/gdbus/gdbus-cxx.h b/src/gdbus/gdbus-cxx.h deleted file mode 100644 index 7af2cdc4..00000000 --- a/src/gdbus/gdbus-cxx.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2009 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef INCL_BDBUS_CXX -#define INCL_BDBUS_CXX - -#include <string> -#include <stdexcept> -#include <boost/function.hpp> -#include <boost/noncopyable.hpp> - -namespace GDBusCXX { - -/** - * An exception class which can be thrown to create - * specific D-Bus exception on the bus. - */ -class dbus_error : public std::runtime_error -{ -public: - /** - * @param dbus_name the D-Bus error name, like "org.example.error.Invalid" - * @param what a more detailed description - */ - dbus_error(const std::string &dbus_name, const std::string &what) : - std::runtime_error(what), - m_dbus_name(dbus_name) - {} - ~dbus_error() throw() {} - - const std::string &dbusName() const { return m_dbus_name; } - -private: - std::string m_dbus_name; -}; - -class Watch; - -/** - * Special parameter type that identifies a caller. A string in practice. - */ -class Caller_t : public std::string -{ - public: - Caller_t() {} - template <class T> Caller_t(T val) : std::string(val) {} - template <class T> Caller_t &operator = (T val) { assign(val); return *this; } -}; - -/** - * Call object which needs to be called with the results - * of an asynchronous method call. So instead of - * "int foo()" one would implement - * "void foo(Result1<int> > *r)" - * and after foo has returned, call r->done(res). Use const - * references as type for complex results. - * - * A Result instance can be copied, but only called once. - */ -class Result -{ - public: - virtual ~Result() {} - - /** report failure to caller */ - virtual void failed(const dbus_error &error) = 0; - - /** - * Calls the given callback once when the peer that the result - * would be delivered to disconnects. The callback will also be - * called if the peer is already gone by the time that the watch - * is requested. - * - * Alternatively a method can ask to get called with a life Watch - * by specifying "const boost::shared_ptr<Watch> &" as parameter - * and then calling its setCallback(). - */ - virtual Watch *createWatch(const boost::function<void (void)> &callback) = 0; - }; - -class Result0 : virtual public Result -{ - public: - /** tell caller that we are done */ - virtual void done() = 0; -}; - -template <typename A1> -class Result1 : virtual public Result -{ - public: - /** return result to caller */ - virtual void done(A1 a1) = 0; -}; - -template <typename A1, typename A2> -struct Result2 : virtual public Result -{ - virtual void done(A1 a1, A2 a2) = 0; -}; - -template <typename A1, typename A2, typename A3> -struct Result3 : virtual public Result -{ - virtual void done(A1 a1, A2 a2, A3 a3) = 0; -}; - -template <typename A1, typename A2, typename A3, typename A4> -struct Result4 : virtual public Result -{ - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4) = 0; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5> -struct Result5 : virtual public Result -{ - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) = 0; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6> -struct Result6 : virtual public Result -{ - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) = 0; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7> -struct Result7 : virtual public Result -{ - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) = 0; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8> -struct Result8 : virtual public Result -{ - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) = 0; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9> -struct Result9 : virtual public Result -{ - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) = 0; -}; - -template <typename A1, typename A2, typename A3, typename A4, typename A5, - typename A6, typename A7, typename A8, typename A9, typename A10> -struct Result10 : virtual public Result -{ - virtual void done(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) = 0; -}; - -} // namespace GDBusCXX - -#endif // INCL_BDBUS_CXX diff --git a/src/gdbus/gdbus.am b/src/gdbus/gdbus.am deleted file mode 100644 index 23568c9b..00000000 --- a/src/gdbus/gdbus.am +++ /dev/null @@ -1,34 +0,0 @@ -# include_HEADERS = src/gdbus/gdbus.h - -dist_noinst_DATA += \ - src/gdbus/README - -if ENABLE_MODULES -lib_LTLIBRARIES += src/gdbus/libgdbussyncevo.la -src_gdbus_version_info = -version-info 0:0:0 -else -noinst_LTLIBRARIES += src/gdbus/libgdbussyncevo.la -endif - -src_gdbus_libgdbussyncevo_la_SOURCES = \ - src/gdbus/debug.h \ - src/gdbus/debug.c \ - src/gdbus/mainloop.c \ - src/gdbus/object.c \ - src/gdbus/watch.c \ - src/gdbus/gdbus.h \ - src/gdbus/gdbus-cxx-bridge.h \ - src/gdbus/gdbus-cxx-bridge.cpp \ - src/gdbus/gdbus-cxx.h -src_gdbus_libgdbussyncevo_la_LDFLAGS = $(src_gdbus_version_info) -export-symbols-regex b_dbus_.* -src_gdbus_libgdbussyncevo_la_LIBADD = @GLIB_LIBS@ @DBUS_LIBS@ -src_gdbus_libgdbussyncevo_la_CFLAGS = @GLIB_CFLAGS@ @DBUS_CFLAGS@ $(SYNCEVO_WFLAGS) -src_gdbus_libgdbussyncevo_la_CXXFLAGS = @GLIB_CFLAGS@ @DBUS_CFLAGS@ $(SYNCEVO_WFLAGS) -src_gdbus_libgdbussyncevo_la_CPPFLAGS = $(BOOST_CPPFLAGS) - -# include_HEADERS = src/gdbus/gdbus-cxx-bridge.h src/gdbus/gdbus-cxx.h -noinst_PROGRAMS += src/gdbus/example -src_gdbus_example_SOURCES = src/gdbus/test/example.cpp -src_gdbus_example_CXXFLAGS = @GLIB_CFLAGS@ @DBUS_CFLAGS@ $(SYNCEVO_WFLAGS) -src_gdbus_example_LDADD = src/gdbus/libgdbussyncevo.la @GLIB_LIBS@ @DBUS_LIBS@ -src_gdbus_example_CPPFLAGS = -I$(top_srcdir)/src/gdbus $(BOOST_CPPFLAGS) diff --git a/src/gdbus/gdbus.h b/src/gdbus/gdbus.h deleted file mode 100644 index c082086e..00000000 --- a/src/gdbus/gdbus.h +++ /dev/null @@ -1,298 +0,0 @@ -/* - * - * Library for simple D-Bus integration with GLib - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __BDBUS_H -#define __BDBUS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdarg.h> -#include <stdint.h> - -#include <dbus/dbus.h> -#include <glib.h> - -/** - * SECTION:gdbus - * @title: D-Bus helper library - * @short_description: Library for simple D-Bus integration with GLib - */ - -/** - * BDBusDestroyFunction: - * @user_data: user data to pass to the function - * - * Destroy function - */ -typedef void (* BDBusDestroyFunction) (void *user_data); - -/** - * BDBusWatchFunction: - * @connection: a #DBusConnection - * @user_data: user data to pass to the function - * - * Watch function - */ -typedef void (* BDBusWatchFunction) (DBusConnection *connection, - void *user_data); - -/** - * BDBusSignalFunction: - * @connection: a #DBusConnection - * @message: a #DBusMessage - * @user_data: user data to pass to the function - * - * Signal function - * - * Returns: #FALSE to remove this watch - */ -typedef gboolean (* BDBusSignalFunction) (DBusConnection *connection, - DBusMessage *message, void *user_data); - -/** - * BDBusMethodFunction: - * @connection: a #DBusConnection - * @message: a #DBusMessage - * @user_data: user data to pass to the function - * - * Method function - * - * Returns: #DBusMessage reply - */ -typedef DBusMessage * (* BDBusMethodFunction) (DBusConnection *connection, - DBusMessage *message, void *user_data); - -/** - * BDBusPropertyGetFunction: - * @connection: a #DBusConnection - * @iter: a #DBusMessageIter - * @user_data: user data to pass to the function - * - * Property get function - * - * Returns: #TRUE on success - */ -typedef dbus_bool_t (* BDBusPropertyGetFunction) (DBusConnection *connection, - DBusMessageIter *iter, void *user_data); - -/** - * BDBusPropertySetFunction: - * @connection: a #DBusConnection - * @iter: a #DBusMessageIter - * @user_data: user data to pass to the function - * - * Property set function - * - * Returns: #TRUE on success - */ -typedef dbus_bool_t (* BDBusPropertySetFunction) (DBusConnection *connection, - DBusMessageIter *iter, void *user_data); - -/** - * BDBusInterfaceFunction: - * @user_data: user data to pass to the function - * - * Callback function for interface - */ -typedef void (* BDBusInterfaceFunction) (void *user_data); - -/** - * BDBusMethodFlags: - * @G_DBUS_METHOD_FLAG_DEPRECATED: annotate deprecated methods - * @G_DBUS_METHOD_FLAG_NOREPLY: annotate methods with no reply - * @G_DBUS_METHOD_FLAG_ASYNC: annotate asynchronous methods - * @G_DBUS_METHOD_FLAG_METHOD_DATA: the method is passed the - * BDBusMethodTable method_data pointer - * instead of the b_dbus_register_interface() - * user_data pointer - * - * Method flags - */ -typedef enum { - G_DBUS_METHOD_FLAG_NONE = 0, - G_DBUS_METHOD_FLAG_DEPRECATED = (1 << 0), - G_DBUS_METHOD_FLAG_NOREPLY = (1 << 1), - G_DBUS_METHOD_FLAG_ASYNC = (1 << 2), - G_DBUS_METHOD_FLAG_METHOD_DATA = (1 << 3), -} BDBusMethodFlags; - -/** - * BDBusSignalFlags: - * @G_DBUS_SIGNAL_FLAG_DEPRECATED: annotate deprecated signals - * - * Signal flags - */ -typedef enum { - G_DBUS_SIGNAL_FLAG_NONE = 0, - G_DBUS_SIGNAL_FLAG_DEPRECATED = (1 << 0), -} BDBusSignalFlags; - -/** - * BDBusPropertyFlags: - * @G_DBUS_PROPERTY_FLAG_DEPRECATED: annotate deprecated properties - * - * Property flags - */ -typedef enum { - G_DBUS_PROPERTY_FLAG_NONE = 0, - G_DBUS_PROPERTY_FLAG_DEPRECATED = (1 << 0), -} BDBusPropertyFlags; - -/** - * BDBusMethodTable: - * @name: method name - * @signature: method signature - * @reply: reply signature - * @function: method function - * @flags: method flags - * @method_data: passed as BDBusMethodFunction user_data if - * G_DBUS_METHOD_FLAG_METHOD_DATA is set - * @destroy: destructor function for method table; not called - * by gdbus itself, because it never frees BDBusMethodTable - * entries, but useful in upper layers - * - * Method table - */ -typedef struct { - const char *name; - const char *signature; - const char *reply; - BDBusMethodFunction function; - BDBusMethodFlags flags; - void *method_data; - BDBusDestroyFunction destroy; -} BDBusMethodTable; - -/** - * BDBusSignalTable: - * @name: signal name - * @signature: signal signature - * @flags: signal flags - * - * Signal table - */ -typedef struct { - const char *name; - const char *signature; - BDBusSignalFlags flags; -} BDBusSignalTable; - -/** - * BDBusPropertyTable: - * @name: property name - * @type: property value type - * @get: property get function - * @set: property set function - * @flags: property flags - * - * Property table - */ -typedef struct { - const char *name; - const char *type; - BDBusPropertyGetFunction get; - BDBusPropertyGetFunction set; - BDBusPropertyFlags flags; -} BDBusPropertyTable; - -void b_dbus_setup_connection(DBusConnection *connection, - gboolean unshared, - GMainContext *context); -void b_dbus_cleanup_connection(DBusConnection *connection); - -void b_dbus_setup_server(DBusServer *server); - -DBusConnection *b_dbus_setup_bus(DBusBusType type, const char *name, - gboolean unshared, - DBusError *error); - -DBusConnection *b_dbus_setup_address(const char *address, DBusError *error); - -gboolean b_dbus_request_name(DBusConnection *connection, const char *name, - DBusError *error); - -gboolean b_dbus_set_disconnect_function(DBusConnection *connection, - BDBusWatchFunction function, - void *user_data, BDBusDestroyFunction destroy); - -gboolean b_dbus_register_interface(DBusConnection *connection, - const char *path, const char *name, - BDBusMethodTable *methods, - BDBusSignalTable *signals, - BDBusPropertyTable *properties, - void *user_data, - BDBusDestroyFunction destroy); -gboolean b_dbus_register_interface_with_callback(DBusConnection *connection, - const char *path, const char *name, - BDBusMethodTable *methods, - BDBusSignalTable *signals, - BDBusPropertyTable *properties, - void *user_data, - BDBusDestroyFunction destroy, - BDBusInterfaceFunction callback); -gboolean b_dbus_unregister_interface(DBusConnection *connection, - const char *path, const char *name); - -DBusMessage *b_dbus_create_error(DBusMessage *message, const char *name, - const char *format, ...); -DBusMessage *b_dbus_create_error_valist(DBusMessage *message, const char *name, - const char *format, va_list args); -DBusMessage *b_dbus_create_reply(DBusMessage *message, int type, ...); -DBusMessage *b_dbus_create_reply_valist(DBusMessage *message, - int type, va_list args); - -gboolean b_dbus_send_message(DBusConnection *connection, DBusMessage *message); -gboolean b_dbus_send_error(DBusConnection *connection, DBusMessage *message, - const char *name, const char *format, ...); - -gboolean b_dbus_send_reply(DBusConnection *connection, - DBusMessage *message, int type, ...); -gboolean b_dbus_send_reply_valist(DBusConnection *connection, - DBusMessage *message, int type, va_list args); - -gboolean b_dbus_emit_signal(DBusConnection *connection, - const char *path, const char *interface, - const char *name, int type, ...); -gboolean b_dbus_emit_signal_valist(DBusConnection *connection, - const char *path, const char *interface, - const char *name, int type, va_list args); - -guint b_dbus_add_service_watch(DBusConnection *connection, const char *name, - BDBusWatchFunction connect, - BDBusWatchFunction disconnect, - void *user_data, BDBusDestroyFunction destroy); -guint b_dbus_add_disconnect_watch(DBusConnection *connection, - const char *name, BDBusWatchFunction function, - void *user_data, BDBusDestroyFunction destroy); -guint b_dbus_add_signal_watch(DBusConnection *connection, - const char *rule, BDBusSignalFunction function, - void *user_data, BDBusDestroyFunction destroy, - gboolean is_bus_conn); -gboolean b_dbus_remove_watch(DBusConnection *connection, guint tag); -void b_dbus_remove_all_watches(DBusConnection *connection); - -#ifdef __cplusplus -} -#endif - -#endif /* __BDBUS_H */ diff --git a/src/gdbus/mainloop.c b/src/gdbus/mainloop.c deleted file mode 100644 index 919fd8c4..00000000 --- a/src/gdbus/mainloop.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * - * Library for simple D-Bus integration with GLib - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <dbus/dbus.h> -#include <glib.h> - -#ifdef NEED_DBUS_WATCH_GET_UNIX_FD -#define dbus_watch_get_unix_fd dbus_watch_get_fd -#endif - -#include "gdbus.h" -#include "debug.h" - -static dbus_int32_t connection_slot = -1; -static dbus_int32_t server_slot = -1; - -typedef struct { - DBusConnection *connection; - GMainContext *context; - GSource *queue; - BDBusWatchFunction disconnect; - void *disconnect_data; - BDBusDestroyFunction disconnect_destroy; - gboolean unshared; -} ConnectionData; - -typedef struct { - DBusWatch *watch; - GSource *source; -} WatchData; - -typedef struct { - DBusTimeout *timeout; - guint id; -} TimeoutData; - -typedef struct { - GSource source; - DBusConnection *connection; -} QueueData; - -static GSList *watches = NULL; -static GSList *timeouts = NULL; - -static gboolean queue_prepare(GSource *source, gint *timeout) -{ - DBusConnection *connection = ((QueueData *) source)->connection; - - DBG("source %p", source); - - *timeout = -1; - - return (dbus_connection_get_dispatch_status(connection) == - DBUS_DISPATCH_DATA_REMAINS); -} - -static gboolean queue_check(GSource *source) -{ - DBG("source %p", source); - - return FALSE; -} - -static gboolean queue_dispatch(GSource *source, GSourceFunc callback, - gpointer user_data) -{ - DBusConnection *connection = ((QueueData *) source)->connection; - - DBG("source %p", source); - - dbus_connection_ref(connection); - - dbus_connection_dispatch(connection); - - dbus_connection_unref(connection); - - return TRUE; -} - -static GSourceFuncs queue_funcs = { - queue_prepare, - queue_check, - queue_dispatch, - NULL -}; - -static gboolean dispatch_watch(GIOChannel *source, - GIOCondition condition, gpointer user_data) -{ - WatchData *data = user_data; - unsigned int flags = 0; - - DBG("source %p condition %d watch data %p", source, condition, data); - - if (condition & G_IO_IN) - flags |= DBUS_WATCH_READABLE; - - if (condition & G_IO_OUT) - flags |= DBUS_WATCH_WRITABLE; - - if (condition & G_IO_ERR) - flags |= DBUS_WATCH_ERROR; - - if (condition & G_IO_HUP) - flags |= DBUS_WATCH_HANGUP; - - dbus_watch_handle(data->watch, flags); - - return TRUE; -} - -static void finalize_watch(gpointer memory) -{ - DBG("watch data %p", memory); -} - -static void free_watch(void *memory) -{ - DBG("watch data %p", memory); - - if (memory == NULL) - return; - - watches = g_slist_remove(watches, memory); - - WatchData *watch_data = (WatchData*)memory; - GSource* source = watch_data->source; - - if (source != NULL) { - g_source_destroy(source); - watch_data->source = NULL; - } - - g_free(watch_data); -} - -static dbus_bool_t add_watch(DBusWatch *watch, void *user_data) -{ - ConnectionData *data = user_data; - GIOCondition condition = G_IO_ERR | G_IO_HUP; - GIOChannel *channel; - GSource *source; - WatchData *watch_data; - unsigned int flags; - int fd; - - DBG("watch %p connection data %p", watch, data); - - if (dbus_watch_get_enabled(watch) == FALSE) - return TRUE; - - flags = dbus_watch_get_flags(watch); - - if (flags & DBUS_WATCH_READABLE) - condition |= G_IO_IN; - - if (flags & DBUS_WATCH_WRITABLE) - condition |= G_IO_OUT; - - fd = dbus_watch_get_unix_fd(watch); - - DBG("flags %d fd %d", flags, fd); - - watch_data = g_new0(WatchData, 1); - - channel = g_io_channel_unix_new(fd); - - source = g_io_create_watch(channel, condition); - - watch_data->watch = watch; - watch_data->source = source; - - g_source_set_callback(source, (GSourceFunc) dispatch_watch, - watch_data, finalize_watch); - - g_source_attach(source, data->context); - - watches = g_slist_prepend(watches, watch_data); - - dbus_watch_set_data(watch, watch_data, free_watch); - - g_io_channel_unref(channel); - - DBG("watch data %p", watch_data); - - return TRUE; -} - -static void remove_watch(DBusWatch *watch, void *user_data) -{ - WatchData *watch_data = dbus_watch_get_data(watch); - - DBG("watch %p watch data %p connection data %p", watch, watch_data, user_data); - - if (watch_data == NULL) - return; - - watches = g_slist_remove(watches, watch_data); - - if (watch_data->source != NULL) { - g_source_destroy(watch_data->source); - // g_source_unref(watch_data->source); - watch_data->source = NULL; - } - - // this will call free_watch() and deallocate watch_data - dbus_watch_set_data(watch, NULL, NULL); -} - -static void watch_toggled(DBusWatch *watch, void *user_data) -{ - DBG("watch %p connection data %p", watch, user_data); - - if (dbus_watch_get_enabled(watch) == TRUE) - add_watch(watch, user_data); - else - remove_watch(watch, user_data); -} - -static gboolean dispatch_timeout(gpointer user_data) -{ - TimeoutData *timeout_data = user_data; - - DBG("timeout data %p", timeout_data); - - dbus_timeout_handle(timeout_data->timeout); - - return FALSE; -} - -static void free_timeout(void *memory) -{ - TimeoutData *timeout_data = memory; - - DBG("timeout data %p", timeout_data); - - if (timeout_data->id > 0) - g_source_remove(timeout_data->id); - - g_free(timeout_data); -} - -static dbus_bool_t add_timeout(DBusTimeout *timeout, void *user_data) -{ - TimeoutData *timeout_data; - - DBG("timeout %p connection data %p", timeout, user_data); - - if (dbus_timeout_get_enabled(timeout) == FALSE) - return TRUE; - - timeout_data = g_new0(TimeoutData, 1); - - timeout_data->timeout = timeout; - - timeout_data->id = g_timeout_add(dbus_timeout_get_interval(timeout), - dispatch_timeout, timeout_data); - - timeouts = g_slist_prepend(timeouts, timeout_data); - - dbus_timeout_set_data(timeout, timeout_data, free_timeout); - - DBG("timeout data %p", timeout_data); - - return TRUE; -} - -static void remove_timeout(DBusTimeout *timeout, void *user_data) -{ - TimeoutData *timeout_data = dbus_timeout_get_data(timeout); - - DBG("timeout %p connection data %p", timeout, user_data); - - if (timeout_data == NULL) - return; - - timeouts = g_slist_remove(timeouts, timeout_data); - - if (timeout_data->id > 0) - g_source_remove(timeout_data->id); - - timeout_data->id = 0; -} - -static void timeout_toggled(DBusTimeout *timeout, void *user_data) -{ - DBG("timeout %p connection data %p", timeout, user_data); - - if (dbus_timeout_get_enabled(timeout) == TRUE) - add_timeout(timeout, user_data); - else - remove_timeout(timeout, user_data); -} - -static void wakeup_context(void *user_data) -{ - ConnectionData *data = user_data; - - DBG("connection data %p", data); - - g_main_context_wakeup(data->context); -} - -static ConnectionData *setup_connection(DBusConnection *connection, - gboolean unshared, - GMainContext *context) -{ - ConnectionData *data; - - DBG("connection %p context %p", connection, context); - - data = g_new0(ConnectionData, 1); - - data->context = g_main_context_ref(context); - data->unshared = unshared; - - DBG("connection data %p", data); - - if (connection == NULL) - return data; - - data->connection = connection; - - data->queue = g_source_new(&queue_funcs, sizeof(QueueData)); - - ((QueueData *) data->queue)->connection = connection; - - g_source_attach(data->queue, context); - - return data; -} - -static void free_connection(void *memory) -{ - ConnectionData *data = memory; - - DBG("connection data %p", data); - - b_dbus_remove_all_watches(data->connection); - - //b_dbus_unregister_all_objects(data->connection); - - if (data->queue) - g_source_destroy(data->queue); - - // At the point when free_connection gets called, - // the last unref already happened and the connection - // is gone; trying to close it here is too later. - // ConnectionData holds *no* reference on data->connection, - // so don't unref either. If it did, the connection would - // never get freed. -#if 0 - if (data->unshared) - dbus_connection_close(data->connection); - dbus_connection_unref(data->connection); -#endif - - if (data->disconnect_destroy) - data->disconnect_destroy (data->disconnect_data); - - g_main_context_unref(data->context); - - g_free(data); -} - -/** - * b_dbus_setup_connection: - * @connection: a #DBusConnection - * @unshared: the connection is private and must be closed explicitly - * @context: a #GMainContext or #NULL for default context - * - * Setup connection with main context - * - * Sets the watch and timeout functions of a #DBusConnection - * to integrate the connection with the GLib main loop. - * Pass in #NULL for the #GMainContext unless you're - * doing something specialized. - */ -void b_dbus_setup_connection(DBusConnection *connection, - gboolean unshared, - GMainContext *context) -{ - ConnectionData *data; - - DBG("connection %p context %p", connection, context); - - if (dbus_connection_allocate_data_slot(&connection_slot) == FALSE) - return; - - DBG("connection slot %d", connection_slot); - - data = dbus_connection_get_data(connection, connection_slot); - if (data != NULL) - return; - - dbus_connection_set_exit_on_disconnect(connection, TRUE); - - if (context == NULL) - context = g_main_context_default(); - - data = setup_connection(connection, unshared, context); - if (data == NULL) - return; - - if (dbus_connection_set_data(connection, connection_slot, - data, free_connection) == FALSE) { - g_free(data); - return; - } - - dbus_connection_set_watch_functions(connection, add_watch, - remove_watch, watch_toggled, data, NULL); - - dbus_connection_set_timeout_functions(connection, add_timeout, - remove_timeout, timeout_toggled, data, NULL); - - dbus_connection_set_wakeup_main_function(connection, - wakeup_context, data, NULL); -} - -/** - * b_dbus_server_connection: - * @server: a #DBusServer - * - * Setup server with main context - * - * Sets the watch and timeout functions of a #DBusServer - * to integrate the connection with the GLib main loop. - */ -void b_dbus_setup_server(DBusServer *server) -{ - ConnectionData *data; - - if (dbus_server_allocate_data_slot(&server_slot) == FALSE) - return; - - DBG("server slot %d", server_slot); - - data = dbus_server_get_data(server, server_slot); - if (data != NULL) - return; - - data = setup_connection(NULL, TRUE, g_main_context_default()); - if (data == NULL) - return; - - if (dbus_server_set_data(server, server_slot, - data, free_connection) == FALSE) { - g_free(data); - return; - } - - dbus_server_set_watch_functions(server, add_watch, - remove_watch, watch_toggled, data, NULL); - - dbus_server_set_timeout_functions(server, add_timeout, - remove_timeout, timeout_toggled, data, NULL); -} - -/** - * b_dbus_cleanup_connection: - * @connection: a #DBusConnection - * - * Cleanup the setup of DBusConnection and free the - * allocated memory. - */ -void b_dbus_cleanup_connection(DBusConnection *connection) -{ - DBG("connection %p slot %d", connection, connection_slot); - - if (connection_slot < 0) - return; - - dbus_connection_set_data(connection, connection_slot, NULL, NULL); - - dbus_connection_free_data_slot(&connection_slot); - - DBG("connection slot %d", connection_slot); -} - -/** - * b_dbus_setup_bus: - * @type: a #DBusBusType - * @name: well known name - * @unshared: use dbus_bus_get_private() to ensure that we have the connection - * for ourself (otherwise assertions and CRITICAL warnings were triggered - * inside glib-dbus when the app also used that) - * @error: a #DBusError - * - * Connect to bus and setup connection - * - * Returns a connection to the given bus and requests a - * well known name for it. Sets the watch and timeout - * functions for it. - * - * Returns: newly setup #DBusConnection - */ -DBusConnection *b_dbus_setup_bus(DBusBusType type, const char *name, - gboolean unshared, - DBusError *error) -{ - DBusConnection *connection; - - DBG("type %d name %s error %p", type, name, error); - - connection = unshared ? dbus_bus_get_private(type, error) : - dbus_bus_get(type, error); - - if (error != NULL) { - if (dbus_error_is_set(error) == TRUE) - return NULL; - } - - if (connection == NULL) - return NULL; - - if (name != NULL) { - if (dbus_bus_request_name(connection, name, - DBUS_NAME_FLAG_DO_NOT_QUEUE, error) != - DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ) { - goto failed; - } - - if (error != NULL) { - if (dbus_error_is_set(error) == TRUE) { - goto failed; - } - } - } - - b_dbus_setup_connection(connection, unshared, NULL); - - return connection; - - failed: - if (unshared) - dbus_connection_close(connection); - dbus_connection_unref(connection); - return NULL; -} - -/** - * b_dbus_setup_address: - * @address: bus address - * @error: a #DBusError - * - * Connect to bus and setup connection - * - * Returns a connection to the bus specified via - * the given address and sets the watch and timeout - * functions for it. - * - * Returns: newly setup #DBusConnection - */ -DBusConnection *b_dbus_setup_address(const char *address, DBusError *error) -{ - DBusConnection *connection; - - DBG("address %s error %p", address, error); - - connection = dbus_connection_open(address, error); - - if (error != NULL) { - if (dbus_error_is_set(error) == TRUE) - return NULL; - } - - if (connection == NULL) - return NULL; - - b_dbus_setup_connection(connection, FALSE, NULL); - - return connection; -} - -/** - * b_dbus_request_name: - * @connection: a #DBusConnection - * @name: well known name - * @error: a #DBusError - * - * Requests a well known name for connection. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_request_name(DBusConnection *connection, const char *name, - DBusError *error) -{ - DBG("connection %p name %s error %p", connection, name, error); - - if (name == NULL) - return FALSE; - - if (dbus_bus_request_name(connection, name, - DBUS_NAME_FLAG_DO_NOT_QUEUE, error) != - DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ) - return FALSE; - - if (error != NULL) { - if (dbus_error_is_set(error) == TRUE) - return FALSE; - } - - return TRUE; -} - -static DBusHandlerResult disconnect_filter(DBusConnection *connection, - DBusMessage *message, void *user_data) -{ - ConnectionData *data = user_data; - - if (dbus_message_is_signal(message, - DBUS_INTERFACE_LOCAL, "Disconnected") == FALSE) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - DBG("disconnected"); - - if (data->disconnect) - data->disconnect (connection, - data->disconnect_data); - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -/** - * b_dbus_set_disconnect_function: - * @connection: a #DBusConnection - * @function: a #BDBusWatchFunction - * @user_data: user data to pass to the function - * @destroy: a #BDBusDestroyFunction - * - * Set a callback function that will be called when the - * D-Bus message bus exits. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_set_disconnect_function(DBusConnection *connection, - BDBusWatchFunction function, - void *user_data, BDBusDestroyFunction destroy) -{ - ConnectionData *data = dbus_connection_get_data(connection, connection_slot); - if (!data) - return FALSE; - - if (data->disconnect_destroy) - data->disconnect_destroy (data->disconnect_data); - data->disconnect_destroy = NULL; - data->disconnect = NULL; - data->disconnect_data = NULL; - - dbus_connection_set_exit_on_disconnect(connection, FALSE); - - if (dbus_connection_add_filter(connection, - disconnect_filter, data, NULL) == FALSE) - return FALSE; - - data = dbus_connection_get_data(connection, connection_slot); - - data->disconnect = function; - data->disconnect_data = user_data; - data->disconnect_destroy = destroy; - return TRUE; -} diff --git a/src/gdbus/object.c b/src/gdbus/object.c deleted file mode 100644 index d4a6b691..00000000 --- a/src/gdbus/object.c +++ /dev/null @@ -1,1440 +0,0 @@ -/* - * - * Library for simple D-Bus integration with GLib - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdarg.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> - -#include <dbus/dbus.h> - -#include "gdbus.h" -#include "debug.h" - -static dbus_int32_t connection_slot = -1; - -typedef struct { - GStaticMutex mutex; - GSList *objects; -} ConnectionData; - -typedef struct { - gint refcount; - char *path; - GStaticMutex mutex; - GSList *interfaces; - char *introspect; -} ObjectData; - -typedef struct { - char *name; - BDBusMethodTable *methods; - BDBusSignalTable *signals; - BDBusPropertyTable *properties; - void *user_data; - BDBusDestroyFunction destroy; - BDBusInterfaceFunction callback; -} InterfaceData; - -static InterfaceData *find_interface(GSList *interfaces, const char *name) -{ - GSList *list; - - for (list = interfaces; list; list = list->next) { - InterfaceData *interface = list->data; - - if (strcmp(name, interface->name) == 0) - return interface; - } - - return NULL; -} - -static ObjectData *find_object(GSList *objects, const char *path) -{ - GSList *list; - - for (list = objects; list; list = list->next) { - ObjectData *object = list->data; - - if (strcmp(path, object->path) == 0) - return object; - } - - return NULL; -} - -static BDBusPropertyTable *find_property(InterfaceData *interface, - const char *name) -{ - BDBusPropertyTable *property; - - if (interface == NULL) - return NULL; - - for (property = interface->properties; property && property->name; property++) - if (strcmp(property->name, name) == 0) - return property; - - return NULL; -} - -static void add_arguments(GString *xml, const char *direction, - const char *signature) -{ - DBusSignatureIter iter; - - dbus_signature_iter_init(&iter, signature); - - if (dbus_signature_iter_get_current_type(&iter) == DBUS_TYPE_INVALID) - return; - - do { - char *sig = dbus_signature_iter_get_signature(&iter); - g_string_append_printf(xml, "\t\t\t<arg type=\"%s\"", sig); - dbus_free (sig); - - if (direction != NULL) - g_string_append_printf(xml, " direction=\"%s\"/>\n", - direction); - else - g_string_append(xml, "/>\n"); - } while (dbus_signature_iter_next(&iter) == TRUE); -} - -static inline void add_annotation(GString *xml, const char *name) -{ - g_string_append_printf(xml, - "\t\t\t<annotation name=\"%s\" value=\"true\"/>\n", name); -} - -static inline void add_methods(GString *xml, BDBusMethodTable *methods) -{ - BDBusMethodTable *method; - - for (method = methods; method && method->name; method++) { - g_string_append_printf(xml, "\t\t<method name=\"%s\">\n", - method->name); - - add_arguments(xml, "in", method->signature); - add_arguments(xml, "out", method->reply); - - if (method->flags & G_DBUS_METHOD_FLAG_DEPRECATED) - add_annotation(xml, "org.freedesktop.DBus.Deprecated"); - - if (method->flags & G_DBUS_METHOD_FLAG_NOREPLY) - add_annotation(xml, "org.freedesktop.DBus.Method.NoReply"); - - g_string_append(xml, "\t\t</method>\n"); - } -} - -static inline void add_signals(GString *xml, BDBusSignalTable *signals) -{ - BDBusSignalTable *signal; - - for (signal = signals; signal && signal->name; signal++) { - g_string_append_printf(xml, "\t\t<signal name=\"%s\">\n", - signal->name); - - add_arguments(xml, NULL, signal->signature); - - if (signal->flags & G_DBUS_SIGNAL_FLAG_DEPRECATED) - add_annotation(xml, "org.freedesktop.DBus.Deprecated"); - - g_string_append(xml, "\t\t</signal>\n"); - } -} - -static inline void add_properties(GString *xml, BDBusPropertyTable *properties) -{ - BDBusPropertyTable *property; - - for (property = properties; property && property->name; property++) { - const char *access; - - if (property->type == NULL) - continue; - - if (property->get == NULL && property->set == NULL) - continue; - - if (property->get != NULL) { - if (property->set == NULL) - access = "read"; - else - access = "readwrite"; - } else - access = "write"; - - g_string_append_printf(xml, - "\t\t<property name=\"%s\" type=\"%s\" access=\"%s\">\n", - property->name, property->type, access); - - if (property->flags & G_DBUS_PROPERTY_FLAG_DEPRECATED) - add_annotation(xml, "org.freedesktop.DBus.Deprecated"); - - g_string_append(xml, "\t\t</property>\n"); - } -} - -static char *generate_introspect(DBusConnection *connection, - const char *path, ObjectData *data) -{ - GString *xml; - GSList *list; - char **children; - int i; - - DBG("connection %p path %s", connection, path); - - xml = g_string_new(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE); - - g_string_append_printf(xml, "<node name=\"%s\">\n", path); - - g_string_append_printf(xml, "\t<interface name=\"%s\">\n", - DBUS_INTERFACE_INTROSPECTABLE); - - g_string_append(xml, "\t\t<method name=\"Introspect\">\n"); - add_arguments(xml, "out", "s"); - g_string_append(xml, "\t\t</method>\n"); - - g_string_append(xml, "\t</interface>\n"); - - g_string_append_printf(xml, "\t<interface name=\"%s\">\n", - DBUS_INTERFACE_PROPERTIES); - - g_string_append(xml, "\t\t<method name=\"Get\">\n"); - add_arguments(xml, "in", "ss"); - add_arguments(xml, "out", "v"); - g_string_append(xml, "\t\t</method>\n"); - - g_string_append(xml, "\t\t<method name=\"Set\">\n"); - add_arguments(xml, "in", "ssv"); - g_string_append(xml, "\t\t</method>\n"); - - g_string_append(xml, "\t\t<method name=\"GetAll\">\n"); - add_arguments(xml, "in", "s"); - add_arguments(xml, "out", "a{sv}"); - g_string_append(xml, "\t\t</method>\n"); - - g_string_append(xml, "\t</interface>\n"); - - for (list = data->interfaces; list; list = list->next) { - InterfaceData *interface = list->data; - - g_string_append_printf(xml, "\t<interface name=\"%s\">\n", - interface->name); - - add_methods(xml, interface->methods); - add_signals(xml, interface->signals); - add_properties(xml, interface->properties); - - g_string_append(xml, "\t</interface>\n"); - } - - if (dbus_connection_list_registered(connection, - path, &children) == FALSE) - goto done; - - for (i = 0; children[i]; i++) - g_string_append_printf(xml, "\t<node name=\"%s\"/>\n", - children[i]); - - dbus_free_string_array(children); - -done: - g_string_append(xml, "</node>\n"); - - return g_string_free(xml, FALSE); -} - -static void update_parent(DBusConnection *connection, const char *path) -{ - ObjectData *data; - char *parent; - - DBG("connection %p path %s", connection, path); - - if (strlen(path) < 2 || path[0] != '/') - return; - - parent = g_path_get_dirname(path); - if (parent == NULL) - return; - - if (dbus_connection_get_object_path_data(connection, - parent, (void *) &data) == FALSE) { - update_parent(connection, parent); - goto done; - } - - if (data == NULL) { - update_parent(connection, parent); - goto done; - } - - g_free(data->introspect); - data->introspect = generate_introspect(connection, parent, data); - -done: - g_free(parent); -} - -static DBusHandlerResult send_message(DBusConnection *connection, - DBusMessage *message) -{ - dbus_bool_t result; - - result = dbus_connection_send(connection, message, NULL); - - dbus_message_unref(message); - - if (result == FALSE) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult send_error(DBusConnection *connection, - DBusMessage *message, - const char *name, const char *text) -{ - DBusMessage *error; - - error = dbus_message_new_error(message, name, text); - if (error == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - return send_message(connection, error); -} - -static DBusHandlerResult introspect(DBusConnection *connection, - DBusMessage *message, ObjectData *data) -{ - DBusMessage *reply; - - DBG("connection %p message %p object data %p", - connection, message, data); - - if (data->introspect == NULL) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (dbus_message_has_signature(message, - DBUS_TYPE_INVALID_AS_STRING) == FALSE) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - reply = dbus_message_new_method_return(message); - if (reply == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, - DBUS_TYPE_STRING, &data->introspect, DBUS_TYPE_INVALID); - - return send_message(connection, reply); -} - -static DBusHandlerResult properties_get(DBusConnection *connection, - DBusMessage *message, ObjectData *data) -{ - DBusMessage *reply; - BDBusPropertyTable *property; - DBusMessageIter iter, value; - dbus_bool_t result; - const char *interface, *name; - InterfaceData *iface; - - DBG("connection %p message %p object data %p", - connection, message, data); - - if (dbus_message_has_signature(message, - DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING - DBUS_TYPE_INVALID_AS_STRING) == FALSE) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &interface, - DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); - - DBG("interface %s name %s", interface, name); - - iface = find_interface(data->interfaces, interface); - property = find_property(iface, name); - if (property == NULL) - return send_error(connection, message, - DBUS_ERROR_BAD_ADDRESS, "Property not found"); - - if (property->get == NULL) - return send_error(connection, message, - DBUS_ERROR_ACCESS_DENIED, - "Reading of property not allowed"); - - reply = dbus_message_new_method_return(message); - if (reply == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_iter_init_append(reply, &iter); - - dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, - property->type, &value); - - result = property->get(connection, &value, iface->user_data); - - dbus_message_iter_close_container(&iter, &value); - - if (result == FALSE) { - dbus_message_unref(reply); - return send_error(connection, message, DBUS_ERROR_FAILED, - "Reading of property failed"); - } - - return send_message(connection, reply); -} - -static DBusHandlerResult properties_set(DBusConnection *connection, - DBusMessage *message, ObjectData *data) -{ - DBusMessage *reply; - BDBusPropertyTable *property; - DBusMessageIter iter, value; - const char *interface, *name; - InterfaceData *iface; - - DBG("connection %p message %p object data %p", - connection, message, data); - - if (dbus_message_has_signature(message, DBUS_TYPE_STRING_AS_STRING - DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING - DBUS_TYPE_INVALID_AS_STRING) == FALSE) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_message_iter_init(message, &iter); - - dbus_message_iter_get_basic(&iter, &interface); - dbus_message_iter_next(&iter); - - dbus_message_iter_get_basic(&iter, &name); - dbus_message_iter_next(&iter); - - dbus_message_iter_recurse(&iter, &value); - - DBG("interface %s name %s", interface, name); - - iface = find_interface(data->interfaces, interface); - property = find_property(iface, name); - if (property == NULL) - return send_error(connection, message, - DBUS_ERROR_BAD_ADDRESS, "Property not found"); - - if (property->set == NULL) - return send_error(connection, message, - DBUS_ERROR_ACCESS_DENIED, - "Writing to property not allowed"); - - reply = dbus_message_new_method_return(message); - if (reply == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_INVALID); - - if (property->set(connection, &value, iface->user_data) == FALSE) { - dbus_message_unref(reply); - return send_error(connection, message, DBUS_ERROR_FAILED, - "Writing to property failed"); - } - - return send_message(connection, reply); -} - -static inline void append_message(DBusMessageIter *value, DBusMessage *message) -{ - DBusMessageIter iter, temp; - - dbus_message_iter_init(message, &temp); - dbus_message_iter_recurse(&temp, &iter); - - do { - int type = dbus_message_iter_get_arg_type(&iter); - void *data; - - dbus_message_iter_get_basic(&iter, &data); - dbus_message_iter_append_basic(value, type, &data); - } while (dbus_message_iter_next(&iter) == TRUE); -} - -static void do_getall(DBusConnection *connection, DBusMessageIter *iter, - InterfaceData *interface, ObjectData *data) -{ - BDBusPropertyTable *property; - - if (interface == NULL) - return; - - for (property = interface->properties; property && property->name; property++) { - DBusMessage *message; - DBusMessageIter entry, value; - dbus_bool_t result; - - if (property->get == NULL) - continue; - - message = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); - if (message == NULL) - continue; - - dbus_message_iter_init_append(message, &entry); - - dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, - property->type, &value); - - result = property->get(connection, &value, interface->user_data); - - dbus_message_iter_close_container(&entry, &value); - - if (result == TRUE) { - dbus_message_iter_open_container(iter, - DBUS_TYPE_DICT_ENTRY, NULL, &entry); - - dbus_message_iter_append_basic(&entry, - DBUS_TYPE_STRING, &property->name); - - dbus_message_iter_open_container(&entry, - DBUS_TYPE_VARIANT, - property->type, &value); - - append_message(&value, message); - - dbus_message_iter_close_container(&entry, &value); - - dbus_message_iter_close_container(iter, &entry); - } - - dbus_message_unref(message); - } -} - -static DBusHandlerResult properties_getall(DBusConnection *connection, - DBusMessage *message, ObjectData *data) -{ - DBusMessage *reply; - DBusMessageIter iter, dict; - const char *interface; - - DBG("connection %p message %p object data %p", - connection, message, data); - - if (dbus_message_has_signature(message, DBUS_TYPE_STRING_AS_STRING - DBUS_TYPE_INVALID_AS_STRING) == FALSE) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &interface, - DBUS_TYPE_INVALID); - - DBG("interface %s", interface); - - reply = dbus_message_new_method_return(message); - if (reply == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_iter_init_append(reply, &iter); - - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING - DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING - DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - - do_getall(connection, &dict, - find_interface(data->interfaces, interface), data); - - dbus_message_iter_close_container(&iter, &dict); - - return send_message(connection, reply); -} - -static DBusHandlerResult handle_message(DBusConnection *connection, - DBusMessage *message, void *user_data) -{ - ObjectData *data = user_data; - InterfaceData *interface; - BDBusMethodTable *method; - - DBG("object data %p", data); - - if (dbus_message_is_method_call(message, - DBUS_INTERFACE_INTROSPECTABLE, "Introspect") == TRUE) - return introspect(connection, message, data); - - if (dbus_message_is_method_call(message, - DBUS_INTERFACE_PROPERTIES, "Get") == TRUE) - return properties_get(connection, message, data); - - if (dbus_message_is_method_call(message, - DBUS_INTERFACE_PROPERTIES, "Set") == TRUE) - return properties_set(connection, message, data); - - if (dbus_message_is_method_call(message, - DBUS_INTERFACE_PROPERTIES, "GetAll") == TRUE) - return properties_getall(connection, message, data); - - interface = find_interface(data->interfaces, - dbus_message_get_interface(message)); - if (interface == NULL) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - DBG("interface data %p name %s", interface, interface->name); - - for (method = interface->methods; - method->name && method->function; method++) { - DBusMessage *reply; - BDBusMethodFlags flags = method->flags; - - if (dbus_message_is_method_call(message, - interface->name, method->name) == FALSE) - continue; - - if (dbus_message_has_signature(message, - method->signature) == FALSE) - continue; - - if(interface->callback) { - interface->callback(interface->user_data); - } - - /* method->function() might disconnect the interface, - in which case the "method" pointer itself becomes - invalid - don't use it below */ - reply = method->function(connection, - message, - (flags & - G_DBUS_METHOD_FLAG_METHOD_DATA) ? - method->method_data : - interface->user_data); - method = NULL; - - if (flags & G_DBUS_METHOD_FLAG_NOREPLY) { - if (reply != NULL) - dbus_message_unref(reply); - return DBUS_HANDLER_RESULT_HANDLED; - } - - if (flags & G_DBUS_METHOD_FLAG_ASYNC) { - if (reply == NULL) - return DBUS_HANDLER_RESULT_HANDLED; - } - - if (reply == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - return send_message(connection, reply); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static void handle_unregister(DBusConnection *connection, void *user_data) -{ - ObjectData *data = user_data; - GSList *list; - - DBG("object data %p path %s", data, data->path); - - g_free(data->path); - - for (list = data->interfaces; list; list = list->next) { - InterfaceData *interface = list->data; - - DBG("interface data %p name %s", interface, interface->name); - - if (interface->destroy) - interface->destroy(interface->user_data); - - g_free(interface->name); - g_free(interface); - } - - g_slist_free(data->interfaces); - - g_free(data->introspect); - g_static_mutex_free(&data->mutex); - g_free(data); -} - -static DBusObjectPathVTable object_table = { - .unregister_function = handle_unregister, - .message_function = handle_message, -}; - -/** - * b_dbus_register_object: - * @connection: the connection - * @path: object path - * - * Registers a path in the object hierarchy. - * - * Returns: #TRUE on success - */ -static gboolean b_dbus_register_object(DBusConnection *connection, - const char *path) -{ - ConnectionData *data; - ObjectData *object; - - DBG("connection %p path %s", connection, path); - - if (dbus_connection_allocate_data_slot(&connection_slot) == FALSE) - return FALSE; - - DBG("connection slot %d", connection_slot); - - data = dbus_connection_get_data(connection, connection_slot); - if (data == NULL) { - data = g_try_new0(ConnectionData, 1); - if (data == NULL) { - dbus_connection_free_data_slot(&connection_slot); - return 0; - } - - g_static_mutex_init(&data->mutex); - - if (dbus_connection_set_data(connection, connection_slot, - data, NULL) == FALSE) { - dbus_connection_free_data_slot(&connection_slot); - g_free(data); - return 0; - } - } - - DBG("connection data %p", data); - - g_static_mutex_lock(&data->mutex); - - object = find_object(data->objects, path); - - if (!object) { - object = g_new0(ObjectData, 1); - g_static_mutex_init(&object->mutex); - object->path = g_strdup(path); - object->interfaces = NULL; - object->refcount = 0; - object->introspect = generate_introspect(connection, path, object); - if (dbus_connection_register_object_path(connection, path, - &object_table, object) == FALSE) { - g_free(object->introspect); - g_free(object); - return FALSE; - } - - data->objects = g_slist_append(data->objects, object); - } - - object->refcount++; - - g_static_mutex_unlock(&data->mutex); - - DBG("object data %p", object); - - update_parent(connection, path); - - return TRUE; -} - -/** - * b_dbus_unregister_object: - * @connection: the connection - * @path: object path - * - * Unregister the given path in the object hierarchy and - * free the assigned data structures. - * - * Returns: #TRUE on success - */ -static gboolean b_dbus_unregister_object(DBusConnection *connection, - const char *path) -{ - ConnectionData *data; - ObjectData *object; - gboolean result = TRUE; - - - DBG("connection %p path %s", connection, path); - - data = dbus_connection_get_data(connection, connection_slot); - if (data == NULL) - return FALSE; - - if (dbus_connection_get_object_path_data(connection, - path, (void *) &object) == FALSE) - return FALSE; - - if (object == NULL) - return FALSE; - - g_static_mutex_lock(&data->mutex); - - object->refcount--; - if (!object->refcount) { - result = dbus_connection_unregister_object_path(connection, path); - data->objects = g_slist_remove(data->objects, object); - if (!data->objects) - dbus_connection_set_data(connection, connection_slot, NULL, NULL); - } - - g_static_mutex_unlock(&data->mutex); - - dbus_connection_free_data_slot(&connection_slot); - - DBG("connection slot %d", connection_slot); - - if (!data->objects) { - g_static_mutex_free(&data->mutex); - g_free(data); - } - - update_parent(connection, path); - - return result; -} - -#if 0 -/** - * b_dbus_unregister_object_hierarchy: - * @connection: the connection - * @path: object path - * - * Unregister the given path and all subpaths in the - * object hierarchy and free all assigned data strcutures. - * - * Returns: #TRUE on success - */ -static gboolean b_dbus_unregister_object_hierarchy(DBusConnection *connection, - const char *path) -{ - ConnectionData *data; - ObjectData *object; - GSList *list; - size_t pathlen; - dbus_bool_t result; - - DBG("connection %p path %s", connection, path); - - data = dbus_connection_get_data(connection, connection_slot); - if (data == NULL) - return FALSE; - - if (dbus_connection_get_object_path_data(connection, - path, (void *) &object) == FALSE) - return FALSE; - - if (object == NULL) - return FALSE; - - pathlen = strlen(path); - - g_static_mutex_lock(&data->mutex); - - for (list = data->objects; list; list = list->next) { - ObjectData *object = list->data; - - if (strlen(object->path) <= pathlen) - continue; - - if (strncmp(object->path, path, pathlen) != 0) - continue; - - DBG("object data %p path %s", object, object->path); - - data->objects = g_slist_remove(data->objects, object); - - dbus_connection_unregister_object_path(connection, - object->path); - - dbus_connection_free_data_slot(&connection_slot); - - DBG("connection slot %d", connection_slot); - } - - g_static_mutex_unlock(&data->mutex); - - result = b_dbus_unregister_object(connection, path); - if (result == FALSE) - return FALSE; - - update_parent(connection, path); - - return TRUE; -} - -/** - * b_dbus_unregister_all_objects: - * @connection: the connection - * - * Unregister the all paths in the object hierarchy. - */ -static void b_dbus_unregister_all_objects(DBusConnection *connection) -{ - ConnectionData *data; - GSList *list; - - DBG("connection %p slot %d", connection, connection_slot); - - if (connection_slot < 0) - return; - - data = dbus_connection_get_data(connection, connection_slot); - if (data == NULL) - return; - - DBG("connection data %p", data); - - g_static_mutex_lock(&data->mutex); - - for (list = data->objects; list; list = list->next) { - ObjectData *object = list->data; - - DBG("object data %p path %s", object, object->path); - - dbus_connection_unregister_object_path(connection, - object->path); - - dbus_connection_free_data_slot(&connection_slot); - - DBG("connection slot %d", connection_slot); - } - - g_slist_free(data->objects); - - g_static_mutex_unlock(&data->mutex); - - g_free(data); -} -#endif - -/** - * b_dbus_register_interface: - * @connection: the connection - * @path: object path - * @name: interface name - * @methods: method table - * @signals: signal table - * @properties: property table - * @user_data: user data to assign to interface - * @destroy: function called to destroy user_data - * - * Registers an interface for the given path in the - * object hierarchy with the given methods, signals - * and/or properties. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_register_interface_with_callback(DBusConnection *connection, - const char *path, const char *name, - BDBusMethodTable *methods, - BDBusSignalTable *signals, - BDBusPropertyTable *properties, - void *user_data, - BDBusDestroyFunction destroy, - BDBusInterfaceFunction callback) -{ - ObjectData *object; - InterfaceData *interface; - - DBG("connection %p path %s name %s", connection, path, name); - - if (b_dbus_register_object(connection, path) == FALSE) - return FALSE; - - if (dbus_connection_get_object_path_data(connection, - path, (void *) &object) == FALSE) - return FALSE; - - if (object == NULL) - return FALSE; - - if (find_interface(object->interfaces, name) != NULL) - return FALSE; - - interface = g_new0(InterfaceData, 1); - - interface->name = g_strdup(name); - interface->methods = methods; - interface->signals = signals; - interface->properties = properties; - interface->user_data = user_data; - interface->destroy = destroy; - interface->callback = callback; - - g_static_mutex_lock(&object->mutex); - - object->interfaces = g_slist_append(object->interfaces, interface); - - g_free(object->introspect); - object->introspect = generate_introspect(connection, path, object); - - g_static_mutex_unlock(&object->mutex); - - return TRUE; -} - -gboolean b_dbus_register_interface(DBusConnection *connection, - const char *path, const char *name, - BDBusMethodTable *methods, - BDBusSignalTable *signals, - BDBusPropertyTable *properties, - void *user_data, - BDBusDestroyFunction destroy) -{ - return b_dbus_register_interface_with_callback(connection, - path, name, methods, signals, properties, user_data, destroy, NULL); -} - -/** - * b_dbus_unregister_interface: - * @connection: the connection - * @path: object path - * @name: interface name - * - * Unregister the given interface for the given path - * in the object hierarchy. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_unregister_interface(DBusConnection *connection, - const char *path, const char *name) -{ - ObjectData *object; - InterfaceData *interface; - - DBG("connection %p path %s name %s", connection, path, name); - - if (dbus_connection_get_object_path_data(connection, - path, (void *) &object) == FALSE) - return FALSE; - - if (object == NULL) - return FALSE; - - interface = find_interface(object->interfaces, name); - if (interface == NULL) - return FALSE; - - g_static_mutex_lock(&object->mutex); - - object->interfaces = g_slist_remove(object->interfaces, interface); - - g_free(object->introspect); - object->introspect = generate_introspect(connection, path, object); - - g_static_mutex_unlock(&object->mutex); - - g_free(interface->name); - g_free(interface); - - b_dbus_unregister_object(connection, path); - - return TRUE; -} - -char *printf_dyn(const char *format, va_list ap) -{ - va_list aq; - - char *buffer = NULL; - ssize_t size = 0; - ssize_t realsize = 255; - do { - // vsnprintf() destroys ap, so make a copy first - va_copy(aq, ap); - - if (size < realsize) { - char *oldbuffer = buffer; - buffer = (char *)realloc(buffer, realsize + 1); - if (!buffer) { - if (oldbuffer) { - free(oldbuffer); - } - va_end(aq); - return strdup(""); - } - size = realsize; - } - - // cppcheck-suppress nullPointer - realsize = vsnprintf(buffer, size + 1, format, aq); - if (realsize == -1) { - // old-style vnsprintf: exact len unknown, try again with doubled size - realsize = size * 2; - } - va_end(aq); - } while(realsize > size); - - return buffer; -} - -/** - * b_dbus_create_error_valist: - * @message: the originating message - * @name: the error name - * @format: the error description - * @args: argument list - * - * Create error reply for the given message. - * - * Returns: reply message on success - */ -DBusMessage *b_dbus_create_error_valist(DBusMessage *message, const char *name, - const char *format, va_list args) -{ - DBusMessage *msg = NULL; - char *descr; - - DBG("message %p name %s", message, name); - - descr = printf_dyn(format, args); - if (descr) { - msg = dbus_message_new_error(message, name, descr); - free(descr); - } - return msg; -} - -/** - * b_dbus_create_error: - * @message: the originating message - * @name: the error name - * @format: the error description - * @varargs: list of parameters - * - * Create error reply for the given message. - * - * Returns: reply message on success - */ -DBusMessage *b_dbus_create_error(DBusMessage *message, const char *name, - const char *format, ...) -{ - va_list args; - DBusMessage *reply; - - DBG("message %p name %s", message, name); - - va_start(args, format); - - reply = b_dbus_create_error_valist(message, name, format, args); - - va_end(args); - - return reply; -} - -/** - * b_dbus_create_reply_valist: - * @message: the originating message - * @type: first argument type - * @args: argument list - * - * Create reply for the given message. - * - * Returns: reply message on success - */ -DBusMessage *b_dbus_create_reply_valist(DBusMessage *message, - int type, va_list args) -{ - DBusMessage *reply; - - DBG("message %p", message); - - reply = dbus_message_new_method_return(message); - if (reply == NULL) - return NULL; - - if (dbus_message_append_args_valist(reply, type, args) == FALSE) { - dbus_message_unref(reply); - return NULL; - } - - return reply; -} - -/** - * b_dbus_create_reply: - * @message: the originating message - * @type: first argument type - * @varargs: list of parameters - * - * Create reply for the given message. - * - * Returns: reply message on success - */ -DBusMessage *b_dbus_create_reply(DBusMessage *message, int type, ...) -{ - va_list args; - DBusMessage *reply; - - DBG("message %p", message); - - va_start(args, type); - - reply = b_dbus_create_reply_valist(message, type, args); - - va_end(args); - - return reply; -} - -/** - * b_dbus_send_message: - * @connection: the connection - * @message: the message to send - * - * Send message via the given D-Bus connection. - * - * The reference count for the message will be decremented by this - * function. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_send_message(DBusConnection *connection, DBusMessage *message) -{ - dbus_bool_t result; - - DBG("connection %p message %p", connection, message); - - result = dbus_connection_send(connection, message, NULL); - - dbus_message_unref(message); - - return result; -} - -/** - * b_dbus_send_error: - * @connection: the connection - * @message: the originating message - * @name: the error name - * @format: the error description - * @varargs: list of parameters - * - * Send error reply for the given message and via the given D-Bus - * connection. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_send_error(DBusConnection *connection, DBusMessage *message, - const char *name, const char *format, ...) -{ - va_list args; - DBusMessage *error; - - DBG("connection %p message %p", connection, message); - - va_start(args, format); - - error = b_dbus_create_error_valist(message, name, format, args); - - va_end(args); - - if (error == NULL) - return FALSE; - - return b_dbus_send_message(connection, error); -} - -/** - * b_dbus_send_reply_valist: - * @connection: the connection - * @message: the originating message - * @type: first argument type - * @args: argument list - * - * Send reply for the given message and via the given D-Bus - * connection. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_send_reply_valist(DBusConnection *connection, - DBusMessage *message, int type, va_list args) -{ - DBusMessage *reply; - - DBG("connection %p message %p", connection, message); - - reply = dbus_message_new_method_return(message); - if (reply == NULL) - return FALSE; - - if (dbus_message_append_args_valist(reply, type, args) == FALSE) { - dbus_message_unref(reply); - return FALSE; - } - - return b_dbus_send_message(connection, reply); -} - -/** - * b_dbus_send_reply: - * @connection: the connection - * @message: the originating message - * @type: first argument type - * @varargs: list of parameters - * - * Send reply for the given message and via the given D-Bus - * connection. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_send_reply(DBusConnection *connection, - DBusMessage *message, int type, ...) -{ - va_list args; - gboolean result; - - DBG("connection %p message %p", connection, message); - - va_start(args, type); - - result = b_dbus_send_reply_valist(connection, message, type, args); - - va_end(args); - - return result; -} - -static BDBusSignalTable *find_signal(GSList *interfaces, - const char *interface, const char *name) -{ - InterfaceData *data; - BDBusSignalTable *signal; - - data = find_interface(interfaces, interface); - if (data == NULL) - return NULL; - - for (signal = data->signals; signal && signal->name; signal++) { - if (strcmp(signal->name, name) == 0) - break; - } - - return signal; -} - -/** - * b_dbus_emit_signal_valist: - * @connection: the connection - * @path: object path - * @interface: interface name - * @name: signal name - * @type: first argument type - * @args: argument list - * - * Emit a signal for the given path and interface with - * the given signal name. - * - * The signal signature will be check against the registered - * signal table. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_emit_signal_valist(DBusConnection *connection, - const char *path, const char *interface, - const char *name, int type, va_list args) -{ - ObjectData *object; - BDBusSignalTable *signal; - DBusMessage *message; - const char *signature; - gboolean result = FALSE; - - DBG("connection %p path %s name %s.%s", - connection, path, interface, name); - - if (dbus_connection_get_object_path_data(connection, - path, (void *) &object) == FALSE) - return FALSE; - - if (object == NULL) - return FALSE; - - signal = find_signal(object->interfaces, interface, name); - if (signal == NULL) - return FALSE; - - message = dbus_message_new_signal(path, interface, name); - if (message == NULL) - return FALSE; - - if (dbus_message_append_args_valist(message, type, args) == FALSE) - goto done; - - signature = dbus_message_get_signature(message); - if (strcmp(signal->signature, signature) != 0) - goto done; - - DBG("connection %p signature \"%s\"", connection, signature); - - if (dbus_connection_send(connection, message, NULL) == FALSE) - goto done; - - result = TRUE; - -done: - dbus_message_unref(message); - - return result; -} - -/** - * b_dbus_emit_signal: - * @connection: the connection - * @path: object path - * @interface: interface name - * @name: signal name - * @type: first argument type - * @varargs: list of parameters - * - * Emit a signal for the given path and interface with - * the given signal name. - * - * The signal signature will be check against the registered - * signal table. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_emit_signal(DBusConnection *connection, - const char *path, const char *interface, - const char *name, int type, ...) -{ - va_list args; - gboolean result; - - DBG("connection %p path %s name %s.%s", - connection, path, interface, name); - - va_start(args, type); - - result = b_dbus_emit_signal_valist(connection, path, interface, - name, type, args); - - va_end(args); - - return result; -} diff --git a/src/gdbus/test/example.cpp b/src/gdbus/test/example.cpp deleted file mode 100644 index be155759..00000000 --- a/src/gdbus/test/example.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - * - * Library for simple D-Bus integration with GLib - * - * Copyright (C) 2009 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <sys/signal.h> - -#include "gdbus-cxx-bridge.h" -#include <memory> -#include <iostream> - -namespace GDBusCXX { - -struct args { - int a; - std::string b; - std::map<std::string, std::string> c; -}; - -static void hello_global() {} - -class Test { - typedef boost::shared_ptr< Result1<const std::string&> > string_result; - struct async - { - async(const boost::shared_ptr<Watch> &watch, Watch *watch2, const string_result &result): - m_watch(watch), - m_watch2(watch2), - m_result(result) - {} - ~async() - { - delete m_watch2; - } - - boost::shared_ptr<Watch> m_watch; - Watch *m_watch2; - string_result m_result; - }; - - - static gboolean method_idle(gpointer data) - { - std::unique_ptr<async> mydata(static_cast<async *>(data)); - std::cout << "replying to method_async" << std::endl; - mydata->m_result->done("Hello World, asynchronous and delayed"); - return false; - } - - static void disconnect(const std::string &id, const std::string &peer) - { - std::cout << id << ": " << peer << " has disconnected." << std::endl; - } - -public: - - static void hello_static() {} - void hello_const() const {} - static void hello_world(const char *msg) { puts(msg); } - void hello_base() {} - - void method(std::string &text) - { - text = "Hello World"; - } - - void method_async(const Caller_t &caller, - const boost::shared_ptr<Watch> &watch, - int32_t secs, - const string_result &r) - { - watch->setCallback(boost::bind(disconnect, "watch1", caller)); - Watch *watch2 = r->createWatch(boost::bind(disconnect, "watch2", caller)); - std::cout << "method_async called by " << caller << " delay " << secs << std::endl; - g_timeout_add_seconds(secs, method_idle, new async(watch, watch2, r)); - } - - void method2(int32_t arg, int32_t &ret) - { - ret = arg * 2; - } - - int32_t method3(int32_t arg) - { - return arg * 3; - } - - void method8_simple(int32_t a1, int32_t a2, int32_t a3, int32_t a4, int32_t a5, - int32_t a6, int32_t a7, int32_t a8) - { - } - - void method9_async(Result9<int32_t, int32_t, int32_t, int32_t, int32_t, - int32_t, int32_t, int32_t, int32_t> *r) - { - r->done(1, 2, 3, 4, 5, 6, 7, 8, 9); - delete r; - } - - int32_t method9(int32_t a1, int32_t a2, int32_t a3, int32_t a4, int32_t a5, - int32_t a6, int32_t a7, int32_t a8, int32_t a9) - { - return 0; - } - - - void hash(const std::map<int8_t, int32_t> &in, std::map<int16_t, int32_t> &out) - { - for (std::map<int8_t, int32_t>::const_iterator it = in.begin(); - it != in.end(); - ++it) { - out.insert(std::make_pair((int16_t)it->first, it->second * it->second)); - } - } - - void array(const std::vector<int32_t> &in, std::vector<int32_t> &out) - { - for (std::vector<int32_t>::const_iterator it = in.begin(); - it != in.end(); - ++it) { - out.push_back(*it * *it); - } - } - - void error() - { - throw dbus_error("org.example.error.Invalid", "error"); - } - - void argtest(const args &in, args &out) - { - out = in; - out.a = in.a + 1; - } -}; - -class Test2 -{ -public: - void test2() {} -}; - -template<> struct dbus_traits<args> : - public dbus_struct_traits<args, dbus_member<args, int, &args::a, - dbus_member<args, std::string, &args::b, - dbus_member_single<args, std::map<std::string, std::string>, &args::c> > > > -{}; - -class DBusTest : public Test, private Test2 -{ - DBusObjectHelper m_object; - DBusObjectHelper m_secondary; - -public: - DBusTest(const DBusConnectionPtr conn) : - m_object(conn, "/test", "org.example.Test"), - // same path! - m_secondary(conn, m_object.getPath(), "org.example.Secondary"), - signal(m_object, "Signal") - { - m_object.add(this, &Test::method8_simple, "Method8Simple"); - // m_object.add(this, &Test::method10_async, "Method10Async", G_DBUS_METHOD_FLAG_ASYNC); - // m_object.add(this, &Test::method9, "Method9"); - m_object.add(this, &Test::method2, "Method2"); - m_object.add(this, &Test::method3, "Method3"); - m_object.add(this, &Test::method, "Test"); - m_object.add(this, &Test::method_async, "TestAsync"); - m_object.add(this, &Test::argtest, "ArgTest"); - m_object.add(this, &Test::hash, "Hash"); - m_object.add(this, &Test::array, "Array"); - m_object.add(this, &Test::error, "Error"); - m_object.add(&hello_global, "Global"); - m_object.add(&DBusTest::hello_static, "Static"); - m_object.add(static_cast<Test2 *>(this), &Test2::test2, "Private"); - // The hello_const() method cannot be registered - // because there is no matching MakeMethodEntry<> - // specialization for it or DBusObjectHelper::add() - // fails to determine the right function type, - // depending how one wants to interpret the problem. - // m_object.add2(this, &DBusTest::hello_const, "Const"); - - m_object.add(signal); - - m_secondary.add(this, &DBusTest::hello, "Hello"); - } - - ~DBusTest() - { - } - - EmitSignal3<int32_t, const std::string &, const std::map<int32_t, int32_t> &>signal; - - void hello() {} - static void hello_static() {} - void hello_const() const {} - - void activate() - { - m_secondary.activate(); - m_object.activate(); - } - - void deactivate() - { - m_object.deactivate(); - m_secondary.deactivate(); - } -}; - -static GMainLoop *main_loop = NULL; - -static void sig_term(int sig) -{ - g_main_loop_quit(main_loop); -} - -} // namespace GDBusCXX - -using namespace GDBusCXX; - -int main(int argc, char *argv[]) -{ - DBusConnectionPtr conn; - DBusErrorCXX err; - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = sig_term; - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); - - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - sigaction(SIGPIPE, &sa, NULL); - - main_loop = g_main_loop_new(NULL, FALSE); - - conn = dbus_get_bus_connection("SESSION", "org.example", false, &err); - if (!conn) { - if (dbus_error_is_set(&err) == TRUE) { - fprintf(stderr, "%s\n", err.message); - dbus_error_free(&err); - } else - fprintf(stderr, "Can't register with session bus\n"); - exit(1); - } - - std::unique_ptr<DBusTest> test(new DBusTest(conn)); - test->activate(); - test->signal(42, "hello world", std::map<int32_t, int32_t>()); - test->deactivate(); - test->activate(); - test->signal(123, "here I am again", std::map<int32_t, int32_t>()); - - g_main_loop_run(main_loop); - - test.reset(); - - g_main_loop_unref(main_loop); - - return 0; -} diff --git a/src/gdbus/test/test-example b/src/gdbus/test/test-example deleted file mode 100755 index ec056186..00000000 --- a/src/gdbus/test/test-example +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/python - -import dbus -from dbus.mainloop.glib import DBusGMainLoop -import gobject - -DBusGMainLoop(set_as_default=True) - -bus = dbus.SessionBus() - -dummy = dbus.Interface(bus.get_object('org.example', '/test'), - 'org.freedesktop.DBus.Introspectable') - -print dummy.Introspect() - - -object = dbus.Interface(bus.get_object('org.example', '/test'), - 'org.example.Secondary') -object.Hello() - -object = dbus.Interface(bus.get_object('org.example', '/test'), - 'org.example.Test') - -print object.Test() -print object.Method2(1) -print object.Method3(1) -print object.Hash({1: 1, 2: 2, 3: 3}) -print object.Array([1, 2, 3, 4]) -print object.ArgTest((1, 'hello', {'foo': 'bar'})) - -loop = gobject.MainLoop() - -def AsyncFinished(x=None): - print "TestAsync:", x - loop.quit() - -print object.TestAsync(2, - reply_handler=AsyncFinished, - error_handler=AsyncFinished) - -# This will trigger the "caller has disconnect" -# because our client-side time out will get us -# out of the loop and then we quit. -object.TestAsync(600, - reply_handler=AsyncFinished, - error_handler=AsyncFinished, - timeout=5) -loop.run() - -object.Error() diff --git a/src/gdbus/watch.c b/src/gdbus/watch.c deleted file mode 100644 index 41bad12e..00000000 --- a/src/gdbus/watch.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * - * Library for simple D-Bus integration with GLib - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include "gdbus.h" -#include "debug.h" - -static dbus_int32_t connection_slot = -1; - -typedef struct { - GSList *watches; - GSList *handlers; - guint next_id; -} ConnectionData; - -typedef struct { - guint id; - char *name; - void *user_data; - char *match; - BDBusWatchFunction connect; - BDBusWatchFunction disconn; - BDBusDestroyFunction destroy; -} WatchData; - -typedef struct { - guint id; - void *user_data; - BDBusWatchFunction function; - BDBusDestroyFunction destroy; -} DisconnectData; - -typedef struct { - guint id; - void *user_data; - char *match; - BDBusSignalFunction function; - BDBusDestroyFunction destroy; -} SignalData; - -static DBusHandlerResult signal_function(DBusConnection *connection, - DBusMessage *message, void *user_data) -{ - ConnectionData *data = user_data; - GSList *list; - - DBG("connection %p message %p", connection, message); - - for (list = data->handlers; list; list = list->next) { - SignalData *signal = list->data; - gboolean result; - - if (signal->function == NULL) - continue; - - result = signal->function(connection, message, - signal->user_data); - if (result == TRUE) - continue; - - if (signal->destroy != NULL) - signal->destroy(signal->user_data); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult owner_function(DBusConnection *connection, - DBusMessage *message, void *user_data) -{ - ConnectionData *data = user_data; - GSList *list; - const char *name, *old, *new; - - DBG("connection %p message %p", connection, message); - - if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &old, - DBUS_TYPE_STRING, &new, - DBUS_TYPE_INVALID) == FALSE) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - DBG("name %s \"%s\" => \"%s\"", name, old, new); - - /* - * Allow the watch to remove itself. That'll make the "list" pointer - * invalid, need to read it before calling the watch. - */ - list = data->watches; - while (list) { - WatchData *watch = list->data; - list = list->next; - - if (strcmp(name, watch->name) != 0) - continue; - - if (watch->connect != NULL && *old == '\0' && *new != '\0') - watch->connect(connection, watch->user_data); - - if (watch->disconn != NULL && *old != '\0' && *new == '\0') - watch->disconn(connection, watch->user_data); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult filter_function(DBusConnection *connection, - DBusMessage *message, void *user_data) -{ - if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, - "NameOwnerChanged") == TRUE) - return owner_function(connection, message, user_data); - - if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) - return signal_function(connection, message, user_data); - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static ConnectionData *get_connection_data(DBusConnection *connection) -{ - ConnectionData *data; - /* dbus_bool_t result; */ - - DBG("connection %p", connection); - - if (dbus_connection_allocate_data_slot(&connection_slot) == FALSE) - return NULL; - - DBG("connection slot %d", connection_slot); - - data = dbus_connection_get_data(connection, connection_slot); - if (data == NULL) { - data = g_try_new0(ConnectionData, 1); - if (data == NULL) { - dbus_connection_free_data_slot(&connection_slot); - return NULL; - } - - data->next_id = 1; - - if (dbus_connection_set_data(connection, connection_slot, - data, NULL) == FALSE) { - dbus_connection_free_data_slot(&connection_slot); - g_free(data); - return NULL; - } - - /* result = */ dbus_connection_add_filter(connection, - filter_function, data, NULL); - } - - return data; -} - -static void put_connection_data(DBusConnection *connection) -{ - dbus_connection_free_data_slot(&connection_slot); -} - -/** - * b_dbus_add_service_watch: - * @connection: the connection - * @name: unique or well known name - * @connect: function called on name connect - * @disconnect: function called on name disconnect - * @user_data: user data to pass to the function - * @destroy: function called to destroy user_data - * - * Add new watch to listen for connects and/or disconnects - * of a client for the given connection. - * - * Returns: identifier of the watch - */ -guint b_dbus_add_service_watch(DBusConnection *connection, const char *name, - BDBusWatchFunction connect, - BDBusWatchFunction disconnect, - void *user_data, BDBusDestroyFunction destroy) -{ - ConnectionData *data; - WatchData *watch; - DBusError error; - - DBG("connection %p name %s", connection, name); - - data = get_connection_data(connection); - if (data == NULL) - return 0; - - DBG("connection data %p", data); - - watch = g_try_new0(WatchData, 1); - if (watch == NULL) - goto error; - - watch->name = g_strdup(name); - if (watch->name == NULL) - goto error; - - watch->user_data = user_data; - - watch->connect = connect; - watch->disconn = disconnect; - watch->destroy = destroy; - watch->match = g_strdup_printf("interface=%s,member=NameOwnerChanged,arg0=%s", - DBUS_INTERFACE_DBUS, name); - if (watch->match == NULL) - goto error; - - dbus_error_init(&error); - - dbus_bus_add_match(connection, watch->match, &error); - - if (dbus_error_is_set(&error) == TRUE) { - dbus_error_free(&error); - goto error; - } - - watch->id = data->next_id++; - - data->watches = g_slist_append(data->watches, watch); - - DBG("tag %d", watch->id); - - return watch->id; - -error: - // Doesn't look valid: Possible null pointer dereference: watch - otherwise it is redundant to check it against null. - // cppcheck-suppress nullPointer - if (watch != NULL) { - g_free(watch->name); - g_free(watch->match); - } - g_free(watch); - - put_connection_data(connection); - - return 0; -} - -/** - * b_dbus_remove_watch: - * @connection: the connection - * @tag: watch identifier - * - * Removes the watch for the given identifier. - * - * Returns: #TRUE on success - */ -gboolean b_dbus_remove_watch(DBusConnection *connection, guint tag) -{ - ConnectionData *data; - GSList *list; - - DBG("connection %p tag %d", connection, tag); - - if (connection_slot < 0) - return FALSE; - - data = dbus_connection_get_data(connection, connection_slot); - if (data == NULL) - return FALSE; - - for (list = data->watches; list; list = list->next) { - WatchData *watch = list->data; - - if (watch->id == tag) { - data->watches = g_slist_remove(data->watches, watch); - if (watch->destroy != NULL) - watch->destroy(watch->user_data); - dbus_bus_remove_match(connection, watch->match, NULL); - g_free(watch->name); - g_free(watch->match); - g_free(watch); - goto done; - } - } - - for (list = data->handlers; list; list = list->next) { - SignalData *signal = list->data; - - if (signal->id == tag) { - data->handlers = g_slist_remove(data->handlers, signal); - if (signal->destroy != NULL) - signal->destroy(signal->user_data); - dbus_bus_remove_match(connection, signal->match, NULL); - g_free(signal->match); - g_free(signal); - goto done; - } - } - - return FALSE; - -done: - if (!data->watches && !data->handlers) { - dbus_connection_remove_filter(connection, - filter_function, data); - dbus_connection_set_data(connection, connection_slot, NULL, NULL); - g_free(data); - } - - dbus_connection_free_data_slot(&connection_slot); - - DBG("connection slot %d", connection_slot); - - return TRUE; -} - -/** - * b_dbus_remove_all_watches: - * @connection: the connection - * - * Removes all registered watches. - */ -void b_dbus_remove_all_watches(DBusConnection *connection) -{ - ConnectionData *data; - GSList *list; - - DBG("connection %p slot %d", connection, connection_slot); - - if (connection_slot < 0) - return; - - data = dbus_connection_get_data(connection, connection_slot); - if (data == NULL) - return; - - DBG("connection data %p", data); - - for (list = data->watches; list; list = list->next) { - WatchData *watch = list->data; - - DBG("watch data %p tag %d", watch, watch->id); - - if (watch->destroy != NULL) - watch->destroy(watch->user_data); - dbus_bus_remove_match(connection, watch->match, NULL); - g_free(watch->match); - g_free(watch->name); - g_free(watch); - - dbus_connection_free_data_slot(&connection_slot); - - DBG("connection slot %d", connection_slot); - } - - g_slist_free(data->watches); - - for (list = data->handlers; list; list = list->next) { - SignalData *signal = list->data; - - DBG("signal data %p tag %d", signal, signal->id); - - if (signal->destroy != NULL) - signal->destroy(signal->user_data); - dbus_bus_remove_match(connection, signal->match, NULL); - g_free(signal->match); - g_free(signal); - - dbus_connection_free_data_slot(&connection_slot); - - DBG("connection slot %d", connection_slot); - } - - g_slist_free(data->handlers); - - dbus_connection_remove_filter(connection, filter_function, data); - - g_free(data); -} - -static void disconnect_function(DBusConnection *connection, void *user_data) -{ - DisconnectData *data = user_data; - - // The callback function might remove the watch, - // which invalidates the data pointer. Remember - // the ID. - guint id = data->id; - - data->function(connection, data->user_data); - - b_dbus_remove_watch(connection, id); -} - -static void disconnect_release(void *user_data) -{ - g_free(user_data); -} - -/** - * b_dbus_add_disconnect_watch: - * @connection: the connection - * @name: unique or well known name - * @function: function called on name disconnect - * @user_data: user data to pass to the function - * @destroy: function called to destroy user_data - * - * Add new watch to listen for disconnect of a client - * for the given connection. - * - * After the callback has been called, this watch will be - * automatically removed. - * - * Returns: identifier of the watch - */ -guint b_dbus_add_disconnect_watch(DBusConnection *connection, - const char *name, BDBusWatchFunction function, - void *user_data, BDBusDestroyFunction destroy) -{ - DisconnectData *data; - - data = g_try_new0(DisconnectData, 1); - if (data == NULL) - return 0; - - data->user_data = user_data; - data->function = function; - data->destroy = destroy; - - data->id = b_dbus_add_service_watch(connection, name, NULL, - disconnect_function, data, disconnect_release); - - if (data->id == 0) { - g_free(data); - return 0; - } - - return data->id; -} - -/** - * b_dbus_add_signal_watch: - * @connection: the connection - * @rule: matching rule for this signal - * @function: function called when signal arrives - * @user_data: user data to pass to the function - * @destroy: function called to destroy user_data - * @is_bus_conn: whether the connection is with the bus - * - * Add new watch to listen for specific signals of - * a client for the given connection. - * - * If the callback returns #FALSE this watch will be - * automatically removed. - * - * Returns: identifier of the watch - */ -guint b_dbus_add_signal_watch(DBusConnection *connection, const char *rule, - BDBusSignalFunction function, void *user_data, - BDBusDestroyFunction destroy, gboolean is_bus_conn) -{ - ConnectionData *data; - SignalData *signal; - DBusError error; - - DBG("connection %p rule %s", connection, rule); - - data = get_connection_data(connection); - if (data == NULL) - return 0; - - DBG("connection data %p", data); - - signal = g_try_new0(SignalData, 1); - if (signal == NULL) - goto error; - - signal->match = g_strdup(rule); - if (!signal->match) - goto error; - - signal->user_data = user_data; - - signal->function = function; - signal->destroy = destroy; - - if (is_bus_conn) { - dbus_error_init(&error); - - dbus_bus_add_match(connection, rule, &error); - - if (dbus_error_is_set(&error) == TRUE) { - dbus_error_free(&error); - goto error; - } - } - - signal->id = data->next_id++; - - data->handlers = g_slist_append(data->handlers, signal); - - DBG("tag %d", signal->id); - - return signal->id; - -error: - // Doesn't look valid: Possible null pointer dereference: signal - otherwise it is redundant to check it against null. - // cppcheck-suppress nullPointer - if (signal) - g_free(signal->match); - g_free(signal); - - put_connection_data(connection); - - return 0; -} @@ -5,13 +5,8 @@ include $(top_srcdir)/src/gnome-bluetooth/gnome-bluetooth.am src_cppflags += -I$(top_srcdir)/src/gnome-bluetooth endif -if COND_GIO_GDBUS include $(top_srcdir)/src/gdbusxx/gdbusxx.am src_cppflags += -I$(top_srcdir)/src/gdbusxx -else -include $(top_srcdir)/src/gdbus/gdbus.am -src_cppflags += -I$(top_srcdir)/src/gdbus -endif if COND_CORE include $(top_srcdir)/src/syncevo/syncevo.am diff --git a/src/syncevo/syncevo.am b/src/syncevo/syncevo.am index 099d5ea5..88f73471 100644 --- a/src/syncevo/syncevo.am +++ b/src/syncevo/syncevo.am @@ -175,12 +175,10 @@ src_syncevo_sources = \ src/syncevo/TrackingSyncSource.h \ src/syncevo/TrackingSyncSource.cpp -if COND_GIO_GDBUS # Only useful in combination with GDBus GIO. src_syncevo_sources += \ src/syncevo/gsignond-pipe-stream.h \ src/syncevo/gsignond-pipe-stream.cpp -endif if ENABLE_ICAL src_syncevo_sources += \ |