- NO FUNCTIONAL CODE CHANGES!!!!

- changed code formating from tabs to spaces and others
- used astyle with this option:
  --style=ansi --indent=spaces=2 -M --pad-oper --unpad-paren --pad-header --align-pointer=name --lineend=linux
This commit is contained in:
Andreas Volz 2011-11-28 12:44:11 +01:00
parent b100e9d32a
commit 1c8e43e6d6
76 changed files with 5691 additions and 5492 deletions

View file

@ -15,13 +15,13 @@ static const char *ECHO_SERVER_NAME = "org.freedesktop.DBus.Examples.Echo";
static const char *ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo"; static const char *ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo";
EchoClient::EchoClient(DBus::Connection &connection, const char *path, const char *name) EchoClient::EchoClient(DBus::Connection &connection, const char *path, const char *name)
: DBus::ObjectProxy(connection, path, name) : DBus::ObjectProxy(connection, path, name)
{ {
} }
void EchoClient::Echoed(const DBus::Variant &value) void EchoClient::Echoed(const DBus::Variant &value)
{ {
cout << "!"; cout << "!";
} }
static const size_t THREADS = 3; static const size_t THREADS = 3;
@ -37,96 +37,96 @@ DBus::DefaultTimeout *timeout;
void *greeter_thread(void *arg) void *greeter_thread(void *arg)
{ {
char idstr[16]; char idstr[16];
size_t i = (size_t) arg; size_t i = (size_t) arg;
snprintf(idstr, sizeof(idstr), "%lu", pthread_self()); snprintf(idstr, sizeof(idstr), "%lu", pthread_self());
thread_pipe_list[i]->write (idstr, strlen (idstr) + 1); thread_pipe_list[i]->write(idstr, strlen(idstr) + 1);
cout << idstr << " done (" << i << ")" << endl; cout << idstr << " done (" << i << ")" << endl;
return NULL; return NULL;
} }
void niam(int sig) void niam(int sig)
{ {
spin = false; spin = false;
dispatcher.leave(); dispatcher.leave();
} }
void handler1 (const void *data, void *buffer, unsigned int nbyte) void handler1(const void *data, void *buffer, unsigned int nbyte)
{ {
char *str = (char*) buffer; char *str = (char *) buffer;
cout << "buffer1: " << str << ", size: " << nbyte << endl; cout << "buffer1: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i) for (int i = 0; i < 30 && spin; ++i)
{ {
cout << "call1: " << g_client->Hello (str) << endl; cout << "call1: " << g_client->Hello(str) << endl;
} }
} }
void handler2 (const void *data, void *buffer, unsigned int nbyte) void handler2(const void *data, void *buffer, unsigned int nbyte)
{ {
char *str = (char*) buffer; char *str = (char *) buffer;
cout << "buffer2: " << str << ", size: " << nbyte <<endl; cout << "buffer2: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i) for (int i = 0; i < 30 && spin; ++i)
{ {
cout << "call2: " << g_client->Hello (str) << endl; cout << "call2: " << g_client->Hello(str) << endl;
} }
} }
void handler3 (const void *data, void *buffer, unsigned int nbyte) void handler3(const void *data, void *buffer, unsigned int nbyte)
{ {
char *str = (char*) buffer; char *str = (char *) buffer;
cout << "buffer3: " << str << ", size: " << nbyte <<endl; cout << "buffer3: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i) for (int i = 0; i < 30 && spin; ++i)
{ {
cout << "call3: " << g_client->Hello (str) << endl; cout << "call3: " << g_client->Hello(str) << endl;
} }
} }
int main() int main()
{ {
size_t i; size_t i;
signal(SIGTERM, niam); signal(SIGTERM, niam);
signal(SIGINT, niam); signal(SIGINT, niam);
DBus::_init_threading(); DBus::_init_threading();
DBus::default_dispatcher = &dispatcher; DBus::default_dispatcher = &dispatcher;
// increase DBus-C++ frequency // increase DBus-C++ frequency
new DBus::DefaultTimeout(100, false, &dispatcher); new DBus::DefaultTimeout(100, false, &dispatcher);
DBus::Connection conn = DBus::Connection::SessionBus(); DBus::Connection conn = DBus::Connection::SessionBus();
EchoClient client (conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME); EchoClient client(conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME);
g_client = &client; g_client = &client;
pthread_t threads[THREADS]; pthread_t threads[THREADS];
thread_pipe_list[0] = dispatcher.add_pipe (handler1, NULL); thread_pipe_list[0] = dispatcher.add_pipe(handler1, NULL);
thread_pipe_list[1] = dispatcher.add_pipe (handler2, NULL); thread_pipe_list[1] = dispatcher.add_pipe(handler2, NULL);
thread_pipe_list[2] = dispatcher.add_pipe (handler3, NULL); thread_pipe_list[2] = dispatcher.add_pipe(handler3, NULL);
for (i = 0; i < THREADS; ++i) for (i = 0; i < THREADS; ++i)
{ {
pthread_create(threads+i, NULL, greeter_thread, (void*) i); pthread_create(threads + i, NULL, greeter_thread, (void *) i);
} }
dispatcher.enter();
cout << "terminating" << endl; dispatcher.enter();
for (i = 0; i < THREADS; ++i) cout << "terminating" << endl;
{
pthread_join(threads[i], NULL);
}
dispatcher.del_pipe (thread_pipe_list[0]); for (i = 0; i < THREADS; ++i)
dispatcher.del_pipe (thread_pipe_list[1]); {
dispatcher.del_pipe (thread_pipe_list[2]); pthread_join(threads[i], NULL);
}
return 0; dispatcher.del_pipe(thread_pipe_list[0]);
dispatcher.del_pipe(thread_pipe_list[1]);
dispatcher.del_pipe(thread_pipe_list[2]);
return 0;
} }

View file

@ -5,15 +5,15 @@
#include "echo-client-glue.h" #include "echo-client-glue.h"
class EchoClient class EchoClient
: public org::freedesktop::DBus::EchoDemo_proxy, : public org::freedesktop::DBus::EchoDemo_proxy,
public DBus::IntrospectableProxy, public DBus::IntrospectableProxy,
public DBus::ObjectProxy public DBus::ObjectProxy
{ {
public: public:
EchoClient(DBus::Connection &connection, const char *path, const char *name); EchoClient(DBus::Connection &connection, const char *path, const char *name);
void Echoed(const DBus::Variant &value); void Echoed(const DBus::Variant &value);
}; };
#endif//__DEMO_ECHO_CLIENT_H #endif//__DEMO_ECHO_CLIENT_H

View file

@ -13,61 +13,61 @@ static const char *ECHO_SERVER_NAME = "org.freedesktop.DBus.Examples.Echo";
static const char *ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo"; static const char *ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo";
EchoServer::EchoServer(DBus::Connection &connection) EchoServer::EchoServer(DBus::Connection &connection)
: DBus::ObjectAdaptor(connection, ECHO_SERVER_PATH) : DBus::ObjectAdaptor(connection, ECHO_SERVER_PATH)
{ {
} }
int32_t EchoServer::Random() int32_t EchoServer::Random()
{ {
return rand(); return rand();
} }
std::string EchoServer::Hello(const std::string &name) std::string EchoServer::Hello(const std::string &name)
{ {
return "Hello " + name + "!"; return "Hello " + name + "!";
} }
DBus::Variant EchoServer::Echo(const DBus::Variant &value) DBus::Variant EchoServer::Echo(const DBus::Variant &value)
{ {
this->Echoed(value); this->Echoed(value);
return value; return value;
} }
std::vector< uint8_t > EchoServer::Cat(const std::string &file) std::vector< uint8_t > EchoServer::Cat(const std::string &file)
{ {
FILE *handle = fopen(file.c_str(), "rb"); FILE *handle = fopen(file.c_str(), "rb");
if (!handle) throw DBus::Error("org.freedesktop.DBus.EchoDemo.ErrorFileNotFound", "file not found"); if (!handle) throw DBus::Error("org.freedesktop.DBus.EchoDemo.ErrorFileNotFound", "file not found");
uint8_t buff[1024]; uint8_t buff[1024];
size_t nread = fread(buff, 1, sizeof(buff), handle); size_t nread = fread(buff, 1, sizeof(buff), handle);
fclose(handle); fclose(handle);
return std::vector< uint8_t > (buff, buff + nread); return std::vector< uint8_t > (buff, buff + nread);
} }
int32_t EchoServer::Sum(const std::vector<int32_t>& ints) int32_t EchoServer::Sum(const std::vector<int32_t>& ints)
{ {
int32_t sum = 0; int32_t sum = 0;
for (size_t i = 0; i < ints.size(); ++i) sum += ints[i]; for (size_t i = 0; i < ints.size(); ++i) sum += ints[i];
return sum; return sum;
} }
std::map< std::string, std::string > EchoServer::Info() std::map< std::string, std::string > EchoServer::Info()
{ {
std::map< std::string, std::string > info; std::map< std::string, std::string > info;
char hostname[HOST_NAME_MAX]; char hostname[HOST_NAME_MAX];
gethostname(hostname, sizeof(hostname)); gethostname(hostname, sizeof(hostname));
info["hostname"] = hostname; info["hostname"] = hostname;
info["username"] = getlogin(); info["username"] = getlogin();
return info; return info;
} }
@ -75,22 +75,22 @@ DBus::BusDispatcher dispatcher;
void niam(int sig) void niam(int sig)
{ {
dispatcher.leave(); dispatcher.leave();
} }
int main() int main()
{ {
signal(SIGTERM, niam); signal(SIGTERM, niam);
signal(SIGINT, niam); signal(SIGINT, niam);
DBus::default_dispatcher = &dispatcher; DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SessionBus(); DBus::Connection conn = DBus::Connection::SessionBus();
conn.request_name(ECHO_SERVER_NAME); conn.request_name(ECHO_SERVER_NAME);
EchoServer server(conn); EchoServer server(conn);
dispatcher.enter(); dispatcher.enter();
return 0; return 0;
} }

View file

@ -5,25 +5,25 @@
#include "echo-server-glue.h" #include "echo-server-glue.h"
class EchoServer class EchoServer
: public org::freedesktop::DBus::EchoDemo_adaptor, : public org::freedesktop::DBus::EchoDemo_adaptor,
public DBus::IntrospectableAdaptor, public DBus::IntrospectableAdaptor,
public DBus::ObjectAdaptor public DBus::ObjectAdaptor
{ {
public: public:
EchoServer(DBus::Connection &connection); EchoServer(DBus::Connection &connection);
int32_t Random(); int32_t Random();
std::string Hello(const std::string &name); std::string Hello(const std::string &name);
DBus::Variant Echo(const DBus::Variant &value); DBus::Variant Echo(const DBus::Variant &value);
std::vector< uint8_t > Cat(const std::string &file); std::vector< uint8_t > Cat(const std::string &file);
int32_t Sum(const std::vector<int32_t> & ints); int32_t Sum(const std::vector<int32_t> & ints);
std::map< std::string, std::string > Info(); std::map< std::string, std::string > Info();
}; };
#endif//__DEMO_ECHO_SERVER_H #endif//__DEMO_ECHO_SERVER_H

View file

@ -15,13 +15,13 @@ static const char *ECHO_SERVER_NAME = "org.freedesktop.DBus.Examples.Echo";
static const char *ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo"; static const char *ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo";
EchoClient::EchoClient(DBus::Connection &connection, const char *path, const char *name) EchoClient::EchoClient(DBus::Connection &connection, const char *path, const char *name)
: DBus::ObjectProxy(connection, path, name) : DBus::ObjectProxy(connection, path, name)
{ {
} }
void EchoClient::Echoed(const DBus::Variant &value) void EchoClient::Echoed(const DBus::Variant &value)
{ {
cout << "!"; cout << "!";
} }
/* /*
@ -41,101 +41,101 @@ DBus::Ecore::BusDispatcher dispatcher;
void *greeter_thread(void *arg) void *greeter_thread(void *arg)
{ {
char idstr[16]; char idstr[16];
size_t i = (size_t) arg; size_t i = (size_t) arg;
snprintf(idstr, sizeof(idstr), "%lu", pthread_self()); snprintf(idstr, sizeof(idstr), "%lu", pthread_self());
thread_pipe_list[i]->write (idstr, strlen (idstr) + 1); thread_pipe_list[i]->write(idstr, strlen(idstr) + 1);
cout << idstr << " done (" << i << ")" << endl; cout << idstr << " done (" << i << ")" << endl;
return NULL; return NULL;
} }
void niam(int sig) void niam(int sig)
{ {
spin = false; spin = false;
ecore_main_loop_quit(); ecore_main_loop_quit();
} }
void handler1 (const void *data, void *buffer, unsigned int nbyte) void handler1(const void *data, void *buffer, unsigned int nbyte)
{ {
char *str = (char*) buffer; char *str = (char *) buffer;
cout << "buffer1: " << str << ", size: " << nbyte << endl; cout << "buffer1: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i) for (int i = 0; i < 30 && spin; ++i)
{ {
cout << "call1: " << g_client->Hello (str) << endl; cout << "call1: " << g_client->Hello(str) << endl;
} }
} }
void handler2 (const void *data, void *buffer, unsigned int nbyte) void handler2(const void *data, void *buffer, unsigned int nbyte)
{ {
char *str = (char*) buffer; char *str = (char *) buffer;
cout << "buffer2: " << str << ", size: " << nbyte <<endl; cout << "buffer2: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i) for (int i = 0; i < 30 && spin; ++i)
{ {
cout << "call2: " << g_client->Hello (str) << endl; cout << "call2: " << g_client->Hello(str) << endl;
} }
} }
void handler3 (const void *data, void *buffer, unsigned int nbyte) void handler3(const void *data, void *buffer, unsigned int nbyte)
{ {
char *str = (char*) buffer; char *str = (char *) buffer;
cout << "buffer3: " << str << ", size: " << nbyte <<endl; cout << "buffer3: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i) for (int i = 0; i < 30 && spin; ++i)
{ {
cout << "call3: " << g_client->Hello (str) << endl; cout << "call3: " << g_client->Hello(str) << endl;
} }
} }
int main() int main()
{ {
size_t i; size_t i;
signal(SIGTERM, niam); signal(SIGTERM, niam);
signal(SIGINT, niam); signal(SIGINT, niam);
ecore_init(); ecore_init();
//DBus::_init_threading(); //DBus::_init_threading();
DBus::default_dispatcher = &dispatcher; DBus::default_dispatcher = &dispatcher;
// increase DBus-C++ frequency // increase DBus-C++ frequency
//new DBus::DefaultTimeout(100, false, &dispatcher); //new DBus::DefaultTimeout(100, false, &dispatcher);
DBus::Connection conn = DBus::Connection::SessionBus(); DBus::Connection conn = DBus::Connection::SessionBus();
EchoClient client (conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME); EchoClient client(conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME);
g_client = &client; g_client = &client;
pthread_t threads[THREADS]; pthread_t threads[THREADS];
/* thread_pipe_list[0] = dispatcher.add_pipe (handler1, NULL); /* thread_pipe_list[0] = dispatcher.add_pipe (handler1, NULL);
thread_pipe_list[1] = dispatcher.add_pipe (handler2, NULL); thread_pipe_list[1] = dispatcher.add_pipe (handler2, NULL);
thread_pipe_list[2] = dispatcher.add_pipe (handler3, NULL);*/ thread_pipe_list[2] = dispatcher.add_pipe (handler3, NULL);*/
for (i = 0; i < THREADS; ++i) for (i = 0; i < THREADS; ++i)
{ {
//pthread_create(threads+i, NULL, greeter_thread, (void*) i); //pthread_create(threads+i, NULL, greeter_thread, (void*) i);
} }
//dispatcher.enter();
cout << "terminating" << endl; //dispatcher.enter();
for (i = 0; i < THREADS; ++i) cout << "terminating" << endl;
{
pthread_join(threads[i], NULL);
}
/*dispatcher.del_pipe (thread_pipe_list[0]); for (i = 0; i < THREADS; ++i)
dispatcher.del_pipe (thread_pipe_list[1]); {
dispatcher.del_pipe (thread_pipe_list[2]);*/ pthread_join(threads[i], NULL);
}
/*dispatcher.del_pipe (thread_pipe_list[0]);
dispatcher.del_pipe (thread_pipe_list[1]);
dispatcher.del_pipe (thread_pipe_list[2]);*/
ecore_main_loop_begin(); ecore_main_loop_begin();
ecore_shutdown(); ecore_shutdown();
return 0; return 0;
} }

View file

@ -8,15 +8,15 @@
#include "echo-client-glue.h" #include "echo-client-glue.h"
class EchoClient class EchoClient
: public org::freedesktop::DBus::EchoDemo_proxy, : public org::freedesktop::DBus::EchoDemo_proxy,
public DBus::IntrospectableProxy, public DBus::IntrospectableProxy,
public DBus::ObjectProxy public DBus::ObjectProxy
{ {
public: public:
EchoClient(DBus::Connection &connection, const char *path, const char *name); EchoClient(DBus::Connection &connection, const char *path, const char *name);
void Echoed(const DBus::Variant &value); void Echoed(const DBus::Variant &value);
}; };
#endif//__DEMO_ECHO_CLIENT_H #endif//__DEMO_ECHO_CLIENT_H

View file

@ -13,61 +13,61 @@ static const char *ECHO_SERVER_NAME = "org.freedesktop.DBus.Examples.Echo";
static const char *ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo"; static const char *ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo";
EchoServer::EchoServer(DBus::Connection &connection) EchoServer::EchoServer(DBus::Connection &connection)
: DBus::ObjectAdaptor(connection, ECHO_SERVER_PATH) : DBus::ObjectAdaptor(connection, ECHO_SERVER_PATH)
{ {
} }
int32_t EchoServer::Random() int32_t EchoServer::Random()
{ {
return rand(); return rand();
} }
std::string EchoServer::Hello(const std::string &name) std::string EchoServer::Hello(const std::string &name)
{ {
return "Hello " + name + "!"; return "Hello " + name + "!";
} }
DBus::Variant EchoServer::Echo(const DBus::Variant &value) DBus::Variant EchoServer::Echo(const DBus::Variant &value)
{ {
this->Echoed(value); this->Echoed(value);
return value; return value;
} }
std::vector< uint8_t > EchoServer::Cat(const std::string &file) std::vector< uint8_t > EchoServer::Cat(const std::string &file)
{ {
FILE *handle = fopen(file.c_str(), "rb"); FILE *handle = fopen(file.c_str(), "rb");
if (!handle) throw DBus::Error("org.freedesktop.DBus.EchoDemo.ErrorFileNotFound", "file not found"); if (!handle) throw DBus::Error("org.freedesktop.DBus.EchoDemo.ErrorFileNotFound", "file not found");
uint8_t buff[1024]; uint8_t buff[1024];
size_t nread = fread(buff, 1, sizeof(buff), handle); size_t nread = fread(buff, 1, sizeof(buff), handle);
fclose(handle); fclose(handle);
return std::vector< uint8_t > (buff, buff + nread); return std::vector< uint8_t > (buff, buff + nread);
} }
int32_t EchoServer::Sum(const std::vector<int32_t>& ints) int32_t EchoServer::Sum(const std::vector<int32_t>& ints)
{ {
int32_t sum = 0; int32_t sum = 0;
for (size_t i = 0; i < ints.size(); ++i) sum += ints[i]; for (size_t i = 0; i < ints.size(); ++i) sum += ints[i];
return sum; return sum;
} }
std::map< std::string, std::string > EchoServer::Info() std::map< std::string, std::string > EchoServer::Info()
{ {
std::map< std::string, std::string > info; std::map< std::string, std::string > info;
char hostname[HOST_NAME_MAX]; char hostname[HOST_NAME_MAX];
gethostname(hostname, sizeof(hostname)); gethostname(hostname, sizeof(hostname));
info["hostname"] = hostname; info["hostname"] = hostname;
info["username"] = getlogin(); info["username"] = getlogin();
return info; return info;
} }
DBus::Ecore::BusDispatcher dispatcher; DBus::Ecore::BusDispatcher dispatcher;
@ -75,25 +75,25 @@ DBus::Ecore::BusDispatcher dispatcher;
void niam(int sig) void niam(int sig)
{ {
ecore_main_loop_quit(); ecore_main_loop_quit();
} }
int main() int main()
{ {
signal(SIGTERM, niam); signal(SIGTERM, niam);
signal(SIGINT, niam); signal(SIGINT, niam);
ecore_init(); ecore_init();
DBus::default_dispatcher = &dispatcher; DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SessionBus(); DBus::Connection conn = DBus::Connection::SessionBus();
conn.request_name(ECHO_SERVER_NAME); conn.request_name(ECHO_SERVER_NAME);
EchoServer server(conn);
EchoServer server(conn);
ecore_main_loop_begin(); ecore_main_loop_begin();
ecore_shutdown(); ecore_shutdown();
return 0; return 0;
} }

View file

@ -8,25 +8,25 @@
#include "echo-server-glue.h" #include "echo-server-glue.h"
class EchoServer class EchoServer
: public org::freedesktop::DBus::EchoDemo_adaptor, : public org::freedesktop::DBus::EchoDemo_adaptor,
public DBus::IntrospectableAdaptor, public DBus::IntrospectableAdaptor,
public DBus::ObjectAdaptor public DBus::ObjectAdaptor
{ {
public: public:
EchoServer(DBus::Connection &connection); EchoServer(DBus::Connection &connection);
int32_t Random(); int32_t Random();
std::string Hello(const std::string &name); std::string Hello(const std::string &name);
DBus::Variant Echo(const DBus::Variant &value); DBus::Variant Echo(const DBus::Variant &value);
std::vector< uint8_t > Cat(const std::string &file); std::vector< uint8_t > Cat(const std::string &file);
int32_t Sum(const std::vector<int32_t> & ints); int32_t Sum(const std::vector<int32_t> & ints);
std::map< std::string, std::string > Info(); std::map< std::string, std::string > Info();
}; };
#endif//__DEMO_ECHO_SERVER_H #endif//__DEMO_ECHO_SERVER_H

View file

@ -10,62 +10,62 @@
using namespace std; using namespace std;
static const char* DBUS_SERVER_NAME = "org.freedesktop.DBus"; static const char *DBUS_SERVER_NAME = "org.freedesktop.DBus";
static const char* DBUS_SERVER_PATH = "/org/freedesktop/DBus"; static const char *DBUS_SERVER_PATH = "/org/freedesktop/DBus";
typedef vector <string> Names; typedef vector <string> Names;
DBusBrowser::DBusBrowser( ::DBus::Connection& conn ) DBusBrowser::DBusBrowser(::DBus::Connection &conn)
: ::DBus::ObjectProxy(conn, DBUS_SERVER_PATH, DBUS_SERVER_NAME) : ::DBus::ObjectProxy(conn, DBUS_SERVER_PATH, DBUS_SERVER_NAME)
{ {
typedef std::vector< std::string > Names; typedef std::vector< std::string > Names;
Names names = ListNames(); Names names = ListNames();
for(Names::iterator it = names.begin(); it != names.end(); ++it) for (Names::iterator it = names.begin(); it != names.end(); ++it)
{ {
cout << *it << endl; cout << *it << endl;
} }
} }
void DBusBrowser::NameOwnerChanged( void DBusBrowser::NameOwnerChanged(
const std::string& name, const std::string& old_owner, const std::string& new_owner ) const std::string &name, const std::string &old_owner, const std::string &new_owner)
{ {
cout << name << ": " << old_owner << " -> " << new_owner << endl; cout << name << ": " << old_owner << " -> " << new_owner << endl;
} }
void DBusBrowser::NameLost( const std::string& name ) void DBusBrowser::NameLost(const std::string &name)
{ {
cout << name << " lost" << endl; cout << name << " lost" << endl;
} }
void DBusBrowser::NameAcquired( const std::string& name ) void DBusBrowser::NameAcquired(const std::string &name)
{ {
cout << name << " acquired" << endl; cout << name << " acquired" << endl;
} }
DBus::Ecore::BusDispatcher dispatcher; DBus::Ecore::BusDispatcher dispatcher;
void niam( int sig ) void niam(int sig)
{ {
ecore_main_loop_quit(); ecore_main_loop_quit();
} }
int main(int argc, char* argv[]) int main(int argc, char *argv[])
{ {
signal(SIGTERM, niam); signal(SIGTERM, niam);
signal(SIGINT, niam); signal(SIGINT, niam);
ecore_init();
DBus::default_dispatcher = &dispatcher; ecore_init();
DBus::Connection conn = DBus::Connection::SessionBus(); DBus::default_dispatcher = &dispatcher;
DBusBrowser browser(conn); DBus::Connection conn = DBus::Connection::SessionBus();
DBusBrowser browser(conn);
ecore_main_loop_begin(); ecore_main_loop_begin();
ecore_shutdown(); ecore_shutdown();
return 0; return 0;
} }

View file

@ -8,21 +8,21 @@
#include "dbus_ecore-glue.h" #include "dbus_ecore-glue.h"
class DBusBrowser class DBusBrowser
: public org::freedesktop::DBus_proxy, : public org::freedesktop::DBus_proxy,
public DBus::IntrospectableProxy, public DBus::IntrospectableProxy,
public DBus::ObjectProxy public DBus::ObjectProxy
{ {
public: public:
DBusBrowser( ::DBus::Connection& conn ); DBusBrowser(::DBus::Connection &conn);
private: private:
void NameOwnerChanged( const std::string&, const std::string&, const std::string& ); void NameOwnerChanged(const std::string &, const std::string &, const std::string &);
void NameLost( const std::string& ); void NameLost(const std::string &);
void NameAcquired( const std::string& ); void NameAcquired(const std::string &);
private: private:

View file

@ -9,131 +9,131 @@ static const char *DBUS_SERVER_NAME = "org.freedesktop.DBus";
static const char *DBUS_SERVER_PATH = "/org/freedesktop/DBus"; static const char *DBUS_SERVER_PATH = "/org/freedesktop/DBus";
DBusBrowser::DBusBrowser(::DBus::Connection &conn) DBusBrowser::DBusBrowser(::DBus::Connection &conn)
: ::DBus::ObjectProxy(conn, DBUS_SERVER_PATH, DBUS_SERVER_NAME) : ::DBus::ObjectProxy(conn, DBUS_SERVER_PATH, DBUS_SERVER_NAME)
{ {
set_title("D-Bus Browser"); set_title("D-Bus Browser");
set_border_width(5); set_border_width(5);
set_default_size(400, 500); set_default_size(400, 500);
typedef std::vector< std::string > Names; typedef std::vector< std::string > Names;
Names names = ListNames(); Names names = ListNames();
for (Names::iterator it = names.begin(); it != names.end(); ++it) for (Names::iterator it = names.begin(); it != names.end(); ++it)
{ {
_cb_busnames.append_text(*it); _cb_busnames.append_text(*it);
} }
_cb_busnames.signal_changed().connect(sigc::mem_fun(*this, &DBusBrowser::on_select_busname)); _cb_busnames.signal_changed().connect(sigc::mem_fun(*this, &DBusBrowser::on_select_busname));
_tm_inspect = Gtk::TreeStore::create(_records); _tm_inspect = Gtk::TreeStore::create(_records);
_tv_inspect.set_model(_tm_inspect); _tv_inspect.set_model(_tm_inspect);
_tv_inspect.append_column("Node", _records.name); _tv_inspect.append_column("Node", _records.name);
_sc_tree.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); _sc_tree.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
_sc_tree.add(_tv_inspect); _sc_tree.add(_tv_inspect);
_vbox.pack_start(_cb_busnames, Gtk::PACK_SHRINK); _vbox.pack_start(_cb_busnames, Gtk::PACK_SHRINK);
_vbox.pack_start(_sc_tree); _vbox.pack_start(_sc_tree);
add(_vbox); add(_vbox);
show_all_children(); show_all_children();
} }
void DBusBrowser::NameOwnerChanged( void DBusBrowser::NameOwnerChanged(
const std::string &name, const std::string &old_owner, const std::string &new_owner) const std::string &name, const std::string &old_owner, const std::string &new_owner)
{ {
cout << name << ": " << old_owner << " -> " << new_owner << endl; cout << name << ": " << old_owner << " -> " << new_owner << endl;
} }
void DBusBrowser::NameLost(const std::string &name) void DBusBrowser::NameLost(const std::string &name)
{ {
cout << name << " lost" << endl; cout << name << " lost" << endl;
} }
void DBusBrowser::NameAcquired(const std::string &name) void DBusBrowser::NameAcquired(const std::string &name)
{ {
cout << name << " acquired" << endl; cout << name << " acquired" << endl;
} }
void DBusBrowser::on_select_busname() void DBusBrowser::on_select_busname()
{ {
Glib::ustring busname = _cb_busnames.get_active_text(); Glib::ustring busname = _cb_busnames.get_active_text();
if (busname.empty()) return; if (busname.empty()) return;
_tm_inspect->clear(); _tm_inspect->clear();
_inspect_append(NULL, "", busname); _inspect_append(NULL, "", busname);
} }
void DBusBrowser::_inspect_append(Gtk::TreeModel::Row *row, const std::string &buspath, const std::string &busname) void DBusBrowser::_inspect_append(Gtk::TreeModel::Row *row, const std::string &buspath, const std::string &busname)
{ {
DBusInspector inspector(conn(), buspath.empty() ? "/" : buspath.c_str(), busname.c_str()); DBusInspector inspector(conn(), buspath.empty() ? "/" : buspath.c_str(), busname.c_str());
::DBus::Xml::Document doc(inspector.Introspect()); ::DBus::Xml::Document doc(inspector.Introspect());
::DBus::Xml::Node &root = *(doc.root); ::DBus::Xml::Node &root = *(doc.root);
::DBus::Xml::Nodes ifaces = root["interface"]; ::DBus::Xml::Nodes ifaces = root["interface"];
for (::DBus::Xml::Nodes::iterator ii = ifaces.begin(); ii != ifaces.end(); ++ii) for (::DBus::Xml::Nodes::iterator ii = ifaces.begin(); ii != ifaces.end(); ++ii)
{ {
::DBus::Xml::Node &iface = **ii; ::DBus::Xml::Node &iface = **ii;
Gtk::TreeModel::Row i_row = row Gtk::TreeModel::Row i_row = row
? *(_tm_inspect->append(row->children())) ? *(_tm_inspect->append(row->children()))
: *(_tm_inspect->append()); : *(_tm_inspect->append());
i_row[_records.name] = "interface: " + iface.get("name"); i_row[_records.name] = "interface: " + iface.get("name");
::DBus::Xml::Nodes methods = iface["method"]; ::DBus::Xml::Nodes methods = iface["method"];
for (::DBus::Xml::Nodes::iterator im = methods.begin(); im != methods.end(); ++im) for (::DBus::Xml::Nodes::iterator im = methods.begin(); im != methods.end(); ++im)
{ {
Gtk::TreeModel::Row m_row = *(_tm_inspect->append(i_row.children())); Gtk::TreeModel::Row m_row = *(_tm_inspect->append(i_row.children()));
m_row[_records.name] = "method: " + (*im)->get("name"); m_row[_records.name] = "method: " + (*im)->get("name");
} }
::DBus::Xml::Nodes signals = iface["signal"]; ::DBus::Xml::Nodes signals = iface["signal"];
for (::DBus::Xml::Nodes::iterator is = signals.begin(); is != signals.end(); ++is) for (::DBus::Xml::Nodes::iterator is = signals.begin(); is != signals.end(); ++is)
{ {
Gtk::TreeModel::Row s_row = *(_tm_inspect->append(i_row.children())); Gtk::TreeModel::Row s_row = *(_tm_inspect->append(i_row.children()));
s_row[_records.name] = "signal: " + (*is)->get("name"); s_row[_records.name] = "signal: " + (*is)->get("name");
} }
} }
::DBus::Xml::Nodes nodes = root["node"]; ::DBus::Xml::Nodes nodes = root["node"];
for (::DBus::Xml::Nodes::iterator in = nodes.begin(); in != nodes.end(); ++in) for (::DBus::Xml::Nodes::iterator in = nodes.begin(); in != nodes.end(); ++in)
{ {
std::string name = (*in)->get("name"); std::string name = (*in)->get("name");
Gtk::TreeModel::Row n_row = row Gtk::TreeModel::Row n_row = row
? *(_tm_inspect->append(row->children())) ? *(_tm_inspect->append(row->children()))
: *(_tm_inspect->append()); : *(_tm_inspect->append());
n_row[_records.name] = name; n_row[_records.name] = name;
_inspect_append(&n_row, buspath + "/" + name, busname); _inspect_append(&n_row, buspath + "/" + name, busname);
} }
} }
DBus::Glib::BusDispatcher dispatcher; DBus::Glib::BusDispatcher dispatcher;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
Gtk::Main kit(argc, argv); Gtk::Main kit(argc, argv);
DBus::default_dispatcher = &dispatcher; DBus::default_dispatcher = &dispatcher;
dispatcher.attach(NULL); dispatcher.attach(NULL);
// activate one of both for either system or session bus // activate one of both for either system or session bus
// TODO: choose in the GUI // TODO: choose in the GUI
DBus::Connection conn = DBus::Connection::SessionBus(); DBus::Connection conn = DBus::Connection::SessionBus();
//DBus::Connection conn = DBus::Connection::SystemBus(); //DBus::Connection conn = DBus::Connection::SystemBus();
DBusBrowser browser(conn); DBusBrowser browser(conn);
Gtk::Main::run(browser); Gtk::Main::run(browser);
return 0; return 0;
} }

View file

@ -8,55 +8,58 @@
#include "dbus-glue.h" #include "dbus-glue.h"
class DBusInspector class DBusInspector
: public DBus::IntrospectableProxy, : public DBus::IntrospectableProxy,
public DBus::ObjectProxy public DBus::ObjectProxy
{ {
public: public:
DBusInspector(DBus::Connection &conn, const char *path, const char *service) DBusInspector(DBus::Connection &conn, const char *path, const char *service)
: DBus::ObjectProxy(conn, path, service) : DBus::ObjectProxy(conn, path, service)
{} {}
}; };
class DBusBrowser class DBusBrowser
: public org::freedesktop::DBus_proxy, : public org::freedesktop::DBus_proxy,
public DBus::IntrospectableProxy, public DBus::IntrospectableProxy,
public DBus::ObjectProxy, public DBus::ObjectProxy,
public Gtk::Window public Gtk::Window
{ {
public: public:
DBusBrowser(::DBus::Connection &); DBusBrowser(::DBus::Connection &);
private: private:
void NameOwnerChanged(const std::string &, const std::string &, const std::string &); void NameOwnerChanged(const std::string &, const std::string &, const std::string &);
void NameLost(const std::string &); void NameLost(const std::string &);
void NameAcquired(const std::string &); void NameAcquired(const std::string &);
void on_select_busname(); void on_select_busname();
void _inspect_append(Gtk::TreeModel::Row *, const std::string &, const std::string &); void _inspect_append(Gtk::TreeModel::Row *, const std::string &, const std::string &);
private: private:
class InspectRecord : public Gtk::TreeModel::ColumnRecord class InspectRecord : public Gtk::TreeModel::ColumnRecord
{ {
public: public:
InspectRecord() { add(name); } InspectRecord()
{
add(name);
}
Gtk::TreeModelColumn<Glib::ustring> name; Gtk::TreeModelColumn<Glib::ustring> name;
}; };
Gtk::VBox _vbox; Gtk::VBox _vbox;
Gtk::ScrolledWindow _sc_tree; Gtk::ScrolledWindow _sc_tree;
Gtk::ComboBoxText _cb_busnames; Gtk::ComboBoxText _cb_busnames;
Gtk::TreeView _tv_inspect; Gtk::TreeView _tv_inspect;
Glib::RefPtr<Gtk::TreeStore> _tm_inspect; Glib::RefPtr<Gtk::TreeStore> _tm_inspect;
InspectRecord _records; InspectRecord _records;
}; };
#endif//__DEMO_DBUS_BROWSER_H #endif//__DEMO_DBUS_BROWSER_H

View file

@ -8,122 +8,122 @@
#include <iostream> #include <iostream>
HalManagerProxy::HalManagerProxy(DBus::Connection &connection) HalManagerProxy::HalManagerProxy(DBus::Connection &connection)
: DBus::InterfaceProxy("org.freedesktop.Hal.Manager"), : DBus::InterfaceProxy("org.freedesktop.Hal.Manager"),
DBus::ObjectProxy(connection, "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal") DBus::ObjectProxy(connection, "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal")
{ {
connect_signal(HalManagerProxy, DeviceAdded, DeviceAddedCb); connect_signal(HalManagerProxy, DeviceAdded, DeviceAddedCb);
connect_signal(HalManagerProxy, DeviceRemoved, DeviceRemovedCb); connect_signal(HalManagerProxy, DeviceRemoved, DeviceRemovedCb);
std::vector< std::string > devices = GetAllDevices(); std::vector< std::string > devices = GetAllDevices();
std::vector< std::string >::iterator it; std::vector< std::string >::iterator it;
for (it = devices.begin(); it != devices.end(); ++it) for (it = devices.begin(); it != devices.end(); ++it)
{ {
DBus::Path udi = *it; DBus::Path udi = *it;
std::cout << "found device " << udi << std::endl; std::cout << "found device " << udi << std::endl;
_devices[udi] = new HalDeviceProxy(connection, udi); _devices[udi] = new HalDeviceProxy(connection, udi);
} }
} }
std::vector< std::string > HalManagerProxy::GetAllDevices() std::vector< std::string > HalManagerProxy::GetAllDevices()
{ {
std::vector< std::string > udis; std::vector< std::string > udis;
DBus::CallMessage call; DBus::CallMessage call;
call.member("GetAllDevices"); call.member("GetAllDevices");
DBus::Message reply = invoke_method(call); DBus::Message reply = invoke_method(call);
DBus::MessageIter it = reply.reader(); DBus::MessageIter it = reply.reader();
it >> udis; it >> udis;
return udis; return udis;
} }
void HalManagerProxy::DeviceAddedCb(const DBus::SignalMessage &sig) void HalManagerProxy::DeviceAddedCb(const DBus::SignalMessage &sig)
{ {
DBus::MessageIter it = sig.reader(); DBus::MessageIter it = sig.reader();
std::string devname; std::string devname;
it >> devname; it >> devname;
DBus::Path udi(devname); DBus::Path udi(devname);
_devices[devname] = new HalDeviceProxy(conn(), udi); _devices[devname] = new HalDeviceProxy(conn(), udi);
std::cout << "added device " << udi << std::endl; std::cout << "added device " << udi << std::endl;
} }
void HalManagerProxy::DeviceRemovedCb(const DBus::SignalMessage &sig) void HalManagerProxy::DeviceRemovedCb(const DBus::SignalMessage &sig)
{ {
DBus::MessageIter it = sig.reader(); DBus::MessageIter it = sig.reader();
std::string devname; std::string devname;
it >> devname; it >> devname;
std::cout << "removed device " << devname << std::endl; std::cout << "removed device " << devname << std::endl;
_devices.erase(devname); _devices.erase(devname);
} }
HalDeviceProxy::HalDeviceProxy(DBus::Connection &connection, DBus::Path &udi) HalDeviceProxy::HalDeviceProxy(DBus::Connection &connection, DBus::Path &udi)
: DBus::InterfaceProxy("org.freedesktop.Hal.Device"), : DBus::InterfaceProxy("org.freedesktop.Hal.Device"),
DBus::ObjectProxy(connection, udi, "org.freedesktop.Hal") DBus::ObjectProxy(connection, udi, "org.freedesktop.Hal")
{ {
connect_signal(HalDeviceProxy, PropertyModified, PropertyModifiedCb); connect_signal(HalDeviceProxy, PropertyModified, PropertyModifiedCb);
connect_signal(HalDeviceProxy, Condition, ConditionCb); connect_signal(HalDeviceProxy, Condition, ConditionCb);
} }
void HalDeviceProxy::PropertyModifiedCb(const DBus::SignalMessage &sig) void HalDeviceProxy::PropertyModifiedCb(const DBus::SignalMessage &sig)
{ {
typedef DBus::Struct< std::string, bool, bool > HalProperty; typedef DBus::Struct< std::string, bool, bool > HalProperty;
DBus::MessageIter it = sig.reader(); DBus::MessageIter it = sig.reader();
int32_t number; int32_t number;
it >> number; it >> number;
DBus::MessageIter arr = it.recurse(); DBus::MessageIter arr = it.recurse();
for (int i = 0; i < number; ++i, ++arr) for (int i = 0; i < number; ++i, ++arr)
{ {
HalProperty hp; HalProperty hp;
arr >> hp; arr >> hp;
std::cout << "modified property " << hp._1 << " in " << path() << std::endl; std::cout << "modified property " << hp._1 << " in " << path() << std::endl;
} }
} }
void HalDeviceProxy::ConditionCb(const DBus::SignalMessage &sig) void HalDeviceProxy::ConditionCb(const DBus::SignalMessage &sig)
{ {
DBus::MessageIter it = sig.reader(); DBus::MessageIter it = sig.reader();
std::string condition; std::string condition;
it >> condition; it >> condition;
std::cout << "encountered condition " << condition << " in " << path() << std::endl; std::cout << "encountered condition " << condition << " in " << path() << std::endl;
} }
DBus::BusDispatcher dispatcher; DBus::BusDispatcher dispatcher;
void niam(int sig) void niam(int sig)
{ {
dispatcher.leave(); dispatcher.leave();
} }
int main() int main()
{ {
signal(SIGTERM, niam); signal(SIGTERM, niam);
signal(SIGINT, niam); signal(SIGINT, niam);
DBus::default_dispatcher = &dispatcher; DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SystemBus(); DBus::Connection conn = DBus::Connection::SystemBus();
HalManagerProxy hal(conn); HalManagerProxy hal(conn);
dispatcher.enter(); dispatcher.enter();
return 0; return 0;
} }

View file

@ -8,37 +8,37 @@
class HalDeviceProxy; class HalDeviceProxy;
class HalManagerProxy class HalManagerProxy
: public DBus::InterfaceProxy, : public DBus::InterfaceProxy,
public DBus::ObjectProxy public DBus::ObjectProxy
{ {
public: public:
HalManagerProxy(DBus::Connection &connection); HalManagerProxy(DBus::Connection &connection);
std::vector< std::string > GetAllDevices(); std::vector< std::string > GetAllDevices();
private: private:
void DeviceAddedCb(const DBus::SignalMessage &sig); void DeviceAddedCb(const DBus::SignalMessage &sig);
void DeviceRemovedCb(const DBus::SignalMessage &sig); void DeviceRemovedCb(const DBus::SignalMessage &sig);
std::map< std::string, DBus::RefPtr< HalDeviceProxy > > _devices; std::map< std::string, DBus::RefPtr< HalDeviceProxy > > _devices;
}; };
class HalDeviceProxy class HalDeviceProxy
: public DBus::InterfaceProxy, : public DBus::InterfaceProxy,
public DBus::ObjectProxy public DBus::ObjectProxy
{ {
public: public:
HalDeviceProxy(DBus::Connection &connection, DBus::Path &udi); HalDeviceProxy(DBus::Connection &connection, DBus::Path &udi);
private: private:
void PropertyModifiedCb(const DBus::SignalMessage &sig); void PropertyModifiedCb(const DBus::SignalMessage &sig);
void ConditionCb(const DBus::SignalMessage &sig); void ConditionCb(const DBus::SignalMessage &sig);
}; };
#endif//__DEMO_HAL_LISTEN_H #endif//__DEMO_HAL_LISTEN_H

View file

@ -9,64 +9,64 @@ static const char *PROPS_SERVER_NAME = "org.freedesktop.DBus.Examples.Properties
static const char *PROPS_SERVER_PATH = "/org/freedesktop/DBus/Examples/Properties"; static const char *PROPS_SERVER_PATH = "/org/freedesktop/DBus/Examples/Properties";
PropsClient::PropsClient(DBus::Connection &connection, const char *path, const char *name) PropsClient::PropsClient(DBus::Connection &connection, const char *path, const char *name)
: DBus::ObjectProxy(connection, path, name) : DBus::ObjectProxy(connection, path, name)
{ {
} }
void PropsClient::MessageChanged(const std::string& message) void PropsClient::MessageChanged(const std::string &message)
{ {
std::cout << "MessageChanged signal, new value: " << message << "\n"; std::cout << "MessageChanged signal, new value: " << message << "\n";
}; };
void PropsClient::DataChanged(const double& data) void PropsClient::DataChanged(const double &data)
{ {
std::cout << "DataChanged signal, new value:" << data << "\n"; std::cout << "DataChanged signal, new value:" << data << "\n";
}; };
void *test_property_proxy(void * input) void *test_property_proxy(void *input)
{ {
PropsClient *client = static_cast<PropsClient*>(input); PropsClient *client = static_cast<PropsClient *>(input);
std::cout << "read property 'Version', value:" << client->Version() << "\n"; std::cout << "read property 'Version', value:" << client->Version() << "\n";
std::cout << "read property 'Message', value:" << client->Message() << "\n"; std::cout << "read property 'Message', value:" << client->Message() << "\n";
client->Message("message set by property access");
std::cout << "wrote property 'Message'\n";
std::cout << "read property 'Message', value:" << client->Message() << "\n";
client->Data(1.1);
std::cout << "wrote property 'Data'\n";
return NULL; client->Message("message set by property access");
std::cout << "wrote property 'Message'\n";
std::cout << "read property 'Message', value:" << client->Message() << "\n";
client->Data(1.1);
std::cout << "wrote property 'Data'\n";
return NULL;
} }
DBus::BusDispatcher dispatcher; DBus::BusDispatcher dispatcher;
void niam(int sig) void niam(int sig)
{ {
dispatcher.leave(); dispatcher.leave();
pthread_exit(NULL); pthread_exit(NULL);
} }
int main() int main()
{ {
signal(SIGTERM, niam); signal(SIGTERM, niam);
signal(SIGINT, niam); signal(SIGINT, niam);
DBus::default_dispatcher = &dispatcher; DBus::default_dispatcher = &dispatcher;
DBus::_init_threading(); DBus::_init_threading();
DBus::Connection conn = DBus::Connection::SessionBus(); DBus::Connection conn = DBus::Connection::SessionBus();
PropsClient client (conn, PROPS_SERVER_PATH, PROPS_SERVER_NAME); PropsClient client(conn, PROPS_SERVER_PATH, PROPS_SERVER_NAME);
pthread_t thread; pthread_t thread;
pthread_create(&thread, NULL, test_property_proxy, &client); pthread_create(&thread, NULL, test_property_proxy, &client);
dispatcher.enter(); dispatcher.enter();
return 0; return 0;
} }

View file

@ -5,18 +5,18 @@
#include "propsgs-glue-proxy.h" #include "propsgs-glue-proxy.h"
class PropsClient class PropsClient
: public org::freedesktop::DBus::PropsGSDemo_proxy, : public org::freedesktop::DBus::PropsGSDemo_proxy,
public DBus::IntrospectableProxy, public DBus::IntrospectableProxy,
public DBus::PropertiesProxy, public DBus::PropertiesProxy,
public DBus::ObjectProxy public DBus::ObjectProxy
{ {
public: public:
PropsClient(DBus::Connection &connection, const char *path, const char *name); PropsClient(DBus::Connection &connection, const char *path, const char *name);
void MessageChanged(const std::string& message);
void DataChanged(const double& data); void MessageChanged(const std::string &message);
void DataChanged(const double &data);
}; };
#endif//__DEMO_PROPS_SERVER_H #endif//__DEMO_PROPS_SERVER_H

View file

@ -6,51 +6,51 @@ static const char *PROPS_SERVER_NAME = "org.freedesktop.DBus.Examples.Properties
static const char *PROPS_SERVER_PATH = "/org/freedesktop/DBus/Examples/Properties"; static const char *PROPS_SERVER_PATH = "/org/freedesktop/DBus/Examples/Properties";
PropsServer::PropsServer(DBus::Connection &connection) PropsServer::PropsServer(DBus::Connection &connection)
: DBus::ObjectAdaptor(connection, PROPS_SERVER_PATH) : DBus::ObjectAdaptor(connection, PROPS_SERVER_PATH)
{ {
Version = 1; Version = 1;
Message = "default message"; Message = "default message";
} }
void PropsServer::on_set_property void PropsServer::on_set_property
(DBus::InterfaceAdaptor &interface, const std::string &property, const DBus::Variant &value) (DBus::InterfaceAdaptor &interface, const std::string &property, const DBus::Variant &value)
{ {
if (property == "Message") if (property == "Message")
{ {
std::cout << "'Message' has been changed\n"; std::cout << "'Message' has been changed\n";
std::string msg = value; std::string msg = value;
this->MessageChanged(msg); this->MessageChanged(msg);
} }
if (property == "Data") if (property == "Data")
{ {
std::cout << "'Data' has been changed\n"; std::cout << "'Data' has been changed\n";
double data = value; double data = value;
this->DataChanged(data); this->DataChanged(data);
} }
} }
DBus::BusDispatcher dispatcher; DBus::BusDispatcher dispatcher;
void niam(int sig) void niam(int sig)
{ {
dispatcher.leave(); dispatcher.leave();
} }
int main() int main()
{ {
signal(SIGTERM, niam); signal(SIGTERM, niam);
signal(SIGINT, niam); signal(SIGINT, niam);
DBus::default_dispatcher = &dispatcher; DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SessionBus(); DBus::Connection conn = DBus::Connection::SessionBus();
conn.request_name(PROPS_SERVER_NAME); conn.request_name(PROPS_SERVER_NAME);
PropsServer server(conn); PropsServer server(conn);
dispatcher.enter(); dispatcher.enter();
return 0; return 0;
} }

View file

@ -5,17 +5,17 @@
#include "propsgs-glue-adaptor.h" #include "propsgs-glue-adaptor.h"
class PropsServer class PropsServer
: public org::freedesktop::DBus::PropsGSDemo_adaptor, : public org::freedesktop::DBus::PropsGSDemo_adaptor,
public DBus::IntrospectableAdaptor, public DBus::IntrospectableAdaptor,
public DBus::PropertiesAdaptor, public DBus::PropertiesAdaptor,
public DBus::ObjectAdaptor public DBus::ObjectAdaptor
{ {
public: public:
PropsServer(DBus::Connection &connection); PropsServer(DBus::Connection &connection);
void on_set_property void on_set_property
(DBus::InterfaceAdaptor &interface, const std::string &property, const DBus::Variant &value); (DBus::InterfaceAdaptor &interface, const std::string &property, const DBus::Variant &value);
}; };
#endif//__DEMO_PROPS_SERVER_H #endif//__DEMO_PROPS_SERVER_H

View file

@ -33,11 +33,12 @@
#include "message.h" #include "message.h"
#include "pendingcall.h" #include "pendingcall.h"
namespace DBus { namespace DBus
{
class Connection; class Connection;
typedef Slot<bool, const Message&> MessageSlot; typedef Slot<bool, const Message &> MessageSlot;
typedef std::list<Connection> ConnectionList; typedef std::list<Connection> ConnectionList;
@ -48,419 +49,419 @@ class DXXAPI Connection
{ {
public: public:
static Connection SystemBus(); static Connection SystemBus();
static Connection SessionBus(); static Connection SessionBus();
static Connection ActivationBus(); static Connection ActivationBus();
struct Private; struct Private;
typedef std::list<Private*> PrivatePList; typedef std::list<Private *> PrivatePList;
Connection( Private* ); Connection(Private *);
Connection( const char* address, bool priv = true ); Connection(const char *address, bool priv = true);
Connection( const Connection& c ); Connection(const Connection &c);
virtual ~Connection(); virtual ~Connection();
Dispatcher* setup( Dispatcher* ); Dispatcher *setup(Dispatcher *);
bool operator == ( const Connection& ) const; bool operator == (const Connection &) const;
/*! /*!
* \brief Adds a match rule to match messages going through the message bus. * \brief Adds a match rule to match messages going through the message bus.
* *
* The "rule" argument is the string form of a match rule. * The "rule" argument is the string form of a match rule.
* *
* If you pass NULL for the error, this function will not block; the match * If you pass NULL for the error, this function will not block; the match
* thus won't be added until you flush the connection, and if there's an error * thus won't be added until you flush the connection, and if there's an error
* adding the match (only possible error is lack of resources in the bus), you * adding the match (only possible error is lack of resources in the bus), you
* won't find out about it. * won't find out about it.
* *
* Normal API conventions would have the function return a boolean value * Normal API conventions would have the function return a boolean value
* indicating whether the error was set, but that would require blocking always * indicating whether the error was set, but that would require blocking always
* to determine the return value. * to determine the return value.
* *
* The AddMatch method is fully documented in the D-Bus specification. For * The AddMatch method is fully documented in the D-Bus specification. For
* quick reference, the format of the match rules is discussed here, but the * quick reference, the format of the match rules is discussed here, but the
* specification is the canonical version of this information. * specification is the canonical version of this information.
* *
* Rules are specified as a string of comma separated key/value pairs. An * Rules are specified as a string of comma separated key/value pairs. An
* example is "type='signal',sender='org.freedesktop.DBus', * example is "type='signal',sender='org.freedesktop.DBus',
* interface='org.freedesktop.DBus',member='Foo', path='/bar/foo',destination=':452345.34'" * interface='org.freedesktop.DBus',member='Foo', path='/bar/foo',destination=':452345.34'"
* *
* Possible keys you can match on are type, sender, interface, member, path, * Possible keys you can match on are type, sender, interface, member, path,
* destination and numbered keys to match message args (keys are 'arg0', 'arg1', etc.). * destination and numbered keys to match message args (keys are 'arg0', 'arg1', etc.).
* Omitting a key from the rule indicates a wildcard match. For instance omitting * Omitting a key from the rule indicates a wildcard match. For instance omitting
* the member from a match rule but adding a sender would let all messages from * the member from a match rule but adding a sender would let all messages from
* that sender through regardless of the member. * that sender through regardless of the member.
* *
* Matches are inclusive not exclusive so as long as one rule matches the * Matches are inclusive not exclusive so as long as one rule matches the
* message will get through. It is important to note this because every time a * message will get through. It is important to note this because every time a
* essage is received the application will be paged into memory to process it. * essage is received the application will be paged into memory to process it.
* This can cause performance problems such as draining batteries on embedded platforms. * This can cause performance problems such as draining batteries on embedded platforms.
* *
* If you match message args ('arg0', 'arg1', and so forth) only string arguments * If you match message args ('arg0', 'arg1', and so forth) only string arguments
* will match. That is, arg0='5' means match the string "5" not the integer 5. * will match. That is, arg0='5' means match the string "5" not the integer 5.
* *
* Currently there is no way to match against non-string arguments. * Currently there is no way to match against non-string arguments.
* *
* Matching on interface is tricky because method call messages only optionally * Matching on interface is tricky because method call messages only optionally
* specify the interface. If a message omits the interface, then it will NOT * specify the interface. If a message omits the interface, then it will NOT
* match if the rule specifies an interface name. This means match rules on * match if the rule specifies an interface name. This means match rules on
* method calls should not usually give an interface. * method calls should not usually give an interface.
* *
* However, signal messages are required to include the interface so when * However, signal messages are required to include the interface so when
* matching signals usually you should specify the interface in the match rule. * matching signals usually you should specify the interface in the match rule.
* *
* For security reasons, you can match arguments only up to DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER. * For security reasons, you can match arguments only up to DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER.
* *
* Match rules have a maximum length of DBUS_MAXIMUM_MATCH_RULE_LENGTH bytes. * Match rules have a maximum length of DBUS_MAXIMUM_MATCH_RULE_LENGTH bytes.
* *
* Both of these maximums are much higher than you're likely to need, they only * Both of these maximums are much higher than you're likely to need, they only
* exist because the D-Bus bus daemon has fixed limits on all resource usage. * exist because the D-Bus bus daemon has fixed limits on all resource usage.
* *
* \param rule Textual form of match rule. * \param rule Textual form of match rule.
* \throw Error * \throw Error
*/ */
void add_match( const char* rule ); void add_match(const char *rule);
/*! /*!
* \brief Removes a previously-added match rule "by value" (the most * \brief Removes a previously-added match rule "by value" (the most
* recently-added identical rule gets removed). * recently-added identical rule gets removed).
* *
* The "rule" argument is the string form of a match rule. * The "rule" argument is the string form of a match rule.
* *
* The bus compares match rules semantically, not textually, so whitespace and * The bus compares match rules semantically, not textually, so whitespace and
* ordering don't have to be identical to the rule you passed to add_match(). * ordering don't have to be identical to the rule you passed to add_match().
* *
* \param rule Textual form of match rule. * \param rule Textual form of match rule.
* \throw Error * \throw Error
*/ */
void remove_match( const char* rule, bool throw_on_error ); void remove_match(const char *rule, bool throw_on_error);
/*! /*!
* \brief Adds a message filter. * \brief Adds a message filter.
* *
* Filters are handlers that are run on all incoming messages, prior to the * Filters are handlers that are run on all incoming messages, prior to the
* objects registered with ObjectAdaptor::register_obj(). Filters are * objects registered with ObjectAdaptor::register_obj(). Filters are
* run in the order that they were added. The same handler can be added as a * run in the order that they were added. The same handler can be added as a
* filter more than once, in which case it will be run more than once. Filters * filter more than once, in which case it will be run more than once. Filters
* added during a filter callback won't be run on the message being processed. * added during a filter callback won't be run on the message being processed.
* *
* \param s The MessageSlot to add. * \param s The MessageSlot to add.
*/ */
bool add_filter( MessageSlot& s); bool add_filter(MessageSlot &s);
/*! /*!
* \brief Removes a previously-added message filter. * \brief Removes a previously-added message filter.
* *
* It is a programming error to call this function for a handler that has not * It is a programming error to call this function for a handler that has not
* been added as a filter. If the given handler was added more than once, only * been added as a filter. If the given handler was added more than once, only
* one instance of it will be removed (the most recently-added instance). * one instance of it will be removed (the most recently-added instance).
* *
* \param s The MessageSlot to remove. * \param s The MessageSlot to remove.
*/ */
void remove_filter( MessageSlot& s); void remove_filter(MessageSlot &s);
/*! /*!
* \brief Sets the unique name of the connection, as assigned by the message bus. * \brief Sets the unique name of the connection, as assigned by the message bus.
* *
* Can only be used if you registered with the bus manually (i.e. if you did * Can only be used if you registered with the bus manually (i.e. if you did
* not call register_bus()). Can only be called once per connection. After * not call register_bus()). Can only be called once per connection. After
* the unique name is set, you can get it with unique_name(void). * the unique name is set, you can get it with unique_name(void).
* *
* The only reason to use this function is to re-implement the equivalent of * The only reason to use this function is to re-implement the equivalent of
* register_bus() yourself. One (probably unusual) reason to do that might * register_bus() yourself. One (probably unusual) reason to do that might
* be to do the bus registration call asynchronously instead of synchronously. * be to do the bus registration call asynchronously instead of synchronously.
* *
* \note Just use dbus_bus_get() or dbus_bus_get_private(), or worst case * \note Just use dbus_bus_get() or dbus_bus_get_private(), or worst case
* register_bus(), instead of messing with this function. There's * register_bus(), instead of messing with this function. There's
* really no point creating pain for yourself by doing things manually. * really no point creating pain for yourself by doing things manually.
* (Not sure if this is yet wrapped.) * (Not sure if this is yet wrapped.)
* *
* It's hard to use this function safely on shared connections (created by * It's hard to use this function safely on shared connections (created by
* Connection()) in a multithreaded application, because only one * Connection()) in a multithreaded application, because only one
* registration attempt can be sent to the bus. If two threads are both * registration attempt can be sent to the bus. If two threads are both
* sending the registration message, there is no mechanism in libdbus itself * sending the registration message, there is no mechanism in libdbus itself
* to avoid sending it twice. * to avoid sending it twice.
* *
* Thus, you need a way to coordinate which thread sends the registration * Thus, you need a way to coordinate which thread sends the registration
* attempt; which also means you know which thread will call * attempt; which also means you know which thread will call
* unique_name(const char*). If you don't know about all threads in the app * unique_name(const char*). If you don't know about all threads in the app
* (for example, if some libraries you're using might start libdbus-using * (for example, if some libraries you're using might start libdbus-using
* threads), then you need to avoid using this function on shared connections. * threads), then you need to avoid using this function on shared connections.
* *
* \param n The unique name. * \param n The unique name.
*/ */
bool unique_name( const char* n ); bool unique_name(const char *n);
/*! /*!
* \brief Gets the unique name of the connection as assigned by the message bus. * \brief Gets the unique name of the connection as assigned by the message bus.
* *
* Only possible after the connection has been registered with the message bus. * Only possible after the connection has been registered with the message bus.
* All connections returned by dbus_bus_get() or dbus_bus_get_private() have * All connections returned by dbus_bus_get() or dbus_bus_get_private() have
* been successfully registered. (Not sure if this is yet wrapped.) * been successfully registered. (Not sure if this is yet wrapped.)
* *
* The name remains valid until the connection is freed, and should not be * The name remains valid until the connection is freed, and should not be
* freed by the caller. * freed by the caller.
* *
* Other than dbus_bus_get(), there are two ways to set the unique name; one * Other than dbus_bus_get(), there are two ways to set the unique name; one
* is register_bus(), the other is unique_name(const char*). You are * is register_bus(), the other is unique_name(const char*). You are
* responsible for calling unique_name(const char*) if you register by hand * responsible for calling unique_name(const char*) if you register by hand
* instead of using register_bus(). * instead of using register_bus().
*/ */
const char* unique_name() const; const char *unique_name() const;
/*! /*!
* \brief Registers a connection with the bus. * \brief Registers a connection with the bus.
* *
* This must be the first thing an application does when connecting to the * This must be the first thing an application does when connecting to the
* message bus. If registration succeeds, the unique name will be set, and * message bus. If registration succeeds, the unique name will be set, and
* can be obtained using unique_name(void). * can be obtained using unique_name(void).
* *
* This function will block until registration is complete. * This function will block until registration is complete.
* *
* If the connection has already registered with the bus (determined by * If the connection has already registered with the bus (determined by
* checking whether unique_name(void) returns a non-NULL value), * checking whether unique_name(void) returns a non-NULL value),
* then this function does nothing. * then this function does nothing.
* *
* If you use dbus_bus_get() or dbus_bus_get_private() this function will be * If you use dbus_bus_get() or dbus_bus_get_private() this function will be
* called for you. (Not sure if this is yet wrapped.) * called for you. (Not sure if this is yet wrapped.)
* *
* \note Just use dbus_bus_get() or dbus_bus_get_private() instead of * \note Just use dbus_bus_get() or dbus_bus_get_private() instead of
* register_bus() and save yourself some pain. Using register_bus() * register_bus() and save yourself some pain. Using register_bus()
* manually is only useful if you have your own custom message bus not found * manually is only useful if you have your own custom message bus not found
* in DBusBusType. * in DBusBusType.
* *
* If you open a bus connection by the contructor of Connection() you will have to register_bus() * If you open a bus connection by the contructor of Connection() you will have to register_bus()
* yourself, or make the appropriate registration method calls yourself. If * yourself, or make the appropriate registration method calls yourself. If
* you send the method calls yourself, call unique_name(const char*) with * you send the method calls yourself, call unique_name(const char*) with
* the unique bus name you get from the bus. * the unique bus name you get from the bus.
* *
* For shared connections (created with dbus_connection_open()) in a * For shared connections (created with dbus_connection_open()) in a
* multithreaded application, you can't really make the registration calls * multithreaded application, you can't really make the registration calls
* yourself, because you don't know whether some other thread is also * yourself, because you don't know whether some other thread is also
* registering, and the bus will kick you off if you send two registration * registering, and the bus will kick you off if you send two registration
* messages. (TODO: how is this done in the wrapper?) * messages. (TODO: how is this done in the wrapper?)
* *
* If you use register_bus() however, there is a lock that keeps both * If you use register_bus() however, there is a lock that keeps both
* apps from registering at the same time. * apps from registering at the same time.
* *
* The rule in a multithreaded app, then, is that register_bus() must be * The rule in a multithreaded app, then, is that register_bus() must be
* used to register, or you need to have your own locks that all threads in * used to register, or you need to have your own locks that all threads in
* the app will respect. * the app will respect.
* *
* In a single-threaded application you can register by hand instead of using * In a single-threaded application you can register by hand instead of using
* register_bus(), as long as you check unique_name(void) to * register_bus(), as long as you check unique_name(void) to
* see if a unique name has already been stored by another thread before you * see if a unique name has already been stored by another thread before you
* send the registration messages. * send the registration messages.
*/ */
bool register_bus(); bool register_bus();
/*! /*!
* \brief Gets whether the connection is currently open. * \brief Gets whether the connection is currently open.
* *
* A connection may become disconnected when the remote application closes its * A connection may become disconnected when the remote application closes its
* end, or exits; a connection may also be disconnected with disconnect(). * end, or exits; a connection may also be disconnected with disconnect().
* *
* There are not separate states for "closed" and "disconnected," the two * There are not separate states for "closed" and "disconnected," the two
* terms are synonymous. * terms are synonymous.
* *
* \return true If the connection is still alive. * \return true If the connection is still alive.
*/ */
bool connected() const; bool connected() const;
/*! /*!
* \brief Closes a private connection, so no further data can be sent or received. * \brief Closes a private connection, so no further data can be sent or received.
* *
* This disconnects the transport (such as a socket) underlying the connection. * This disconnects the transport (such as a socket) underlying the connection.
* *
* Attempts to send messages after closing a connection are safe, but will * Attempts to send messages after closing a connection are safe, but will
* result in error replies generated locally in libdbus. * result in error replies generated locally in libdbus.
* *
* This function does not affect the connection's reference count. It's safe * This function does not affect the connection's reference count. It's safe
* to close a connection more than once; all calls after the first do nothing. * to close a connection more than once; all calls after the first do nothing.
* It's impossible to "reopen" a connection, a new connection must be created. * It's impossible to "reopen" a connection, a new connection must be created.
* This function may result in a call to the DBusDispatchStatusFunction set * This function may result in a call to the DBusDispatchStatusFunction set
* with Private::init(), as the disconnect * with Private::init(), as the disconnect
* message it generates needs to be dispatched. * message it generates needs to be dispatched.
* *
* If a connection is dropped by the remote application, it will close itself. * If a connection is dropped by the remote application, it will close itself.
* *
* You must close a connection prior to releasing the last reference to the * You must close a connection prior to releasing the last reference to the
* connection. * connection.
* *
* You may not close a shared connection. Connections created with * You may not close a shared connection. Connections created with
* dbus_connection_open() or dbus_bus_get() are shared. These connections are * dbus_connection_open() or dbus_bus_get() are shared. These connections are
* owned by libdbus, and applications should only unref them, never close them. * owned by libdbus, and applications should only unref them, never close them.
* Applications can know it is safe to unref these connections because libdbus * Applications can know it is safe to unref these connections because libdbus
* will be holding a reference as long as the connection is open. Thus, either * will be holding a reference as long as the connection is open. Thus, either
* the connection is closed and it is OK to drop the last reference, or the * the connection is closed and it is OK to drop the last reference, or the
* connection is open and the app knows it does not have the last reference. * connection is open and the app knows it does not have the last reference.
* *
* Connections created with dbus_connection_open_private() or * Connections created with dbus_connection_open_private() or
* dbus_bus_get_private() are not kept track of or referenced by libdbus. * dbus_bus_get_private() are not kept track of or referenced by libdbus.
* The creator of these connections is responsible for calling * The creator of these connections is responsible for calling
* dbus_connection_close() prior to releasing the last reference, if the * dbus_connection_close() prior to releasing the last reference, if the
* connection is not already disconnected. * connection is not already disconnected.
* *
* \todo dbus_connection_disconnect() was removed in dbus 0.9x. Maybe this * \todo dbus_connection_disconnect() was removed in dbus 0.9x. Maybe this
* function should be renamed to close(). * function should be renamed to close().
*/ */
void disconnect(); void disconnect();
/*! /*!
* \brief Set whether _exit() should be called when the connection receives a * \brief Set whether _exit() should be called when the connection receives a
* disconnect signal. * disconnect signal.
* *
* The call to _exit() comes after any handlers for the disconnect signal run; * The call to _exit() comes after any handlers for the disconnect signal run;
* handlers can cancel the exit by calling this function. * handlers can cancel the exit by calling this function.
* *
* By default, exit_on_disconnect is false; but for message bus connections * By default, exit_on_disconnect is false; but for message bus connections
* returned from dbus_bus_get() it will be toggled on by default. * returned from dbus_bus_get() it will be toggled on by default.
* *
* \param exit true If _exit() should be called after a disconnect signal. * \param exit true If _exit() should be called after a disconnect signal.
*/ */
void exit_on_disconnect( bool exit ); void exit_on_disconnect(bool exit);
/*! /*!
* \brief Blocks until the outgoing message queue is empty. * \brief Blocks until the outgoing message queue is empty.
*/ */
void flush(); void flush();
/*! /*!
* \brief Adds a message to the outgoing message queue. * \brief Adds a message to the outgoing message queue.
* *
* Does not block to write the message to the network; that happens * Does not block to write the message to the network; that happens
* asynchronously. To force the message to be written, call * asynchronously. To force the message to be written, call
* dbus_connection_flush(). Because this only queues the message, the only * dbus_connection_flush(). Because this only queues the message, the only
* reason it can fail is lack of memory. Even if the connection is disconnected, * reason it can fail is lack of memory. Even if the connection is disconnected,
* no error will be returned. * no error will be returned.
* *
* If the function fails due to lack of memory, it returns FALSE. The function * If the function fails due to lack of memory, it returns FALSE. The function
* will never fail for other reasons; even if the connection is disconnected, * will never fail for other reasons; even if the connection is disconnected,
* you can queue an outgoing message, though obviously it won't be sent. * you can queue an outgoing message, though obviously it won't be sent.
* *
* The message serial is used by the remote application to send a reply; see * The message serial is used by the remote application to send a reply; see
* Message::serial() or the D-Bus specification. * Message::serial() or the D-Bus specification.
* *
* \param msg The Message to write. * \param msg The Message to write.
* \param serial Return location for message serial, or NULL if you don't care. * \param serial Return location for message serial, or NULL if you don't care.
* \return true On success. * \return true On success.
*/ */
bool send( const Message& msg, unsigned int* serial = NULL ); bool send(const Message &msg, unsigned int *serial = NULL);
/*! /*!
* \brief Sends a message and blocks a certain time period while waiting for a reply. * \brief Sends a message and blocks a certain time period while waiting for a reply.
* *
* This function does not reenter the main loop, i.e. messages other than the * This function does not reenter the main loop, i.e. messages other than the
* reply are queued up but not processed. This function is used to invoke * reply are queued up but not processed. This function is used to invoke
* method calls on a remote object. * method calls on a remote object.
* *
* If a normal reply is received, it is returned, and removed from the * If a normal reply is received, it is returned, and removed from the
* incoming message queue. If it is not received, NULL is returned and the * incoming message queue. If it is not received, NULL is returned and the
* error is set to DBUS_ERROR_NO_REPLY. If an error reply is received, it is * error is set to DBUS_ERROR_NO_REPLY. If an error reply is received, it is
* converted to a DBusError and returned as an error, then the reply message * converted to a DBusError and returned as an error, then the reply message
* is deleted and NULL is returned. If something else goes wrong, result is * is deleted and NULL is returned. If something else goes wrong, result is
* set to whatever is appropriate, such as DBUS_ERROR_NO_MEMORY or DBUS_ERROR_DISCONNECTED. * set to whatever is appropriate, such as DBUS_ERROR_NO_MEMORY or DBUS_ERROR_DISCONNECTED.
* *
* \warning While this function blocks the calling thread will not be * \warning While this function blocks the calling thread will not be
* processing the incoming message queue. This means you can end up * processing the incoming message queue. This means you can end up
* deadlocked if the application you're talking to needs you to reply * deadlocked if the application you're talking to needs you to reply
* to a method. To solve this, either avoid the situation, block in a * to a method. To solve this, either avoid the situation, block in a
* separate thread from the main connection-dispatching thread, or * separate thread from the main connection-dispatching thread, or
* use PendingCall to avoid blocking. * use PendingCall to avoid blocking.
* *
* \param msg The Message to write. * \param msg The Message to write.
* \param timeout Timeout in milliseconds (omit for default). * \param timeout Timeout in milliseconds (omit for default).
* \throw Error * \throw Error
*/ */
Message send_blocking( Message& msg, int timeout = -1); Message send_blocking(Message &msg, int timeout = -1);
/*!
* \brief Queues a message to send, as with send(), but also
* returns a DBusPendingCall used to receive a reply to the message.
*
* If no reply is received in the given timeout_milliseconds, this function
* expires the pending reply and generates a synthetic error reply (generated
* in-process, not by the remote application) indicating that a timeout occurred.
*
* A PendingCall will see a reply message before any filters or registered
* object path handlers. See Connection::Private::do_dispatch() in dbus documentation
* for details on when handlers are run. (here: Connection::Private::do_dispatch())
*
* A PendingCall will always see exactly one reply message, unless it's
* cancelled with PendingCall::cancel().
*
* If -1 is passed for the timeout, a sane default timeout is used. -1 is
* typically the best value for the timeout for this reason, unless you want
* a very short or very long timeout. There is no way to avoid a timeout
* entirely, other than passing INT_MAX for the timeout to mean "very long
* timeout." libdbus clamps an INT_MAX timeout down to a few hours timeout though.
*
* \param msg The Message to write.
* \param timeout Timeout in milliseconds (omit for default).
* \throw ErrorNoMemory
*/
PendingCall send_async( Message& msg, int timeout = -1);
void request_name( const char* name, int flags = 0 ); /*!
* \brief Queues a message to send, as with send(), but also
unsigned long sender_unix_uid(const char *sender); * returns a DBusPendingCall used to receive a reply to the message.
*
* If no reply is received in the given timeout_milliseconds, this function
* expires the pending reply and generates a synthetic error reply (generated
* in-process, not by the remote application) indicating that a timeout occurred.
*
* A PendingCall will see a reply message before any filters or registered
* object path handlers. See Connection::Private::do_dispatch() in dbus documentation
* for details on when handlers are run. (here: Connection::Private::do_dispatch())
*
* A PendingCall will always see exactly one reply message, unless it's
* cancelled with PendingCall::cancel().
*
* If -1 is passed for the timeout, a sane default timeout is used. -1 is
* typically the best value for the timeout for this reason, unless you want
* a very short or very long timeout. There is no way to avoid a timeout
* entirely, other than passing INT_MAX for the timeout to mean "very long
* timeout." libdbus clamps an INT_MAX timeout down to a few hours timeout though.
*
* \param msg The Message to write.
* \param timeout Timeout in milliseconds (omit for default).
* \throw ErrorNoMemory
*/
PendingCall send_async(Message &msg, int timeout = -1);
/*! void request_name(const char *name, int flags = 0);
* \brief Asks the bus whether a certain name has an owner.
*
* Using this can easily result in a race condition, since an owner can appear
* or disappear after you call this.
*
* If you want to request a name, just request it; if you want to avoid
* replacing a current owner, don't specify DBUS_NAME_FLAG_REPLACE_EXISTING
* and you will get an error if there's already an owner.
*
* \param name The name.
* \throw Error
*/
bool has_name( const char* name );
/*! unsigned long sender_unix_uid(const char *sender);
* \brief Starts a service that will request ownership of the given name.
*
* The returned result will be one of be one of DBUS_START_REPLY_SUCCESS or
* DBUS_START_REPLY_ALREADY_RUNNING if successful. Pass NULL if you don't
* care about the result.
*
* The flags parameter is for future expansion, currently you should specify 0.
*
* It's often easier to avoid explicitly starting services, and just send a
* method call to the service's bus name instead. Method calls start a service
* to handle them by default unless you call dbus_message_set_auto_start() to
* disable this behavior.
*
* \todo dbus_message_set_auto_start() not yet wrapped!
*/
bool start_service( const char* name, unsigned long flags );
const std::vector<std::string>& names(); /*!
* \brief Asks the bus whether a certain name has an owner.
void set_timeout(int timeout); *
* Using this can easily result in a race condition, since an owner can appear
int get_timeout(); * or disappear after you call this.
*
* If you want to request a name, just request it; if you want to avoid
* replacing a current owner, don't specify DBUS_NAME_FLAG_REPLACE_EXISTING
* and you will get an error if there's already an owner.
*
* \param name The name.
* \throw Error
*/
bool has_name(const char *name);
/*!
* \brief Starts a service that will request ownership of the given name.
*
* The returned result will be one of be one of DBUS_START_REPLY_SUCCESS or
* DBUS_START_REPLY_ALREADY_RUNNING if successful. Pass NULL if you don't
* care about the result.
*
* The flags parameter is for future expansion, currently you should specify 0.
*
* It's often easier to avoid explicitly starting services, and just send a
* method call to the service's bus name instead. Method calls start a service
* to handle them by default unless you call dbus_message_set_auto_start() to
* disable this behavior.
*
* \todo dbus_message_set_auto_start() not yet wrapped!
*/
bool start_service(const char *name, unsigned long flags);
const std::vector<std::string>& names();
void set_timeout(int timeout);
int get_timeout();
private: private:
DXXAPILOCAL void init(); DXXAPILOCAL void init();
private: private:
RefPtrI<Private> _pvt; RefPtrI<Private> _pvt;
int _timeout; int _timeout;
friend class ObjectAdaptor; // needed in order to register object paths for a connection friend class ObjectAdaptor; // needed in order to register object paths for a connection
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -27,7 +27,8 @@
#include "api.h" #include "api.h"
namespace DBus { namespace DBus
{
typedef void (*LogFunction)(const char *format, ...); typedef void (*LogFunction)(const char *format, ...);

View file

@ -29,157 +29,158 @@
#include "connection.h" #include "connection.h"
#include "eventloop.h" #include "eventloop.h"
namespace DBus { namespace DBus
{
class DXXAPI Timeout class DXXAPI Timeout
{ {
public: public:
class Internal; class Internal;
Timeout(Internal *i); Timeout(Internal *i);
virtual ~Timeout(){} virtual ~Timeout() {}
/*! /*!
* \brief Gets the timeout interval. * \brief Gets the timeout interval.
* *
* The handle() should be called each time this interval elapses, * The handle() should be called each time this interval elapses,
* starting after it elapses once. * starting after it elapses once.
* *
* The interval may change during the life of the timeout; if so, the timeout * The interval may change during the life of the timeout; if so, the timeout
* will be disabled and re-enabled (calling the "timeout toggled function") to * will be disabled and re-enabled (calling the "timeout toggled function") to
* notify you of the change. * notify you of the change.
* *
* return The interval in miliseconds. * return The interval in miliseconds.
*/ */
int interval() const; int interval() const;
bool enabled() const; bool enabled() const;
/*! /*!
* \brief Calls the timeout handler for this timeout. * \brief Calls the timeout handler for this timeout.
* *
* This function should be called when the timeout occurs. * This function should be called when the timeout occurs.
* *
* If this function returns FALSE, then there wasn't enough memory to handle * If this function returns FALSE, then there wasn't enough memory to handle
* the timeout. Typically just letting the timeout fire again next time it * the timeout. Typically just letting the timeout fire again next time it
* naturally times out is an adequate response to that problem, but you could * naturally times out is an adequate response to that problem, but you could
* try to do more if you wanted. * try to do more if you wanted.
* *
* return false If there wasn't enough memory. * return false If there wasn't enough memory.
*/ */
bool handle(); bool handle();
virtual void toggle() = 0; virtual void toggle() = 0;
private: private:
DXXAPILOCAL Timeout(const Timeout &); DXXAPILOCAL Timeout(const Timeout &);
private: private:
Internal *_int; Internal *_int;
}; };
class DXXAPI Watch class DXXAPI Watch
{ {
public: public:
class Internal; class Internal;
Watch(Internal *i); Watch(Internal *i);
virtual ~Watch(){} virtual ~Watch() {}
/*! /*!
* \brief A main loop could poll this descriptor to integrate dbus-c++. * \brief A main loop could poll this descriptor to integrate dbus-c++.
* *
* This function calls dbus_watch_get_socket() on win32 and * This function calls dbus_watch_get_socket() on win32 and
* dbus_watch_get_unix_fd() on all other systems. (see dbus documentation) * dbus_watch_get_unix_fd() on all other systems. (see dbus documentation)
* *
* @return The file descriptor. * @return The file descriptor.
*/ */
int descriptor() const; int descriptor() const;
/*! /*!
* \brief Gets flags from DBusWatchFlags indicating what conditions should be * \brief Gets flags from DBusWatchFlags indicating what conditions should be
* monitored on the file descriptor. * monitored on the file descriptor.
* *
* The flags returned will only contain DBUS_WATCH_READABLE and DBUS_WATCH_WRITABLE, * The flags returned will only contain DBUS_WATCH_READABLE and DBUS_WATCH_WRITABLE,
* never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR; all watches implicitly include * never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR; all watches implicitly include
* a watch for hangups, errors, and other exceptional conditions. * a watch for hangups, errors, and other exceptional conditions.
* *
* @return The conditions to watch. * @return The conditions to watch.
*/ */
int flags() const; int flags() const;
bool enabled() const; bool enabled() const;
/*! /*!
* \brief Called to notify the D-Bus library when a previously-added watch * \brief Called to notify the D-Bus library when a previously-added watch
* is ready for reading or writing, or has an exception such as a hangup. * is ready for reading or writing, or has an exception such as a hangup.
* *
* If this function returns FALSE, then the file descriptor may still be * If this function returns FALSE, then the file descriptor may still be
* ready for reading or writing, but more memory is needed in order to do the * ready for reading or writing, but more memory is needed in order to do the
* reading or writing. If you ignore the FALSE return, your application may * reading or writing. If you ignore the FALSE return, your application may
* spin in a busy loop on the file descriptor until memory becomes available, * spin in a busy loop on the file descriptor until memory becomes available,
* but nothing more catastrophic should happen. * but nothing more catastrophic should happen.
* *
* dbus_watch_handle() cannot be called during the DBusAddWatchFunction, as the * dbus_watch_handle() cannot be called during the DBusAddWatchFunction, as the
* connection will not be ready to handle that watch yet. * connection will not be ready to handle that watch yet.
* *
* It is not allowed to reference a DBusWatch after it has been passed to remove_function. * It is not allowed to reference a DBusWatch after it has been passed to remove_function.
* *
* @param flags The poll condition using DBusWatchFlags values. * @param flags The poll condition using DBusWatchFlags values.
* @return false If there wasn't enough memory. * @return false If there wasn't enough memory.
*/ */
bool handle(int flags); bool handle(int flags);
virtual void toggle() = 0; virtual void toggle() = 0;
private: private:
DXXAPILOCAL Watch(const Watch &); DXXAPILOCAL Watch(const Watch &);
private: private:
Internal *_int; Internal *_int;
}; };
class DXXAPI Dispatcher class DXXAPI Dispatcher
{ {
public: public:
virtual ~Dispatcher() virtual ~Dispatcher()
{} {}
void queue_connection(Connection::Private *); void queue_connection(Connection::Private *);
void dispatch_pending(); void dispatch_pending();
bool has_something_to_dispatch(); bool has_something_to_dispatch();
virtual void enter() = 0; virtual void enter() = 0;
virtual void leave() = 0; virtual void leave() = 0;
virtual Timeout *add_timeout(Timeout::Internal *) = 0; virtual Timeout *add_timeout(Timeout::Internal *) = 0;
virtual void rem_timeout(Timeout *) = 0; virtual void rem_timeout(Timeout *) = 0;
virtual Watch *add_watch(Watch::Internal *) = 0; virtual Watch *add_watch(Watch::Internal *) = 0;
virtual void rem_watch(Watch *) = 0; virtual void rem_watch(Watch *) = 0;
struct Private; struct Private;
private: private:
void dispatch_pending(Connection::PrivatePList& pending_queue); void dispatch_pending(Connection::PrivatePList &pending_queue);
DefaultMutex _mutex_p; DefaultMutex _mutex_p;
DefaultMutex _mutex_p_copy; DefaultMutex _mutex_p_copy;
Connection::PrivatePList _pending_queue; Connection::PrivatePList _pending_queue;
}; };
extern DXXAPI Dispatcher *default_dispatcher; extern DXXAPI Dispatcher *default_dispatcher;
@ -191,38 +192,38 @@ class DXXAPI Mutex
{ {
public: public:
virtual ~Mutex() {} virtual ~Mutex() {}
virtual void lock() = 0; virtual void lock() = 0;
virtual void unlock() = 0; virtual void unlock() = 0;
struct Internal; struct Internal;
protected: protected:
Internal *_int; Internal *_int;
}; };
class DXXAPI CondVar class DXXAPI CondVar
{ {
public: public:
virtual ~CondVar() {} virtual ~CondVar() {}
virtual void wait(Mutex *) = 0; virtual void wait(Mutex *) = 0;
virtual bool wait_timeout(Mutex *, int timeout) = 0; virtual bool wait_timeout(Mutex *, int timeout) = 0;
virtual void wake_one() = 0; virtual void wake_one() = 0;
virtual void wake_all() = 0; virtual void wake_all() = 0;
struct Internal; struct Internal;
protected: protected:
Internal *_int; Internal *_int;
}; };
typedef Mutex *(*MutexNewFn)(); typedef Mutex *(*MutexNewFn)();
@ -246,70 +247,70 @@ typedef void (*CondVarWakeAllFn)(CondVar *cv);
void DXXAPI _init_threading(); void DXXAPI _init_threading();
void DXXAPI _init_threading( void DXXAPI _init_threading(
MutexNewFn, MutexFreeFn, MutexLockFn, MutexUnlockFn, MutexNewFn, MutexFreeFn, MutexLockFn, MutexUnlockFn,
CondVarNewFn, CondVarFreeFn, CondVarWaitFn, CondVarWaitTimeoutFn, CondVarWakeOneFn, CondVarWakeAllFn CondVarNewFn, CondVarFreeFn, CondVarWaitFn, CondVarWaitTimeoutFn, CondVarWakeOneFn, CondVarWakeAllFn
); );
template<class Mx, class Cv> template<class Mx, class Cv>
struct Threading struct Threading
{ {
static void init() static void init()
{ {
_init_threading( _init_threading(
mutex_new, mutex_free, mutex_lock, mutex_unlock, mutex_new, mutex_free, mutex_lock, mutex_unlock,
condvar_new, condvar_free, condvar_wait, condvar_wait_timeout, condvar_wake_one, condvar_wake_all condvar_new, condvar_free, condvar_wait, condvar_wait_timeout, condvar_wake_one, condvar_wake_all
); );
} }
static Mutex *mutex_new() static Mutex *mutex_new()
{ {
return new Mx; return new Mx;
} }
static void mutex_free(Mutex *mx) static void mutex_free(Mutex *mx)
{ {
delete mx; delete mx;
} }
static void mutex_lock(Mutex *mx) static void mutex_lock(Mutex *mx)
{ {
mx->lock(); mx->lock();
} }
static void mutex_unlock(Mutex *mx) static void mutex_unlock(Mutex *mx)
{ {
mx->unlock(); mx->unlock();
} }
static CondVar *condvar_new() static CondVar *condvar_new()
{ {
return new Cv; return new Cv;
} }
static void condvar_free(CondVar *cv) static void condvar_free(CondVar *cv)
{ {
delete cv; delete cv;
} }
static void condvar_wait(CondVar *cv, Mutex *mx) static void condvar_wait(CondVar *cv, Mutex *mx)
{ {
cv->wait(mx); cv->wait(mx);
} }
static bool condvar_wait_timeout(CondVar *cv, Mutex *mx, int timeout) static bool condvar_wait_timeout(CondVar *cv, Mutex *mx, int timeout)
{ {
return cv->wait_timeout(mx, timeout); return cv->wait_timeout(mx, timeout);
} }
static void condvar_wake_one(CondVar *cv) static void condvar_wake_one(CondVar *cv)
{ {
cv->wake_one(); cv->wake_one();
} }
static void condvar_wake_all(CondVar *cv) static void condvar_wake_all(CondVar *cv)
{ {
cv->wake_all(); cv->wake_all();
} }
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -31,9 +31,11 @@
#include "dispatcher.h" #include "dispatcher.h"
#include "Ecore.h" #include "Ecore.h"
namespace DBus { namespace DBus
{
namespace Ecore { namespace Ecore
{
class BusDispatcher; class BusDispatcher;
@ -41,70 +43,70 @@ class DXXAPI BusTimeout : public Timeout
{ {
private: private:
BusTimeout( Timeout::Internal*); BusTimeout(Timeout::Internal *);
~BusTimeout(); ~BusTimeout();
void toggle(); void toggle();
static Eina_Bool timeout_handler( void* ); static Eina_Bool timeout_handler(void *);
void _enable(); void _enable();
void _disable(); void _disable();
private: private:
Ecore_Timer *_etimer; Ecore_Timer *_etimer;
friend class BusDispatcher; friend class BusDispatcher;
}; };
class DXXAPI BusWatch : public Watch class DXXAPI BusWatch : public Watch
{ {
private: private:
BusWatch( Watch::Internal*); BusWatch(Watch::Internal *);
~BusWatch(); ~BusWatch();
void toggle(); void toggle();
static Eina_Bool watch_check ( void *data, Ecore_Fd_Handler *fdh); static Eina_Bool watch_check(void *data, Ecore_Fd_Handler *fdh);
static Eina_Bool watch_prepare ( void *data, Ecore_Fd_Handler *fdh); static Eina_Bool watch_prepare(void *data, Ecore_Fd_Handler *fdh);
static Eina_Bool watch_dispatch ( void *data, Ecore_Fd_Handler *fdh); static Eina_Bool watch_dispatch(void *data, Ecore_Fd_Handler *fdh);
void _enable(); void _enable();
void _disable(); void _disable();
void data (Ecore::BusDispatcher *bd); void data(Ecore::BusDispatcher *bd);
private: private:
Ecore_Fd_Handler *fd_handler; Ecore_Fd_Handler *fd_handler;
Ecore::BusDispatcher *_bd; Ecore::BusDispatcher *_bd;
friend class BusDispatcher; friend class BusDispatcher;
}; };
class DXXAPI BusDispatcher : public Dispatcher class DXXAPI BusDispatcher : public Dispatcher
{ {
public: public:
BusDispatcher(); BusDispatcher();
void enter() {} void enter() {}
void leave() {} void leave() {}
Timeout* add_timeout( Timeout::Internal* ); Timeout *add_timeout(Timeout::Internal *);
void rem_timeout( Timeout* ); void rem_timeout(Timeout *);
Watch* add_watch( Watch::Internal* ); Watch *add_watch(Watch::Internal *);
void rem_watch( Watch* ); void rem_watch(Watch *);
static Eina_Bool dispatch ( void *data, Ecore_Fd_Handler *fdh); static Eina_Bool dispatch(void *data, Ecore_Fd_Handler *fdh);
static Eina_Bool check ( void *data, Ecore_Fd_Handler *fdh); static Eina_Bool check(void *data, Ecore_Fd_Handler *fdh);
private: private:
}; };

View file

@ -30,7 +30,8 @@
#include <exception> #include <exception>
namespace DBus { namespace DBus
{
class Message; class Message;
class InternalError; class InternalError;
@ -39,245 +40,245 @@ class DXXAPI Error : public std::exception
{ {
public: public:
Error(); Error();
Error(InternalError &); Error(InternalError &);
Error(const char *name, const char *message); Error(const char *name, const char *message);
Error(Message &);
~Error() throw(); Error(Message &);
const char *what() const throw(); ~Error() throw();
const char *name() const; const char *what() const throw();
const char *message() const; const char *name() const;
void set(const char *name, const char *message); const char *message() const;
// parameters MUST be static strings
bool is_set() const; void set(const char *name, const char *message);
// parameters MUST be static strings
operator bool() const bool is_set() const;
{
return is_set(); operator bool() const
} {
return is_set();
}
private: private:
RefPtrI<InternalError> _int; RefPtrI<InternalError> _int;
}; };
struct DXXAPI ErrorFailed : public Error struct DXXAPI ErrorFailed : public Error
{ {
ErrorFailed(const char *message) ErrorFailed(const char *message)
: Error("org.freedesktop.DBus.Error.Failed", message) : Error("org.freedesktop.DBus.Error.Failed", message)
{} {}
}; };
struct DXXAPI ErrorNoMemory : public Error struct DXXAPI ErrorNoMemory : public Error
{ {
ErrorNoMemory(const char *message) ErrorNoMemory(const char *message)
: Error("org.freedesktop.DBus.Error.NoMemory", message) : Error("org.freedesktop.DBus.Error.NoMemory", message)
{} {}
}; };
struct DXXAPI ErrorServiceUnknown : public Error struct DXXAPI ErrorServiceUnknown : public Error
{ {
ErrorServiceUnknown(const char *message) ErrorServiceUnknown(const char *message)
: Error("org.freedesktop.DBus.Error.ServiceUnknown", message) : Error("org.freedesktop.DBus.Error.ServiceUnknown", message)
{} {}
}; };
struct DXXAPI ErrorNameHasNoOwner : public Error struct DXXAPI ErrorNameHasNoOwner : public Error
{ {
ErrorNameHasNoOwner(const char *message) ErrorNameHasNoOwner(const char *message)
: Error("org.freedesktop.DBus.Error.NameHasNoOwner", message) : Error("org.freedesktop.DBus.Error.NameHasNoOwner", message)
{} {}
}; };
struct DXXAPI ErrorNoReply : public Error struct DXXAPI ErrorNoReply : public Error
{ {
ErrorNoReply(const char *message) ErrorNoReply(const char *message)
: Error("org.freedesktop.DBus.Error.NoReply", message) : Error("org.freedesktop.DBus.Error.NoReply", message)
{} {}
}; };
struct DXXAPI ErrorIOError : public Error struct DXXAPI ErrorIOError : public Error
{ {
ErrorIOError(const char *message) ErrorIOError(const char *message)
: Error("org.freedesktop.DBus.Error.IOError", message) : Error("org.freedesktop.DBus.Error.IOError", message)
{} {}
}; };
struct DXXAPI ErrorBadAddress : public Error struct DXXAPI ErrorBadAddress : public Error
{ {
ErrorBadAddress(const char *message) ErrorBadAddress(const char *message)
: Error("org.freedesktop.DBus.Error.BadAddress", message) : Error("org.freedesktop.DBus.Error.BadAddress", message)
{} {}
}; };
struct DXXAPI ErrorNotSupported : public Error struct DXXAPI ErrorNotSupported : public Error
{ {
ErrorNotSupported(const char *message) ErrorNotSupported(const char *message)
: Error("org.freedesktop.DBus.Error.NotSupported", message) : Error("org.freedesktop.DBus.Error.NotSupported", message)
{} {}
}; };
struct DXXAPI ErrorLimitsExceeded : public Error struct DXXAPI ErrorLimitsExceeded : public Error
{ {
ErrorLimitsExceeded(const char *message) ErrorLimitsExceeded(const char *message)
: Error("org.freedesktop.DBus.Error.LimitsExceeded", message) : Error("org.freedesktop.DBus.Error.LimitsExceeded", message)
{} {}
}; };
struct DXXAPI ErrorAccessDenied : public Error struct DXXAPI ErrorAccessDenied : public Error
{ {
ErrorAccessDenied(const char *message) ErrorAccessDenied(const char *message)
: Error("org.freedesktop.DBus.Error.AccessDenied", message) : Error("org.freedesktop.DBus.Error.AccessDenied", message)
{} {}
}; };
struct DXXAPI ErrorAuthFailed : public Error struct DXXAPI ErrorAuthFailed : public Error
{ {
ErrorAuthFailed(const char *message) ErrorAuthFailed(const char *message)
: Error("org.freedesktop.DBus.Error.AuthFailed", message) : Error("org.freedesktop.DBus.Error.AuthFailed", message)
{} {}
}; };
struct DXXAPI ErrorNoServer : public Error struct DXXAPI ErrorNoServer : public Error
{ {
ErrorNoServer(const char *message) ErrorNoServer(const char *message)
: Error("org.freedesktop.DBus.Error.NoServer", message) : Error("org.freedesktop.DBus.Error.NoServer", message)
{} {}
}; };
struct DXXAPI ErrorTimeout : public Error struct DXXAPI ErrorTimeout : public Error
{ {
ErrorTimeout(const char *message) ErrorTimeout(const char *message)
: Error("org.freedesktop.DBus.Error.Timeout", message) : Error("org.freedesktop.DBus.Error.Timeout", message)
{} {}
}; };
struct DXXAPI ErrorNoNetwork : public Error struct DXXAPI ErrorNoNetwork : public Error
{ {
ErrorNoNetwork(const char *message) ErrorNoNetwork(const char *message)
: Error("org.freedesktop.DBus.Error.NoNetwork", message) : Error("org.freedesktop.DBus.Error.NoNetwork", message)
{} {}
}; };
struct DXXAPI ErrorAddressInUse : public Error struct DXXAPI ErrorAddressInUse : public Error
{ {
ErrorAddressInUse(const char *message) ErrorAddressInUse(const char *message)
: Error("org.freedesktop.DBus.Error.AddressInUse", message) : Error("org.freedesktop.DBus.Error.AddressInUse", message)
{} {}
}; };
struct DXXAPI ErrorDisconnected : public Error struct DXXAPI ErrorDisconnected : public Error
{ {
ErrorDisconnected(const char *message) ErrorDisconnected(const char *message)
: Error("org.freedesktop.DBus.Error.Disconnected", message) : Error("org.freedesktop.DBus.Error.Disconnected", message)
{} {}
}; };
struct DXXAPI ErrorInvalidArgs : public Error struct DXXAPI ErrorInvalidArgs : public Error
{ {
ErrorInvalidArgs(const char *message) ErrorInvalidArgs(const char *message)
: Error("org.freedesktop.DBus.Error.InvalidArgs", message) : Error("org.freedesktop.DBus.Error.InvalidArgs", message)
{} {}
}; };
struct DXXAPI ErrorFileNotFound : public Error struct DXXAPI ErrorFileNotFound : public Error
{ {
ErrorFileNotFound(const char *message) ErrorFileNotFound(const char *message)
: Error("org.freedesktop.DBus.Error.FileNotFound", message) : Error("org.freedesktop.DBus.Error.FileNotFound", message)
{} {}
}; };
struct DXXAPI ErrorUnknownMethod : public Error struct DXXAPI ErrorUnknownMethod : public Error
{ {
ErrorUnknownMethod(const char *message) ErrorUnknownMethod(const char *message)
: Error("org.freedesktop.DBus.Error.UnknownMethod", message) : Error("org.freedesktop.DBus.Error.UnknownMethod", message)
{} {}
}; };
struct DXXAPI ErrorTimedOut : public Error struct DXXAPI ErrorTimedOut : public Error
{ {
ErrorTimedOut(const char *message) ErrorTimedOut(const char *message)
: Error("org.freedesktop.DBus.Error.TimedOut", message) : Error("org.freedesktop.DBus.Error.TimedOut", message)
{} {}
}; };
struct DXXAPI ErrorMatchRuleNotFound : public Error struct DXXAPI ErrorMatchRuleNotFound : public Error
{ {
ErrorMatchRuleNotFound(const char *message) ErrorMatchRuleNotFound(const char *message)
: Error("org.freedesktop.DBus.Error.MatchRuleNotFound", message) : Error("org.freedesktop.DBus.Error.MatchRuleNotFound", message)
{} {}
}; };
struct DXXAPI ErrorMatchRuleInvalid : public Error struct DXXAPI ErrorMatchRuleInvalid : public Error
{ {
ErrorMatchRuleInvalid(const char *message) ErrorMatchRuleInvalid(const char *message)
: Error("org.freedesktop.DBus.Error.MatchRuleInvalid", message) : Error("org.freedesktop.DBus.Error.MatchRuleInvalid", message)
{} {}
}; };
struct DXXAPI ErrorSpawnExecFailed : public Error struct DXXAPI ErrorSpawnExecFailed : public Error
{ {
ErrorSpawnExecFailed(const char *message) ErrorSpawnExecFailed(const char *message)
: Error("org.freedesktop.DBus.Error.Spawn.ExecFailed", message) : Error("org.freedesktop.DBus.Error.Spawn.ExecFailed", message)
{} {}
}; };
struct DXXAPI ErrorSpawnForkFailed : public Error struct DXXAPI ErrorSpawnForkFailed : public Error
{ {
ErrorSpawnForkFailed(const char *message) ErrorSpawnForkFailed(const char *message)
: Error("org.freedesktop.DBus.Error.Spawn.ForkFailed", message) : Error("org.freedesktop.DBus.Error.Spawn.ForkFailed", message)
{} {}
}; };
struct DXXAPI ErrorSpawnChildExited : public Error struct DXXAPI ErrorSpawnChildExited : public Error
{ {
ErrorSpawnChildExited(const char *message) ErrorSpawnChildExited(const char *message)
: Error("org.freedesktop.DBus.Error.Spawn.ChildExited", message) : Error("org.freedesktop.DBus.Error.Spawn.ChildExited", message)
{} {}
}; };
struct DXXAPI ErrorSpawnChildSignaled : public Error struct DXXAPI ErrorSpawnChildSignaled : public Error
{ {
ErrorSpawnChildSignaled(const char *message) ErrorSpawnChildSignaled(const char *message)
: Error("org.freedesktop.DBus.Error.Spawn.ChildSignaled", message) : Error("org.freedesktop.DBus.Error.Spawn.ChildSignaled", message)
{} {}
}; };
struct DXXAPI ErrorSpawnFailed : public Error struct DXXAPI ErrorSpawnFailed : public Error
{ {
ErrorSpawnFailed(const char *message) ErrorSpawnFailed(const char *message)
: Error("org.freedesktop.DBus.Error.Spawn.Failed", message) : Error("org.freedesktop.DBus.Error.Spawn.Failed", message)
{} {}
}; };
struct DXXAPI ErrorInvalidSignature : public Error struct DXXAPI ErrorInvalidSignature : public Error
{ {
ErrorInvalidSignature(const char *message) ErrorInvalidSignature(const char *message)
: Error("org.freedesktop.DBus.Error.InvalidSignature", message) : Error("org.freedesktop.DBus.Error.InvalidSignature", message)
{} {}
}; };
struct DXXAPI ErrorUnixProcessIdUnknown : public Error struct DXXAPI ErrorUnixProcessIdUnknown : public Error
{ {
ErrorUnixProcessIdUnknown(const char *message) ErrorUnixProcessIdUnknown(const char *message)
: Error("org.freedesktop.DBus.Error.UnixProcessIdUnknown", message) : Error("org.freedesktop.DBus.Error.UnixProcessIdUnknown", message)
{} {}
}; };
struct DXXAPI ErrorSELinuxSecurityContextUnknown : public Error struct DXXAPI ErrorSELinuxSecurityContextUnknown : public Error
{ {
ErrorSELinuxSecurityContextUnknown(const char *message) ErrorSELinuxSecurityContextUnknown(const char *message)
: Error("org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown", message) : Error("org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown", message)
{} {}
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -31,9 +31,10 @@
#include "util.h" #include "util.h"
#include "eventloop.h" #include "eventloop.h"
namespace DBus { namespace DBus
{
/* /*
* Glue between the event loop and the DBus library * Glue between the event loop and the DBus library
*/ */
@ -42,55 +43,55 @@ class Pipe;
class DXXAPI BusTimeout : public Timeout, public DefaultTimeout class DXXAPI BusTimeout : public Timeout, public DefaultTimeout
{ {
BusTimeout(Timeout::Internal *, BusDispatcher *); BusTimeout(Timeout::Internal *, BusDispatcher *);
void toggle(); void toggle();
friend class BusDispatcher; friend class BusDispatcher;
}; };
class DXXAPI BusWatch : public Watch, public DefaultWatch class DXXAPI BusWatch : public Watch, public DefaultWatch
{ {
BusWatch(Watch::Internal *, BusDispatcher *); BusWatch(Watch::Internal *, BusDispatcher *);
void toggle(); void toggle();
friend class BusDispatcher; friend class BusDispatcher;
}; };
class DXXAPI BusDispatcher : public Dispatcher, public DefaultMainLoop class DXXAPI BusDispatcher : public Dispatcher, public DefaultMainLoop
{ {
public: public:
BusDispatcher(); BusDispatcher();
~BusDispatcher() {}
virtual void enter(); ~BusDispatcher() {}
virtual void leave(); virtual void enter();
virtual void leave();
virtual Pipe *add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data); virtual Pipe *add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data);
virtual void del_pipe (Pipe *pipe); virtual void del_pipe(Pipe *pipe);
virtual void do_iteration();
virtual Timeout *add_timeout(Timeout::Internal *); virtual void do_iteration();
virtual void rem_timeout(Timeout *); virtual Timeout *add_timeout(Timeout::Internal *);
virtual Watch *add_watch(Watch::Internal *); virtual void rem_timeout(Timeout *);
virtual void rem_watch(Watch *); virtual Watch *add_watch(Watch::Internal *);
void watch_ready(DefaultWatch &); virtual void rem_watch(Watch *);
void timeout_expired(DefaultTimeout &); void watch_ready(DefaultWatch &);
void timeout_expired(DefaultTimeout &);
private: private:
bool _running; bool _running;
int _pipe[2]; int _pipe[2];
std::list <Pipe*> pipe_list; std::list <Pipe *> pipe_list;
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -31,7 +31,8 @@
#include "api.h" #include "api.h"
#include "util.h" #include "util.h"
namespace DBus { namespace DBus
{
/* /*
* these Default *classes implement a very simple event loop which * these Default *classes implement a very simple event loop which
@ -46,38 +47,62 @@ class DXXAPI DefaultTimeout
{ {
public: public:
DefaultTimeout(int interval, bool repeat, DefaultMainLoop *); DefaultTimeout(int interval, bool repeat, DefaultMainLoop *);
virtual ~DefaultTimeout(); virtual ~DefaultTimeout();
bool enabled(){ return _enabled; } bool enabled()
void enabled(bool e){ _enabled = e; } {
return _enabled;
}
void enabled(bool e)
{
_enabled = e;
}
int interval(){ return _interval; } int interval()
void interval(int i){ _interval = i; } {
return _interval;
}
void interval(int i)
{
_interval = i;
}
bool repeat(){ return _repeat; } bool repeat()
void repeat(bool r){ _repeat = r; } {
return _repeat;
}
void repeat(bool r)
{
_repeat = r;
}
void *data(){ return _data; } void *data()
void data(void *d){ _data = d; } {
return _data;
}
void data(void *d)
{
_data = d;
}
Slot<void, DefaultTimeout &> expired;
Slot<void, DefaultTimeout &> expired;
private: private:
bool _enabled; bool _enabled;
int _interval; int _interval;
bool _repeat; bool _repeat;
double _expiration; double _expiration;
void *_data; void *_data;
DefaultMainLoop *_disp;
friend class DefaultMainLoop; DefaultMainLoop *_disp;
friend class DefaultMainLoop;
}; };
typedef std::list< DefaultTimeout *> DefaultTimeouts; typedef std::list< DefaultTimeout *> DefaultTimeouts;
@ -86,38 +111,62 @@ class DXXAPI DefaultWatch
{ {
public: public:
DefaultWatch(int fd, int flags, DefaultMainLoop *); DefaultWatch(int fd, int flags, DefaultMainLoop *);
virtual ~DefaultWatch(); virtual ~DefaultWatch();
bool enabled(){ return _enabled; } bool enabled()
void enabled(bool e){ _enabled = e; } {
return _enabled;
}
void enabled(bool e)
{
_enabled = e;
}
int descriptor(){ return _fd; } int descriptor()
{
return _fd;
}
int flags(){ return _flags; } int flags()
void flags(int f){ _flags = f; } {
return _flags;
}
void flags(int f)
{
_flags = f;
}
int state(){ return _state; } int state()
{
return _state;
}
void *data(){ return _data; } void *data()
void data(void *d){ _data = d; } {
return _data;
}
void data(void *d)
{
_data = d;
}
Slot<void, DefaultWatch &> ready; Slot<void, DefaultWatch &> ready;
private: private:
bool _enabled; bool _enabled;
int _fd; int _fd;
int _flags; int _flags;
int _state; int _state;
void *_data; void *_data;
DefaultMainLoop *_disp; DefaultMainLoop *_disp;
friend class DefaultMainLoop; friend class DefaultMainLoop;
}; };
typedef std::list< DefaultWatch *> DefaultWatches; typedef std::list< DefaultWatch *> DefaultWatches;
@ -135,40 +184,40 @@ public:
* Constructor * Constructor
* \param recursive Set if Mutex should be recursive or not. * \param recursive Set if Mutex should be recursive or not.
*/ */
DefaultMutex(bool recursive); DefaultMutex(bool recursive);
~DefaultMutex(); ~DefaultMutex();
void lock(); void lock();
void unlock(); void unlock();
private: private:
pthread_mutex_t _mutex; pthread_mutex_t _mutex;
}; };
class DXXAPI DefaultMainLoop class DXXAPI DefaultMainLoop
{ {
public: public:
DefaultMainLoop(); DefaultMainLoop();
virtual ~DefaultMainLoop(); virtual ~DefaultMainLoop();
virtual void dispatch(); virtual void dispatch();
int _fdunlock[2]; int _fdunlock[2];
private: private:
DefaultMutex _mutex_t; DefaultMutex _mutex_t;
DefaultTimeouts _timeouts; DefaultTimeouts _timeouts;
DefaultMutex _mutex_w; DefaultMutex _mutex_w;
DefaultWatches _watches; DefaultWatches _watches;
friend class DefaultTimeout; friend class DefaultTimeout;
friend class DefaultWatch; friend class DefaultWatch;
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -30,9 +30,11 @@
#include "api.h" #include "api.h"
#include "dispatcher.h" #include "dispatcher.h"
namespace DBus { namespace DBus
{
namespace Glib { namespace Glib
{
class BusDispatcher; class BusDispatcher;
@ -40,80 +42,80 @@ class DXXAPI BusTimeout : public Timeout
{ {
private: private:
BusTimeout(Timeout::Internal *, GMainContext *, int); BusTimeout(Timeout::Internal *, GMainContext *, int);
~BusTimeout(); ~BusTimeout();
void toggle(); void toggle();
static gboolean timeout_handler(gpointer); static gboolean timeout_handler(gpointer);
void _enable(); void _enable();
void _disable(); void _disable();
private: private:
GMainContext *_ctx; GMainContext *_ctx;
int _priority; int _priority;
GSource *_source; GSource *_source;
friend class BusDispatcher; friend class BusDispatcher;
}; };
class DXXAPI BusWatch : public Watch class DXXAPI BusWatch : public Watch
{ {
private: private:
BusWatch(Watch::Internal *, GMainContext *, int); BusWatch(Watch::Internal *, GMainContext *, int);
~BusWatch(); ~BusWatch();
void toggle(); void toggle();
static gboolean watch_handler(gpointer); static gboolean watch_handler(gpointer);
void _enable(); void _enable();
void _disable(); void _disable();
private: private:
GMainContext *_ctx; GMainContext *_ctx;
int _priority; int _priority;
GSource *_source; GSource *_source;
friend class BusDispatcher; friend class BusDispatcher;
}; };
class DXXAPI BusDispatcher : public Dispatcher class DXXAPI BusDispatcher : public Dispatcher
{ {
public: public:
BusDispatcher(); BusDispatcher();
~BusDispatcher(); ~BusDispatcher();
void attach(GMainContext *); void attach(GMainContext *);
void enter() {} void enter() {}
void leave() {} void leave() {}
Timeout *add_timeout(Timeout::Internal *); Timeout *add_timeout(Timeout::Internal *);
void rem_timeout(Timeout *); void rem_timeout(Timeout *);
Watch *add_watch(Watch::Internal *); Watch *add_watch(Watch::Internal *);
void rem_watch(Watch *); void rem_watch(Watch *);
void set_priority(int priority); void set_priority(int priority);
private: private:
GMainContext *_ctx; GMainContext *_ctx;
int _priority; int _priority;
GSource *_source; GSource *_source;
}; };
} /* namespace Glib */ } /* namespace Glib */

View file

@ -33,15 +33,16 @@
#include "message.h" #include "message.h"
namespace DBus { namespace DBus
{
//todo: this should belong to to properties.h //todo: this should belong to to properties.h
struct DXXAPI PropertyData struct DXXAPI PropertyData
{ {
bool read; bool read;
bool write; bool write;
std::string sig; std::string sig;
Variant value; Variant value;
}; };
typedef std::map<std::string, PropertyData> PropertyTable; typedef std::map<std::string, PropertyData> PropertyTable;
@ -58,18 +59,18 @@ class DXXAPI AdaptorBase
{ {
public: public:
virtual const ObjectAdaptor *object() const = 0 ; virtual const ObjectAdaptor *object() const = 0 ;
protected: protected:
InterfaceAdaptor *find_interface(const std::string &name); InterfaceAdaptor *find_interface(const std::string &name);
virtual ~AdaptorBase() virtual ~AdaptorBase()
{} {}
virtual void _emit_signal(SignalMessage &) = 0; virtual void _emit_signal(SignalMessage &) = 0;
InterfaceAdaptorTable _interfaces; InterfaceAdaptorTable _interfaces;
}; };
/* /*
@ -85,35 +86,35 @@ class DXXAPI ProxyBase
{ {
public: public:
virtual const ObjectProxy *object() const = 0 ; virtual const ObjectProxy *object() const = 0 ;
protected: protected:
InterfaceProxy *find_interface(const std::string &name); InterfaceProxy *find_interface(const std::string &name);
virtual ~ProxyBase() virtual ~ProxyBase()
{} {}
virtual Message _invoke_method(CallMessage &) = 0; virtual Message _invoke_method(CallMessage &) = 0;
virtual bool _invoke_method_noreply(CallMessage &call) = 0;
InterfaceProxyTable _interfaces; virtual bool _invoke_method_noreply(CallMessage &call) = 0;
InterfaceProxyTable _interfaces;
}; };
class DXXAPI Interface class DXXAPI Interface
{ {
public: public:
Interface(const std::string &name);
virtual ~Interface();
inline const std::string &name() const; Interface(const std::string &name);
virtual ~Interface();
inline const std::string &name() const;
private: private:
std::string _name; std::string _name;
}; };
/* /*
@ -121,7 +122,7 @@ private:
const std::string &Interface::name() const const std::string &Interface::name() const
{ {
return _name; return _name;
} }
/* /*
@ -133,25 +134,25 @@ class DXXAPI InterfaceAdaptor : public Interface, public virtual AdaptorBase
{ {
public: public:
InterfaceAdaptor(const std::string &name); InterfaceAdaptor(const std::string &name);
Message dispatch_method(const CallMessage &); Message dispatch_method(const CallMessage &);
void emit_signal(const SignalMessage &); void emit_signal(const SignalMessage &);
Variant *get_property(const std::string &name); Variant *get_property(const std::string &name);
void set_property(const std::string &name, Variant &value); void set_property(const std::string &name, Variant &value);
virtual IntrospectedInterface * introspect() const virtual IntrospectedInterface *introspect() const
{ {
return NULL; return NULL;
} }
protected: protected:
MethodTable _methods; MethodTable _methods;
PropertyTable _properties; PropertyTable _properties;
}; };
/* /*
@ -163,17 +164,17 @@ class DXXAPI InterfaceProxy : public Interface, public virtual ProxyBase
{ {
public: public:
InterfaceProxy(const std::string &name); InterfaceProxy(const std::string &name);
Message invoke_method(const CallMessage &); Message invoke_method(const CallMessage &);
bool invoke_method_noreply(const CallMessage &call); bool invoke_method_noreply(const CallMessage &call);
bool dispatch_signal(const SignalMessage &); bool dispatch_signal(const SignalMessage &);
protected: protected:
SignalTable _signals; SignalTable _signals;
}; };
# define register_method(interface, method, callback) \ # define register_method(interface, method, callback) \
@ -185,7 +186,7 @@ protected:
InterfaceAdaptor::_properties[ #variable ].write = can_write; \ InterfaceAdaptor::_properties[ #variable ].write = can_write; \
InterfaceAdaptor::_properties[ #variable ].sig = type; \ InterfaceAdaptor::_properties[ #variable ].sig = type; \
variable.bind(InterfaceAdaptor::_properties[ #variable ]); variable.bind(InterfaceAdaptor::_properties[ #variable ]);
# define connect_signal(interface, signal, callback) \ # define connect_signal(interface, signal, callback) \
InterfaceProxy::_signals[ #signal ] = \ InterfaceProxy::_signals[ #signal ] = \
new ::DBus::Callback< interface, void, const ::DBus::SignalMessage &>(this, & interface :: callback); new ::DBus::Callback< interface, void, const ::DBus::SignalMessage &>(this, & interface :: callback);

View file

@ -28,57 +28,58 @@
#include "api.h" #include "api.h"
#include "interface.h" #include "interface.h"
namespace DBus { namespace DBus
{
struct DXXAPI IntrospectedArgument struct DXXAPI IntrospectedArgument
{ {
const char *name; const char *name;
const char *type; const char *type;
const bool in; const bool in;
}; };
struct DXXAPI IntrospectedMethod struct DXXAPI IntrospectedMethod
{ {
const char *name; const char *name;
const IntrospectedArgument *args; const IntrospectedArgument *args;
}; };
struct DXXAPI IntrospectedProperty struct DXXAPI IntrospectedProperty
{ {
const char *name; const char *name;
const char *type; const char *type;
const bool read; const bool read;
const bool write; const bool write;
}; };
struct DXXAPI IntrospectedInterface struct DXXAPI IntrospectedInterface
{ {
const char *name; const char *name;
const IntrospectedMethod *methods; const IntrospectedMethod *methods;
const IntrospectedMethod *signals; const IntrospectedMethod *signals;
const IntrospectedProperty *properties; const IntrospectedProperty *properties;
}; };
class DXXAPI IntrospectableAdaptor : public InterfaceAdaptor class DXXAPI IntrospectableAdaptor : public InterfaceAdaptor
{ {
public: public:
IntrospectableAdaptor(); IntrospectableAdaptor();
Message Introspect(const CallMessage &); Message Introspect(const CallMessage &);
protected: protected:
IntrospectedInterface * introspect() const; IntrospectedInterface *introspect() const;
}; };
class DXXAPI IntrospectableProxy : public InterfaceProxy class DXXAPI IntrospectableProxy : public InterfaceProxy
{ {
public: public:
IntrospectableProxy(); IntrospectableProxy();
std::string Introspect(); std::string Introspect();
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -31,7 +31,8 @@
#include "api.h" #include "api.h"
#include "util.h" #include "util.h"
namespace DBus { namespace DBus
{
class Message; class Message;
class ErrorMessage; class ErrorMessage;
@ -44,175 +45,175 @@ class DXXAPI MessageIter
{ {
public: public:
MessageIter() {} MessageIter() {}
int type(); int type();
bool at_end(); bool at_end();
bool has_next(); bool has_next();
MessageIter &operator ++(); MessageIter &operator ++();
MessageIter operator ++(int); MessageIter operator ++(int);
bool append_byte(unsigned char byte); bool append_byte(unsigned char byte);
unsigned char get_byte(); unsigned char get_byte();
bool append_bool(bool b); bool append_bool(bool b);
bool get_bool(); bool get_bool();
bool append_int16(signed short i); bool append_int16(signed short i);
signed short get_int16(); signed short get_int16();
bool append_uint16(unsigned short u); bool append_uint16(unsigned short u);
unsigned short get_uint16(); unsigned short get_uint16();
bool append_int32(signed int i); bool append_int32(signed int i);
signed int get_int32(); signed int get_int32();
bool append_uint32(unsigned int u); bool append_uint32(unsigned int u);
unsigned int get_uint32(); unsigned int get_uint32();
bool append_int64(signed long long i); bool append_int64(signed long long i);
signed long long get_int64(); signed long long get_int64();
bool append_uint64(unsigned long long i); bool append_uint64(unsigned long long i);
unsigned long long get_uint64(); unsigned long long get_uint64();
bool append_double(double d); bool append_double(double d);
double get_double(); double get_double();
bool append_string(const char *chars);
const char *get_string(); bool append_string(const char *chars);
bool append_path(const char *chars); const char *get_string();
const char *get_path(); bool append_path(const char *chars);
bool append_signature(const char *chars); const char *get_path();
const char *get_signature(); bool append_signature(const char *chars);
char *signature() const; //returned string must be manually free()'d const char *get_signature();
MessageIter recurse();
bool append_array(char type, const void *ptr, size_t length); char *signature() const; //returned string must be manually free()'d
int array_type(); MessageIter recurse();
int get_array(void *ptr); bool append_array(char type, const void *ptr, size_t length);
bool is_array(); int array_type();
bool is_dict(); int get_array(void *ptr);
MessageIter new_array(const char *sig); bool is_array();
MessageIter new_variant(const char *sig); bool is_dict();
MessageIter new_struct(); MessageIter new_array(const char *sig);
MessageIter new_dict_entry(); MessageIter new_variant(const char *sig);
void close_container(MessageIter &container); MessageIter new_struct();
void copy_data(MessageIter &to); MessageIter new_dict_entry();
Message &msg() const void close_container(MessageIter &container);
{
return *_msg; void copy_data(MessageIter &to);
}
Message &msg() const
{
return *_msg;
}
private: private:
DXXAPILOCAL MessageIter(Message &msg) : _msg(&msg) {} DXXAPILOCAL MessageIter(Message &msg) : _msg(&msg) {}
DXXAPILOCAL bool append_basic(int type_id, void *value); DXXAPILOCAL bool append_basic(int type_id, void *value);
DXXAPILOCAL void get_basic(int type_id, void *ptr); DXXAPILOCAL void get_basic(int type_id, void *ptr);
private: private:
/* I'm sorry, but don't want to include dbus.h in the public api /* I'm sorry, but don't want to include dbus.h in the public api
*/ */
unsigned char _iter[sizeof(void *)*3+sizeof(int)*11]; unsigned char _iter[sizeof(void *) * 3 + sizeof(int) * 11];
Message *_msg; Message *_msg;
friend class Message; friend class Message;
}; };
class DXXAPI Message class DXXAPI Message
{ {
public: public:
struct Private;
Message(Private *, bool incref = true); struct Private;
Message(const Message &m); Message(Private *, bool incref = true);
~Message(); Message(const Message &m);
Message &operator = (const Message &m); ~Message();
Message copy(); Message &operator = (const Message &m);
int type() const; Message copy();
int serial() const; int type() const;
int reply_serial() const; int serial() const;
bool reply_serial(int); int reply_serial() const;
const char *sender() const; bool reply_serial(int);
bool sender(const char *s); const char *sender() const;
const char *destination() const; bool sender(const char *s);
bool destination(const char *s); const char *destination() const;
bool is_error() const; bool destination(const char *s);
bool is_signal(const char *interface, const char *member) const; bool is_error() const;
MessageIter reader() const; bool is_signal(const char *interface, const char *member) const;
MessageIter writer(); MessageIter reader() const;
bool append(int first_type, ...); MessageIter writer();
void terminate(); bool append(int first_type, ...);
void terminate();
protected: protected:
Message(); Message();
protected: protected:
RefPtrI<Private> _pvt; RefPtrI<Private> _pvt;
/* classes who need to read `_pvt` directly /* classes who need to read `_pvt` directly
*/ */
friend class ErrorMessage; friend class ErrorMessage;
friend class ReturnMessage; friend class ReturnMessage;
friend class MessageIter; friend class MessageIter;
friend class Error; friend class Error;
friend class Connection; friend class Connection;
}; };
/* /*
@ -221,16 +222,16 @@ friend class Connection;
class DXXAPI ErrorMessage : public Message class DXXAPI ErrorMessage : public Message
{ {
public: public:
ErrorMessage();
ErrorMessage(const Message &, const char *name, const char *message); ErrorMessage();
const char *name() const; ErrorMessage(const Message &, const char *name, const char *message);
bool name(const char *n); const char *name() const;
bool operator == (const ErrorMessage &) const; bool name(const char *n);
bool operator == (const ErrorMessage &) const;
}; };
/* /*
@ -240,25 +241,25 @@ class DXXAPI SignalMessage : public Message
{ {
public: public:
SignalMessage(const char *name); SignalMessage(const char *name);
SignalMessage(const char *path, const char *interface, const char *name); SignalMessage(const char *path, const char *interface, const char *name);
const char *interface() const; const char *interface() const;
bool interface(const char *i); bool interface(const char *i);
const char *member() const; const char *member() const;
bool member(const char *m); bool member(const char *m);
const char *path() const; const char *path() const;
char ** path_split() const; char **path_split() const;
bool path(const char *p); bool path(const char *p);
bool operator == (const SignalMessage &) const; bool operator == (const SignalMessage &) const;
}; };
/* /*
@ -267,28 +268,28 @@ public:
class DXXAPI CallMessage : public Message class DXXAPI CallMessage : public Message
{ {
public: public:
CallMessage();
CallMessage(const char *dest, const char *path, const char *iface, const char *method); CallMessage();
const char *interface() const; CallMessage(const char *dest, const char *path, const char *iface, const char *method);
bool interface(const char *i); const char *interface() const;
const char *member() const; bool interface(const char *i);
bool member(const char *m); const char *member() const;
const char *path() const; bool member(const char *m);
char ** path_split() const; const char *path() const;
bool path(const char *p); char **path_split() const;
const char *signature() const; bool path(const char *p);
bool operator == (const CallMessage &) const; const char *signature() const;
bool operator == (const CallMessage &) const;
}; };
/* /*
@ -297,10 +298,10 @@ public:
class DXXAPI ReturnMessage : public Message class DXXAPI ReturnMessage : public Message
{ {
public: public:
ReturnMessage(const CallMessage &callee);
const char *signature() const; ReturnMessage(const CallMessage &callee);
const char *signature() const;
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -34,40 +34,41 @@
#include "message.h" #include "message.h"
#include "types.h" #include "types.h"
namespace DBus { namespace DBus
{
class DXXAPI Object class DXXAPI Object
{ {
protected: protected:
Object(Connection &conn, const Path &path, const char *service); Object(Connection &conn, const Path &path, const char *service);
public: public:
virtual ~Object(); virtual ~Object();
inline const DBus::Path &path() const; inline const DBus::Path &path() const;
inline const std::string &service() const; inline const std::string &service() const;
inline Connection &conn();
void set_timeout(int new_timeout = -1); inline Connection &conn();
inline int get_timeout() const; void set_timeout(int new_timeout = -1);
inline int get_timeout() const;
private: private:
DXXAPILOCAL virtual bool handle_message(const Message &) = 0; DXXAPILOCAL virtual bool handle_message(const Message &) = 0;
DXXAPILOCAL virtual void register_obj() = 0; DXXAPILOCAL virtual void register_obj() = 0;
DXXAPILOCAL virtual void unregister_obj(bool throw_on_error = true) = 0; DXXAPILOCAL virtual void unregister_obj(bool throw_on_error = true) = 0;
private: private:
Connection _conn; Connection _conn;
DBus::Path _path; DBus::Path _path;
std::string _service; std::string _service;
int _default_timeout; int _default_timeout;
}; };
/* /*
@ -75,22 +76,22 @@ private:
Connection &Object::conn() Connection &Object::conn()
{ {
return _conn; return _conn;
} }
const DBus::Path &Object::path() const const DBus::Path &Object::path() const
{ {
return _path; return _path;
} }
const std::string &Object::service() const const std::string &Object::service() const
{ {
return _service; return _service;
} }
int Object::get_timeout() const int Object::get_timeout() const
{ {
return _default_timeout; return _default_timeout;
} }
/* /*
@ -100,8 +101,8 @@ class DXXAPI Tag
{ {
public: public:
virtual ~Tag() virtual ~Tag()
{} {}
}; };
/* /*
@ -116,79 +117,79 @@ class DXXAPI ObjectAdaptor : public Object, public virtual AdaptorBase
{ {
public: public:
static ObjectAdaptor *from_path(const Path &path); static ObjectAdaptor *from_path(const Path &path);
static ObjectAdaptorPList from_path_prefix(const std::string &prefix); static ObjectAdaptorPList from_path_prefix(const std::string &prefix);
static ObjectPathList child_nodes_from_prefix(const std::string &prefix); static ObjectPathList child_nodes_from_prefix(const std::string &prefix);
struct Private; struct Private;
ObjectAdaptor(Connection &conn, const Path &path); ObjectAdaptor(Connection &conn, const Path &path);
~ObjectAdaptor(); ~ObjectAdaptor();
inline const ObjectAdaptor *object() const; inline const ObjectAdaptor *object() const;
protected: protected:
class DXXAPI Continuation class DXXAPI Continuation
{ {
public: public:
inline MessageIter &writer(); inline MessageIter &writer();
inline Tag *tag(); inline Tag *tag();
private: private:
Continuation(Connection &conn, const CallMessage &call, const Tag *tag); Continuation(Connection &conn, const CallMessage &call, const Tag *tag);
Connection _conn; Connection _conn;
CallMessage _call; CallMessage _call;
MessageIter _writer; MessageIter _writer;
ReturnMessage _return; ReturnMessage _return;
const Tag *_tag; const Tag *_tag;
friend class ObjectAdaptor; friend class ObjectAdaptor;
}; };
void return_later(const Tag *tag); void return_later(const Tag *tag);
void return_now(Continuation *ret); void return_now(Continuation *ret);
void return_error(Continuation *ret, const Error error); void return_error(Continuation *ret, const Error error);
Continuation *find_continuation(const Tag *tag); Continuation *find_continuation(const Tag *tag);
private: private:
void _emit_signal(SignalMessage &); void _emit_signal(SignalMessage &);
bool handle_message(const Message &); bool handle_message(const Message &);
void register_obj(); void register_obj();
void unregister_obj(bool throw_on_error = true); void unregister_obj(bool throw_on_error = true);
typedef std::map<const Tag *, Continuation *> ContinuationMap; typedef std::map<const Tag *, Continuation *> ContinuationMap;
ContinuationMap _continuations; ContinuationMap _continuations;
friend struct Private; friend struct Private;
}; };
const ObjectAdaptor *ObjectAdaptor::object() const const ObjectAdaptor *ObjectAdaptor::object() const
{ {
return this; return this;
} }
Tag *ObjectAdaptor::Continuation::tag() Tag *ObjectAdaptor::Continuation::tag()
{ {
return const_cast<Tag *>(_tag); return const_cast<Tag *>(_tag);
} }
MessageIter &ObjectAdaptor::Continuation::writer() MessageIter &ObjectAdaptor::Continuation::writer()
{ {
return _writer; return _writer;
} }
/* /*
@ -202,31 +203,31 @@ class DXXAPI ObjectProxy : public Object, public virtual ProxyBase
{ {
public: public:
ObjectProxy(Connection &conn, const Path &path, const char *service = ""); ObjectProxy(Connection &conn, const Path &path, const char *service = "");
~ObjectProxy(); ~ObjectProxy();
inline const ObjectProxy *object() const; inline const ObjectProxy *object() const;
private: private:
Message _invoke_method(CallMessage &); Message _invoke_method(CallMessage &);
bool _invoke_method_noreply(CallMessage &call);
bool handle_message(const Message &); bool _invoke_method_noreply(CallMessage &call);
void register_obj(); bool handle_message(const Message &);
void unregister_obj(bool throw_on_error = true);
void register_obj();
void unregister_obj(bool throw_on_error = true);
private: private:
MessageSlot _filtered; MessageSlot _filtered;
}; };
const ObjectProxy *ObjectProxy::object() const const ObjectProxy *ObjectProxy::object() const
{ {
return this; return this;
} }
} /* namespace DBus */ } /* namespace DBus */

View file

@ -29,7 +29,8 @@
#include "util.h" #include "util.h"
#include "message.h" #include "message.h"
namespace DBus { namespace DBus
{
class Connection; class Connection;
@ -37,94 +38,94 @@ class DXXAPI PendingCall
{ {
public: public:
struct Private; struct Private;
PendingCall(Private *); PendingCall(Private *);
PendingCall(const PendingCall &); PendingCall(const PendingCall &);
virtual ~PendingCall(); virtual ~PendingCall();
PendingCall &operator = (const PendingCall &); PendingCall &operator = (const PendingCall &);
/*! /*!
* \brief Checks whether the pending call has received a reply yet, or not. * \brief Checks whether the pending call has received a reply yet, or not.
* *
* \return true If a reply has been received. * \return true If a reply has been received.
*/ */
bool completed(); bool completed();
/*!
* \brief Cancels the pending call, such that any reply or error received will
* just be ignored.
*
* Drops the dbus library's internal reference to the DBusPendingCall so will
* free the call if nobody else is holding a reference. However you usually
* get a reference from Connection::send_async() so probably your app
* owns a ref also.
*
* Note that canceling a pending call will not simulate a timed-out call; if a
* call times out, then a timeout error reply is received. If you cancel the
* call, no reply is received unless the the reply was already received before
* you canceled.
*/
void cancel();
/*! /*!
* \brief Block until the pending call is completed. * \brief Cancels the pending call, such that any reply or error received will
* * just be ignored.
* The blocking is as with Connection::send_blocking(); it *
* does not enter the main loop or process other messages, it simply waits for * Drops the dbus library's internal reference to the DBusPendingCall so will
* the reply in question. * free the call if nobody else is holding a reference. However you usually
* * get a reference from Connection::send_async() so probably your app
* If the pending call is already completed, this function returns immediately. * owns a ref also.
*/ *
void block(); * Note that canceling a pending call will not simulate a timed-out call; if a
* call times out, then a timeout error reply is received. If you cancel the
* call, no reply is received unless the the reply was already received before
* you canceled.
*/
void cancel();
/*! /*!
* \brief Stores a pointer on a PendingCall, along with an optional function to * \brief Block until the pending call is completed.
* be used for freeing the data when the data is set again, or when the *
* pending call is finalized. * The blocking is as with Connection::send_blocking(); it
* * does not enter the main loop or process other messages, it simply waits for
* The slot is allocated automatic. * the reply in question.
* *
* \param data The data to store. * If the pending call is already completed, this function returns immediately.
* \throw ErrorNoMemory */
*/ void block();
void data( void* data );
/*! /*!
* \brief Retrieves data previously set with dbus_pending_call_set_data(). * \brief Stores a pointer on a PendingCall, along with an optional function to
* * be used for freeing the data when the data is set again, or when the
* The slot must still be allocated (must not have been freed). * pending call is finalized.
* *
* \return The data, or NULL if not found. * The slot is allocated automatic.
*/ *
void *data(); * \param data The data to store.
* \throw ErrorNoMemory
*/
void data(void *data);
/*! /*!
* \return The data slot. * \brief Retrieves data previously set with dbus_pending_call_set_data().
*/ *
Slot<void, PendingCall &>& slot(); * The slot must still be allocated (must not have been freed).
*
* \return The data, or NULL if not found.
*/
void *data();
/*! /*!
* \brief Gets the reply * \return The data slot.
* */
* Ownership of the reply message passes to the caller. This function can only Slot<void, PendingCall &>& slot();
* be called once per pending call, since the reply message is tranferred to
* the caller. /*!
* * \brief Gets the reply
* \return The reply Message. *
* \throw ErrorNoReply * Ownership of the reply message passes to the caller. This function can only
*/ * be called once per pending call, since the reply message is tranferred to
Message steal_reply(); * the caller.
*
* \return The reply Message.
* \throw ErrorNoReply
*/
Message steal_reply();
private: private:
RefPtrI<Private> _pvt; RefPtrI<Private> _pvt;
friend struct Private; friend struct Private;
friend class Connection; friend class Connection;
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -30,38 +30,39 @@
/* STD */ /* STD */
#include <cstdlib> #include <cstdlib>
namespace DBus { namespace DBus
{
class DXXAPI Pipe class DXXAPI Pipe
{ {
public: public:
/*! /*!
* Write some data into the communication pipe. * Write some data into the communication pipe.
* *
* @param buffer The raw data to write. * @param buffer The raw data to write.
* @param nbytes The number of bytes to write from the buffer. * @param nbytes The number of bytes to write from the buffer.
*/ */
void write(const void *buffer, unsigned int nbytes); void write(const void *buffer, unsigned int nbytes);
ssize_t read(void *buffer, unsigned int &nbytes); ssize_t read(void *buffer, unsigned int &nbytes);
/*! /*!
* Simply write one single byte into the pipe. This is a shortcut * Simply write one single byte into the pipe. This is a shortcut
* if there's really no data to transport, but to activate the handler. * if there's really no data to transport, but to activate the handler.
*/ */
void signal(); void signal();
private:
void(*_handler)(const void *data, void *buffer, unsigned int nbyte);
int _fd_write;
int _fd_read;
const void *_data;
// allow construction only in BusDispatcher
Pipe (void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data);
~Pipe () {};
friend class BusDispatcher; private:
void(*_handler)(const void *data, void *buffer, unsigned int nbyte);
int _fd_write;
int _fd_read;
const void *_data;
// allow construction only in BusDispatcher
Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data);
~Pipe() {};
friend class BusDispatcher;
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -29,37 +29,38 @@
#include "types.h" #include "types.h"
#include "interface.h" #include "interface.h"
namespace DBus { namespace DBus
{
template <typename T> template <typename T>
class PropertyAdaptor class PropertyAdaptor
{ {
public: public:
PropertyAdaptor() : _data(0) PropertyAdaptor() : _data(0)
{} {}
void bind(PropertyData &data) void bind(PropertyData &data)
{ {
_data = &data; _data = &data;
} }
T operator() (void) const T operator()(void) const
{ {
return _data->value.operator T(); return _data->value.operator T();
} }
PropertyAdaptor &operator = (const T &t) PropertyAdaptor &operator = (const T &t)
{ {
_data->value.clear(); _data->value.clear();
MessageIter wi = _data->value.writer(); MessageIter wi = _data->value.writer();
wi << t; wi << t;
return *this; return *this;
} }
private: private:
PropertyData *_data; PropertyData *_data;
}; };
struct IntrospectedInterface; struct IntrospectedInterface;
@ -68,32 +69,32 @@ class DXXAPI PropertiesAdaptor : public InterfaceAdaptor
{ {
public: public:
PropertiesAdaptor(); PropertiesAdaptor();
Message Get(const CallMessage &); Message Get(const CallMessage &);
Message Set(const CallMessage &); Message Set(const CallMessage &);
protected: protected:
virtual void on_get_property(InterfaceAdaptor &/*interface*/, const std::string &/*property*/, Variant &/*value*/) virtual void on_get_property(InterfaceAdaptor &/*interface*/, const std::string &/*property*/, Variant &/*value*/)
{} {}
virtual void on_set_property(InterfaceAdaptor &/*interface*/, const std::string &/*property*/, const Variant &/*value*/) virtual void on_set_property(InterfaceAdaptor &/*interface*/, const std::string &/*property*/, const Variant &/*value*/)
{} {}
IntrospectedInterface * introspect() const; IntrospectedInterface *introspect() const;
}; };
class DXXAPI PropertiesProxy : public InterfaceProxy class DXXAPI PropertiesProxy : public InterfaceProxy
{ {
public: public:
PropertiesProxy(); PropertiesProxy();
Variant Get(const std::string &interface, const std::string &property); Variant Get(const std::string &interface, const std::string &property);
void Set(const std::string &interface, const std::string &property, const Variant &value); void Set(const std::string &interface, const std::string &property, const Variant &value);
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -28,17 +28,18 @@
#include "api.h" #include "api.h"
#include "util.h" #include "util.h"
namespace DBus { namespace DBus
{
template <class T> template <class T>
RefPtrI<T>::RefPtrI(T *ptr) RefPtrI<T>::RefPtrI(T *ptr)
: __ptr(ptr) : __ptr(ptr)
{} {}
template <class T> template <class T>
RefPtrI<T>::~RefPtrI() RefPtrI<T>::~RefPtrI()
{ {
if (__cnt.one()) delete __ptr; if (__cnt.one()) delete __ptr;
} }
} /* namespace DBus */ } /* namespace DBus */

View file

@ -33,7 +33,8 @@
#include "util.h" #include "util.h"
#include "dispatcher.h" #include "dispatcher.h"
namespace DBus { namespace DBus
{
class Server; class Server;
@ -43,30 +44,30 @@ class DXXAPI Server
{ {
public: public:
Server(const char *address); Server(const char *address);
Dispatcher *setup(Dispatcher *); Dispatcher *setup(Dispatcher *);
virtual ~Server(); virtual ~Server();
bool listening() const; bool listening() const;
bool operator == (const Server &) const; bool operator == (const Server &) const;
void disconnect(); void disconnect();
struct Private; struct Private;
protected: protected:
Server(const Server &s) Server(const Server &s)
{} {}
virtual void on_new_connection(Connection &c) = 0; virtual void on_new_connection(Connection &c) = 0;
private: private:
RefPtrI<Private> _pvt; RefPtrI<Private> _pvt;
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -35,30 +35,31 @@
#include "message.h" #include "message.h"
#include "error.h" #include "error.h"
namespace DBus { namespace DBus
{
struct DXXAPI Path : public std::string struct DXXAPI Path : public std::string
{ {
Path() {} Path() {}
Path(const std::string &s) : std::string(s) {} Path(const std::string &s) : std::string(s) {}
Path(const char *c) : std::string(c) {} Path(const char *c) : std::string(c) {}
Path &operator = (std::string &s) Path &operator = (std::string &s)
{ {
std::string::operator = (s); std::string::operator = (s);
return *this; return *this;
} }
}; };
struct DXXAPI Signature : public std::string struct DXXAPI Signature : public std::string
{ {
Signature() {} Signature() {}
Signature(const std::string &s) : std::string(s) {} Signature(const std::string &s) : std::string(s) {}
Signature(const char *c) : std::string(c) {} Signature(const char *c) : std::string(c) {}
Signature &operator = (std::string &s) Signature &operator = (std::string &s)
{ {
std::string::operator = (s); std::string::operator = (s);
return *this; return *this;
} }
}; };
struct DXXAPI Invalid {}; struct DXXAPI Invalid {};
@ -67,474 +68,583 @@ class DXXAPI Variant
{ {
public: public:
Variant(); Variant();
Variant(MessageIter &it); Variant(MessageIter &it);
Variant &operator = (const Variant &v); Variant &operator = (const Variant &v);
const Signature signature() const; const Signature signature() const;
void clear(); void clear();
MessageIter reader() const MessageIter reader() const
{ {
return _msg.reader(); return _msg.reader();
} }
MessageIter writer() MessageIter writer()
{ {
return _msg.writer(); return _msg.writer();
} }
template <typename T> template <typename T>
operator T() const operator T() const
{ {
T cast; T cast;
MessageIter ri = _msg.reader(); MessageIter ri = _msg.reader();
ri >> cast; ri >> cast;
return cast; return cast;
} }
private: private:
Message _msg; Message _msg;
}; };
template < template <
typename T1, typename T1,
typename T2 = Invalid, typename T2 = Invalid,
typename T3 = Invalid, typename T3 = Invalid,
typename T4 = Invalid, typename T4 = Invalid,
typename T5 = Invalid, typename T5 = Invalid,
typename T6 = Invalid, typename T6 = Invalid,
typename T7 = Invalid, typename T7 = Invalid,
typename T8 = Invalid, typename T8 = Invalid,
typename T9 = Invalid, typename T9 = Invalid,
typename T10 = Invalid, typename T10 = Invalid,
typename T11 = Invalid, typename T11 = Invalid,
typename T12 = Invalid, typename T12 = Invalid,
typename T13 = Invalid, typename T13 = Invalid,
typename T14 = Invalid, typename T14 = Invalid,
typename T15 = Invalid, typename T15 = Invalid,
typename T16 = Invalid // nobody needs more than 16 typename T16 = Invalid // nobody needs more than 16
> >
struct Struct struct Struct
{ {
T1 _1; T2 _2; T3 _3; T4 _4; T5 _5; T6 _6; T7 _7; T8 _8; T9 _9; T1 _1;
T10 _10; T11 _11; T12 _12; T13 _13; T14 _14; T15 _15; T16 _16; T2 _2;
T3 _3;
T4 _4;
T5 _5;
T6 _6;
T7 _7;
T8 _8;
T9 _9;
T10 _10;
T11 _11;
T12 _12;
T13 _13;
T14 _14;
T15 _15;
T16 _16;
}; };
template<typename K, typename V> template<typename K, typename V>
inline bool dict_has_key(const std::map<K,V>& map, const K &key) inline bool dict_has_key(const std::map<K, V>& map, const K &key)
{ {
return map.find(key) != map.end(); return map.find(key) != map.end();
} }
template <typename T> template <typename T>
struct type struct type
{ {
static std::string sig() static std::string sig()
{ {
throw ErrorInvalidArgs("unknown type"); throw ErrorInvalidArgs("unknown type");
return ""; return "";
} }
}; };
template <> struct type<Variant> { static std::string sig(){ return "v"; } }; template <> struct type<Variant>
template <> struct type<uint8_t> { static std::string sig(){ return "y"; } }; {
template <> struct type<bool> { static std::string sig(){ return "b"; } }; static std::string sig()
template <> struct type<int16_t> { static std::string sig(){ return "n"; } }; {
template <> struct type<uint16_t> { static std::string sig(){ return "q"; } }; return "v";
template <> struct type<int32_t> { static std::string sig(){ return "i"; } }; }
template <> struct type<uint32_t> { static std::string sig(){ return "u"; } }; };
template <> struct type<int64_t> { static std::string sig(){ return "x"; } }; template <> struct type<uint8_t>
template <> struct type<uint64_t> { static std::string sig(){ return "t"; } }; {
template <> struct type<double> { static std::string sig(){ return "d"; } }; static std::string sig()
template <> struct type<std::string> { static std::string sig(){ return "s"; } }; {
template <> struct type<Path> { static std::string sig(){ return "o"; } }; return "y";
template <> struct type<Signature> { static std::string sig(){ return "g"; } }; }
template <> struct type<Invalid> { static std::string sig(){ return ""; } }; };
template <> struct type<bool>
{
static std::string sig()
{
return "b";
}
};
template <> struct type<int16_t>
{
static std::string sig()
{
return "n";
}
};
template <> struct type<uint16_t>
{
static std::string sig()
{
return "q";
}
};
template <> struct type<int32_t>
{
static std::string sig()
{
return "i";
}
};
template <> struct type<uint32_t>
{
static std::string sig()
{
return "u";
}
};
template <> struct type<int64_t>
{
static std::string sig()
{
return "x";
}
};
template <> struct type<uint64_t>
{
static std::string sig()
{
return "t";
}
};
template <> struct type<double>
{
static std::string sig()
{
return "d";
}
};
template <> struct type<std::string>
{
static std::string sig()
{
return "s";
}
};
template <> struct type<Path>
{
static std::string sig()
{
return "o";
}
};
template <> struct type<Signature>
{
static std::string sig()
{
return "g";
}
};
template <> struct type<Invalid>
{
static std::string sig()
{
return "";
}
};
template <typename E> template <typename E>
struct type< std::vector<E> > struct type< std::vector<E> >
{ static std::string sig(){ return "a" + type<E>::sig(); } }; {
static std::string sig()
{
return "a" + type<E>::sig();
}
};
template <typename K, typename V> template <typename K, typename V>
struct type< std::map<K,V> > struct type< std::map<K, V> >
{ static std::string sig(){ return "a{" + type<K>::sig() + type<V>::sig() + "}"; } }; {
static std::string sig()
{
return "a{" + type<K>::sig() + type<V>::sig() + "}";
}
};
template < template <
typename T1, typename T1,
typename T2, typename T2,
typename T3, typename T3,
typename T4, typename T4,
typename T5, typename T5,
typename T6, typename T6,
typename T7, typename T7,
typename T8, typename T8,
typename T9, typename T9,
typename T10, typename T10,
typename T11, typename T11,
typename T12, typename T12,
typename T13, typename T13,
typename T14, typename T14,
typename T15, typename T15,
typename T16 // nobody needs more than 16 typename T16 // nobody needs more than 16
> >
struct type< Struct<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16> > struct type< Struct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> >
{ {
static std::string sig() static std::string sig()
{ {
return "(" return "("
+ type<T1>::sig() + type<T1>::sig()
+ type<T2>::sig() + type<T2>::sig()
+ type<T3>::sig() + type<T3>::sig()
+ type<T4>::sig() + type<T4>::sig()
+ type<T5>::sig() + type<T5>::sig()
+ type<T6>::sig() + type<T6>::sig()
+ type<T7>::sig() + type<T7>::sig()
+ type<T8>::sig() + type<T8>::sig()
+ type<T9>::sig() + type<T9>::sig()
+ type<T10>::sig() + type<T10>::sig()
+ type<T11>::sig() + type<T11>::sig()
+ type<T12>::sig() + type<T12>::sig()
+ type<T13>::sig() + type<T13>::sig()
+ type<T14>::sig() + type<T14>::sig()
+ type<T15>::sig() + type<T15>::sig()
+ type<T16>::sig() + type<T16>::sig()
+ ")"; + ")";
} }
}; };
} /* namespace DBus */ } /* namespace DBus */
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Invalid &) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Invalid &)
{ {
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint8_t &val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint8_t &val)
{ {
iter.append_byte(val); iter.append_byte(val);
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const bool &val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const bool &val)
{ {
iter.append_bool(val); iter.append_bool(val);
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int16_t& val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int16_t &val)
{ {
iter.append_int16(val); iter.append_int16(val);
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint16_t& val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint16_t &val)
{ {
iter.append_uint16(val); iter.append_uint16(val);
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int32_t& val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int32_t &val)
{ {
iter.append_int32(val); iter.append_int32(val);
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint32_t& val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint32_t &val)
{ {
iter.append_uint32(val); iter.append_uint32(val);
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int64_t& val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int64_t &val)
{ {
iter.append_int64(val); iter.append_int64(val);
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint64_t& val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint64_t &val)
{ {
iter.append_uint64(val); iter.append_uint64(val);
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const double &val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const double &val)
{ {
iter.append_double(val); iter.append_double(val);
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::string &val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::string &val)
{ {
iter.append_string(val.c_str()); iter.append_string(val.c_str());
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Path &val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Path &val)
{ {
iter.append_path(val.c_str()); iter.append_path(val.c_str());
return iter; return iter;
} }
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Signature &val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Signature &val)
{ {
iter.append_signature(val.c_str()); iter.append_signature(val.c_str());
return iter; return iter;
} }
template<typename E> template<typename E>
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<E>& val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<E>& val)
{ {
const std::string sig = DBus::type<E>::sig(); const std::string sig = DBus::type<E>::sig();
DBus::MessageIter ait = iter.new_array(sig.c_str()); DBus::MessageIter ait = iter.new_array(sig.c_str());
typename std::vector<E>::const_iterator vit; typename std::vector<E>::const_iterator vit;
for (vit = val.begin(); vit != val.end(); ++vit) for (vit = val.begin(); vit != val.end(); ++vit)
{ {
ait << *vit; ait << *vit;
} }
iter.close_container(ait); iter.close_container(ait);
return iter; return iter;
} }
template<> template<>
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<uint8_t>& val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<uint8_t>& val)
{ {
DBus::MessageIter ait = iter.new_array("y"); DBus::MessageIter ait = iter.new_array("y");
ait.append_array('y', &val.front(), val.size()); ait.append_array('y', &val.front(), val.size());
iter.close_container(ait); iter.close_container(ait);
return iter; return iter;
} }
template<typename K, typename V> template<typename K, typename V>
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::map<K,V>& val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::map<K, V>& val)
{ {
const std::string sig = "{" + DBus::type<K>::sig() + DBus::type<V>::sig() + "}"; const std::string sig = "{" + DBus::type<K>::sig() + DBus::type<V>::sig() + "}";
DBus::MessageIter ait = iter.new_array(sig.c_str()); DBus::MessageIter ait = iter.new_array(sig.c_str());
typename std::map<K,V>::const_iterator mit; typename std::map<K, V>::const_iterator mit;
for (mit = val.begin(); mit != val.end(); ++mit) for (mit = val.begin(); mit != val.end(); ++mit)
{ {
DBus::MessageIter eit = ait.new_dict_entry(); DBus::MessageIter eit = ait.new_dict_entry();
eit << mit->first << mit->second; eit << mit->first << mit->second;
ait.close_container(eit); ait.close_container(eit);
} }
iter.close_container(ait); iter.close_container(ait);
return iter; return iter;
} }
template < template <
typename T1, typename T1,
typename T2, typename T2,
typename T3, typename T3,
typename T4, typename T4,
typename T5, typename T5,
typename T6, typename T6,
typename T7, typename T7,
typename T8, typename T8,
typename T9, typename T9,
typename T10, typename T10,
typename T11, typename T11,
typename T12, typename T12,
typename T13, typename T13,
typename T14, typename T14,
typename T15, typename T15,
typename T16 typename T16
> >
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Struct<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16>& val) inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Struct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>& val)
{ {
DBus::MessageIter sit = iter.new_struct(); DBus::MessageIter sit = iter.new_struct();
sit << val._1 << val._2 << val._3 << val._4 sit << val._1 << val._2 << val._3 << val._4
<< val._5 << val._6 << val._7 << val._8 << val._5 << val._6 << val._7 << val._8
<< val._9 << val._10 << val._11 << val._12 << val._9 << val._10 << val._11 << val._12
<< val._13 << val._14 << val._15 << val._16; << val._13 << val._14 << val._15 << val._16;
iter.close_container(sit); iter.close_container(sit);
return iter; return iter;
} }
extern DXXAPI DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Variant &val); extern DXXAPI DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Variant &val);
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Invalid &) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Invalid &)
{ {
return iter; return iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint8_t &val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint8_t &val)
{ {
val = iter.get_byte(); val = iter.get_byte();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, bool &val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, bool &val)
{ {
val = iter.get_bool(); val = iter.get_bool();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int16_t& val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int16_t &val)
{ {
val = iter.get_int16(); val = iter.get_int16();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint16_t& val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint16_t &val)
{ {
val = iter.get_uint16(); val = iter.get_uint16();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int32_t& val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int32_t &val)
{ {
val = iter.get_int32(); val = iter.get_int32();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint32_t& val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint32_t &val)
{ {
val = iter.get_uint32(); val = iter.get_uint32();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int64_t& val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int64_t &val)
{ {
val = iter.get_int64(); val = iter.get_int64();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint64_t& val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint64_t &val)
{ {
val = iter.get_uint64(); val = iter.get_uint64();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, double &val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, double &val)
{ {
val = iter.get_double(); val = iter.get_double();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::string &val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::string &val)
{ {
val = iter.get_string(); val = iter.get_string();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Path &val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Path &val)
{ {
val = iter.get_path(); val = iter.get_path();
return ++iter; return ++iter;
} }
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Signature &val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Signature &val)
{ {
val = iter.get_signature(); val = iter.get_signature();
return ++iter; return ++iter;
} }
template<typename E> template<typename E>
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<E>& val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<E>& val)
{ {
if (!iter.is_array()) if (!iter.is_array())
throw DBus::ErrorInvalidArgs("array expected"); throw DBus::ErrorInvalidArgs("array expected");
DBus::MessageIter ait = iter.recurse(); DBus::MessageIter ait = iter.recurse();
while (!ait.at_end()) while (!ait.at_end())
{ {
E elem; E elem;
ait >> elem; ait >> elem;
val.push_back(elem); val.push_back(elem);
} }
return ++iter; return ++iter;
} }
template<> template<>
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<uint8_t>& val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<uint8_t>& val)
{ {
if (!iter.is_array()) if (!iter.is_array())
throw DBus::ErrorInvalidArgs("array expected"); throw DBus::ErrorInvalidArgs("array expected");
if (iter.array_type() != 'y') if (iter.array_type() != 'y')
throw DBus::ErrorInvalidArgs("byte-array expected"); throw DBus::ErrorInvalidArgs("byte-array expected");
DBus::MessageIter ait = iter.recurse(); DBus::MessageIter ait = iter.recurse();
uint8_t *array; uint8_t *array;
size_t length = ait.get_array(&array); size_t length = ait.get_array(&array);
val.insert(val.end(), array, array+length); val.insert(val.end(), array, array + length);
return ++iter; return ++iter;
} }
template<typename K, typename V> template<typename K, typename V>
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::map<K,V>& val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::map<K, V>& val)
{ {
if (!iter.is_dict()) if (!iter.is_dict())
throw DBus::ErrorInvalidArgs("dictionary value expected"); throw DBus::ErrorInvalidArgs("dictionary value expected");
DBus::MessageIter mit = iter.recurse(); DBus::MessageIter mit = iter.recurse();
while (!mit.at_end()) while (!mit.at_end())
{ {
K key; V value; K key;
V value;
DBus::MessageIter eit = mit.recurse(); DBus::MessageIter eit = mit.recurse();
eit >> key >> value; eit >> key >> value;
val[key] = value; val[key] = value;
++mit; ++mit;
} }
return ++iter; return ++iter;
} }
template < template <
typename T1, typename T1,
typename T2, typename T2,
typename T3, typename T3,
typename T4, typename T4,
typename T5, typename T5,
typename T6, typename T6,
typename T7, typename T7,
typename T8, typename T8,
typename T9, typename T9,
typename T10, typename T10,
typename T11, typename T11,
typename T12, typename T12,
typename T13, typename T13,
typename T14, typename T14,
typename T15, typename T15,
typename T16 typename T16
> >
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Struct<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16>& val) inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Struct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>& val)
{ {
DBus::MessageIter sit = iter.recurse(); DBus::MessageIter sit = iter.recurse();
sit >> val._1 >> val._2 >> val._3 >> val._4 sit >> val._1 >> val._2 >> val._3 >> val._4
>> val._5 >> val._6 >> val._7 >> val._8 >> val._5 >> val._6 >> val._7 >> val._8
>> val._9 >> val._10 >> val._11 >> val._12 >> val._9 >> val._10 >> val._11 >> val._12
>> val._13 >> val._14 >> val._15 >> val._16; >> val._13 >> val._14 >> val._15 >> val._16;
return ++iter; return ++iter;
} }
extern DXXAPI DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Variant &val); extern DXXAPI DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Variant &val);
#endif//__DBUSXX_TYPES_H #endif//__DBUSXX_TYPES_H

View file

@ -33,7 +33,8 @@
#include "api.h" #include "api.h"
#include "debug.h" #include "debug.h"
namespace DBus { namespace DBus
{
/* /*
* Very simple reference counting * Very simple reference counting
@ -43,65 +44,65 @@ class DXXAPI RefCnt
{ {
public: public:
RefCnt() RefCnt()
{ {
__ref = new int; __ref = new int;
(*__ref) = 1; (*__ref) = 1;
} }
RefCnt(const RefCnt &rc) RefCnt(const RefCnt &rc)
{ {
__ref = rc.__ref; __ref = rc.__ref;
ref(); ref();
} }
virtual ~RefCnt() virtual ~RefCnt()
{ {
unref(); unref();
} }
RefCnt &operator = (const RefCnt &ref) RefCnt &operator = (const RefCnt &ref)
{ {
ref.ref(); ref.ref();
unref(); unref();
__ref = ref.__ref; __ref = ref.__ref;
return *this; return *this;
} }
bool noref() const bool noref() const
{ {
return (*__ref) == 0; return (*__ref) == 0;
} }
bool one() const bool one() const
{ {
return (*__ref) == 1; return (*__ref) == 1;
} }
private: private:
DXXAPILOCAL void ref() const DXXAPILOCAL void ref() const
{ {
++ (*__ref); ++ (*__ref);
} }
DXXAPILOCAL void unref() const DXXAPILOCAL void unref() const
{ {
-- (*__ref); -- (*__ref);
if ((*__ref) < 0) if ((*__ref) < 0)
{ {
debug_log("%p: refcount dropped below zero!", __ref); debug_log("%p: refcount dropped below zero!", __ref);
} }
if (noref()) if (noref())
{ {
delete __ref; delete __ref;
} }
} }
private: private:
int *__ref; int *__ref;
}; };
/* /*
@ -113,45 +114,45 @@ class RefPtrI // RefPtr to incomplete type
{ {
public: public:
RefPtrI(T *ptr = 0); RefPtrI(T *ptr = 0);
~RefPtrI(); ~RefPtrI();
RefPtrI &operator = (const RefPtrI &ref) RefPtrI &operator = (const RefPtrI &ref)
{ {
if (this != &ref) if (this != &ref)
{ {
if (__cnt.one()) delete __ptr; if (__cnt.one()) delete __ptr;
__ptr = ref.__ptr; __ptr = ref.__ptr;
__cnt = ref.__cnt; __cnt = ref.__cnt;
} }
return *this; return *this;
} }
T &operator *() const T &operator *() const
{ {
return *__ptr; return *__ptr;
} }
T *operator ->() const T *operator ->() const
{ {
if (__cnt.noref()) return 0; if (__cnt.noref()) return 0;
return __ptr;
}
T *get() const return __ptr;
{ }
if (__cnt.noref()) return 0;
T *get() const
return __ptr; {
} if (__cnt.noref()) return 0;
return __ptr;
}
private: private:
T *__ptr; T *__ptr;
RefCnt __cnt; RefCnt __cnt;
}; };
template <class T> template <class T>
@ -159,50 +160,50 @@ class RefPtr
{ {
public: public:
RefPtr(T *ptr = 0) RefPtr(T *ptr = 0)
: __ptr(ptr) : __ptr(ptr)
{} {}
~RefPtr() ~RefPtr()
{ {
if (__cnt.one()) delete __ptr; if (__cnt.one()) delete __ptr;
} }
RefPtr &operator = (const RefPtr &ref) RefPtr &operator = (const RefPtr &ref)
{ {
if (this != &ref) if (this != &ref)
{ {
if (__cnt.one()) delete __ptr; if (__cnt.one()) delete __ptr;
__ptr = ref.__ptr; __ptr = ref.__ptr;
__cnt = ref.__cnt; __cnt = ref.__cnt;
} }
return *this; return *this;
} }
T &operator *() const T &operator *() const
{ {
return *__ptr; return *__ptr;
} }
T *operator ->() const T *operator ->() const
{ {
if (__cnt.noref()) return 0; if (__cnt.noref()) return 0;
return __ptr;
}
T *get() const return __ptr;
{ }
if (__cnt.noref()) return 0;
T *get() const
return __ptr; {
} if (__cnt.noref()) return 0;
return __ptr;
}
private: private:
T *__ptr; T *__ptr;
RefCnt __cnt; RefCnt __cnt;
}; };
/* /*
@ -214,10 +215,10 @@ class Callback_Base
{ {
public: public:
virtual R call(P param) const = 0; virtual R call(P param) const = 0;
virtual ~Callback_Base() virtual ~Callback_Base()
{} {}
}; };
template <class R, class P> template <class R, class P>
@ -225,28 +226,16 @@ class Slot
{ {
public: public:
Slot &operator = (Callback_Base<R,P>* s) Slot &operator = (Callback_Base<R, P>* s)
{ {
_cb = s; _cb = s;
return *this; return *this;
} }
R operator()(P param) const R operator()(P param) const
{ {
if (!empty()) if (!empty())
{
return _cb->call(param);
}
// TODO: think about return type in this case
// this assert should help me to find the use case where it's needed...
//assert (false);
}
R call(P param) const
{
if (!empty())
{ {
return _cb->call(param); return _cb->call(param);
} }
@ -254,46 +243,59 @@ public:
// TODO: think about return type in this case // TODO: think about return type in this case
// this assert should help me to find the use case where it's needed... // this assert should help me to find the use case where it's needed...
//assert (false); //assert (false);
} }
bool empty() const R call(P param) const
{ {
return _cb.get() == 0; if (!empty())
} {
return _cb->call(param);
}
// TODO: think about return type in this case
// this assert should help me to find the use case where it's needed...
//assert (false);
}
bool empty() const
{
return _cb.get() == 0;
}
private: private:
RefPtr< Callback_Base<R,P> > _cb; RefPtr< Callback_Base<R, P> > _cb;
}; };
template <class C, class R, class P> template <class C, class R, class P>
class Callback : public Callback_Base<R,P> class Callback : public Callback_Base<R, P>
{ {
public: public:
typedef R (C::*M)(P); typedef R(C::*M)(P);
Callback(C *c, M m) Callback(C *c, M m)
: _c(c), _m(m) : _c(c), _m(m)
{} {}
R call(P param) const R call(P param) const
{ {
/*if (_c)*/ return (_c->*_m)(param); /*if (_c)*/ return (_c->*_m)(param);
} }
private: private:
C *_c; M _m; C *_c;
M _m;
}; };
/// create std::string from any number /// create std::string from any number
template <typename T> template <typename T>
std::string toString (const T &thing, int w = 0, int p = 0) std::string toString(const T &thing, int w = 0, int p = 0)
{ {
std::ostringstream os; std::ostringstream os;
os << std::setw(w) << std::setprecision(p) << thing; os << std::setw(w) << std::setprecision(p) << thing;
return os.str(); return os.str();
} }
} /* namespace DBus */ } /* namespace DBus */

View file

@ -42,432 +42,433 @@
using namespace DBus; using namespace DBus;
Connection::Private::Private(DBusConnection *c, Server::Private *s) Connection::Private::Private(DBusConnection *c, Server::Private *s)
: conn(c) , dispatcher(NULL), server(s) : conn(c) , dispatcher(NULL), server(s)
{ {
init(); init();
} }
Connection::Private::Private(DBusBusType type) Connection::Private::Private(DBusBusType type)
: dispatcher(NULL), server(NULL) : dispatcher(NULL), server(NULL)
{ {
InternalError e; InternalError e;
conn = dbus_bus_get_private(type, e); conn = dbus_bus_get_private(type, e);
if (e) throw Error(e); if (e) throw Error(e);
init(); init();
} }
Connection::Private::~Private() Connection::Private::~Private()
{ {
debug_log("terminating connection 0x%08x", conn); debug_log("terminating connection 0x%08x", conn);
detach_server(); detach_server();
if (dbus_connection_get_is_connected(conn)) if (dbus_connection_get_is_connected(conn))
{ {
std::vector<std::string>::iterator i = names.begin(); std::vector<std::string>::iterator i = names.begin();
while (i != names.end()) while (i != names.end())
{ {
debug_log("%s: releasing bus name %s", dbus_bus_get_unique_name(conn), i->c_str()); debug_log("%s: releasing bus name %s", dbus_bus_get_unique_name(conn), i->c_str());
dbus_bus_release_name(conn, i->c_str(), NULL); dbus_bus_release_name(conn, i->c_str(), NULL);
++i; ++i;
} }
dbus_connection_close(conn); dbus_connection_close(conn);
} }
dbus_connection_unref(conn); dbus_connection_unref(conn);
} }
void Connection::Private::init() void Connection::Private::init()
{ {
dbus_connection_ref(conn); dbus_connection_ref(conn);
dbus_connection_ref(conn); //todo: the library has to own another reference dbus_connection_ref(conn); //todo: the library has to own another reference
disconn_filter = new Callback<Connection::Private, bool, const Message &>( disconn_filter = new Callback<Connection::Private, bool, const Message &>(
this, &Connection::Private::disconn_filter_function this, &Connection::Private::disconn_filter_function
); );
dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL); // TODO: some assert at least dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL); // TODO: some assert at least
dbus_connection_set_dispatch_status_function(conn, dispatch_status_stub, this, 0); dbus_connection_set_dispatch_status_function(conn, dispatch_status_stub, this, 0);
dbus_connection_set_exit_on_disconnect(conn, false); //why was this set to true?? dbus_connection_set_exit_on_disconnect(conn, false); //why was this set to true??
} }
void Connection::Private::detach_server() void Connection::Private::detach_server()
{ {
/* Server::Private *tmp = server; /* Server::Private *tmp = server;
server = NULL; server = NULL;
if (tmp) if (tmp)
{ {
ConnectionList::iterator i; ConnectionList::iterator i;
for (i = tmp->connections.begin(); i != tmp->connections.end(); ++i) for (i = tmp->connections.begin(); i != tmp->connections.end(); ++i)
{ {
if (i->_pvt.get() == this) if (i->_pvt.get() == this)
{ {
tmp->connections.erase(i); tmp->connections.erase(i);
break; break;
} }
} }
}*/ }*/
} }
bool Connection::Private::do_dispatch() bool Connection::Private::do_dispatch()
{ {
debug_log("dispatching on %p", conn); debug_log("dispatching on %p", conn);
if (!dbus_connection_get_is_connected(conn)) if (!dbus_connection_get_is_connected(conn))
{ {
debug_log("connection terminated"); debug_log("connection terminated");
detach_server(); detach_server();
return true; return true;
} }
return dbus_connection_dispatch(conn) != DBUS_DISPATCH_DATA_REMAINS; return dbus_connection_dispatch(conn) != DBUS_DISPATCH_DATA_REMAINS;
} }
void Connection::Private::dispatch_status_stub(DBusConnection *dc, DBusDispatchStatus status, void *data) void Connection::Private::dispatch_status_stub(DBusConnection *dc, DBusDispatchStatus status, void *data)
{ {
Private *p = static_cast<Private *>(data); Private *p = static_cast<Private *>(data);
switch (status) switch (status)
{ {
case DBUS_DISPATCH_DATA_REMAINS: case DBUS_DISPATCH_DATA_REMAINS:
debug_log("some dispatching to do on %p", dc); debug_log("some dispatching to do on %p", dc);
p->dispatcher->queue_connection(p); p->dispatcher->queue_connection(p);
break; break;
case DBUS_DISPATCH_COMPLETE: case DBUS_DISPATCH_COMPLETE:
debug_log("all dispatching done on %p", dc); debug_log("all dispatching done on %p", dc);
break; break;
case DBUS_DISPATCH_NEED_MEMORY: //uh oh... case DBUS_DISPATCH_NEED_MEMORY: //uh oh...
debug_log("connection %p needs memory", dc); debug_log("connection %p needs memory", dc);
break; break;
} }
} }
DBusHandlerResult Connection::Private::message_filter_stub(DBusConnection *conn, DBusMessage *dmsg, void *data) DBusHandlerResult Connection::Private::message_filter_stub(DBusConnection *conn, DBusMessage *dmsg, void *data)
{ {
MessageSlot *slot = static_cast<MessageSlot *>(data); MessageSlot *slot = static_cast<MessageSlot *>(data);
Message msg = Message(new Message::Private(dmsg)); Message msg = Message(new Message::Private(dmsg));
return slot && !slot->empty() && slot->call(msg) return slot && !slot->empty() && slot->call(msg)
? DBUS_HANDLER_RESULT_HANDLED ? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED; : DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
} }
bool Connection::Private::disconn_filter_function(const Message &msg) bool Connection::Private::disconn_filter_function(const Message &msg)
{ {
if (msg.is_signal(DBUS_INTERFACE_LOCAL,"Disconnected")) if (msg.is_signal(DBUS_INTERFACE_LOCAL, "Disconnected"))
{ {
debug_log("%p disconnected by local bus", conn); debug_log("%p disconnected by local bus", conn);
dbus_connection_close(conn); dbus_connection_close(conn);
return true; return true;
} }
return false; return false;
} }
DBusDispatchStatus Connection::Private::dispatch_status() DBusDispatchStatus Connection::Private::dispatch_status()
{ {
return dbus_connection_get_dispatch_status(conn); return dbus_connection_get_dispatch_status(conn);
} }
bool Connection::Private::has_something_to_dispatch() bool Connection::Private::has_something_to_dispatch()
{ {
return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS; return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS;
} }
Connection Connection::SystemBus() Connection Connection::SystemBus()
{ {
return Connection(new Private(DBUS_BUS_SYSTEM)); return Connection(new Private(DBUS_BUS_SYSTEM));
} }
Connection Connection::SessionBus() Connection Connection::SessionBus()
{ {
return Connection(new Private(DBUS_BUS_SESSION)); return Connection(new Private(DBUS_BUS_SESSION));
} }
Connection Connection::ActivationBus() Connection Connection::ActivationBus()
{ {
return Connection(new Private(DBUS_BUS_STARTER)); return Connection(new Private(DBUS_BUS_STARTER));
} }
Connection::Connection(const char *address, bool priv) Connection::Connection(const char *address, bool priv)
: _timeout(-1) : _timeout(-1)
{ {
InternalError e; InternalError e;
DBusConnection *conn = priv DBusConnection *conn = priv
? dbus_connection_open_private(address, e) ? dbus_connection_open_private(address, e)
: dbus_connection_open(address, e); : dbus_connection_open(address, e);
if (e) throw Error(e); if (e) throw Error(e);
_pvt = new Private(conn); _pvt = new Private(conn);
setup(default_dispatcher); setup(default_dispatcher);
debug_log("connected to %s", address); debug_log("connected to %s", address);
} }
Connection::Connection(Connection::Private *p) Connection::Connection(Connection::Private *p)
: _pvt(p), _timeout(-1) : _pvt(p), _timeout(-1)
{ {
setup(default_dispatcher); setup(default_dispatcher);
} }
Connection::Connection(const Connection &c) Connection::Connection(const Connection &c)
: _pvt(c._pvt),_timeout(c._timeout) : _pvt(c._pvt), _timeout(c._timeout)
{ {
dbus_connection_ref(_pvt->conn); dbus_connection_ref(_pvt->conn);
} }
Connection::~Connection() Connection::~Connection()
{ {
dbus_connection_unref(_pvt->conn); dbus_connection_unref(_pvt->conn);
} }
Dispatcher *Connection::setup(Dispatcher *dispatcher) Dispatcher *Connection::setup(Dispatcher *dispatcher)
{ {
debug_log("registering stubs for connection %p", _pvt->conn); debug_log("registering stubs for connection %p", _pvt->conn);
if (!dispatcher) dispatcher = default_dispatcher; if (!dispatcher) dispatcher = default_dispatcher;
if (!dispatcher) throw ErrorFailed("no default dispatcher set for new connection"); if (!dispatcher) throw ErrorFailed("no default dispatcher set for new connection");
Dispatcher *prev = _pvt->dispatcher; Dispatcher *prev = _pvt->dispatcher;
_pvt->dispatcher = dispatcher; _pvt->dispatcher = dispatcher;
dispatcher->queue_connection(_pvt.get()); dispatcher->queue_connection(_pvt.get());
dbus_connection_set_watch_functions( dbus_connection_set_watch_functions(
_pvt->conn, _pvt->conn,
Dispatcher::Private::on_add_watch, Dispatcher::Private::on_add_watch,
Dispatcher::Private::on_rem_watch, Dispatcher::Private::on_rem_watch,
Dispatcher::Private::on_toggle_watch, Dispatcher::Private::on_toggle_watch,
dispatcher, dispatcher,
0 0
); );
dbus_connection_set_timeout_functions( dbus_connection_set_timeout_functions(
_pvt->conn, _pvt->conn,
Dispatcher::Private::on_add_timeout, Dispatcher::Private::on_add_timeout,
Dispatcher::Private::on_rem_timeout, Dispatcher::Private::on_rem_timeout,
Dispatcher::Private::on_toggle_timeout, Dispatcher::Private::on_toggle_timeout,
dispatcher, dispatcher,
0 0
); );
return prev; return prev;
} }
bool Connection::operator == (const Connection &c) const bool Connection::operator == (const Connection &c) const
{ {
return _pvt->conn == c._pvt->conn; return _pvt->conn == c._pvt->conn;
} }
bool Connection::register_bus() bool Connection::register_bus()
{ {
InternalError e; InternalError e;
bool r = dbus_bus_register(_pvt->conn, e); bool r = dbus_bus_register(_pvt->conn, e);
if (e) throw (e);
return r; if (e) throw(e);
return r;
} }
bool Connection::connected() const bool Connection::connected() const
{ {
return dbus_connection_get_is_connected(_pvt->conn); return dbus_connection_get_is_connected(_pvt->conn);
} }
void Connection::disconnect() void Connection::disconnect()
{ {
// dbus_connection_disconnect(_pvt->conn); // disappeared in 0.9x // dbus_connection_disconnect(_pvt->conn); // disappeared in 0.9x
dbus_connection_close(_pvt->conn); dbus_connection_close(_pvt->conn);
} }
void Connection::exit_on_disconnect(bool exit) void Connection::exit_on_disconnect(bool exit)
{ {
dbus_connection_set_exit_on_disconnect(_pvt->conn, exit); dbus_connection_set_exit_on_disconnect(_pvt->conn, exit);
} }
bool Connection::unique_name(const char *n) bool Connection::unique_name(const char *n)
{ {
return dbus_bus_set_unique_name(_pvt->conn, n); return dbus_bus_set_unique_name(_pvt->conn, n);
} }
const char *Connection::unique_name() const const char *Connection::unique_name() const
{ {
return dbus_bus_get_unique_name(_pvt->conn); return dbus_bus_get_unique_name(_pvt->conn);
} }
void Connection::flush() void Connection::flush()
{ {
dbus_connection_flush(_pvt->conn); dbus_connection_flush(_pvt->conn);
} }
void Connection::add_match(const char *rule) void Connection::add_match(const char *rule)
{ {
InternalError e; InternalError e;
dbus_bus_add_match(_pvt->conn, rule, e); dbus_bus_add_match(_pvt->conn, rule, e);
debug_log("%s: added match rule %s", unique_name(), rule); debug_log("%s: added match rule %s", unique_name(), rule);
if (e) throw Error(e); if (e) throw Error(e);
} }
void Connection::remove_match(const char *rule, void Connection::remove_match(const char *rule,
bool throw_on_error) bool throw_on_error)
{ {
InternalError e; InternalError e;
dbus_bus_remove_match(_pvt->conn, rule, e);
debug_log("%s: removed match rule %s", unique_name(), rule); dbus_bus_remove_match(_pvt->conn, rule, e);
if (e) { debug_log("%s: removed match rule %s", unique_name(), rule);
if (throw_on_error)
throw Error(e); if (e)
else {
debug_log("DBus::Connection::remove_match: %s (%s).", if (throw_on_error)
static_cast<DBusError*>(e)->message, throw Error(e);
static_cast<DBusError*>(e)->name); else
} debug_log("DBus::Connection::remove_match: %s (%s).",
static_cast<DBusError *>(e)->message,
static_cast<DBusError *>(e)->name);
}
} }
bool Connection::add_filter(MessageSlot &s) bool Connection::add_filter(MessageSlot &s)
{ {
debug_log("%s: adding filter", unique_name()); debug_log("%s: adding filter", unique_name());
return dbus_connection_add_filter(_pvt->conn, Private::message_filter_stub, &s, NULL); return dbus_connection_add_filter(_pvt->conn, Private::message_filter_stub, &s, NULL);
} }
void Connection::remove_filter(MessageSlot &s) void Connection::remove_filter(MessageSlot &s)
{ {
debug_log("%s: removing filter", unique_name()); debug_log("%s: removing filter", unique_name());
dbus_connection_remove_filter(_pvt->conn, Private::message_filter_stub, &s); dbus_connection_remove_filter(_pvt->conn, Private::message_filter_stub, &s);
} }
bool Connection::send(const Message &msg, unsigned int *serial) bool Connection::send(const Message &msg, unsigned int *serial)
{ {
return dbus_connection_send(_pvt->conn, msg._pvt->msg, serial); return dbus_connection_send(_pvt->conn, msg._pvt->msg, serial);
} }
Message Connection::send_blocking(Message &msg, int timeout) Message Connection::send_blocking(Message &msg, int timeout)
{ {
DBusMessage *reply; DBusMessage *reply;
InternalError e; InternalError e;
if (this->_timeout != -1)
{
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, this->_timeout, e);
}
else
{
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, timeout, e);
}
if (e) throw Error(e); if (this->_timeout != -1)
{
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, this->_timeout, e);
}
else
{
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, timeout, e);
}
return Message(new Message::Private(reply), false); if (e) throw Error(e);
return Message(new Message::Private(reply), false);
} }
PendingCall Connection::send_async(Message &msg, int timeout) PendingCall Connection::send_async(Message &msg, int timeout)
{ {
DBusPendingCall *pending; DBusPendingCall *pending;
if (!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout)) if (!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout))
{ {
throw ErrorNoMemory("Unable to start asynchronous call"); throw ErrorNoMemory("Unable to start asynchronous call");
} }
return PendingCall(new PendingCall::Private(pending)); return PendingCall(new PendingCall::Private(pending));
} }
void Connection::request_name(const char *name, int flags) void Connection::request_name(const char *name, int flags)
{ {
InternalError e; InternalError e;
debug_log("%s: registering bus name %s", unique_name(), name); debug_log("%s: registering bus name %s", unique_name(), name);
/* /*
* TODO: * TODO:
* Think about giving back the 'ret' value. Some people on the list * Think about giving back the 'ret' value. Some people on the list
* requested about this... * requested about this...
*/ */
int ret = dbus_bus_request_name(_pvt->conn, name, flags, e); int ret = dbus_bus_request_name(_pvt->conn, name, flags, e);
if (ret == -1) if (ret == -1)
{ {
if (e) throw Error(e); if (e) throw Error(e);
} }
// this->remove_match("destination"); // this->remove_match("destination");
if (name) if (name)
{ {
_pvt->names.push_back(name); _pvt->names.push_back(name);
std::string match = "destination='" + _pvt->names.back() + "'"; std::string match = "destination='" + _pvt->names.back() + "'";
add_match(match.c_str()); add_match(match.c_str());
} }
} }
unsigned long Connection::sender_unix_uid(const char *sender) unsigned long Connection::sender_unix_uid(const char *sender)
{ {
InternalError e; InternalError e;
unsigned long ul = dbus_bus_get_unix_user(_pvt->conn, sender, e); unsigned long ul = dbus_bus_get_unix_user(_pvt->conn, sender, e);
if (e) throw Error(e); if (e) throw Error(e);
return ul; return ul;
} }
bool Connection::has_name(const char *name) bool Connection::has_name(const char *name)
{ {
InternalError e; InternalError e;
bool b = dbus_bus_name_has_owner(_pvt->conn, name, e); bool b = dbus_bus_name_has_owner(_pvt->conn, name, e);
if (e) throw Error(e); if (e) throw Error(e);
return b; return b;
} }
const std::vector<std::string>& Connection::names() const std::vector<std::string>& Connection::names()
{ {
return _pvt->names; return _pvt->names;
} }
bool Connection::start_service(const char *name, unsigned long flags) bool Connection::start_service(const char *name, unsigned long flags)
{ {
InternalError e; InternalError e;
bool b = dbus_bus_start_service_by_name(_pvt->conn, name, flags, NULL, e); bool b = dbus_bus_start_service_by_name(_pvt->conn, name, flags, NULL, e);
if (e) throw Error(e); if (e) throw Error(e);
return b; return b;
} }
void Connection::set_timeout(int timeout) void Connection::set_timeout(int timeout)
{ {
_timeout=timeout; _timeout = timeout;
} }
int Connection::get_timeout() int Connection::get_timeout()
{ {
return _timeout; return _timeout;
} }

View file

@ -38,37 +38,38 @@
#include <string> #include <string>
namespace DBus { namespace DBus
{
struct DXXAPILOCAL Connection::Private struct DXXAPILOCAL Connection::Private
{ {
DBusConnection * conn; DBusConnection *conn;
std::vector<std::string> names; std::vector<std::string> names;
Dispatcher *dispatcher; Dispatcher *dispatcher;
bool do_dispatch(); bool do_dispatch();
MessageSlot disconn_filter; MessageSlot disconn_filter;
bool disconn_filter_function(const Message &); bool disconn_filter_function(const Message &);
Server::Private *server; Server::Private *server;
void detach_server(); void detach_server();
Private(DBusConnection *, Server::Private * = NULL); Private(DBusConnection *, Server::Private * = NULL);
Private(DBusBusType); Private(DBusBusType);
~Private(); ~Private();
void init(); void init();
DBusDispatchStatus dispatch_status(); DBusDispatchStatus dispatch_status();
bool has_something_to_dispatch(); bool has_something_to_dispatch();
static void dispatch_status_stub(DBusConnection *, DBusDispatchStatus, void *); static void dispatch_status_stub(DBusConnection *, DBusDispatchStatus, void *);
static DBusHandlerResult message_filter_stub(DBusConnection *, DBusMessage *, void *); static DBusHandlerResult message_filter_stub(DBusConnection *, DBusMessage *, void *);
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -35,19 +35,19 @@ static void _debug_log_default(const char *format, ...)
{ {
//#ifdef DEBUG //#ifdef DEBUG
static int debug_env = getenv("DBUSXX_VERBOSE") ? 1 : 0; static int debug_env = getenv("DBUSXX_VERBOSE") ? 1 : 0;
if (debug_env) if (debug_env)
{ {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
fprintf(stderr, "dbus-c++: "); fprintf(stderr, "dbus-c++: ");
vfprintf(stderr, format, args); vfprintf(stderr, format, args);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
va_end(args); va_end(args);
} }
//#endif//DEBUG //#endif//DEBUG
} }

View file

@ -38,64 +38,64 @@ DBus::Dispatcher *DBus::default_dispatcher = NULL;
using namespace DBus; using namespace DBus;
Timeout::Timeout(Timeout::Internal *i) Timeout::Timeout(Timeout::Internal *i)
: _int(i) : _int(i)
{ {
dbus_timeout_set_data((DBusTimeout *)i, this, NULL); dbus_timeout_set_data((DBusTimeout *)i, this, NULL);
} }
int Timeout::interval() const int Timeout::interval() const
{ {
return dbus_timeout_get_interval((DBusTimeout *)_int); return dbus_timeout_get_interval((DBusTimeout *)_int);
} }
bool Timeout::enabled() const bool Timeout::enabled() const
{ {
return dbus_timeout_get_enabled((DBusTimeout *)_int); return dbus_timeout_get_enabled((DBusTimeout *)_int);
} }
bool Timeout::handle() bool Timeout::handle()
{ {
return dbus_timeout_handle((DBusTimeout *)_int); return dbus_timeout_handle((DBusTimeout *)_int);
} }
/* /*
*/ */
Watch::Watch(Watch::Internal *i) Watch::Watch(Watch::Internal *i)
: _int(i) : _int(i)
{ {
dbus_watch_set_data((DBusWatch *)i, this, NULL); dbus_watch_set_data((DBusWatch *)i, this, NULL);
} }
int Watch::descriptor() const int Watch::descriptor() const
{ {
#if HAVE_WIN32 #if HAVE_WIN32
return dbus_watch_get_socket((DBusWatch*)_int); return dbus_watch_get_socket((DBusWatch *)_int);
#else #else
// check dbus version and use dbus_watch_get_unix_fd() only in dbus >= 1.1.1 // check dbus version and use dbus_watch_get_unix_fd() only in dbus >= 1.1.1
#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || \ #if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || \
(DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MAJOR > 1) || \ (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MAJOR > 1) || \
(DBUS_VERSION_MAJOR > 1) (DBUS_VERSION_MAJOR > 1)
return dbus_watch_get_unix_fd((DBusWatch*)_int); return dbus_watch_get_unix_fd((DBusWatch *)_int);
#else #else
return dbus_watch_get_fd((DBusWatch*)_int); return dbus_watch_get_fd((DBusWatch *)_int);
#endif #endif
#endif #endif
} }
int Watch::flags() const int Watch::flags() const
{ {
return dbus_watch_get_flags((DBusWatch *)_int); return dbus_watch_get_flags((DBusWatch *)_int);
} }
bool Watch::enabled() const bool Watch::enabled() const
{ {
return dbus_watch_get_enabled((DBusWatch *)_int); return dbus_watch_get_enabled((DBusWatch *)_int);
} }
bool Watch::handle(int flags) bool Watch::handle(int flags)
{ {
return dbus_watch_handle((DBusWatch *)_int, flags); return dbus_watch_handle((DBusWatch *)_int, flags);
} }
/* /*
@ -103,216 +103,218 @@ bool Watch::handle(int flags)
dbus_bool_t Dispatcher::Private::on_add_watch(DBusWatch *watch, void *data) dbus_bool_t Dispatcher::Private::on_add_watch(DBusWatch *watch, void *data)
{ {
Dispatcher *d = static_cast<Dispatcher *>(data); Dispatcher *d = static_cast<Dispatcher *>(data);
Watch::Internal *w = reinterpret_cast<Watch::Internal *>(watch); Watch::Internal *w = reinterpret_cast<Watch::Internal *>(watch);
d->add_watch(w); d->add_watch(w);
return true; return true;
} }
void Dispatcher::Private::on_rem_watch(DBusWatch *watch, void *data) void Dispatcher::Private::on_rem_watch(DBusWatch *watch, void *data)
{ {
Dispatcher *d = static_cast<Dispatcher *>(data); Dispatcher *d = static_cast<Dispatcher *>(data);
Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch)); Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
d->rem_watch(w); d->rem_watch(w);
} }
void Dispatcher::Private::on_toggle_watch(DBusWatch *watch, void *data) void Dispatcher::Private::on_toggle_watch(DBusWatch *watch, void *data)
{ {
Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch)); Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
w->toggle(); w->toggle();
} }
dbus_bool_t Dispatcher::Private::on_add_timeout(DBusTimeout *timeout, void *data) dbus_bool_t Dispatcher::Private::on_add_timeout(DBusTimeout *timeout, void *data)
{ {
Dispatcher *d = static_cast<Dispatcher *>(data); Dispatcher *d = static_cast<Dispatcher *>(data);
Timeout::Internal *t = reinterpret_cast<Timeout::Internal *>(timeout); Timeout::Internal *t = reinterpret_cast<Timeout::Internal *>(timeout);
d->add_timeout(t); d->add_timeout(t);
return true; return true;
} }
void Dispatcher::Private::on_rem_timeout(DBusTimeout *timeout, void *data) void Dispatcher::Private::on_rem_timeout(DBusTimeout *timeout, void *data)
{ {
Dispatcher *d = static_cast<Dispatcher *>(data); Dispatcher *d = static_cast<Dispatcher *>(data);
Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout)); Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
d->rem_timeout(t); d->rem_timeout(t);
} }
void Dispatcher::Private::on_toggle_timeout(DBusTimeout *timeout, void *data) void Dispatcher::Private::on_toggle_timeout(DBusTimeout *timeout, void *data)
{ {
Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout)); Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
t->toggle(); t->toggle();
} }
void Dispatcher::queue_connection(Connection::Private *cp) void Dispatcher::queue_connection(Connection::Private *cp)
{ {
_mutex_p.lock(); _mutex_p.lock();
_pending_queue.push_back(cp); _pending_queue.push_back(cp);
_mutex_p.unlock(); _mutex_p.unlock();
} }
bool Dispatcher::has_something_to_dispatch() bool Dispatcher::has_something_to_dispatch()
{ {
_mutex_p.lock(); _mutex_p.lock();
bool has_something = false; bool has_something = false;
for(Connection::PrivatePList::iterator it = _pending_queue.begin(); for (Connection::PrivatePList::iterator it = _pending_queue.begin();
it != _pending_queue.end() && !has_something; it != _pending_queue.end() && !has_something;
++it) ++it)
{ {
has_something = (*it)->has_something_to_dispatch(); has_something = (*it)->has_something_to_dispatch();
} }
_mutex_p.unlock(); _mutex_p.unlock();
return has_something; return has_something;
} }
void Dispatcher::dispatch_pending() void Dispatcher::dispatch_pending()
{ {
while (1) while (1)
{ {
_mutex_p.lock(); _mutex_p.lock();
if (_pending_queue.empty()) if (_pending_queue.empty())
{ {
_mutex_p.unlock(); _mutex_p.unlock();
break; break;
} }
Connection::PrivatePList pending_queue_copy(_pending_queue); Connection::PrivatePList pending_queue_copy(_pending_queue);
_mutex_p.unlock(); _mutex_p.unlock();
size_t copy_elem_num(pending_queue_copy.size()); size_t copy_elem_num(pending_queue_copy.size());
dispatch_pending(pending_queue_copy); dispatch_pending(pending_queue_copy);
//only push_back on list is mandatory! //only push_back on list is mandatory!
_mutex_p.lock(); _mutex_p.lock();
Connection::PrivatePList::iterator i, j; Connection::PrivatePList::iterator i, j;
i = _pending_queue.begin(); i = _pending_queue.begin();
size_t counter = 0; size_t counter = 0;
while (counter < copy_elem_num && i != _pending_queue.end()) while (counter < copy_elem_num && i != _pending_queue.end())
{ {
j = i; j = i;
++j; ++j;
_pending_queue.erase(i); _pending_queue.erase(i);
i = j; i = j;
++counter; ++counter;
} }
_mutex_p.unlock(); _mutex_p.unlock();
} }
} }
void Dispatcher::dispatch_pending(Connection::PrivatePList& pending_queue) void Dispatcher::dispatch_pending(Connection::PrivatePList &pending_queue)
{ {
// SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things... // SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things...
_mutex_p_copy.lock(); _mutex_p_copy.lock();
while (pending_queue.size() > 0) while (pending_queue.size() > 0)
{ {
Connection::PrivatePList::iterator i, j; Connection::PrivatePList::iterator i, j;
i = pending_queue.begin(); i = pending_queue.begin();
while (i != pending_queue.end()) while (i != pending_queue.end())
{ {
j = i; j = i;
++j; ++j;
if ((*i)->do_dispatch()) if ((*i)->do_dispatch())
pending_queue.erase(i); pending_queue.erase(i);
else else
debug_log("dispatch_pending_private: do_dispatch error"); debug_log("dispatch_pending_private: do_dispatch error");
i = j; i = j;
} }
} }
_mutex_p_copy.unlock(); _mutex_p_copy.unlock();
} }
void DBus::_init_threading() void DBus::_init_threading()
{ {
#ifdef DBUS_HAS_THREADS_INIT_DEFAULT #ifdef DBUS_HAS_THREADS_INIT_DEFAULT
dbus_threads_init_default(); dbus_threads_init_default();
#else #else
debug_log("Thread support is not enabled! Your D-Bus version is too old!"); debug_log("Thread support is not enabled! Your D-Bus version is too old!");
#endif//DBUS_HAS_THREADS_INIT_DEFAULT #endif//DBUS_HAS_THREADS_INIT_DEFAULT
} }
void DBus::_init_threading( void DBus::_init_threading(
MutexNewFn m1, MutexNewFn m1,
MutexFreeFn m2, MutexFreeFn m2,
MutexLockFn m3, MutexLockFn m3,
MutexUnlockFn m4, MutexUnlockFn m4,
CondVarNewFn c1, CondVarNewFn c1,
CondVarFreeFn c2, CondVarFreeFn c2,
CondVarWaitFn c3, CondVarWaitFn c3,
CondVarWaitTimeoutFn c4, CondVarWaitTimeoutFn c4,
CondVarWakeOneFn c5, CondVarWakeOneFn c5,
CondVarWakeAllFn c6 CondVarWakeAllFn c6
) )
{ {
#ifndef DBUS_HAS_RECURSIVE_MUTEX #ifndef DBUS_HAS_RECURSIVE_MUTEX
DBusThreadFunctions functions = { DBusThreadFunctions functions =
DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK | {
DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK | DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK | DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK | DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK | DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK | DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK | DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK | DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK| DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK, DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
(DBusMutexNewFunction) m1, DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
(DBusMutexFreeFunction) m2, (DBusMutexNewFunction) m1,
(DBusMutexLockFunction) m3, (DBusMutexFreeFunction) m2,
(DBusMutexUnlockFunction) m4, (DBusMutexLockFunction) m3,
(DBusCondVarNewFunction) c1, (DBusMutexUnlockFunction) m4,
(DBusCondVarFreeFunction) c2, (DBusCondVarNewFunction) c1,
(DBusCondVarWaitFunction) c3, (DBusCondVarFreeFunction) c2,
(DBusCondVarWaitTimeoutFunction) c4, (DBusCondVarWaitFunction) c3,
(DBusCondVarWakeOneFunction) c5, (DBusCondVarWaitTimeoutFunction) c4,
(DBusCondVarWakeAllFunction) c6 (DBusCondVarWakeOneFunction) c5,
}; (DBusCondVarWakeAllFunction) c6
};
#else #else
DBusThreadFunctions functions = { DBusThreadFunctions functions =
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK | {
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK | DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK | DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK | DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK | DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK | DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK | DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK | DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK| DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK, DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
0, 0, 0, 0, DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
(DBusCondVarNewFunction) c1, 0, 0, 0, 0,
(DBusCondVarFreeFunction) c2, (DBusCondVarNewFunction) c1,
(DBusCondVarWaitFunction) c3, (DBusCondVarFreeFunction) c2,
(DBusCondVarWaitTimeoutFunction) c4, (DBusCondVarWaitFunction) c3,
(DBusCondVarWakeOneFunction) c5, (DBusCondVarWaitTimeoutFunction) c4,
(DBusCondVarWakeAllFunction) c6, (DBusCondVarWakeOneFunction) c5,
(DBusRecursiveMutexNewFunction) m1, (DBusCondVarWakeAllFunction) c6,
(DBusRecursiveMutexFreeFunction) m2, (DBusRecursiveMutexNewFunction) m1,
(DBusRecursiveMutexLockFunction) m3, (DBusRecursiveMutexFreeFunction) m2,
(DBusRecursiveMutexUnlockFunction) m4 (DBusRecursiveMutexLockFunction) m3,
}; (DBusRecursiveMutexUnlockFunction) m4
};
#endif//DBUS_HAS_RECURSIVE_MUTEX #endif//DBUS_HAS_RECURSIVE_MUTEX
dbus_threads_init(&functions); dbus_threads_init(&functions);
} }

View file

@ -35,21 +35,22 @@
#include "internalerror.h" #include "internalerror.h"
namespace DBus { namespace DBus
{
struct DXXAPILOCAL Dispatcher::Private struct DXXAPILOCAL Dispatcher::Private
{ {
static dbus_bool_t on_add_watch(DBusWatch *watch, void *data); static dbus_bool_t on_add_watch(DBusWatch *watch, void *data);
static void on_rem_watch(DBusWatch *watch, void *data); static void on_rem_watch(DBusWatch *watch, void *data);
static void on_toggle_watch(DBusWatch *watch, void *data); static void on_toggle_watch(DBusWatch *watch, void *data);
static dbus_bool_t on_add_timeout(DBusTimeout *timeout, void *data); static dbus_bool_t on_add_timeout(DBusTimeout *timeout, void *data);
static void on_rem_timeout(DBusTimeout *timeout, void *data); static void on_rem_timeout(DBusTimeout *timeout, void *data);
static void on_toggle_timeout(DBusTimeout *timeout, void *data); static void on_toggle_timeout(DBusTimeout *timeout, void *data);
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -33,120 +33,120 @@ using namespace DBus;
Dispatcher *gdispatcher = NULL; Dispatcher *gdispatcher = NULL;
Ecore::BusTimeout::BusTimeout( Timeout::Internal* ti) Ecore::BusTimeout::BusTimeout(Timeout::Internal *ti)
: Timeout(ti) : Timeout(ti)
{ {
if (Timeout::enabled()) if (Timeout::enabled())
{ {
_enable(); _enable();
} }
} }
Ecore::BusTimeout::~BusTimeout() Ecore::BusTimeout::~BusTimeout()
{ {
_disable(); _disable();
} }
void Ecore::BusTimeout::toggle() void Ecore::BusTimeout::toggle()
{ {
debug_log("ecore: timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off"); debug_log("ecore: timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
if(Timeout::enabled()) if (Timeout::enabled())
{ {
_enable(); _enable();
} }
else else
{ {
_disable(); _disable();
} }
} }
Eina_Bool Ecore::BusTimeout::timeout_handler( void *data ) Eina_Bool Ecore::BusTimeout::timeout_handler(void *data)
{ {
Ecore::BusTimeout* t = reinterpret_cast<Ecore::BusTimeout*>(data); Ecore::BusTimeout *t = reinterpret_cast<Ecore::BusTimeout *>(data);
debug_log("Ecore::BusTimeout::timeout_handler( void *data )"); debug_log("Ecore::BusTimeout::timeout_handler( void *data )");
t->handle(); t->handle();
return ECORE_CALLBACK_RENEW; return ECORE_CALLBACK_RENEW;
} }
void Ecore::BusTimeout::_enable() void Ecore::BusTimeout::_enable()
{ {
debug_log("Ecore::BusTimeout::_enable()"); debug_log("Ecore::BusTimeout::_enable()");
_etimer = ecore_timer_add (((double)Timeout::interval())/1000, timeout_handler, this); _etimer = ecore_timer_add(((double)Timeout::interval()) / 1000, timeout_handler, this);
} }
void Ecore::BusTimeout::_disable() void Ecore::BusTimeout::_disable()
{ {
debug_log("Ecore::BusTimeout::_disable()"); debug_log("Ecore::BusTimeout::_disable()");
ecore_timer_del (_etimer); ecore_timer_del(_etimer);
} }
Ecore::BusWatch::BusWatch( Watch::Internal* wi) Ecore::BusWatch::BusWatch(Watch::Internal *wi)
: Watch(wi), fd_handler (NULL), _bd (NULL) : Watch(wi), fd_handler(NULL), _bd(NULL)
{ {
if (Watch::enabled()) if (Watch::enabled())
{ {
_enable(); _enable();
} }
} }
Ecore::BusWatch::~BusWatch() Ecore::BusWatch::~BusWatch()
{ {
_disable(); _disable();
} }
void Ecore::BusWatch::toggle() void Ecore::BusWatch::toggle()
{ {
debug_log("ecore: watch %p toggled (%s)", this, Watch::enabled() ? "on":"off"); debug_log("ecore: watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
if(Watch::enabled()) _enable(); if (Watch::enabled()) _enable();
else _disable(); else _disable();
} }
Eina_Bool Ecore::BusWatch::watch_dispatch( void *data, Ecore_Fd_Handler *fdh ) Eina_Bool Ecore::BusWatch::watch_dispatch(void *data, Ecore_Fd_Handler *fdh)
{ {
Ecore::BusWatch* w = reinterpret_cast<Ecore::BusWatch*>(data); Ecore::BusWatch *w = reinterpret_cast<Ecore::BusWatch *>(data);
debug_log("Ecore::BusWatch watch_handler"); debug_log("Ecore::BusWatch watch_handler");
int flags = w->flags(); int flags = w->flags();
if (w->flags() & DBUS_WATCH_READABLE) if (w->flags() & DBUS_WATCH_READABLE)
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_READ); ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_READ);
if (w->flags() & DBUS_WATCH_WRITABLE) if (w->flags() & DBUS_WATCH_WRITABLE)
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_WRITE); ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_WRITE);
w->handle(flags); w->handle(flags);
w->_bd->dispatch_pending(); w->_bd->dispatch_pending();
return 1; return 1;
} }
void Ecore::BusWatch::_enable() void Ecore::BusWatch::_enable()
{ {
debug_log("Ecore::BusWatch::_enable()"); debug_log("Ecore::BusWatch::_enable()");
fd_handler = ecore_main_fd_handler_add (descriptor(), fd_handler = ecore_main_fd_handler_add(descriptor(),
(Ecore_Fd_Handler_Flags) (ECORE_FD_READ | ECORE_FD_WRITE), (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_WRITE),
watch_dispatch, this, watch_dispatch, this,
NULL, NULL); NULL, NULL);
} }
void Ecore::BusWatch::_disable() void Ecore::BusWatch::_disable()
{ {
if (fd_handler) if (fd_handler)
{ {
ecore_main_fd_handler_del (fd_handler); ecore_main_fd_handler_del(fd_handler);
fd_handler = NULL; fd_handler = NULL;
} }
} }
void Ecore::BusWatch::data (Ecore::BusDispatcher *bd) void Ecore::BusWatch::data(Ecore::BusDispatcher *bd)
{ {
_bd = bd; _bd = bd;
} }
@ -155,41 +155,41 @@ Ecore::BusDispatcher::BusDispatcher()
{ {
} }
Eina_Bool Ecore::BusDispatcher::check ( void *data, Ecore_Fd_Handler *fdh) Eina_Bool Ecore::BusDispatcher::check(void *data, Ecore_Fd_Handler *fdh)
{ {
return 0; return 0;
} }
Timeout* Ecore::BusDispatcher::add_timeout( Timeout::Internal* wi ) Timeout *Ecore::BusDispatcher::add_timeout(Timeout::Internal *wi)
{ {
Timeout* t = new Ecore::BusTimeout( wi ); Timeout *t = new Ecore::BusTimeout(wi);
debug_log("ecore: added timeout %p (%s)", t, t->enabled() ? "on":"off"); debug_log("ecore: added timeout %p (%s)", t, t->enabled() ? "on" : "off");
return t; return t;
} }
void Ecore::BusDispatcher::rem_timeout( Timeout* t ) void Ecore::BusDispatcher::rem_timeout(Timeout *t)
{ {
debug_log("ecore: removed timeout %p", t); debug_log("ecore: removed timeout %p", t);
delete t; delete t;
} }
Watch* Ecore::BusDispatcher::add_watch( Watch::Internal* wi ) Watch *Ecore::BusDispatcher::add_watch(Watch::Internal *wi)
{ {
Ecore::BusWatch* w = new Ecore::BusWatch(wi); Ecore::BusWatch *w = new Ecore::BusWatch(wi);
w->data (this); w->data(this);
debug_log("ecore: added watch %p (%s) fd=%d flags=%d", debug_log("ecore: added watch %p (%s) fd=%d flags=%d",
w, w->enabled() ? "on":"off", w->descriptor(), w->flags() w, w->enabled() ? "on" : "off", w->descriptor(), w->flags()
); );
return w; return w;
} }
void Ecore::BusDispatcher::rem_watch( Watch* w ) void Ecore::BusDispatcher::rem_watch(Watch *w)
{ {
debug_log("ecore: removed watch %p", w); debug_log("ecore: removed watch %p", w);
delete w; delete w;
} }

View file

@ -39,23 +39,23 @@ using namespace DBus;
*/ */
Error::Error() Error::Error()
: _int(new InternalError) : _int(new InternalError)
{} {}
Error::Error(InternalError &i) Error::Error(InternalError &i)
: _int(new InternalError(i)) : _int(new InternalError(i))
{} {}
Error::Error(const char *name, const char *message) Error::Error(const char *name, const char *message)
: _int(new InternalError) : _int(new InternalError)
{ {
set(name, message); set(name, message);
} }
Error::Error(Message &m) Error::Error(Message &m)
: _int(new InternalError) : _int(new InternalError)
{ {
dbus_set_error_from_message(&(_int->error), m._pvt->msg); dbus_set_error_from_message(&(_int->error), m._pvt->msg);
} }
Error::~Error() throw() Error::~Error() throw()
@ -64,26 +64,26 @@ Error::~Error() throw()
const char *Error::name() const const char *Error::name() const
{ {
return _int->error.name; return _int->error.name;
} }
const char *Error::message() const const char *Error::message() const
{ {
return _int->error.message; return _int->error.message;
} }
bool Error::is_set() const bool Error::is_set() const
{ {
return *(_int); return *(_int);
} }
void Error::set(const char *name, const char *message) void Error::set(const char *name, const char *message)
{ {
dbus_set_error_const(&(_int->error), name, message); dbus_set_error_const(&(_int->error), name, message);
} }
const char *Error::what() const throw() const char *Error::what() const throw()
{ {
return _int->error.message; return _int->error.message;
} }

View file

@ -43,182 +43,182 @@ using namespace DBus;
using namespace std; using namespace std;
BusTimeout::BusTimeout(Timeout::Internal *ti, BusDispatcher *bd) BusTimeout::BusTimeout(Timeout::Internal *ti, BusDispatcher *bd)
: Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd) : Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd)
{ {
DefaultTimeout::enabled(Timeout::enabled()); DefaultTimeout::enabled(Timeout::enabled());
} }
void BusTimeout::toggle() void BusTimeout::toggle()
{ {
debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off"); debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
DefaultTimeout::enabled(Timeout::enabled()); DefaultTimeout::enabled(Timeout::enabled());
} }
BusWatch::BusWatch(Watch::Internal *wi, BusDispatcher *bd) BusWatch::BusWatch(Watch::Internal *wi, BusDispatcher *bd)
: Watch(wi), DefaultWatch(Watch::descriptor(), 0, bd) : Watch(wi), DefaultWatch(Watch::descriptor(), 0, bd)
{ {
int flags = POLLHUP | POLLERR; int flags = POLLHUP | POLLERR;
if (Watch::flags() & DBUS_WATCH_READABLE) if (Watch::flags() & DBUS_WATCH_READABLE)
flags |= POLLIN; flags |= POLLIN;
if (Watch::flags() & DBUS_WATCH_WRITABLE) if (Watch::flags() & DBUS_WATCH_WRITABLE)
flags |= POLLOUT; flags |= POLLOUT;
DefaultWatch::flags(flags); DefaultWatch::flags(flags);
DefaultWatch::enabled(Watch::enabled()); DefaultWatch::enabled(Watch::enabled());
} }
void BusWatch::toggle() void BusWatch::toggle()
{ {
debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on":"off"); debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
DefaultWatch::enabled(Watch::enabled()); DefaultWatch::enabled(Watch::enabled());
} }
BusDispatcher::BusDispatcher() : BusDispatcher::BusDispatcher() :
_running(false) _running(false)
{ {
// pipe to create a new fd used to unlock a dispatcher at any // pipe to create a new fd used to unlock a dispatcher at any
// moment (used by leave function) // moment (used by leave function)
int ret = pipe(_pipe); int ret = pipe(_pipe);
if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str()); if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());
_fdunlock[0] = _pipe[0]; _fdunlock[0] = _pipe[0];
_fdunlock[1] = _pipe[1]; _fdunlock[1] = _pipe[1];
} }
void BusDispatcher::enter() void BusDispatcher::enter()
{ {
debug_log("entering dispatcher %p", this); debug_log("entering dispatcher %p", this);
_running = true; _running = true;
while (_running) while (_running)
{ {
do_iteration(); do_iteration();
for (std::list <Pipe*>::iterator p_it = pipe_list.begin (); for (std::list <Pipe *>::iterator p_it = pipe_list.begin();
p_it != pipe_list.end (); p_it != pipe_list.end();
++p_it) ++p_it)
{ {
Pipe* read_pipe = *p_it; Pipe *read_pipe = *p_it;
char buffer[1024]; // TODO: should be max pipe size char buffer[1024]; // TODO: should be max pipe size
unsigned int nbytes = 0; unsigned int nbytes = 0;
while (read_pipe->read(buffer, nbytes) > 0) while (read_pipe->read(buffer, nbytes) > 0)
{ {
read_pipe->_handler (read_pipe->_data, buffer, nbytes); read_pipe->_handler(read_pipe->_data, buffer, nbytes);
} }
} }
} }
debug_log("leaving dispatcher %p", this); debug_log("leaving dispatcher %p", this);
} }
void BusDispatcher::leave() void BusDispatcher::leave()
{ {
_running = false; _running = false;
int ret = write(_fdunlock[1],"exit",strlen("exit")); int ret = write(_fdunlock[1], "exit", strlen("exit"));
if (ret == -1) throw Error("WriteError:errno", toString(errno).c_str()); if (ret == -1) throw Error("WriteError:errno", toString(errno).c_str());
close(_fdunlock[1]); close(_fdunlock[1]);
close(_fdunlock[0]); close(_fdunlock[0]);
} }
Pipe *BusDispatcher::add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data) Pipe *BusDispatcher::add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data)
{ {
Pipe *new_pipe = new Pipe (handler, data); Pipe *new_pipe = new Pipe(handler, data);
pipe_list.push_back (new_pipe); pipe_list.push_back(new_pipe);
return new_pipe; return new_pipe;
} }
void BusDispatcher::del_pipe (Pipe *pipe) void BusDispatcher::del_pipe(Pipe *pipe)
{ {
pipe_list.remove (pipe); pipe_list.remove(pipe);
delete pipe; delete pipe;
} }
void BusDispatcher::do_iteration() void BusDispatcher::do_iteration()
{ {
dispatch_pending(); dispatch_pending();
dispatch(); dispatch();
} }
Timeout *BusDispatcher::add_timeout(Timeout::Internal *ti) Timeout *BusDispatcher::add_timeout(Timeout::Internal *ti)
{ {
BusTimeout *bt = new BusTimeout(ti, this); BusTimeout *bt = new BusTimeout(ti, this);
bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &>(this, &BusDispatcher::timeout_expired); bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &>(this, &BusDispatcher::timeout_expired);
bt->data(bt); bt->data(bt);
debug_log("added timeout %p (%s) (%d millies)", debug_log("added timeout %p (%s) (%d millies)",
bt, bt,
((Timeout*)bt)->enabled() ? "on":"off", ((Timeout *)bt)->enabled() ? "on" : "off",
((Timeout*)bt)->interval() ((Timeout *)bt)->interval()
); );
return bt; return bt;
} }
void BusDispatcher::rem_timeout(Timeout *t) void BusDispatcher::rem_timeout(Timeout *t)
{ {
debug_log("removed timeout %p", t); debug_log("removed timeout %p", t);
delete t; delete t;
} }
Watch *BusDispatcher::add_watch(Watch::Internal *wi) Watch *BusDispatcher::add_watch(Watch::Internal *wi)
{ {
BusWatch *bw = new BusWatch(wi, this); BusWatch *bw = new BusWatch(wi, this);
bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready); bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready);
bw->data(bw); bw->data(bw);
debug_log("added watch %p (%s) fd=%d flags=%d", debug_log("added watch %p (%s) fd=%d flags=%d",
bw, ((Watch *)bw)->enabled() ? "on":"off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags()); bw, ((Watch *)bw)->enabled() ? "on" : "off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());
return bw; return bw;
} }
void BusDispatcher::rem_watch(Watch *w) void BusDispatcher::rem_watch(Watch *w)
{ {
debug_log("removed watch %p", w); debug_log("removed watch %p", w);
delete w; delete w;
} }
void BusDispatcher::timeout_expired(DefaultTimeout &et) void BusDispatcher::timeout_expired(DefaultTimeout &et)
{ {
debug_log("timeout %p expired", &et); debug_log("timeout %p expired", &et);
BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data()); BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data());
timeout->handle(); timeout->handle();
} }
void BusDispatcher::watch_ready(DefaultWatch &ew) void BusDispatcher::watch_ready(DefaultWatch &ew)
{ {
BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data()); BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());
debug_log("watch %p ready, flags=%d state=%d", debug_log("watch %p ready, flags=%d state=%d",
watch, ((Watch *)watch)->flags(), watch->state() watch, ((Watch *)watch)->flags(), watch->state()
); );
int flags = 0; int flags = 0;
if (watch->state() & POLLIN) if (watch->state() & POLLIN)
flags |= DBUS_WATCH_READABLE; flags |= DBUS_WATCH_READABLE;
if (watch->state() & POLLOUT) if (watch->state() & POLLOUT)
flags |= DBUS_WATCH_WRITABLE; flags |= DBUS_WATCH_WRITABLE;
if (watch->state() & POLLHUP) if (watch->state() & POLLHUP)
flags |= DBUS_WATCH_HANGUP; flags |= DBUS_WATCH_HANGUP;
if (watch->state() & POLLERR) if (watch->state() & POLLERR)
flags |= DBUS_WATCH_ERROR; flags |= DBUS_WATCH_ERROR;
watch->handle(flags); watch->handle(flags);
} }

View file

@ -38,225 +38,226 @@ using namespace std;
static double millis(timeval tv) static double millis(timeval tv)
{ {
return (tv.tv_sec *1000.0 + tv.tv_usec/1000.0); return (tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0);
} }
DefaultTimeout::DefaultTimeout(int interval, bool repeat, DefaultMainLoop *ed) DefaultTimeout::DefaultTimeout(int interval, bool repeat, DefaultMainLoop *ed)
: _enabled(true), _interval(interval), _repeat(repeat), _expiration(0), _data(0), _disp(ed) : _enabled(true), _interval(interval), _repeat(repeat), _expiration(0), _data(0), _disp(ed)
{ {
timeval now; timeval now;
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
_expiration = millis(now) + interval; _expiration = millis(now) + interval;
_disp->_mutex_t.lock(); _disp->_mutex_t.lock();
_disp->_timeouts.push_back(this); _disp->_timeouts.push_back(this);
_disp->_mutex_t.unlock(); _disp->_mutex_t.unlock();
} }
DefaultTimeout::~DefaultTimeout() DefaultTimeout::~DefaultTimeout()
{ {
_disp->_mutex_t.lock(); _disp->_mutex_t.lock();
_disp->_timeouts.remove(this); _disp->_timeouts.remove(this);
_disp->_mutex_t.unlock(); _disp->_mutex_t.unlock();
} }
DefaultWatch::DefaultWatch(int fd, int flags, DefaultMainLoop *ed) DefaultWatch::DefaultWatch(int fd, int flags, DefaultMainLoop *ed)
: _enabled(true), _fd(fd), _flags(flags), _state(0), _data(0), _disp(ed) : _enabled(true), _fd(fd), _flags(flags), _state(0), _data(0), _disp(ed)
{ {
_disp->_mutex_w.lock(); _disp->_mutex_w.lock();
_disp->_watches.push_back(this); _disp->_watches.push_back(this);
_disp->_mutex_w.unlock(); _disp->_mutex_w.unlock();
} }
DefaultWatch::~DefaultWatch() DefaultWatch::~DefaultWatch()
{ {
_disp->_mutex_w.lock(); _disp->_mutex_w.lock();
_disp->_watches.remove(this); _disp->_watches.remove(this);
_disp->_mutex_w.unlock(); _disp->_mutex_w.unlock();
} }
DefaultMutex::DefaultMutex() DefaultMutex::DefaultMutex()
{ {
pthread_mutex_init(&_mutex, NULL); pthread_mutex_init(&_mutex, NULL);
} }
DefaultMutex::DefaultMutex(bool recursive) DefaultMutex::DefaultMutex(bool recursive)
{ {
if (recursive) if (recursive)
{ {
pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
_mutex = recmutex; _mutex = recmutex;
} }
else else
{ {
pthread_mutex_init(&_mutex, NULL); pthread_mutex_init(&_mutex, NULL);
} }
} }
DefaultMutex::~DefaultMutex() DefaultMutex::~DefaultMutex()
{ {
pthread_mutex_destroy(&_mutex); pthread_mutex_destroy(&_mutex);
} }
void DefaultMutex::lock() void DefaultMutex::lock()
{ {
pthread_mutex_lock(&_mutex); pthread_mutex_lock(&_mutex);
} }
void DefaultMutex::unlock() void DefaultMutex::unlock()
{ {
pthread_mutex_unlock(&_mutex); pthread_mutex_unlock(&_mutex);
} }
DefaultMainLoop::DefaultMainLoop() : DefaultMainLoop::DefaultMainLoop() :
_mutex_w(true) _mutex_w(true)
{ {
} }
DefaultMainLoop::~DefaultMainLoop() DefaultMainLoop::~DefaultMainLoop()
{ {
_mutex_w.lock(); _mutex_w.lock();
DefaultWatches::iterator wi = _watches.begin(); DefaultWatches::iterator wi = _watches.begin();
while (wi != _watches.end()) while (wi != _watches.end())
{ {
DefaultWatches::iterator wmp = wi; DefaultWatches::iterator wmp = wi;
++wmp; ++wmp;
_mutex_w.unlock(); _mutex_w.unlock();
delete (*wi); delete(*wi);
_mutex_w.lock(); _mutex_w.lock();
wi = wmp; wi = wmp;
} }
_mutex_w.unlock(); _mutex_w.unlock();
_mutex_t.lock(); _mutex_t.lock();
DefaultTimeouts::iterator ti = _timeouts.begin(); DefaultTimeouts::iterator ti = _timeouts.begin();
while (ti != _timeouts.end()) while (ti != _timeouts.end())
{ {
DefaultTimeouts::iterator tmp = ti; DefaultTimeouts::iterator tmp = ti;
++tmp; ++tmp;
_mutex_t.unlock(); _mutex_t.unlock();
delete (*ti); delete(*ti);
_mutex_t.lock(); _mutex_t.lock();
ti = tmp; ti = tmp;
} }
_mutex_t.unlock(); _mutex_t.unlock();
} }
void DefaultMainLoop::dispatch() void DefaultMainLoop::dispatch()
{ {
_mutex_w.lock(); _mutex_w.lock();
int nfd = _watches.size(); int nfd = _watches.size();
if(_fdunlock) if (_fdunlock)
{ {
nfd=nfd+2; nfd = nfd + 2;
} }
pollfd fds[nfd]; pollfd fds[nfd];
DefaultWatches::iterator wi = _watches.begin(); DefaultWatches::iterator wi = _watches.begin();
for (nfd = 0; wi != _watches.end(); ++wi) for (nfd = 0; wi != _watches.end(); ++wi)
{ {
if ((*wi)->enabled()) if ((*wi)->enabled())
{ {
fds[nfd].fd = (*wi)->descriptor(); fds[nfd].fd = (*wi)->descriptor();
fds[nfd].events = (*wi)->flags(); fds[nfd].events = (*wi)->flags();
fds[nfd].revents = 0; fds[nfd].revents = 0;
++nfd; ++nfd;
} }
} }
if(_fdunlock){ if (_fdunlock)
fds[nfd].fd = _fdunlock[0]; {
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ; fds[nfd].fd = _fdunlock[0];
fds[nfd].revents = 0; fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
fds[nfd].revents = 0;
nfd++;
fds[nfd].fd = _fdunlock[1];
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
fds[nfd].revents = 0;
}
_mutex_w.unlock(); nfd++;
fds[nfd].fd = _fdunlock[1];
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
fds[nfd].revents = 0;
}
int wait_min = 10000; _mutex_w.unlock();
DefaultTimeouts::iterator ti; int wait_min = 10000;
_mutex_t.lock(); DefaultTimeouts::iterator ti;
for (ti = _timeouts.begin(); ti != _timeouts.end(); ++ti) _mutex_t.lock();
{
if ((*ti)->enabled() && (*ti)->interval() < wait_min)
wait_min = (*ti)->interval();
}
_mutex_t.unlock(); for (ti = _timeouts.begin(); ti != _timeouts.end(); ++ti)
{
if ((*ti)->enabled() && (*ti)->interval() < wait_min)
wait_min = (*ti)->interval();
}
poll(fds, nfd, wait_min); _mutex_t.unlock();
timeval now; poll(fds, nfd, wait_min);
gettimeofday(&now, NULL);
double now_millis = millis(now); timeval now;
gettimeofday(&now, NULL);
_mutex_t.lock(); double now_millis = millis(now);
ti = _timeouts.begin(); _mutex_t.lock();
while (ti != _timeouts.end()) ti = _timeouts.begin();
{
DefaultTimeouts::iterator tmp = ti;
++tmp;
if ((*ti)->enabled() && now_millis >= (*ti)->_expiration) while (ti != _timeouts.end())
{ {
(*ti)->expired(*(*ti)); DefaultTimeouts::iterator tmp = ti;
++tmp;
if ((*ti)->_repeat) if ((*ti)->enabled() && now_millis >= (*ti)->_expiration)
{ {
(*ti)->_expiration = now_millis + (*ti)->_interval; (*ti)->expired(*(*ti));
}
} if ((*ti)->_repeat)
{
(*ti)->_expiration = now_millis + (*ti)->_interval;
}
ti = tmp; }
}
_mutex_t.unlock(); ti = tmp;
}
_mutex_w.lock(); _mutex_t.unlock();
for (int j = 0; j < nfd; ++j) _mutex_w.lock();
{
DefaultWatches::iterator wi;
for (wi = _watches.begin(); wi != _watches.end();) for (int j = 0; j < nfd; ++j)
{ {
DefaultWatches::iterator tmp = wi; DefaultWatches::iterator wi;
++tmp;
if ((*wi)->enabled() && (*wi)->_fd == fds[j].fd) for (wi = _watches.begin(); wi != _watches.end();)
{ {
if (fds[j].revents) DefaultWatches::iterator tmp = wi;
{ ++tmp;
(*wi)->_state = fds[j].revents;
(*wi)->ready(*(*wi)); if ((*wi)->enabled() && (*wi)->_fd == fds[j].fd)
{
if (fds[j].revents)
{
(*wi)->_state = fds[j].revents;
fds[j].revents = 0; (*wi)->ready(*(*wi));
}
}
wi = tmp; fds[j].revents = 0;
} }
} }
_mutex_w.unlock();
wi = tmp;
}
}
_mutex_w.unlock();
} }

View file

@ -31,169 +31,170 @@
using namespace DBus; using namespace DBus;
Glib::BusTimeout::BusTimeout(Timeout::Internal *ti, GMainContext *ctx, int priority) Glib::BusTimeout::BusTimeout(Timeout::Internal *ti, GMainContext *ctx, int priority)
: Timeout(ti), _ctx(ctx), _priority(priority), _source(NULL) : Timeout(ti), _ctx(ctx), _priority(priority), _source(NULL)
{ {
if (Timeout::enabled()) if (Timeout::enabled())
_enable(); _enable();
} }
Glib::BusTimeout::~BusTimeout() Glib::BusTimeout::~BusTimeout()
{ {
_disable(); _disable();
} }
void Glib::BusTimeout::toggle() void Glib::BusTimeout::toggle()
{ {
debug_log("glib: timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off"); debug_log("glib: timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
if (Timeout::enabled()) _enable(); if (Timeout::enabled()) _enable();
else _disable(); else _disable();
} }
gboolean Glib::BusTimeout::timeout_handler(gpointer data) gboolean Glib::BusTimeout::timeout_handler(gpointer data)
{ {
Glib::BusTimeout *t = reinterpret_cast<Glib::BusTimeout *>(data); Glib::BusTimeout *t = reinterpret_cast<Glib::BusTimeout *>(data);
t->handle(); t->handle();
return TRUE; return TRUE;
} }
void Glib::BusTimeout::_enable() void Glib::BusTimeout::_enable()
{ {
if (_source) if (_source)
_disable(); // be sane _disable(); // be sane
_source = g_timeout_source_new(Timeout::interval()); _source = g_timeout_source_new(Timeout::interval());
g_source_set_priority(_source, _priority); g_source_set_priority(_source, _priority);
g_source_set_callback(_source, timeout_handler, this, NULL); g_source_set_callback(_source, timeout_handler, this, NULL);
g_source_attach(_source, _ctx); g_source_attach(_source, _ctx);
} }
void Glib::BusTimeout::_disable() void Glib::BusTimeout::_disable()
{ {
if (_source) if (_source)
{ {
g_source_destroy(_source); g_source_destroy(_source);
_source = NULL; _source = NULL;
} }
} }
struct BusSource struct BusSource
{ {
GSource source; GSource source;
GPollFD poll; GPollFD poll;
}; };
static gboolean watch_prepare(GSource *source, gint *timeout) static gboolean watch_prepare(GSource *source, gint *timeout)
{ {
debug_log("glib: watch_prepare"); debug_log("glib: watch_prepare");
*timeout = -1; *timeout = -1;
return FALSE; return FALSE;
} }
static gboolean watch_check(GSource *source) static gboolean watch_check(GSource *source)
{ {
debug_log("glib: watch_check"); debug_log("glib: watch_check");
BusSource *io = (BusSource *)source; BusSource *io = (BusSource *)source;
return io->poll.revents ? TRUE : FALSE; return io->poll.revents ? TRUE : FALSE;
} }
static gboolean watch_dispatch(GSource *source, GSourceFunc callback, gpointer data) static gboolean watch_dispatch(GSource *source, GSourceFunc callback, gpointer data)
{ {
debug_log("glib: watch_dispatch"); debug_log("glib: watch_dispatch");
gboolean cb = callback(data); gboolean cb = callback(data);
return cb; return cb;
} }
static GSourceFuncs watch_funcs = { static GSourceFuncs watch_funcs =
watch_prepare, {
watch_check, watch_prepare,
watch_dispatch, watch_check,
NULL watch_dispatch,
NULL
}; };
Glib::BusWatch::BusWatch(Watch::Internal *wi, GMainContext *ctx, int priority) Glib::BusWatch::BusWatch(Watch::Internal *wi, GMainContext *ctx, int priority)
: Watch(wi), _ctx(ctx), _priority(priority), _source(NULL) : Watch(wi), _ctx(ctx), _priority(priority), _source(NULL)
{ {
if (Watch::enabled()) if (Watch::enabled())
_enable(); _enable();
} }
Glib::BusWatch::~BusWatch() Glib::BusWatch::~BusWatch()
{ {
_disable(); _disable();
} }
void Glib::BusWatch::toggle() void Glib::BusWatch::toggle()
{ {
debug_log("glib: watch %p toggled (%s)", this, Watch::enabled() ? "on":"off"); debug_log("glib: watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
if (Watch::enabled()) _enable(); if (Watch::enabled()) _enable();
else _disable(); else _disable();
} }
gboolean Glib::BusWatch::watch_handler(gpointer data) gboolean Glib::BusWatch::watch_handler(gpointer data)
{ {
Glib::BusWatch *w = reinterpret_cast<Glib::BusWatch *>(data); Glib::BusWatch *w = reinterpret_cast<Glib::BusWatch *>(data);
BusSource *io = (BusSource *)(w->_source); BusSource *io = (BusSource *)(w->_source);
int flags = 0; int flags = 0;
if (io->poll.revents &G_IO_IN) if (io->poll.revents & G_IO_IN)
flags |= DBUS_WATCH_READABLE; flags |= DBUS_WATCH_READABLE;
if (io->poll.revents &G_IO_OUT) if (io->poll.revents & G_IO_OUT)
flags |= DBUS_WATCH_WRITABLE; flags |= DBUS_WATCH_WRITABLE;
if (io->poll.revents &G_IO_ERR) if (io->poll.revents & G_IO_ERR)
flags |= DBUS_WATCH_ERROR; flags |= DBUS_WATCH_ERROR;
if (io->poll.revents &G_IO_HUP) if (io->poll.revents & G_IO_HUP)
flags |= DBUS_WATCH_HANGUP; flags |= DBUS_WATCH_HANGUP;
w->handle(flags); w->handle(flags);
return TRUE; return TRUE;
} }
void Glib::BusWatch::_enable() void Glib::BusWatch::_enable()
{ {
if (_source) if (_source)
_disable(); // be sane _disable(); // be sane
_source = g_source_new(&watch_funcs, sizeof(BusSource)); _source = g_source_new(&watch_funcs, sizeof(BusSource));
g_source_set_priority(_source, _priority); g_source_set_priority(_source, _priority);
g_source_set_callback(_source, watch_handler, this, NULL); g_source_set_callback(_source, watch_handler, this, NULL);
int flags = Watch::flags(); int flags = Watch::flags();
int condition = 0; int condition = 0;
if (flags &DBUS_WATCH_READABLE) if (flags & DBUS_WATCH_READABLE)
condition |= G_IO_IN; condition |= G_IO_IN;
if (flags &DBUS_WATCH_WRITABLE) if (flags & DBUS_WATCH_WRITABLE)
condition |= G_IO_OUT; condition |= G_IO_OUT;
if (flags &DBUS_WATCH_ERROR) if (flags & DBUS_WATCH_ERROR)
condition |= G_IO_ERR; condition |= G_IO_ERR;
if (flags &DBUS_WATCH_HANGUP) if (flags & DBUS_WATCH_HANGUP)
condition |= G_IO_HUP; condition |= G_IO_HUP;
GPollFD *poll = &(((BusSource *)_source)->poll); GPollFD *poll = &(((BusSource *)_source)->poll);
poll->fd = Watch::descriptor(); poll->fd = Watch::descriptor();
poll->events = condition; poll->events = condition;
poll->revents = 0; poll->revents = 0;
g_source_add_poll(_source, poll); g_source_add_poll(_source, poll);
g_source_attach(_source, _ctx); g_source_attach(_source, _ctx);
} }
void Glib::BusWatch::_disable() void Glib::BusWatch::_disable()
{ {
if (!_source) if (!_source)
return; return;
GPollFD *poll = &(((BusSource *)_source)->poll); GPollFD *poll = &(((BusSource *)_source)->poll);
g_source_remove_poll(_source, poll); g_source_remove_poll(_source, poll);
g_source_destroy(_source); g_source_destroy(_source);
_source = NULL; _source = NULL;
} }
/* /*
@ -203,23 +204,23 @@ void Glib::BusWatch::_disable()
*/ */
struct DispatcherSource struct DispatcherSource
{ {
GSource source; GSource source;
Dispatcher *dispatcher; Dispatcher *dispatcher;
}; };
static gboolean dispatcher_prepare(GSource *source, gint *timeout) static gboolean dispatcher_prepare(GSource *source, gint *timeout)
{ {
Dispatcher *dispatcher = ((DispatcherSource*)source)->dispatcher; Dispatcher *dispatcher = ((DispatcherSource *)source)->dispatcher;
*timeout = -1;
return dispatcher->has_something_to_dispatch()? TRUE:FALSE; *timeout = -1;
return dispatcher->has_something_to_dispatch() ? TRUE : FALSE;
} }
static gboolean dispatcher_check(GSource *source) static gboolean dispatcher_check(GSource *source)
{ {
return FALSE; return FALSE;
} }
static gboolean static gboolean
@ -227,88 +228,89 @@ dispatcher_dispatch(GSource *source,
GSourceFunc callback, GSourceFunc callback,
gpointer user_data) gpointer user_data)
{ {
Dispatcher *dispatcher = ((DispatcherSource*)source)->dispatcher; Dispatcher *dispatcher = ((DispatcherSource *)source)->dispatcher;
dispatcher->dispatch_pending(); dispatcher->dispatch_pending();
return TRUE; return TRUE;
} }
static const GSourceFuncs dispatcher_funcs = { static const GSourceFuncs dispatcher_funcs =
dispatcher_prepare, {
dispatcher_check, dispatcher_prepare,
dispatcher_dispatch, dispatcher_check,
NULL dispatcher_dispatch,
NULL
}; };
Glib::BusDispatcher::BusDispatcher() Glib::BusDispatcher::BusDispatcher()
: _ctx(NULL), _priority(G_PRIORITY_DEFAULT), _source(NULL) : _ctx(NULL), _priority(G_PRIORITY_DEFAULT), _source(NULL)
{ {
} }
Glib::BusDispatcher::~BusDispatcher() Glib::BusDispatcher::~BusDispatcher()
{ {
if (_source) if (_source)
{ {
GSource *temp = _source; GSource *temp = _source;
_source = NULL; _source = NULL;
g_source_destroy (temp); g_source_destroy(temp);
g_source_unref (temp); g_source_unref(temp);
} }
if (_ctx) if (_ctx)
g_main_context_unref(_ctx); g_main_context_unref(_ctx);
} }
void Glib::BusDispatcher::attach(GMainContext *ctx) void Glib::BusDispatcher::attach(GMainContext *ctx)
{ {
g_assert(_ctx == NULL); // just to be sane g_assert(_ctx == NULL); // just to be sane
_ctx = ctx ? ctx : g_main_context_default(); _ctx = ctx ? ctx : g_main_context_default();
g_main_context_ref(_ctx); g_main_context_ref(_ctx);
// create the source for dispatching messages
_source = g_source_new((GSourceFuncs *) &dispatcher_funcs,
sizeof(DispatcherSource));
((DispatcherSource*)_source)->dispatcher = this; // create the source for dispatching messages
g_source_attach (_source, _ctx); _source = g_source_new((GSourceFuncs *) &dispatcher_funcs,
sizeof(DispatcherSource));
((DispatcherSource *)_source)->dispatcher = this;
g_source_attach(_source, _ctx);
} }
Timeout *Glib::BusDispatcher::add_timeout(Timeout::Internal *wi) Timeout *Glib::BusDispatcher::add_timeout(Timeout::Internal *wi)
{ {
Timeout *t = new Glib::BusTimeout(wi, _ctx, _priority); Timeout *t = new Glib::BusTimeout(wi, _ctx, _priority);
debug_log("glib: added timeout %p (%s)", t, t->enabled() ? "on":"off"); debug_log("glib: added timeout %p (%s)", t, t->enabled() ? "on" : "off");
return t; return t;
} }
void Glib::BusDispatcher::rem_timeout(Timeout *t) void Glib::BusDispatcher::rem_timeout(Timeout *t)
{ {
debug_log("glib: removed timeout %p", t); debug_log("glib: removed timeout %p", t);
delete t; delete t;
} }
Watch *Glib::BusDispatcher::add_watch(Watch::Internal *wi) Watch *Glib::BusDispatcher::add_watch(Watch::Internal *wi)
{ {
Watch *w = new Glib::BusWatch(wi, _ctx, _priority); Watch *w = new Glib::BusWatch(wi, _ctx, _priority);
debug_log("glib: added watch %p (%s) fd=%d flags=%d", debug_log("glib: added watch %p (%s) fd=%d flags=%d",
w, w->enabled() ? "on":"off", w->descriptor(), w->flags() w, w->enabled() ? "on" : "off", w->descriptor(), w->flags()
); );
return w; return w;
} }
void Glib::BusDispatcher::rem_watch(Watch *w) void Glib::BusDispatcher::rem_watch(Watch *w)
{ {
debug_log("glib: removed watch %p", w); debug_log("glib: removed watch %p", w);
delete w; delete w;
} }
void Glib::BusDispatcher::set_priority(int priority) void Glib::BusDispatcher::set_priority(int priority)
{ {
_priority = priority; _priority = priority;
} }

View file

@ -33,7 +33,7 @@
using namespace DBus; using namespace DBus;
Interface::Interface(const std::string &name) Interface::Interface(const std::string &name)
: _name(name) : _name(name)
{} {}
Interface::~Interface() Interface::~Interface()
@ -41,129 +41,129 @@ Interface::~Interface()
InterfaceAdaptor *AdaptorBase::find_interface(const std::string &name) InterfaceAdaptor *AdaptorBase::find_interface(const std::string &name)
{ {
InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name); InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name);
return ii != _interfaces.end() ? ii->second : NULL; return ii != _interfaces.end() ? ii->second : NULL;
} }
InterfaceAdaptor::InterfaceAdaptor(const std::string &name) InterfaceAdaptor::InterfaceAdaptor(const std::string &name)
: Interface(name) : Interface(name)
{ {
debug_log("adding interface %s", name.c_str()); debug_log("adding interface %s", name.c_str());
_interfaces[name] = this; _interfaces[name] = this;
} }
Message InterfaceAdaptor::dispatch_method(const CallMessage &msg) Message InterfaceAdaptor::dispatch_method(const CallMessage &msg)
{ {
const char *name = msg.member(); const char *name = msg.member();
MethodTable::iterator mi = _methods.find(name); MethodTable::iterator mi = _methods.find(name);
if (mi != _methods.end()) if (mi != _methods.end())
{ {
return mi->second.call(msg); return mi->second.call(msg);
} }
else else
{ {
return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name); return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name);
} }
} }
void InterfaceAdaptor::emit_signal(const SignalMessage &sig) void InterfaceAdaptor::emit_signal(const SignalMessage &sig)
{ {
SignalMessage &sig2 = const_cast<SignalMessage &>(sig); SignalMessage &sig2 = const_cast<SignalMessage &>(sig);
if (sig2.interface() == NULL) if (sig2.interface() == NULL)
sig2.interface(name().c_str()); sig2.interface(name().c_str());
_emit_signal(sig2); _emit_signal(sig2);
} }
Variant *InterfaceAdaptor::get_property(const std::string &name) Variant *InterfaceAdaptor::get_property(const std::string &name)
{ {
PropertyTable::iterator pti = _properties.find(name); PropertyTable::iterator pti = _properties.find(name);
if (pti != _properties.end()) if (pti != _properties.end())
{ {
if (!pti->second.read) if (!pti->second.read)
throw ErrorAccessDenied("property is not readable"); throw ErrorAccessDenied("property is not readable");
return &(pti->second.value); return &(pti->second.value);
} }
return NULL; return NULL;
} }
void InterfaceAdaptor::set_property(const std::string &name, Variant &value) void InterfaceAdaptor::set_property(const std::string &name, Variant &value)
{ {
PropertyTable::iterator pti = _properties.find(name); PropertyTable::iterator pti = _properties.find(name);
if (pti != _properties.end()) if (pti != _properties.end())
{ {
if (!pti->second.write) if (!pti->second.write)
throw ErrorAccessDenied("property is not writeable"); throw ErrorAccessDenied("property is not writeable");
Signature sig = value.signature(); Signature sig = value.signature();
if (pti->second.sig != sig) if (pti->second.sig != sig)
throw ErrorInvalidSignature("property expects a different type"); throw ErrorInvalidSignature("property expects a different type");
pti->second.value = value; pti->second.value = value;
return; return;
} }
throw ErrorFailed("requested property not found"); throw ErrorFailed("requested property not found");
} }
InterfaceProxy *ProxyBase::find_interface(const std::string &name) InterfaceProxy *ProxyBase::find_interface(const std::string &name)
{ {
InterfaceProxyTable::const_iterator ii = _interfaces.find(name); InterfaceProxyTable::const_iterator ii = _interfaces.find(name);
return ii != _interfaces.end() ? ii->second : NULL; return ii != _interfaces.end() ? ii->second : NULL;
} }
InterfaceProxy::InterfaceProxy(const std::string &name) InterfaceProxy::InterfaceProxy(const std::string &name)
: Interface(name) : Interface(name)
{ {
debug_log("adding interface %s", name.c_str()); debug_log("adding interface %s", name.c_str());
_interfaces[name] = this; _interfaces[name] = this;
} }
bool InterfaceProxy::dispatch_signal(const SignalMessage &msg) bool InterfaceProxy::dispatch_signal(const SignalMessage &msg)
{ {
const char *name = msg.member(); const char *name = msg.member();
SignalTable::iterator si = _signals.find(name); SignalTable::iterator si = _signals.find(name);
if (si != _signals.end()) if (si != _signals.end())
{ {
si->second.call(msg); si->second.call(msg);
// Here we always return false because there might be // Here we always return false because there might be
// another InterfaceProxy listening for the same signal. // another InterfaceProxy listening for the same signal.
// This way we instruct libdbus-1 to go on dispatching // This way we instruct libdbus-1 to go on dispatching
// the signal. // the signal.
return false; return false;
} }
else else
{ {
return false; return false;
} }
} }
Message InterfaceProxy::invoke_method(const CallMessage &call) Message InterfaceProxy::invoke_method(const CallMessage &call)
{ {
CallMessage &call2 = const_cast<CallMessage &>(call); CallMessage &call2 = const_cast<CallMessage &>(call);
if (call.interface() == NULL) if (call.interface() == NULL)
call2.interface(name().c_str()); call2.interface(name().c_str());
return _invoke_method(call2); return _invoke_method(call2);
} }
bool InterfaceProxy::invoke_method_noreply(const CallMessage &call) bool InterfaceProxy::invoke_method_noreply(const CallMessage &call)
{ {
CallMessage &call2 = const_cast<CallMessage &>(call); CallMessage &call2 = const_cast<CallMessage &>(call);
if (call.interface() == NULL) if (call.interface() == NULL)
call2.interface(name().c_str()); call2.interface(name().c_str());
return _invoke_method_noreply(call2); return _invoke_method_noreply(call2);
} }

View file

@ -33,43 +33,44 @@
#include <dbus/dbus.h> #include <dbus/dbus.h>
namespace DBus { namespace DBus
{
struct DXXAPI InternalError struct DXXAPI InternalError
{ {
DBusError error; DBusError error;
InternalError() InternalError()
{ {
dbus_error_init(&error); dbus_error_init(&error);
} }
explicit InternalError(DBusError *e) explicit InternalError(DBusError *e)
{ {
dbus_error_init(&error); dbus_error_init(&error);
dbus_move_error(e, &error); dbus_move_error(e, &error);
} }
InternalError(const InternalError &ie) InternalError(const InternalError &ie)
{ {
dbus_error_init(&error); dbus_error_init(&error);
dbus_move_error(const_cast<DBusError *>(&(ie.error)), &error); dbus_move_error(const_cast<DBusError *>(&(ie.error)), &error);
} }
~InternalError()
{
dbus_error_free(&error);
}
operator DBusError *() ~InternalError()
{ {
return &error; dbus_error_free(&error);
} }
operator bool() operator DBusError *()
{ {
return dbus_error_is_set(&error); return &error;
} }
operator bool()
{
return dbus_error_is_set(&error);
}
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -38,156 +38,156 @@ using namespace DBus;
static const char *introspectable_name = "org.freedesktop.DBus.Introspectable"; static const char *introspectable_name = "org.freedesktop.DBus.Introspectable";
IntrospectableAdaptor::IntrospectableAdaptor() IntrospectableAdaptor::IntrospectableAdaptor()
: InterfaceAdaptor(introspectable_name) : InterfaceAdaptor(introspectable_name)
{ {
register_method(IntrospectableAdaptor, Introspect, Introspect); register_method(IntrospectableAdaptor, Introspect, Introspect);
} }
Message IntrospectableAdaptor::Introspect(const CallMessage &call) Message IntrospectableAdaptor::Introspect(const CallMessage &call)
{ {
debug_log("requested introspection data"); debug_log("requested introspection data");
std::ostringstream xml; std::ostringstream xml;
xml << DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE; xml << DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE;
const std::string path = object()->path(); const std::string path = object()->path();
xml << "<node name=\"" << path << "\">"; xml << "<node name=\"" << path << "\">";
InterfaceAdaptorTable::const_iterator iti; InterfaceAdaptorTable::const_iterator iti;
for (iti = _interfaces.begin(); iti != _interfaces.end(); ++iti) for (iti = _interfaces.begin(); iti != _interfaces.end(); ++iti)
{ {
debug_log("introspecting interface %s", iti->first.c_str()); debug_log("introspecting interface %s", iti->first.c_str());
IntrospectedInterface *const intro = iti->second->introspect(); IntrospectedInterface *const intro = iti->second->introspect();
if (intro) if (intro)
{ {
xml << "\n\t<interface name=\"" << intro->name << "\">"; xml << "\n\t<interface name=\"" << intro->name << "\">";
for (const IntrospectedProperty *p = intro->properties; p->name; ++p) for (const IntrospectedProperty *p = intro->properties; p->name; ++p)
{ {
std::string access; std::string access;
if (p->read) access += "read"; if (p->read) access += "read";
if (p->write) access += "write"; if (p->write) access += "write";
xml << "\n\t\t<property name=\"" << p->name << "\"" xml << "\n\t\t<property name=\"" << p->name << "\""
<< " type=\"" << p->type << "\"" << " type=\"" << p->type << "\""
<< " access=\"" << access << "\"/>"; << " access=\"" << access << "\"/>";
} }
for (const IntrospectedMethod *m = intro->methods; m->args; ++m) for (const IntrospectedMethod *m = intro->methods; m->args; ++m)
{ {
xml << "\n\t\t<method name=\"" << m->name << "\">"; xml << "\n\t\t<method name=\"" << m->name << "\">";
for (const IntrospectedArgument *a = m->args; a->type; ++a) for (const IntrospectedArgument *a = m->args; a->type; ++a)
{ {
xml << "\n\t\t\t<arg direction=\"" << (a->in ? "in" : "out") << "\"" xml << "\n\t\t\t<arg direction=\"" << (a->in ? "in" : "out") << "\""
<< " type=\"" << a->type << "\""; << " type=\"" << a->type << "\"";
if (a->name) xml << " name=\"" << a->name << "\""; if (a->name) xml << " name=\"" << a->name << "\"";
xml << "/>"; xml << "/>";
} }
xml << "\n\t\t</method>"; xml << "\n\t\t</method>";
} }
for (const IntrospectedMethod *m = intro->signals; m->args; ++m) for (const IntrospectedMethod *m = intro->signals; m->args; ++m)
{ {
xml << "\n\t\t<signal name=\"" << m->name << "\">"; xml << "\n\t\t<signal name=\"" << m->name << "\">";
for (const IntrospectedArgument *a = m->args; a->type; ++a) for (const IntrospectedArgument *a = m->args; a->type; ++a)
{ {
xml << "<arg type=\"" << a->type << "\""; xml << "<arg type=\"" << a->type << "\"";
if (a->name) xml << " name=\"" << a->name << "\""; if (a->name) xml << " name=\"" << a->name << "\"";
xml << "/>"; xml << "/>";
} }
xml << "\n\t\t</signal>"; xml << "\n\t\t</signal>";
} }
xml << "\n\t</interface>"; xml << "\n\t</interface>";
} }
} }
const ObjectPathList nodes = ObjectAdaptor::child_nodes_from_prefix(path + '/'); const ObjectPathList nodes = ObjectAdaptor::child_nodes_from_prefix(path + '/');
ObjectPathList::const_iterator oni; ObjectPathList::const_iterator oni;
for (oni = nodes.begin(); oni != nodes.end(); ++oni) for (oni = nodes.begin(); oni != nodes.end(); ++oni)
{ {
xml << "\n\t<node name=\"" << (*oni) << "\"/>"; xml << "\n\t<node name=\"" << (*oni) << "\"/>";
} }
/* broken /* broken
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/'); const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/');
ObjectAdaptorPList::const_iterator oci; ObjectAdaptorPList::const_iterator oci;
for (oci = children.begin(); oci != children.end(); ++oci) for (oci = children.begin(); oci != children.end(); ++oci)
{ {
std::string name = (*oci)->path().substr(path.length()+1); std::string name = (*oci)->path().substr(path.length()+1);
name.substr(name.find('/')); name.substr(name.find('/'));
xml << "<node name=\"" << name << "\"/>"; xml << "<node name=\"" << name << "\"/>";
} }
*/ */
xml << "\n</node>"; xml << "\n</node>";
ReturnMessage reply(call); ReturnMessage reply(call);
MessageIter wi = reply.writer(); MessageIter wi = reply.writer();
wi.append_string(xml.str().c_str()); wi.append_string(xml.str().c_str());
return reply; return reply;
} }
IntrospectedInterface * IntrospectableAdaptor::introspect() const IntrospectedInterface *IntrospectableAdaptor::introspect() const
{ {
static IntrospectedArgument Introspect_args[] = static IntrospectedArgument Introspect_args[] =
{ {
{ "data", "s", false }, { "data", "s", false },
{ 0, 0, 0 } { 0, 0, 0 }
}; };
static IntrospectedMethod Introspectable_methods[] = static IntrospectedMethod Introspectable_methods[] =
{ {
{ "Introspect", Introspect_args }, { "Introspect", Introspect_args },
{ 0, 0 } { 0, 0 }
}; };
static IntrospectedMethod Introspectable_signals[] = static IntrospectedMethod Introspectable_signals[] =
{ {
{ 0, 0 } { 0, 0 }
}; };
static IntrospectedProperty Introspectable_properties[] = static IntrospectedProperty Introspectable_properties[] =
{ {
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
static IntrospectedInterface Introspectable_interface = static IntrospectedInterface Introspectable_interface =
{ {
introspectable_name, introspectable_name,
Introspectable_methods, Introspectable_methods,
Introspectable_signals, Introspectable_signals,
Introspectable_properties Introspectable_properties
}; };
return &Introspectable_interface; return &Introspectable_interface;
} }
IntrospectableProxy::IntrospectableProxy() IntrospectableProxy::IntrospectableProxy()
: InterfaceProxy(introspectable_name) : InterfaceProxy(introspectable_name)
{} {}
std::string IntrospectableProxy::Introspect() std::string IntrospectableProxy::Introspect()
{ {
DBus::CallMessage call; DBus::CallMessage call;
call.member("Introspect"); call.member("Introspect");
DBus::Message ret = invoke_method(call); DBus::Message ret = invoke_method(call);
DBus::MessageIter ri = ret.reader(); DBus::MessageIter ri = ret.reader();
const char *str = ri.get_string(); const char *str = ri.get_string();
return str; return str;
} }

View file

@ -40,475 +40,475 @@ using namespace DBus;
int MessageIter::type() int MessageIter::type()
{ {
return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter); return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter);
} }
bool MessageIter::at_end() bool MessageIter::at_end()
{ {
return type() == DBUS_TYPE_INVALID; return type() == DBUS_TYPE_INVALID;
} }
bool MessageIter::has_next() bool MessageIter::has_next()
{ {
return dbus_message_iter_has_next((DBusMessageIter *)&_iter); return dbus_message_iter_has_next((DBusMessageIter *)&_iter);
} }
MessageIter &MessageIter::operator ++() MessageIter &MessageIter::operator ++()
{ {
dbus_message_iter_next((DBusMessageIter *)&_iter); dbus_message_iter_next((DBusMessageIter *)&_iter);
return (*this); return (*this);
} }
MessageIter MessageIter::operator ++(int) MessageIter MessageIter::operator ++(int)
{ {
MessageIter copy(*this); MessageIter copy(*this);
++(*this); ++(*this);
return copy; return copy;
} }
bool MessageIter::append_basic(int type_id, void *value) bool MessageIter::append_basic(int type_id, void *value)
{ {
return dbus_message_iter_append_basic((DBusMessageIter *)&_iter, type_id, value); return dbus_message_iter_append_basic((DBusMessageIter *)&_iter, type_id, value);
} }
void MessageIter::get_basic(int type_id, void *ptr) void MessageIter::get_basic(int type_id, void *ptr)
{ {
if (type() != type_id) if (type() != type_id)
throw ErrorInvalidArgs("type mismatch"); throw ErrorInvalidArgs("type mismatch");
dbus_message_iter_get_basic((DBusMessageIter *)_iter, ptr); dbus_message_iter_get_basic((DBusMessageIter *)_iter, ptr);
} }
bool MessageIter::append_byte(unsigned char b) bool MessageIter::append_byte(unsigned char b)
{ {
return append_basic(DBUS_TYPE_BYTE, &b); return append_basic(DBUS_TYPE_BYTE, &b);
} }
unsigned char MessageIter::get_byte() unsigned char MessageIter::get_byte()
{ {
unsigned char b; unsigned char b;
get_basic(DBUS_TYPE_BYTE, &b); get_basic(DBUS_TYPE_BYTE, &b);
return b; return b;
} }
bool MessageIter::append_bool(bool b) bool MessageIter::append_bool(bool b)
{ {
dbus_bool_t db = b; dbus_bool_t db = b;
return append_basic(DBUS_TYPE_BOOLEAN, &db); return append_basic(DBUS_TYPE_BOOLEAN, &db);
} }
bool MessageIter::get_bool() bool MessageIter::get_bool()
{ {
dbus_bool_t db; dbus_bool_t db;
get_basic(DBUS_TYPE_BOOLEAN, &db); get_basic(DBUS_TYPE_BOOLEAN, &db);
return (bool)db; return (bool)db;
} }
bool MessageIter::append_int16(signed short i) bool MessageIter::append_int16(signed short i)
{ {
return append_basic(DBUS_TYPE_INT16, &i); return append_basic(DBUS_TYPE_INT16, &i);
} }
signed short MessageIter::get_int16() signed short MessageIter::get_int16()
{ {
signed short i; signed short i;
get_basic(DBUS_TYPE_INT16, &i); get_basic(DBUS_TYPE_INT16, &i);
return i; return i;
} }
bool MessageIter::append_uint16(unsigned short u) bool MessageIter::append_uint16(unsigned short u)
{ {
return append_basic(DBUS_TYPE_UINT16, &u); return append_basic(DBUS_TYPE_UINT16, &u);
} }
unsigned short MessageIter::get_uint16() unsigned short MessageIter::get_uint16()
{ {
unsigned short u; unsigned short u;
get_basic(DBUS_TYPE_UINT16, &u); get_basic(DBUS_TYPE_UINT16, &u);
return u; return u;
} }
bool MessageIter::append_int32(signed int i) bool MessageIter::append_int32(signed int i)
{ {
return append_basic(DBUS_TYPE_INT32, &i); return append_basic(DBUS_TYPE_INT32, &i);
} }
signed int MessageIter::get_int32() signed int MessageIter::get_int32()
{ {
signed int i; signed int i;
get_basic(DBUS_TYPE_INT32, &i); get_basic(DBUS_TYPE_INT32, &i);
return i; return i;
} }
bool MessageIter::append_uint32(unsigned int u) bool MessageIter::append_uint32(unsigned int u)
{ {
return append_basic(DBUS_TYPE_UINT32, &u); return append_basic(DBUS_TYPE_UINT32, &u);
} }
unsigned int MessageIter::get_uint32() unsigned int MessageIter::get_uint32()
{ {
unsigned int u; unsigned int u;
get_basic(DBUS_TYPE_UINT32, &u); get_basic(DBUS_TYPE_UINT32, &u);
return u; return u;
} }
signed long long MessageIter::get_int64() signed long long MessageIter::get_int64()
{ {
signed long long i; signed long long i;
get_basic(DBUS_TYPE_INT64, &i); get_basic(DBUS_TYPE_INT64, &i);
return i; return i;
} }
bool MessageIter::append_int64(signed long long i) bool MessageIter::append_int64(signed long long i)
{ {
return append_basic(DBUS_TYPE_INT64, &i); return append_basic(DBUS_TYPE_INT64, &i);
} }
unsigned long long MessageIter::get_uint64() unsigned long long MessageIter::get_uint64()
{ {
unsigned long long u; unsigned long long u;
get_basic(DBUS_TYPE_UINT64, &u); get_basic(DBUS_TYPE_UINT64, &u);
return u; return u;
} }
bool MessageIter::append_uint64(unsigned long long u) bool MessageIter::append_uint64(unsigned long long u)
{ {
return append_basic(DBUS_TYPE_UINT64, &u); return append_basic(DBUS_TYPE_UINT64, &u);
} }
double MessageIter::get_double() double MessageIter::get_double()
{ {
double d; double d;
get_basic(DBUS_TYPE_DOUBLE, &d); get_basic(DBUS_TYPE_DOUBLE, &d);
return d; return d;
} }
bool MessageIter::append_double(double d) bool MessageIter::append_double(double d)
{ {
return append_basic(DBUS_TYPE_DOUBLE, &d); return append_basic(DBUS_TYPE_DOUBLE, &d);
} }
bool MessageIter::append_string(const char *chars) bool MessageIter::append_string(const char *chars)
{ {
return append_basic(DBUS_TYPE_STRING, &chars); return append_basic(DBUS_TYPE_STRING, &chars);
} }
const char *MessageIter::get_string() const char *MessageIter::get_string()
{ {
char *chars; char *chars;
get_basic(DBUS_TYPE_STRING, &chars); get_basic(DBUS_TYPE_STRING, &chars);
return chars; return chars;
} }
bool MessageIter::append_path(const char *chars) bool MessageIter::append_path(const char *chars)
{ {
return append_basic(DBUS_TYPE_OBJECT_PATH, &chars); return append_basic(DBUS_TYPE_OBJECT_PATH, &chars);
} }
const char *MessageIter::get_path() const char *MessageIter::get_path()
{ {
char *chars; char *chars;
get_basic(DBUS_TYPE_OBJECT_PATH, &chars); get_basic(DBUS_TYPE_OBJECT_PATH, &chars);
return chars; return chars;
} }
bool MessageIter::append_signature(const char *chars) bool MessageIter::append_signature(const char *chars)
{ {
return append_basic(DBUS_TYPE_SIGNATURE, &chars); return append_basic(DBUS_TYPE_SIGNATURE, &chars);
} }
const char *MessageIter::get_signature() const char *MessageIter::get_signature()
{ {
char *chars; char *chars;
get_basic(DBUS_TYPE_SIGNATURE, &chars); get_basic(DBUS_TYPE_SIGNATURE, &chars);
return chars; return chars;
} }
MessageIter MessageIter::recurse() MessageIter MessageIter::recurse()
{ {
MessageIter iter(msg()); MessageIter iter(msg());
dbus_message_iter_recurse((DBusMessageIter *)&_iter, (DBusMessageIter *)&(iter._iter)); dbus_message_iter_recurse((DBusMessageIter *)&_iter, (DBusMessageIter *) & (iter._iter));
return iter; return iter;
} }
char *MessageIter::signature() const char *MessageIter::signature() const
{ {
return dbus_message_iter_get_signature((DBusMessageIter *)&_iter); return dbus_message_iter_get_signature((DBusMessageIter *)&_iter);
} }
bool MessageIter::append_array(char type, const void *ptr, size_t length) bool MessageIter::append_array(char type, const void *ptr, size_t length)
{ {
return dbus_message_iter_append_fixed_array((DBusMessageIter *)&_iter, type, &ptr, length); return dbus_message_iter_append_fixed_array((DBusMessageIter *)&_iter, type, &ptr, length);
} }
int MessageIter::array_type() int MessageIter::array_type()
{ {
return dbus_message_iter_get_element_type((DBusMessageIter *)&_iter); return dbus_message_iter_get_element_type((DBusMessageIter *)&_iter);
} }
int MessageIter::get_array(void *ptr) int MessageIter::get_array(void *ptr)
{ {
int length; int length;
dbus_message_iter_get_fixed_array((DBusMessageIter *)&_iter, ptr, &length); dbus_message_iter_get_fixed_array((DBusMessageIter *)&_iter, ptr, &length);
return length; return length;
} }
bool MessageIter::is_array() bool MessageIter::is_array()
{ {
return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter) == DBUS_TYPE_ARRAY; return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter) == DBUS_TYPE_ARRAY;
} }
bool MessageIter::is_dict() bool MessageIter::is_dict()
{ {
return is_array() && dbus_message_iter_get_element_type((DBusMessageIter *)_iter) == DBUS_TYPE_DICT_ENTRY; return is_array() && dbus_message_iter_get_element_type((DBusMessageIter *)_iter) == DBUS_TYPE_DICT_ENTRY;
} }
MessageIter MessageIter::new_array(const char *sig) MessageIter MessageIter::new_array(const char *sig)
{ {
MessageIter arr(msg()); MessageIter arr(msg());
dbus_message_iter_open_container( dbus_message_iter_open_container(
(DBusMessageIter *)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *)&(arr._iter) (DBusMessageIter *)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *) & (arr._iter)
); );
return arr; return arr;
} }
MessageIter MessageIter::new_variant(const char *sig) MessageIter MessageIter::new_variant(const char *sig)
{ {
MessageIter var(msg()); MessageIter var(msg());
dbus_message_iter_open_container( dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *)&(var._iter) (DBusMessageIter *)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *) & (var._iter)
); );
return var; return var;
} }
MessageIter MessageIter::new_struct() MessageIter MessageIter::new_struct()
{ {
MessageIter stu(msg()); MessageIter stu(msg());
dbus_message_iter_open_container( dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *)&(stu._iter) (DBusMessageIter *)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *) & (stu._iter)
); );
return stu; return stu;
} }
MessageIter MessageIter::new_dict_entry() MessageIter MessageIter::new_dict_entry()
{ {
MessageIter ent(msg()); MessageIter ent(msg());
dbus_message_iter_open_container( dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *)&(ent._iter) (DBusMessageIter *)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *) & (ent._iter)
); );
return ent; return ent;
} }
void MessageIter::close_container(MessageIter &container) void MessageIter::close_container(MessageIter &container)
{ {
dbus_message_iter_close_container((DBusMessageIter *)&_iter, (DBusMessageIter *)&(container._iter)); dbus_message_iter_close_container((DBusMessageIter *)&_iter, (DBusMessageIter *) & (container._iter));
} }
static bool is_basic_type(int typecode) static bool is_basic_type(int typecode)
{ {
switch (typecode) switch (typecode)
{ {
case 'y': case 'y':
case 'b': case 'b':
case 'n': case 'n':
case 'q': case 'q':
case 'i': case 'i':
case 'u': case 'u':
case 'x': case 'x':
case 't': case 't':
case 'd': case 'd':
case 's': case 's':
case 'o': case 'o':
case 'g': case 'g':
return true; return true;
default: default:
return false; return false;
} }
} }
void MessageIter::copy_data(MessageIter &to) void MessageIter::copy_data(MessageIter &to)
{ {
for (MessageIter &from = *this; !from.at_end(); ++from) for (MessageIter &from = *this; !from.at_end(); ++from)
{ {
if (is_basic_type(from.type())) if (is_basic_type(from.type()))
{ {
debug_log("copying basic type: %c", from.type()); debug_log("copying basic type: %c", from.type());
unsigned char value[8]; unsigned char value[8];
from.get_basic(from.type(), &value); from.get_basic(from.type(), &value);
to.append_basic(from.type(), &value); to.append_basic(from.type(), &value);
} }
else else
{ {
MessageIter from_container = from.recurse(); MessageIter from_container = from.recurse();
char *sig = from_container.signature(); char *sig = from_container.signature();
debug_log("copying compound type: %c[%s]", from.type(), sig); debug_log("copying compound type: %c[%s]", from.type(), sig);
MessageIter to_container (to.msg()); MessageIter to_container(to.msg());
dbus_message_iter_open_container dbus_message_iter_open_container
( (
(DBusMessageIter *)&(to._iter), (DBusMessageIter *) & (to._iter),
from.type(), from.type(),
from.type() == DBUS_TYPE_VARIANT ? NULL : sig, from.type() == DBUS_TYPE_VARIANT ? NULL : sig,
(DBusMessageIter *)&(to_container._iter) (DBusMessageIter *) & (to_container._iter)
); );
from_container.copy_data(to_container); from_container.copy_data(to_container);
to.close_container(to_container); to.close_container(to_container);
free(sig); free(sig);
} }
} }
} }
/* /*
*/ */
Message::Message() Message::Message()
: _pvt(new Private) : _pvt(new Private)
{ {
} }
Message::Message(Message::Private *p, bool incref) Message::Message(Message::Private *p, bool incref)
: _pvt(p) : _pvt(p)
{ {
if (_pvt->msg && incref) dbus_message_ref(_pvt->msg); if (_pvt->msg && incref) dbus_message_ref(_pvt->msg);
} }
Message::Message(const Message &m) Message::Message(const Message &m)
: _pvt(m._pvt) : _pvt(m._pvt)
{ {
dbus_message_ref(_pvt->msg); dbus_message_ref(_pvt->msg);
} }
Message::~Message() Message::~Message()
{ {
dbus_message_unref(_pvt->msg); dbus_message_unref(_pvt->msg);
} }
Message &Message::operator = (const Message &m) Message &Message::operator = (const Message &m)
{ {
if (&m != this) if (&m != this)
{ {
dbus_message_unref(_pvt->msg); dbus_message_unref(_pvt->msg);
_pvt = m._pvt; _pvt = m._pvt;
dbus_message_ref(_pvt->msg); dbus_message_ref(_pvt->msg);
} }
return *this; return *this;
} }
Message Message::copy() Message Message::copy()
{ {
Private *pvt = new Private(dbus_message_copy(_pvt->msg)); Private *pvt = new Private(dbus_message_copy(_pvt->msg));
return Message(pvt); return Message(pvt);
} }
bool Message::append(int first_type, ...) bool Message::append(int first_type, ...)
{ {
va_list vl; va_list vl;
va_start(vl, first_type); va_start(vl, first_type);
bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl); bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl);
va_end(vl); va_end(vl);
return b; return b;
} }
void Message::terminate() void Message::terminate()
{ {
dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID); dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID);
} }
int Message::type() const int Message::type() const
{ {
return dbus_message_get_type(_pvt->msg); return dbus_message_get_type(_pvt->msg);
} }
int Message::serial() const int Message::serial() const
{ {
return dbus_message_get_serial(_pvt->msg); return dbus_message_get_serial(_pvt->msg);
} }
int Message::reply_serial() const int Message::reply_serial() const
{ {
return dbus_message_get_reply_serial(_pvt->msg); return dbus_message_get_reply_serial(_pvt->msg);
} }
bool Message::reply_serial(int s) bool Message::reply_serial(int s)
{ {
return dbus_message_set_reply_serial(_pvt->msg, s); return dbus_message_set_reply_serial(_pvt->msg, s);
} }
const char *Message::sender() const const char *Message::sender() const
{ {
return dbus_message_get_sender(_pvt->msg); return dbus_message_get_sender(_pvt->msg);
} }
bool Message::sender(const char *s) bool Message::sender(const char *s)
{ {
return dbus_message_set_sender(_pvt->msg, s); return dbus_message_set_sender(_pvt->msg, s);
} }
const char *Message::destination() const const char *Message::destination() const
{ {
return dbus_message_get_destination(_pvt->msg); return dbus_message_get_destination(_pvt->msg);
} }
bool Message::destination(const char *s) bool Message::destination(const char *s)
{ {
return dbus_message_set_destination(_pvt->msg, s); return dbus_message_set_destination(_pvt->msg, s);
} }
bool Message::is_error() const bool Message::is_error() const
{ {
return type() == DBUS_MESSAGE_TYPE_ERROR; return type() == DBUS_MESSAGE_TYPE_ERROR;
} }
bool Message::is_signal(const char *interface, const char *member) const bool Message::is_signal(const char *interface, const char *member) const
{ {
return dbus_message_is_signal(_pvt->msg, interface, member); return dbus_message_is_signal(_pvt->msg, interface, member);
} }
MessageIter Message::writer() MessageIter Message::writer()
{ {
MessageIter iter(*this); MessageIter iter(*this);
dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *)&(iter._iter)); dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *) & (iter._iter));
return iter; return iter;
} }
MessageIter Message::reader() const MessageIter Message::reader() const
{ {
MessageIter iter(const_cast<Message &>(*this)); MessageIter iter(const_cast<Message &>(*this));
dbus_message_iter_init(_pvt->msg, (DBusMessageIter *)&(iter._iter)); dbus_message_iter_init(_pvt->msg, (DBusMessageIter *) & (iter._iter));
return iter; return iter;
} }
/* /*
*/ */
ErrorMessage::ErrorMessage() ErrorMessage::ErrorMessage()
{ {
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
} }
ErrorMessage::ErrorMessage(const Message &to_reply, const char *name, const char *message) ErrorMessage::ErrorMessage(const Message &to_reply, const char *name, const char *message)
{ {
_pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message); _pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message);
} }
bool ErrorMessage::operator == (const ErrorMessage &m) const bool ErrorMessage::operator == (const ErrorMessage &m) const
{ {
return dbus_message_is_error(_pvt->msg, m.name()); return dbus_message_is_error(_pvt->msg, m.name());
} }
const char *ErrorMessage::name() const const char *ErrorMessage::name() const
{ {
return dbus_message_get_error_name(_pvt->msg); return dbus_message_get_error_name(_pvt->msg);
} }
bool ErrorMessage::name(const char *n) bool ErrorMessage::name(const char *n)
{ {
return dbus_message_set_error_name(_pvt->msg, n); return dbus_message_set_error_name(_pvt->msg, n);
} }
/* /*
@ -516,55 +516,55 @@ bool ErrorMessage::name(const char *n)
SignalMessage::SignalMessage(const char *name) SignalMessage::SignalMessage(const char *name)
{ {
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
member(name); member(name);
} }
SignalMessage::SignalMessage(const char *path, const char *interface, const char *name) SignalMessage::SignalMessage(const char *path, const char *interface, const char *name)
{ {
_pvt->msg = dbus_message_new_signal(path, interface, name); _pvt->msg = dbus_message_new_signal(path, interface, name);
} }
bool SignalMessage::operator == (const SignalMessage &m) const bool SignalMessage::operator == (const SignalMessage &m) const
{ {
return dbus_message_is_signal(_pvt->msg, m.interface(), m.member()); return dbus_message_is_signal(_pvt->msg, m.interface(), m.member());
} }
const char *SignalMessage::interface() const const char *SignalMessage::interface() const
{ {
return dbus_message_get_interface(_pvt->msg); return dbus_message_get_interface(_pvt->msg);
} }
bool SignalMessage::interface(const char *i) bool SignalMessage::interface(const char *i)
{ {
return dbus_message_set_interface(_pvt->msg, i); return dbus_message_set_interface(_pvt->msg, i);
} }
const char *SignalMessage::member() const const char *SignalMessage::member() const
{ {
return dbus_message_get_member(_pvt->msg); return dbus_message_get_member(_pvt->msg);
} }
bool SignalMessage::member(const char *m) bool SignalMessage::member(const char *m)
{ {
return dbus_message_set_member(_pvt->msg, m); return dbus_message_set_member(_pvt->msg, m);
} }
const char *SignalMessage::path() const const char *SignalMessage::path() const
{ {
return dbus_message_get_path(_pvt->msg); return dbus_message_get_path(_pvt->msg);
} }
char ** SignalMessage::path_split() const char **SignalMessage::path_split() const
{ {
char ** p; char **p;
dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ? dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ?
return p; return p;
} }
bool SignalMessage::path(const char *p) bool SignalMessage::path(const char *p)
{ {
return dbus_message_set_path(_pvt->msg, p); return dbus_message_set_path(_pvt->msg, p);
} }
/* /*
@ -572,59 +572,59 @@ bool SignalMessage::path(const char *p)
CallMessage::CallMessage() CallMessage::CallMessage()
{ {
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL); _pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
} }
CallMessage::CallMessage(const char *dest, const char *path, const char *iface, const char *method) CallMessage::CallMessage(const char *dest, const char *path, const char *iface, const char *method)
{ {
_pvt->msg = dbus_message_new_method_call(dest, path, iface, method); _pvt->msg = dbus_message_new_method_call(dest, path, iface, method);
} }
bool CallMessage::operator == (const CallMessage &m) const bool CallMessage::operator == (const CallMessage &m) const
{ {
return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member()); return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member());
} }
const char *CallMessage::interface() const const char *CallMessage::interface() const
{ {
return dbus_message_get_interface(_pvt->msg); return dbus_message_get_interface(_pvt->msg);
} }
bool CallMessage::interface(const char *i) bool CallMessage::interface(const char *i)
{ {
return dbus_message_set_interface(_pvt->msg, i); return dbus_message_set_interface(_pvt->msg, i);
} }
const char *CallMessage::member() const const char *CallMessage::member() const
{ {
return dbus_message_get_member(_pvt->msg); return dbus_message_get_member(_pvt->msg);
} }
bool CallMessage::member(const char *m) bool CallMessage::member(const char *m)
{ {
return dbus_message_set_member(_pvt->msg, m); return dbus_message_set_member(_pvt->msg, m);
} }
const char *CallMessage::path() const const char *CallMessage::path() const
{ {
return dbus_message_get_path(_pvt->msg); return dbus_message_get_path(_pvt->msg);
} }
char ** CallMessage::path_split() const char **CallMessage::path_split() const
{ {
char ** p; char **p;
dbus_message_get_path_decomposed(_pvt->msg, &p); dbus_message_get_path_decomposed(_pvt->msg, &p);
return p; return p;
} }
bool CallMessage::path(const char *p) bool CallMessage::path(const char *p)
{ {
return dbus_message_set_path(_pvt->msg, p); return dbus_message_set_path(_pvt->msg, p);
} }
const char *CallMessage::signature() const const char *CallMessage::signature() const
{ {
return dbus_message_get_signature(_pvt->msg); return dbus_message_get_signature(_pvt->msg);
} }
/* /*
@ -632,11 +632,11 @@ const char *CallMessage::signature() const
ReturnMessage::ReturnMessage(const CallMessage &callee) ReturnMessage::ReturnMessage(const CallMessage &callee)
{ {
_pvt = new Private(dbus_message_new_method_return(callee._pvt->msg)); _pvt = new Private(dbus_message_new_method_return(callee._pvt->msg));
} }
const char *ReturnMessage::signature() const const char *ReturnMessage::signature() const
{ {
return dbus_message_get_signature(_pvt->msg); return dbus_message_get_signature(_pvt->msg);
} }

View file

@ -34,17 +34,18 @@
#include <dbus/dbus.h> #include <dbus/dbus.h>
namespace DBus { namespace DBus
{
struct DXXAPILOCAL Message::Private struct DXXAPILOCAL Message::Private
{ {
DBusMessage *msg; DBusMessage *msg;
Private() : msg(0) Private() : msg(0)
{} {}
Private(DBusMessage *m) : msg(m) Private(DBusMessage *m) : msg(m)
{} {}
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -40,7 +40,7 @@
using namespace DBus; using namespace DBus;
Object::Object(Connection &conn, const Path &path, const char *service) Object::Object(Connection &conn, const Path &path, const char *service)
: _conn(conn), _path(path), _service(service ? service : ""), _default_timeout(-1) : _conn(conn), _path(path), _service(service ? service : ""), _default_timeout(-1)
{ {
} }
@ -50,53 +50,53 @@ Object::~Object()
void Object::set_timeout(int new_timeout) void Object::set_timeout(int new_timeout)
{ {
debug_log("%s: %d millies", __PRETTY_FUNCTION__, new_timeout); debug_log("%s: %d millies", __PRETTY_FUNCTION__, new_timeout);
if(new_timeout < 0 && new_timeout != -1) if (new_timeout < 0 && new_timeout != -1)
throw ErrorInvalidArgs("Bad timeout, cannot set it"); throw ErrorInvalidArgs("Bad timeout, cannot set it");
_default_timeout = new_timeout; _default_timeout = new_timeout;
} }
struct ObjectAdaptor::Private struct ObjectAdaptor::Private
{ {
static void unregister_function_stub(DBusConnection *, void *); static void unregister_function_stub(DBusConnection *, void *);
static DBusHandlerResult message_function_stub(DBusConnection *, DBusMessage *, void *); static DBusHandlerResult message_function_stub(DBusConnection *, DBusMessage *, void *);
}; };
static DBusObjectPathVTable _vtable = static DBusObjectPathVTable _vtable =
{ {
ObjectAdaptor::Private::unregister_function_stub, ObjectAdaptor::Private::unregister_function_stub,
ObjectAdaptor::Private::message_function_stub, ObjectAdaptor::Private::message_function_stub,
NULL, NULL, NULL, NULL NULL, NULL, NULL, NULL
}; };
void ObjectAdaptor::Private::unregister_function_stub(DBusConnection *conn, void *data) void ObjectAdaptor::Private::unregister_function_stub(DBusConnection *conn, void *data)
{ {
//TODO: what do we have to do here ? //TODO: what do we have to do here ?
} }
DBusHandlerResult ObjectAdaptor::Private::message_function_stub(DBusConnection *, DBusMessage *dmsg, void *data) DBusHandlerResult ObjectAdaptor::Private::message_function_stub(DBusConnection *, DBusMessage *dmsg, void *data)
{ {
ObjectAdaptor *o = static_cast<ObjectAdaptor *>(data); ObjectAdaptor *o = static_cast<ObjectAdaptor *>(data);
if (o) if (o)
{ {
Message msg(new Message::Private(dmsg)); Message msg(new Message::Private(dmsg));
debug_log("in object %s", o->path().c_str()); debug_log("in object %s", o->path().c_str());
debug_log(" got message #%d from %s to %s", debug_log(" got message #%d from %s to %s",
msg.serial(), msg.serial(),
msg.sender(), msg.sender(),
msg.destination() msg.destination()
); );
return o->handle_message(msg) return o->handle_message(msg)
? DBUS_HANDLER_RESULT_HANDLED ? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED; : DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
} }
else else
{ {
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
} }
} }
typedef std::map<Path, ObjectAdaptor *> ObjectAdaptorTable; typedef std::map<Path, ObjectAdaptor *> ObjectAdaptorTable;
@ -104,282 +104,282 @@ static ObjectAdaptorTable _adaptor_table;
ObjectAdaptor *ObjectAdaptor::from_path(const Path &path) ObjectAdaptor *ObjectAdaptor::from_path(const Path &path)
{ {
ObjectAdaptorTable::iterator ati = _adaptor_table.find(path); ObjectAdaptorTable::iterator ati = _adaptor_table.find(path);
if (ati != _adaptor_table.end()) if (ati != _adaptor_table.end())
return ati->second; return ati->second;
return NULL; return NULL;
} }
ObjectAdaptorPList ObjectAdaptor::from_path_prefix(const std::string &prefix) ObjectAdaptorPList ObjectAdaptor::from_path_prefix(const std::string &prefix)
{ {
ObjectAdaptorPList ali; ObjectAdaptorPList ali;
ObjectAdaptorTable::iterator ati = _adaptor_table.begin(); ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
size_t plen = prefix.length(); size_t plen = prefix.length();
while (ati != _adaptor_table.end()) while (ati != _adaptor_table.end())
{ {
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen)) if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
ali.push_back(ati->second); ali.push_back(ati->second);
++ati; ++ati;
} }
return ali; return ali;
} }
ObjectPathList ObjectAdaptor::child_nodes_from_prefix(const std::string &prefix) ObjectPathList ObjectAdaptor::child_nodes_from_prefix(const std::string &prefix)
{ {
ObjectPathList ali; ObjectPathList ali;
ObjectAdaptorTable::iterator ati = _adaptor_table.begin(); ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
size_t plen = prefix.length(); size_t plen = prefix.length();
while (ati != _adaptor_table.end()) while (ati != _adaptor_table.end())
{ {
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen)) if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
{ {
std::string p = ati->second->path().substr(plen); std::string p = ati->second->path().substr(plen);
p = p.substr(0,p.find('/')); p = p.substr(0, p.find('/'));
ali.push_back(p); ali.push_back(p);
} }
++ati; ++ati;
} }
ali.sort(); ali.sort();
ali.unique(); ali.unique();
return ali; return ali;
} }
ObjectAdaptor::ObjectAdaptor(Connection &conn, const Path &path) ObjectAdaptor::ObjectAdaptor(Connection &conn, const Path &path)
: Object(conn, path, conn.unique_name()) : Object(conn, path, conn.unique_name())
{ {
register_obj(); register_obj();
} }
ObjectAdaptor::~ObjectAdaptor() ObjectAdaptor::~ObjectAdaptor()
{ {
unregister_obj(false); unregister_obj(false);
} }
void ObjectAdaptor::register_obj() void ObjectAdaptor::register_obj()
{ {
debug_log("registering local object %s", path().c_str()); debug_log("registering local object %s", path().c_str());
if (!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this)) if (!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this))
{ {
throw ErrorNoMemory("unable to register object path"); throw ErrorNoMemory("unable to register object path");
} }
_adaptor_table[path()] = this; _adaptor_table[path()] = this;
} }
void ObjectAdaptor::unregister_obj(bool) void ObjectAdaptor::unregister_obj(bool)
{ {
_adaptor_table.erase(path()); _adaptor_table.erase(path());
debug_log("unregistering local object %s", path().c_str()); debug_log("unregistering local object %s", path().c_str());
dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str()); dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str());
} }
void ObjectAdaptor::_emit_signal(SignalMessage &sig) void ObjectAdaptor::_emit_signal(SignalMessage &sig)
{ {
sig.path(path().c_str()); sig.path(path().c_str());
conn().send(sig); conn().send(sig);
} }
struct ReturnLaterError struct ReturnLaterError
{ {
const Tag *tag; const Tag *tag;
}; };
bool ObjectAdaptor::handle_message(const Message &msg) bool ObjectAdaptor::handle_message(const Message &msg)
{ {
switch (msg.type()) switch (msg.type())
{ {
case DBUS_MESSAGE_TYPE_METHOD_CALL: case DBUS_MESSAGE_TYPE_METHOD_CALL:
{ {
const CallMessage &cmsg = reinterpret_cast<const CallMessage &>(msg); const CallMessage &cmsg = reinterpret_cast<const CallMessage &>(msg);
const char *member = cmsg.member(); const char *member = cmsg.member();
const char *interface = cmsg.interface(); const char *interface = cmsg.interface();
debug_log(" invoking method %s.%s", interface, member); debug_log(" invoking method %s.%s", interface, member);
InterfaceAdaptor *ii = find_interface(interface); InterfaceAdaptor *ii = find_interface(interface);
if (ii) if (ii)
{ {
try try
{ {
Message ret = ii->dispatch_method(cmsg); Message ret = ii->dispatch_method(cmsg);
conn().send(ret); conn().send(ret);
} }
catch(Error &e) catch (Error &e)
{ {
ErrorMessage em(cmsg, e.name(), e.message()); ErrorMessage em(cmsg, e.name(), e.message());
conn().send(em); conn().send(em);
} }
catch(ReturnLaterError &rle) catch (ReturnLaterError &rle)
{ {
_continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag); _continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag);
} }
return true; return true;
} }
else else
{ {
return false; return false;
} }
} }
default: default:
{ {
return false; return false;
} }
} }
} }
void ObjectAdaptor::return_later(const Tag *tag) void ObjectAdaptor::return_later(const Tag *tag)
{ {
ReturnLaterError rle = { tag }; ReturnLaterError rle = { tag };
throw rle; throw rle;
} }
void ObjectAdaptor::return_now(Continuation *ret) void ObjectAdaptor::return_now(Continuation *ret)
{ {
ret->_conn.send(ret->_return); ret->_conn.send(ret->_return);
ContinuationMap::iterator di = _continuations.find(ret->_tag); ContinuationMap::iterator di = _continuations.find(ret->_tag);
delete di->second; delete di->second;
_continuations.erase(di); _continuations.erase(di);
} }
void ObjectAdaptor::return_error(Continuation *ret, const Error error) void ObjectAdaptor::return_error(Continuation *ret, const Error error)
{ {
ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message())); ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message()));
ContinuationMap::iterator di = _continuations.find(ret->_tag); ContinuationMap::iterator di = _continuations.find(ret->_tag);
delete di->second; delete di->second;
_continuations.erase(di); _continuations.erase(di);
} }
ObjectAdaptor::Continuation *ObjectAdaptor::find_continuation(const Tag *tag) ObjectAdaptor::Continuation *ObjectAdaptor::find_continuation(const Tag *tag)
{ {
ContinuationMap::iterator di = _continuations.find(tag); ContinuationMap::iterator di = _continuations.find(tag);
return di != _continuations.end() ? di->second : NULL; return di != _continuations.end() ? di->second : NULL;
} }
ObjectAdaptor::Continuation::Continuation(Connection &conn, const CallMessage &call, const Tag *tag) ObjectAdaptor::Continuation::Continuation(Connection &conn, const CallMessage &call, const Tag *tag)
: _conn(conn), _call(call), _return(_call), _tag(tag) : _conn(conn), _call(call), _return(_call), _tag(tag)
{ {
_writer = _return.writer(); //todo: verify _writer = _return.writer(); //todo: verify
} }
/* /*
*/ */
ObjectProxy::ObjectProxy(Connection &conn, const Path &path, const char *service) ObjectProxy::ObjectProxy(Connection &conn, const Path &path, const char *service)
: Object(conn, path, service) : Object(conn, path, service)
{ {
register_obj(); register_obj();
} }
ObjectProxy::~ObjectProxy() ObjectProxy::~ObjectProxy()
{ {
unregister_obj(false); unregister_obj(false);
} }
void ObjectProxy::register_obj() void ObjectProxy::register_obj()
{ {
debug_log("registering remote object %s", path().c_str()); debug_log("registering remote object %s", path().c_str());
_filtered = new Callback<ObjectProxy, bool, const Message &>(this, &ObjectProxy::handle_message); _filtered = new Callback<ObjectProxy, bool, const Message &>(this, &ObjectProxy::handle_message);
conn().add_filter(_filtered);
InterfaceProxyTable::const_iterator ii = _interfaces.begin(); conn().add_filter(_filtered);
while (ii != _interfaces.end())
{ InterfaceProxyTable::const_iterator ii = _interfaces.begin();
std::string im = "type='signal',interface='"+ii->first+"',path='"+path()+"'"; while (ii != _interfaces.end())
conn().add_match(im.c_str()); {
++ii; std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
} conn().add_match(im.c_str());
++ii;
}
} }
void ObjectProxy::unregister_obj(bool throw_on_error) void ObjectProxy::unregister_obj(bool throw_on_error)
{ {
debug_log("unregistering remote object %s", path().c_str()); debug_log("unregistering remote object %s", path().c_str());
InterfaceProxyTable::const_iterator ii = _interfaces.begin(); InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while (ii != _interfaces.end()) while (ii != _interfaces.end())
{ {
std::string im = "type='signal',interface='"+ii->first+"',path='"+path()+"'"; std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
conn().remove_match(im.c_str(), throw_on_error); conn().remove_match(im.c_str(), throw_on_error);
++ii; ++ii;
} }
conn().remove_filter(_filtered); conn().remove_filter(_filtered);
} }
Message ObjectProxy::_invoke_method(CallMessage &call) Message ObjectProxy::_invoke_method(CallMessage &call)
{ {
if (call.path() == NULL) if (call.path() == NULL)
call.path(path().c_str()); call.path(path().c_str());
if (call.destination() == NULL) if (call.destination() == NULL)
call.destination(service().c_str()); call.destination(service().c_str());
return conn().send_blocking(call, get_timeout()); return conn().send_blocking(call, get_timeout());
} }
bool ObjectProxy::_invoke_method_noreply(CallMessage &call) bool ObjectProxy::_invoke_method_noreply(CallMessage &call)
{ {
if (call.path() == NULL) if (call.path() == NULL)
call.path(path().c_str()); call.path(path().c_str());
if (call.destination() == NULL) if (call.destination() == NULL)
call.destination(service().c_str()); call.destination(service().c_str());
return conn().send(call); return conn().send(call);
} }
bool ObjectProxy::handle_message(const Message &msg) bool ObjectProxy::handle_message(const Message &msg)
{ {
switch (msg.type()) switch (msg.type())
{ {
case DBUS_MESSAGE_TYPE_SIGNAL: case DBUS_MESSAGE_TYPE_SIGNAL:
{ {
const SignalMessage &smsg = reinterpret_cast<const SignalMessage &>(msg); const SignalMessage &smsg = reinterpret_cast<const SignalMessage &>(msg);
const char *interface = smsg.interface(); const char *interface = smsg.interface();
const char *member = smsg.member(); const char *member = smsg.member();
const char *objpath = smsg.path(); const char *objpath = smsg.path();
if (objpath != path()) return false; if (objpath != path()) return false;
debug_log("filtered signal %s(in %s) from %s to object %s", debug_log("filtered signal %s(in %s) from %s to object %s",
member, interface, msg.sender(), objpath); member, interface, msg.sender(), objpath);
InterfaceProxy *ii = find_interface(interface); InterfaceProxy *ii = find_interface(interface);
if (ii) if (ii)
{ {
return ii->dispatch_signal(smsg); return ii->dispatch_signal(smsg);
} }
else else
{ {
return false; return false;
} }
} }
default: default:
{ {
return false; return false;
} }
} }
} }

View file

@ -36,107 +36,107 @@
using namespace DBus; using namespace DBus;
PendingCall::Private::Private(DBusPendingCall *dpc) PendingCall::Private::Private(DBusPendingCall *dpc)
: call(dpc), dataslot(-1) : call(dpc), dataslot(-1)
{ {
if (!dbus_pending_call_allocate_data_slot(&dataslot)) if (!dbus_pending_call_allocate_data_slot(&dataslot))
{ {
throw ErrorNoMemory("Unable to allocate data slot"); throw ErrorNoMemory("Unable to allocate data slot");
} }
} }
PendingCall::Private::~Private() PendingCall::Private::~Private()
{ {
if (dataslot != -1) if (dataslot != -1)
{ {
dbus_pending_call_allocate_data_slot(&dataslot); dbus_pending_call_allocate_data_slot(&dataslot);
} }
} }
void PendingCall::Private::notify_stub(DBusPendingCall *dpc, void *data) void PendingCall::Private::notify_stub(DBusPendingCall *dpc, void *data)
{ {
PendingCall::Private *pvt = static_cast<PendingCall::Private *>(data); PendingCall::Private *pvt = static_cast<PendingCall::Private *>(data);
PendingCall pc(pvt); PendingCall pc(pvt);
pvt->slot(pc); pvt->slot(pc);
} }
PendingCall::PendingCall(PendingCall::Private *p) PendingCall::PendingCall(PendingCall::Private *p)
: _pvt(p) : _pvt(p)
{ {
if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL)) if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL))
{ {
throw ErrorNoMemory("Unable to initialize pending call"); throw ErrorNoMemory("Unable to initialize pending call");
} }
} }
PendingCall::PendingCall(const PendingCall &c) PendingCall::PendingCall(const PendingCall &c)
: _pvt(c._pvt) : _pvt(c._pvt)
{ {
dbus_pending_call_ref(_pvt->call); dbus_pending_call_ref(_pvt->call);
} }
PendingCall::~PendingCall() PendingCall::~PendingCall()
{ {
dbus_pending_call_unref(_pvt->call); dbus_pending_call_unref(_pvt->call);
} }
PendingCall &PendingCall::operator = (const PendingCall &c) PendingCall &PendingCall::operator = (const PendingCall &c)
{ {
if (&c != this) if (&c != this)
{ {
dbus_pending_call_unref(_pvt->call); dbus_pending_call_unref(_pvt->call);
_pvt = c._pvt; _pvt = c._pvt;
dbus_pending_call_ref(_pvt->call); dbus_pending_call_ref(_pvt->call);
} }
return *this; return *this;
} }
bool PendingCall::completed() bool PendingCall::completed()
{ {
return dbus_pending_call_get_completed(_pvt->call); return dbus_pending_call_get_completed(_pvt->call);
} }
void PendingCall::cancel() void PendingCall::cancel()
{ {
dbus_pending_call_cancel(_pvt->call); dbus_pending_call_cancel(_pvt->call);
} }
void PendingCall::block() void PendingCall::block()
{ {
dbus_pending_call_block(_pvt->call); dbus_pending_call_block(_pvt->call);
} }
void PendingCall::data(void *p) void PendingCall::data(void *p)
{ {
if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL)) if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
{ {
throw ErrorNoMemory("Unable to initialize data slot"); throw ErrorNoMemory("Unable to initialize data slot");
} }
} }
void *PendingCall::data() void *PendingCall::data()
{ {
return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot); return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot);
} }
Slot<void, PendingCall &>& PendingCall::slot() Slot<void, PendingCall &>& PendingCall::slot()
{ {
return _pvt->slot; return _pvt->slot;
} }
Message PendingCall::steal_reply() Message PendingCall::steal_reply()
{ {
DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call); DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call);
if (!dmsg) if (!dmsg)
{ {
dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call); dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call);
if (callComplete) if (callComplete)
throw ErrorNoReply("No reply available"); throw ErrorNoReply("No reply available");
else else
throw ErrorNoReply("Call not complete"); throw ErrorNoReply("Call not complete");
} }
return Message(new Message::Private(dmsg)); return Message(new Message::Private(dmsg));
} }

View file

@ -34,19 +34,20 @@
#include <dbus/dbus.h> #include <dbus/dbus.h>
namespace DBus { namespace DBus
{
struct DXXAPILOCAL PendingCall::Private struct DXXAPILOCAL PendingCall::Private
{ {
DBusPendingCall *call; DBusPendingCall *call;
int dataslot; int dataslot;
Slot<void, PendingCall &> slot; Slot<void, PendingCall &> slot;
Private(DBusPendingCall *);
~Private(); Private(DBusPendingCall *);
static void notify_stub(DBusPendingCall *dpc, void *data); ~Private();
static void notify_stub(DBusPendingCall *dpc, void *data);
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -42,13 +42,13 @@ using namespace std;
Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data) : Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data) :
_handler(handler), _handler(handler),
_fd_write (0), _fd_write(0),
_fd_read (0), _fd_read(0),
_data(data) _data(data)
{ {
int fd[2]; int fd[2];
if(pipe(fd) == 0) if (pipe(fd) == 0)
{ {
_fd_read = fd[0]; _fd_read = fd[0];
_fd_write = fd[1]; _fd_write = fd[1];
@ -56,23 +56,23 @@ Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), c
} }
else else
{ {
throw Error("PipeError:errno", toString(errno).c_str()); throw Error("PipeError:errno", toString(errno).c_str());
} }
} }
void Pipe::write(const void *buffer, unsigned int nbytes) void Pipe::write(const void *buffer, unsigned int nbytes)
{ {
// first write the size into the pipe... // first write the size into the pipe...
::write(_fd_write, static_cast <const void*> (&nbytes), sizeof(nbytes)); ::write(_fd_write, static_cast <const void *>(&nbytes), sizeof(nbytes));
// ...then write the real data // ...then write the real data
::write(_fd_write, buffer, nbytes); ::write(_fd_write, buffer, nbytes);
} }
ssize_t Pipe::read(void *buffer, unsigned int &nbytes) ssize_t Pipe::read(void *buffer, unsigned int &nbytes)
{ {
// first read the size from the pipe... // first read the size from the pipe...
::read(_fd_read, &nbytes, sizeof (nbytes)); ::read(_fd_read, &nbytes, sizeof(nbytes));
//ssize_t size = 0; //ssize_t size = 0;
return ::read(_fd_read, buffer, nbytes); return ::read(_fd_read, buffer, nbytes);
@ -80,5 +80,5 @@ ssize_t Pipe::read(void *buffer, unsigned int &nbytes)
void Pipe::signal() void Pipe::signal()
{ {
::write(_fd_write, '\0', 1); ::write(_fd_write, '\0', 1);
} }

View file

@ -35,117 +35,117 @@ using namespace DBus;
static const char *properties_name = "org.freedesktop.DBus.Properties"; static const char *properties_name = "org.freedesktop.DBus.Properties";
PropertiesAdaptor::PropertiesAdaptor() PropertiesAdaptor::PropertiesAdaptor()
: InterfaceAdaptor(properties_name) : InterfaceAdaptor(properties_name)
{ {
register_method(PropertiesAdaptor, Get, Get); register_method(PropertiesAdaptor, Get, Get);
register_method(PropertiesAdaptor, Set, Set); register_method(PropertiesAdaptor, Set, Set);
} }
Message PropertiesAdaptor::Get(const CallMessage &call) Message PropertiesAdaptor::Get(const CallMessage &call)
{ {
MessageIter ri = call.reader(); MessageIter ri = call.reader();
std::string iface_name; std::string iface_name;
std::string property_name; std::string property_name;
ri >> iface_name >> property_name; ri >> iface_name >> property_name;
debug_log("requesting property %s on interface %s", property_name.c_str(), iface_name.c_str()); debug_log("requesting property %s on interface %s", property_name.c_str(), iface_name.c_str());
InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name); InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);
if (!interface) if (!interface)
throw ErrorFailed("requested interface not found"); throw ErrorFailed("requested interface not found");
Variant *value = interface->get_property(property_name); Variant *value = interface->get_property(property_name);
if (!value) if (!value)
throw ErrorFailed("requested property not found"); throw ErrorFailed("requested property not found");
on_get_property(*interface, property_name, *value); on_get_property(*interface, property_name, *value);
ReturnMessage reply(call); ReturnMessage reply(call);
MessageIter wi = reply.writer(); MessageIter wi = reply.writer();
wi << *value; wi << *value;
return reply; return reply;
} }
Message PropertiesAdaptor::Set(const CallMessage &call) Message PropertiesAdaptor::Set(const CallMessage &call)
{ {
MessageIter ri = call.reader(); MessageIter ri = call.reader();
std::string iface_name; std::string iface_name;
std::string property_name; std::string property_name;
Variant value; Variant value;
ri >> iface_name >> property_name >> value; ri >> iface_name >> property_name >> value;
InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name); InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);
if (!interface) if (!interface)
throw ErrorFailed("requested interface not found"); throw ErrorFailed("requested interface not found");
on_set_property(*interface, property_name, value); on_set_property(*interface, property_name, value);
interface->set_property(property_name, value); interface->set_property(property_name, value);
ReturnMessage reply(call); ReturnMessage reply(call);
return reply; return reply;
} }
IntrospectedInterface * PropertiesAdaptor::introspect() const IntrospectedInterface *PropertiesAdaptor::introspect() const
{ {
static IntrospectedArgument Get_args[] = static IntrospectedArgument Get_args[] =
{ {
{ "interface_name", "s", true }, { "interface_name", "s", true },
{ "property_name", "s", true }, { "property_name", "s", true },
{ "value", "v", false }, { "value", "v", false },
{ 0, 0, 0 } { 0, 0, 0 }
}; };
static IntrospectedArgument Set_args[] = static IntrospectedArgument Set_args[] =
{ {
{ "interface_name", "s", true }, { "interface_name", "s", true },
{ "property_name", "s", true }, { "property_name", "s", true },
{ "value", "v", true }, { "value", "v", true },
{ 0, 0, 0 } { 0, 0, 0 }
}; };
static IntrospectedMethod Properties_methods[] = static IntrospectedMethod Properties_methods[] =
{ {
{ "Get", Get_args }, { "Get", Get_args },
{ "Set", Set_args }, { "Set", Set_args },
{ 0, 0 } { 0, 0 }
}; };
static IntrospectedMethod Properties_signals[] = static IntrospectedMethod Properties_signals[] =
{ {
{ 0, 0 } { 0, 0 }
}; };
static IntrospectedProperty Properties_properties[] = static IntrospectedProperty Properties_properties[] =
{ {
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
static IntrospectedInterface Properties_interface = static IntrospectedInterface Properties_interface =
{ {
properties_name, properties_name,
Properties_methods, Properties_methods,
Properties_signals, Properties_signals,
Properties_properties Properties_properties
}; };
return &Properties_interface; return &Properties_interface;
} }
PropertiesProxy::PropertiesProxy() PropertiesProxy::PropertiesProxy()
: InterfaceProxy(properties_name) : InterfaceProxy(properties_name)
{ {
} }
Variant PropertiesProxy::Get(const std::string &iface, const std::string &property) Variant PropertiesProxy::Get(const std::string &iface, const std::string &property)
{ {
//todo //todo
Variant v; Variant v;
return v; return v;
} }
void PropertiesProxy::Set(const std::string &iface, const std::string &property, const Variant &value) void PropertiesProxy::Set(const std::string &iface, const std::string &property, const Variant &value)

View file

@ -36,7 +36,7 @@
using namespace DBus; using namespace DBus;
Server::Private::Private(DBusServer *s) Server::Private::Private(DBusServer *s)
: server(s) : server(s)
{ {
} }
@ -46,31 +46,31 @@ Server::Private::~Private()
void Server::Private::on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data) void Server::Private::on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data)
{ {
Server *s = static_cast<Server *>(data); Server *s = static_cast<Server *>(data);
Connection nc (new Connection::Private(conn, s->_pvt.get())); Connection nc(new Connection::Private(conn, s->_pvt.get()));
s->_pvt->connections.push_back(nc); s->_pvt->connections.push_back(nc);
s->on_new_connection(nc); s->on_new_connection(nc);
debug_log("incoming connection 0x%08x", conn); debug_log("incoming connection 0x%08x", conn);
} }
Server::Server(const char *address) Server::Server(const char *address)
{ {
InternalError e; InternalError e;
DBusServer *server = dbus_server_listen(address, e); DBusServer *server = dbus_server_listen(address, e);
if (e) throw Error(e); if (e) throw Error(e);
debug_log("server 0x%08x listening on %s", server, address); debug_log("server 0x%08x listening on %s", server, address);
_pvt = new Private(server); _pvt = new Private(server);
dbus_server_set_new_connection_function(_pvt->server, Private::on_new_conn_cb, this, NULL); dbus_server_set_new_connection_function(_pvt->server, Private::on_new_conn_cb, this, NULL);
setup(default_dispatcher); setup(default_dispatcher);
} }
/* /*
Server::Server(const Server &s) Server::Server(const Server &s)
@ -81,49 +81,49 @@ Server::Server(const Server &s)
*/ */
Server::~Server() Server::~Server()
{ {
dbus_server_unref(_pvt->server); dbus_server_unref(_pvt->server);
} }
Dispatcher *Server::setup(Dispatcher *dispatcher) Dispatcher *Server::setup(Dispatcher *dispatcher)
{ {
debug_log("registering stubs for server %p", _pvt->server); debug_log("registering stubs for server %p", _pvt->server);
Dispatcher *prev = _pvt->dispatcher; Dispatcher *prev = _pvt->dispatcher;
dbus_server_set_watch_functions( dbus_server_set_watch_functions(
_pvt->server, _pvt->server,
Dispatcher::Private::on_add_watch, Dispatcher::Private::on_add_watch,
Dispatcher::Private::on_rem_watch, Dispatcher::Private::on_rem_watch,
Dispatcher::Private::on_toggle_watch, Dispatcher::Private::on_toggle_watch,
dispatcher, dispatcher,
0 0
); );
dbus_server_set_timeout_functions( dbus_server_set_timeout_functions(
_pvt->server, _pvt->server,
Dispatcher::Private::on_add_timeout, Dispatcher::Private::on_add_timeout,
Dispatcher::Private::on_rem_timeout, Dispatcher::Private::on_rem_timeout,
Dispatcher::Private::on_toggle_timeout, Dispatcher::Private::on_toggle_timeout,
dispatcher, dispatcher,
0 0
); );
_pvt->dispatcher = dispatcher; _pvt->dispatcher = dispatcher;
return prev; return prev;
} }
bool Server::operator == (const Server &s) const bool Server::operator == (const Server &s) const
{ {
return _pvt->server == s._pvt->server; return _pvt->server == s._pvt->server;
} }
bool Server::listening() const bool Server::listening() const
{ {
return dbus_server_get_is_connected(_pvt->server); return dbus_server_get_is_connected(_pvt->server);
} }
void Server::disconnect() void Server::disconnect()
{ {
dbus_server_disconnect(_pvt->server); dbus_server_disconnect(_pvt->server);
} }

View file

@ -35,21 +35,22 @@
#include <dbus/dbus.h> #include <dbus/dbus.h>
namespace DBus { namespace DBus
struct DXXAPILOCAL Server::Private
{ {
DBusServer *server;
Dispatcher *dispatcher; struct DXXAPILOCAL Server::Private
{
DBusServer *server;
ConnectionList connections; Dispatcher *dispatcher;
Private(DBusServer *); ConnectionList connections;
~Private(); Private(DBusServer *);
static void on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data); ~Private();
static void on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data);
}; };
} /* namespace DBus */ } /* namespace DBus */

View file

@ -37,70 +37,70 @@
using namespace DBus; using namespace DBus;
Variant::Variant() Variant::Variant()
: _msg(CallMessage()) // dummy message used as temporary storage for variant data : _msg(CallMessage()) // dummy message used as temporary storage for variant data
{ {
} }
Variant::Variant(MessageIter &it) Variant::Variant(MessageIter &it)
: _msg(CallMessage()) : _msg(CallMessage())
{ {
MessageIter vi = it.recurse(); MessageIter vi = it.recurse();
MessageIter mi = _msg.writer(); MessageIter mi = _msg.writer();
vi.copy_data(mi); vi.copy_data(mi);
} }
Variant &Variant::operator = (const Variant &v) Variant &Variant::operator = (const Variant &v)
{ {
if (&v != this) if (&v != this)
{ {
_msg = v._msg; _msg = v._msg;
} }
return *this; return *this;
} }
void Variant::clear() void Variant::clear()
{ {
CallMessage empty; CallMessage empty;
_msg = empty; _msg = empty;
} }
const Signature Variant::signature() const const Signature Variant::signature() const
{ {
char *sigbuf = reader().signature(); char *sigbuf = reader().signature();
Signature signature = sigbuf; Signature signature = sigbuf;
free(sigbuf); free(sigbuf);
return signature; return signature;
} }
MessageIter &operator << (MessageIter &iter, const Variant &val) MessageIter &operator << (MessageIter &iter, const Variant &val)
{ {
const Signature sig = val.signature(); const Signature sig = val.signature();
MessageIter rit = val.reader(); MessageIter rit = val.reader();
MessageIter wit = iter.new_variant(sig.c_str()); MessageIter wit = iter.new_variant(sig.c_str());
rit.copy_data(wit); rit.copy_data(wit);
iter.close_container(wit); iter.close_container(wit);
return iter; return iter;
} }
MessageIter &operator >> (MessageIter &iter, Variant &val) MessageIter &operator >> (MessageIter &iter, Variant &val)
{ {
if (iter.type() != DBUS_TYPE_VARIANT) if (iter.type() != DBUS_TYPE_VARIANT)
throw ErrorInvalidArgs("variant type expected"); throw ErrorInvalidArgs("variant type expected");
val.clear(); val.clear();
MessageIter vit = iter.recurse(); MessageIter vit = iter.recurse();
MessageIter mit = val.writer(); MessageIter mit = val.writer();
vit.copy_data(mit); vit.copy_data(mit);
return ++iter; return ++iter;
} }

View file

@ -20,16 +20,16 @@ std::list <std::string> testList;
pthread_mutex_t clientMutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t clientMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t clientCondition = PTHREAD_COND_INITIALIZER; pthread_cond_t clientCondition = PTHREAD_COND_INITIALIZER;
TestApp::TestApp () TestApp::TestApp()
{ {
testList.push_back ("test1"); testList.push_back("test1");
testList.push_back ("testByte"); testList.push_back("testByte");
cout << "initialize DBus..." << endl; cout << "initialize DBus..." << endl;
initDBus (); initDBus();
} }
void TestApp::initDBus () void TestApp::initDBus()
{ {
DBus::_init_threading(); DBus::_init_threading();
@ -39,68 +39,68 @@ void TestApp::initDBus ()
DBus::Connection conn = DBus::Connection::SessionBus(); DBus::Connection conn = DBus::Connection::SessionBus();
TestAppIntro testComIntro (conn, clientCondition, testResult); TestAppIntro testComIntro(conn, clientCondition, testResult);
g_testComIntro = &testComIntro; g_testComIntro = &testComIntro;
cout << "Start server..." << endl; cout << "Start server..." << endl;
TestAppIntroProvider testComProviderIntro (conn, &testComIntro); TestAppIntroProvider testComProviderIntro(conn, &testComIntro);
conn.request_name ("DBusCpp.Test.Com.Intro"); conn.request_name("DBusCpp.Test.Com.Intro");
mTestToDBusPipe = dispatcher.add_pipe (TestApp::testHandler, NULL); mTestToDBusPipe = dispatcher.add_pipe(TestApp::testHandler, NULL);
cout << "Start client thread..." << endl; cout << "Start client thread..." << endl;
pthread_create (&testThread, NULL, TestApp::testThreadRunner, &conn); pthread_create(&testThread, NULL, TestApp::testThreadRunner, &conn);
dispatcher.enter(); dispatcher.enter();
pthread_join (testThread, NULL); pthread_join(testThread, NULL);
cout << "Testresult = " << string (testResult ? "OK" : "NOK") << endl; cout << "Testresult = " << string(testResult ? "OK" : "NOK") << endl;
} }
void *TestApp::testThreadRunner (void *arg) void *TestApp::testThreadRunner(void *arg)
{ {
for (std::list <std::string>::const_iterator tl_it = testList.begin (); for (std::list <std::string>::const_iterator tl_it = testList.begin();
tl_it != testList.end (); tl_it != testList.end();
++tl_it) ++tl_it)
{ {
const string &testString = *tl_it; const string &testString = *tl_it;
cout << "write to pipe" << endl; cout << "write to pipe" << endl;
mTestToDBusPipe->write (testString.c_str (), testString.length () + 1); mTestToDBusPipe->write(testString.c_str(), testString.length() + 1);
struct timespec abstime; struct timespec abstime;
clock_gettime(CLOCK_REALTIME, &abstime); clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += 1; abstime.tv_sec += 1;
pthread_mutex_lock (&clientMutex); pthread_mutex_lock(&clientMutex);
if (pthread_cond_timedwait (&clientCondition, &clientMutex, &abstime) == ETIMEDOUT) if (pthread_cond_timedwait(&clientCondition, &clientMutex, &abstime) == ETIMEDOUT)
{ {
cout << "client timeout!" << endl; cout << "client timeout!" << endl;
testResult = false; testResult = false;
} }
pthread_mutex_unlock (&clientMutex); pthread_mutex_unlock(&clientMutex);
} }
cout << "leave!" << endl; cout << "leave!" << endl;
dispatcher.leave (); dispatcher.leave();
return NULL; return NULL;
} }
void TestApp::testHandler (const void *data, void *buffer, unsigned int nbyte) void TestApp::testHandler(const void *data, void *buffer, unsigned int nbyte)
{ {
char *str = (char*) buffer; char *str = (char *) buffer;
cout << "buffer1: " << str << ", size: " << nbyte << endl; cout << "buffer1: " << str << ", size: " << nbyte << endl;
cout << "run it!" << endl; cout << "run it!" << endl;
if (string (str) == "test1") if (string(str) == "test1")
{ {
g_testComIntro->test1 (); g_testComIntro->test1();
} }
else if (string (str) == "testByte") else if (string(str) == "testByte")
{ {
g_testComIntro->testByte (4); g_testComIntro->testByte(4);
} }
} }

View file

@ -13,15 +13,15 @@
class TestApp class TestApp
{ {
public: public:
TestApp (); TestApp();
private: private:
void initDBus (); void initDBus();
static void testHandler(const void *data, void *buffer, unsigned int nbyte);
static void *testThreadRunner(void *arg);
static void *testThreadRunnerProvider(void *arg);
static void testHandler (const void *data, void *buffer, unsigned int nbyte);
static void *testThreadRunner (void *arg);
static void *testThreadRunnerProvider (void *arg);
// variables // variables
pthread_t testThread; pthread_t testThread;
}; };

View file

@ -15,24 +15,24 @@ class TestAppIntro :
public DBus::ObjectProxy public DBus::ObjectProxy
{ {
public: public:
TestAppIntro (DBus::Connection& connection, pthread_cond_t &condition, bool &testResult) : TestAppIntro(DBus::Connection &connection, pthread_cond_t &condition, bool &testResult) :
DBus::ObjectProxy (connection, "/DBusCpp/Test/Com/Intro", "DBusCpp.Test.Com.Intro"), DBus::ObjectProxy(connection, "/DBusCpp/Test/Com/Intro", "DBusCpp.Test.Com.Intro"),
mCondition (condition), mCondition(condition),
mTestResult (testResult) mTestResult(testResult)
{} {}
void test1Result () void test1Result()
{ {
cout << "Test1Result" << endl; cout << "Test1Result" << endl;
mTestResult = true; mTestResult = true;
pthread_cond_signal (&mCondition); pthread_cond_signal(&mCondition);
} }
void testByteResult (const uint8_t& Byte) void testByteResult(const uint8_t &Byte)
{ {
printf ("TestByteResult: %d\n", Byte); printf("TestByteResult: %d\n", Byte);
mTestResult = true; mTestResult = true;
pthread_cond_signal (&mCondition); pthread_cond_signal(&mCondition);
} }
private: private:

View file

@ -9,27 +9,27 @@
using namespace std; using namespace std;
class TestAppIntroProvider : class TestAppIntroProvider :
public DBusCpp::Test::Com::Intro_adaptor, public DBusCpp::Test::Com::Intro_adaptor,
public DBus::IntrospectableAdaptor, public DBus::IntrospectableAdaptor,
public DBus::ObjectAdaptor public DBus::ObjectAdaptor
{ {
public: public:
TestAppIntroProvider (DBus::Connection& connection, TestAppIntro *testComIntro) : TestAppIntroProvider(DBus::Connection &connection, TestAppIntro *testComIntro) :
DBus::ObjectAdaptor(connection, "/DBusCpp/Test/Com/Intro"), DBus::ObjectAdaptor(connection, "/DBusCpp/Test/Com/Intro"),
mTestAppIntro (testComIntro) mTestAppIntro(testComIntro)
{} {}
void test1 () void test1()
{ {
cout << "Test1" << endl; cout << "Test1" << endl;
mTestAppIntro->test1Result (); mTestAppIntro->test1Result();
} }
void testByte (const uint8_t& Byte) void testByte(const uint8_t &Byte)
{ {
printf ("TestByte: %d\n", Byte); printf("TestByte: %d\n", Byte);
mTestAppIntro->testByteResult (Byte); mTestAppIntro->testByteResult(Byte);
} }
private: private:

View file

@ -6,7 +6,7 @@
using namespace std; using namespace std;
int main (int argc, char **argv) int main(int argc, char **argv)
{ {
TestApp testCom; TestApp testCom;
} }

View file

@ -1,6 +1,6 @@
#include <dbuscxx_test_generator-client.h> #include <dbuscxx_test_generator-client.h>
int main (int argc, char **argv) int main(int argc, char **argv)
{ {
return 0; return 0;

View file

@ -1,6 +1,6 @@
#include <dbuscxx_test_generator-server.h> #include <dbuscxx_test_generator-server.h>
int main (int argc, char **argv) int main(int argc, char **argv)
{ {
return 0; return 0;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -42,136 +42,140 @@ const char *dbus_includes = "\n\
#include <cassert>\n\ #include <cassert>\n\
"; ";
void underscorize(string &str) void underscorize(string &str)
{ {
for (unsigned int i = 0; i < str.length(); ++i) for (unsigned int i = 0; i < str.length(); ++i)
{ {
if (!isalpha(str[i]) && !isdigit(str[i])) str[i] = '_'; if (!isalpha(str[i]) && !isdigit(str[i])) str[i] = '_';
} }
} }
string stub_name(string name) string stub_name(string name)
{ {
underscorize(name); underscorize(name);
return "_" + name + "_stub"; return "_" + name + "_stub";
} }
const char *atomic_type_to_string(char t) const char *atomic_type_to_string(char t)
{ {
static struct { char type; const char *name; } atos[] = static struct
{ {
{ 'y', "uint8_t" }, char type;
{ 'b', "bool" }, const char *name;
{ 'n', "int16_t" }, } atos[] =
{ 'q', "uint16_t" }, {
{ 'i', "int32_t" }, { 'y', "uint8_t" },
{ 'u', "uint32_t" }, { 'b', "bool" },
{ 'x', "int64_t" }, { 'n', "int16_t" },
{ 't', "uint64_t" }, { 'q', "uint16_t" },
{ 'd', "double" }, { 'i', "int32_t" },
{ 's', "std::string" }, { 'u', "uint32_t" },
{ 'o', "::DBus::Path" }, { 'x', "int64_t" },
{ 'g', "::DBus::Signature" }, { 't', "uint64_t" },
{ 'v', "::DBus::Variant" }, { 'd', "double" },
{ '\0', "" } { 's', "std::string" },
}; { 'o', "::DBus::Path" },
int i; { 'g', "::DBus::Signature" },
{ 'v', "::DBus::Variant" },
{ '\0', "" }
};
int i;
for (i = 0; atos[i].type; ++i) for (i = 0; atos[i].type; ++i)
{ {
if (atos[i].type == t) break; if (atos[i].type == t) break;
} }
return atos[i].name; return atos[i].name;
} }
static void _parse_signature(const string &signature, string &type, unsigned int &i, bool only_once = false) static void _parse_signature(const string &signature, string &type, unsigned int &i, bool only_once = false)
{ {
/*cout << "signature: " << signature << endl; /*cout << "signature: " << signature << endl;
cout << "type: " << type << endl; cout << "type: " << type << endl;
cout << "i: " << i << ", signature[i]: " << signature[i] << endl;*/ cout << "i: " << i << ", signature[i]: " << signature[i] << endl;*/
for (; i < signature.length(); ++i)
{
switch (signature[i])
{
case 'a':
{
switch (signature[++i])
{
case '{':
{
type += "std::map< ";
++i;
_parse_signature(signature, type, i);
type += " >";
break;
}
case '(':
{
type += "std::vector< ::DBus::Struct< ";
++i;
_parse_signature(signature, type, i);
type += " > >";
break; for (; i < signature.length(); ++i)
} {
default: switch (signature[i])
{ {
type += "std::vector< "; case 'a':
_parse_signature(signature, type, i, true); {
switch (signature[++i])
{
case '{':
{
type += "std::map< ";
++i;
_parse_signature(signature, type, i);
type += " >";
type += " >"; break;
}
break; case '(':
} {
} type += "std::vector< ::DBus::Struct< ";
break; ++i;
} _parse_signature(signature, type, i);
case '(': type += " > >";
{
type += "::DBus::Struct< ";
++i;
_parse_signature(signature, type, i); break;
}
default:
{
type += "std::vector< ";
_parse_signature(signature, type, i, true);
type += " >"; type += " >";
break;
}
case ')':
case '}':
{
return;
}
default:
{
const char *atom = atomic_type_to_string(signature[i]);
if (!atom)
{
cerr << "invalid signature" << endl;
exit(-1);
}
type += atom;
break; break;
} }
} }
break;
}
case '(':
{
type += "::DBus::Struct< ";
++i;
if (only_once) _parse_signature(signature, type, i);
return;
if (i+1 < signature.length() && signature[i+1] != ')' && signature[i+1] != '}') type += " >";
{ break;
type += ", "; }
} case ')':
} case '}':
} {
return;
}
default:
{
const char *atom = atomic_type_to_string(signature[i]);
if (!atom)
{
cerr << "invalid signature" << endl;
exit(-1);
}
type += atom;
string signature_to_type(const string &signature) break;
{ }
string type; }
unsigned int i = 0;
_parse_signature(signature, type, i); if (only_once)
return type; return;
}
if (i + 1 < signature.length() && signature[i + 1] != ')' && signature[i + 1] != '}')
{
type += ", ";
}
}
}
string signature_to_type(const string &signature)
{
string type;
unsigned int i = 0;
_parse_signature(signature, type, i);
return type;
}

View file

@ -35,7 +35,7 @@ void underscorize(std::string &str);
/// create std::string from any number /// create std::string from any number
template <typename T> template <typename T>
std::string toString (const T &thing, int w = 0, int p = 0) std::string toString(const T &thing, int w = 0, int p = 0)
{ {
std::ostringstream os; std::ostringstream os;
os << std::setw(w) << std::setprecision(p) << thing; os << std::setw(w) << std::setprecision(p) << thing;

View file

@ -34,46 +34,46 @@ static char *service;
void niam(int sig) void niam(int sig)
{ {
DBus::Connection conn = systembus ? DBus::Connection::SystemBus() : DBus::Connection::SessionBus(); DBus::Connection conn = systembus ? DBus::Connection::SystemBus() : DBus::Connection::SessionBus();
IntrospectedObject io(conn, path, service); IntrospectedObject io(conn, path, service);
std::cout << io.Introspect(); std::cout << io.Introspect();
dispatcher.leave(); dispatcher.leave();
} }
int main(int argc, char ** argv) int main(int argc, char **argv)
{ {
signal(SIGTERM, niam); signal(SIGTERM, niam);
signal(SIGINT, niam); signal(SIGINT, niam);
signal(SIGALRM, niam); signal(SIGALRM, niam);
if (argc == 1) if (argc == 1)
{ {
std::cerr << std::endl << "Usage: " << argv[0] << " [--system] <object_path> [<destination>]" << std::endl << std::endl; std::cerr << std::endl << "Usage: " << argv[0] << " [--system] <object_path> [<destination>]" << std::endl << std::endl;
} }
else else
{ {
if (strcmp(argv[1], "--system")) if (strcmp(argv[1], "--system"))
{ {
systembus = false; systembus = false;
path = argv[1]; path = argv[1];
service = argc > 2 ? argv[2] : 0; service = argc > 2 ? argv[2] : 0;
} }
else else
{ {
systembus = true; systembus = true;
path = argv[2]; path = argv[2];
service = argc > 3 ? argv[3] : 0; service = argc > 3 ? argv[3] : 0;
} }
DBus::default_dispatcher = &dispatcher; DBus::default_dispatcher = &dispatcher;
alarm(1); alarm(1);
dispatcher.enter(); dispatcher.enter();
} }
return 0; return 0;
} }

View file

@ -36,9 +36,9 @@ class IntrospectedObject : public DBus::IntrospectableProxy, public DBus::Object
{ {
public: public:
IntrospectedObject(DBus::Connection &conn, const char *path, const char *service) IntrospectedObject(DBus::Connection &conn, const char *path, const char *service)
: DBus::ObjectProxy(conn, path, service) : DBus::ObjectProxy(conn, path, service)
{} {}
}; };
#endif//__DBUSXX_TOOLS_INTROSPECT_H #endif//__DBUSXX_TOOLS_INTROSPECT_H

View file

@ -28,16 +28,16 @@
std::istream &operator >> (std::istream &in, DBus::Xml::Document &doc) std::istream &operator >> (std::istream &in, DBus::Xml::Document &doc)
{ {
std::stringbuf xmlbuf; std::stringbuf xmlbuf;
in.get(xmlbuf, '\0'); in.get(xmlbuf, '\0');
doc.from_xml(xmlbuf.str()); doc.from_xml(xmlbuf.str());
return in; return in;
} }
std::ostream &operator << (std::ostream &out, const DBus::Xml::Document &doc) std::ostream &operator << (std::ostream &out, const DBus::Xml::Document &doc)
{ {
return out << doc.to_xml(); return out << doc.to_xml();
} }
using namespace DBus; using namespace DBus;
@ -45,209 +45,209 @@ using namespace DBus::Xml;
Error::Error(const char *error, int line, int column) Error::Error(const char *error, int line, int column)
{ {
std::ostringstream estream; std::ostringstream estream;
estream << "line " << line << ", column " << column << ": " << error; estream << "line " << line << ", column " << column << ": " << error;
_error = estream.str(); _error = estream.str();
} }
Node::Node(const char *n, const char ** a) Node::Node(const char *n, const char **a)
: name(n) : name(n)
{ {
if (a) if (a)
for (int i = 0; a[i]; i += 2) for (int i = 0; a[i]; i += 2)
{ {
_attrs[a[i]] = a[i+1]; _attrs[a[i]] = a[i + 1];
//debug_log("xml:\t%s = %s", a[i], a[i+1]); //debug_log("xml:\t%s = %s", a[i], a[i+1]);
} }
} }
Nodes Nodes::operator[](const std::string &key) Nodes Nodes::operator[](const std::string &key)
{ {
Nodes result; Nodes result;
for (iterator i = begin(); i != end(); ++i) for (iterator i = begin(); i != end(); ++i)
{ {
Nodes part = (**i)[key]; Nodes part = (**i)[key];
result.insert(result.end(), part.begin(), part.end()); result.insert(result.end(), part.begin(), part.end());
} }
return result; return result;
} }
Nodes Nodes::select(const std::string &attr, const std::string &value) Nodes Nodes::select(const std::string &attr, const std::string &value)
{ {
Nodes result; Nodes result;
for (iterator i = begin(); i != end(); ++i) for (iterator i = begin(); i != end(); ++i)
{ {
if ((*i)->get(attr) == value) if ((*i)->get(attr) == value)
result.insert(result.end(), *i); result.insert(result.end(), *i);
} }
return result; return result;
} }
Nodes Node::operator[](const std::string &key) Nodes Node::operator[](const std::string &key)
{ {
Nodes result; Nodes result;
if (key.length() == 0) return result; if (key.length() == 0) return result;
for (Children::iterator i = children.begin(); i != children.end(); ++i) for (Children::iterator i = children.begin(); i != children.end(); ++i)
{ {
if (i->name == key) if (i->name == key)
result.push_back(&(*i)); result.push_back(&(*i));
} }
return result; return result;
} }
std::string Node::get(const std::string &attribute) std::string Node::get(const std::string &attribute)
{ {
if (_attrs.find(attribute) != _attrs.end()) if (_attrs.find(attribute) != _attrs.end())
return _attrs[attribute]; return _attrs[attribute];
else else
return ""; return "";
} }
void Node::set(const std::string &attribute, std::string value) void Node::set(const std::string &attribute, std::string value)
{ {
if (value.length()) if (value.length())
_attrs[attribute] = value; _attrs[attribute] = value;
else else
_attrs.erase(value); _attrs.erase(value);
} }
std::string Node::to_xml() const std::string Node::to_xml() const
{ {
std::string xml; std::string xml;
int depth = 0; int depth = 0;
_raw_xml(xml, depth); _raw_xml(xml, depth);
return xml; return xml;
} }
void Node::_raw_xml(std::string &xml, int &depth) const void Node::_raw_xml(std::string &xml, int &depth) const
{ {
xml.append(depth *2, ' '); xml.append(depth * 2, ' ');
xml.append("<"+name); xml.append("<" + name);
for (Attributes::const_iterator i = _attrs.begin(); i != _attrs.end(); ++i) for (Attributes::const_iterator i = _attrs.begin(); i != _attrs.end(); ++i)
{ {
xml.append(" "+i->first+"=\""+i->second+"\""); xml.append(" " + i->first + "=\"" + i->second + "\"");
} }
if (cdata.length() == 0 && children.size() == 0) if (cdata.length() == 0 && children.size() == 0)
{ {
xml.append("/>\n"); xml.append("/>\n");
} }
else else
{ {
xml.append(">"); xml.append(">");
if (cdata.length())
{
xml.append(cdata);
}
if (children.size()) if (cdata.length())
{ {
xml.append("\n"); xml.append(cdata);
depth++; }
for (Children::const_iterator i = children.begin(); i != children.end(); ++i) if (children.size())
{ {
i->_raw_xml(xml, depth); xml.append("\n");
} depth++;
depth--; for (Children::const_iterator i = children.begin(); i != children.end(); ++i)
xml.append(depth *2, ' '); {
} i->_raw_xml(xml, depth);
xml.append("</"+name+">\n"); }
}
depth--;
xml.append(depth * 2, ' ');
}
xml.append("</" + name + ">\n");
}
} }
Document::Document() Document::Document()
: root(0), _depth(0) : root(0), _depth(0)
{ {
} }
Document::Document(const std::string &xml) Document::Document(const std::string &xml)
: root(0), _depth(0) : root(0), _depth(0)
{ {
from_xml(xml); from_xml(xml);
} }
Document::~Document() Document::~Document()
{ {
delete root; delete root;
} }
struct Document::Expat struct Document::Expat
{ {
static void start_doctype_decl_handler( static void start_doctype_decl_handler(
void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset
); );
static void end_doctype_decl_handler(void *data); static void end_doctype_decl_handler(void *data);
static void start_element_handler(void *data, const XML_Char *name, const XML_Char **atts); static void start_element_handler(void *data, const XML_Char *name, const XML_Char **atts);
static void character_data_handler(void *data, const XML_Char *chars, int len); static void character_data_handler(void *data, const XML_Char *chars, int len);
static void end_element_handler(void *data, const XML_Char *name); static void end_element_handler(void *data, const XML_Char *name);
}; };
void Document::from_xml(const std::string &xml) void Document::from_xml(const std::string &xml)
{ {
_depth = 0; _depth = 0;
delete root; delete root;
root = 0; root = 0;
XML_Parser parser = XML_ParserCreate("UTF-8"); XML_Parser parser = XML_ParserCreate("UTF-8");
XML_SetUserData(parser, this); XML_SetUserData(parser, this);
XML_SetDoctypeDeclHandler( XML_SetDoctypeDeclHandler(
parser, parser,
Document::Expat::start_doctype_decl_handler, Document::Expat::start_doctype_decl_handler,
Document::Expat::end_doctype_decl_handler Document::Expat::end_doctype_decl_handler
); );
XML_SetElementHandler( XML_SetElementHandler(
parser, parser,
Document::Expat::start_element_handler, Document::Expat::start_element_handler,
Document::Expat::end_element_handler Document::Expat::end_element_handler
); );
XML_SetCharacterDataHandler( XML_SetCharacterDataHandler(
parser, parser,
Document::Expat::character_data_handler Document::Expat::character_data_handler
); );
XML_Status status = XML_Parse(parser, xml.c_str(), xml.length(), true); XML_Status status = XML_Parse(parser, xml.c_str(), xml.length(), true);
if (status == XML_STATUS_ERROR) if (status == XML_STATUS_ERROR)
{ {
const char *error = XML_ErrorString(XML_GetErrorCode(parser)); const char *error = XML_ErrorString(XML_GetErrorCode(parser));
int line = XML_GetCurrentLineNumber(parser); int line = XML_GetCurrentLineNumber(parser);
int column = XML_GetCurrentColumnNumber(parser); int column = XML_GetCurrentColumnNumber(parser);
XML_ParserFree(parser); XML_ParserFree(parser);
throw Error(error, line, column); throw Error(error, line, column);
} }
else else
{ {
XML_ParserFree(parser); XML_ParserFree(parser);
} }
} }
std::string Document::to_xml() const std::string Document::to_xml() const
{ {
return root->to_xml(); return root->to_xml();
} }
void Document::Expat::start_doctype_decl_handler( void Document::Expat::start_doctype_decl_handler(
void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset
) )
{ {
} }
@ -258,56 +258,56 @@ void Document::Expat::end_doctype_decl_handler(void *data)
void Document::Expat::start_element_handler(void *data, const XML_Char *name, const XML_Char **atts) void Document::Expat::start_element_handler(void *data, const XML_Char *name, const XML_Char **atts)
{ {
Document *doc = (Document *)data; Document *doc = (Document *)data;
//debug_log("xml:%d -> %s", doc->_depth, name); //debug_log("xml:%d -> %s", doc->_depth, name);
if (!doc->root) if (!doc->root)
{ {
doc->root = new Node(name, atts); doc->root = new Node(name, atts);
} }
else else
{ {
Node::Children *cld = &(doc->root->children); Node::Children *cld = &(doc->root->children);
for (int i = 1; i < doc->_depth; ++i) for (int i = 1; i < doc->_depth; ++i)
{ {
cld = &(cld->back().children); cld = &(cld->back().children);
} }
cld->push_back(Node(name, atts)); cld->push_back(Node(name, atts));
//std::cerr << doc->to_xml() << std::endl; //std::cerr << doc->to_xml() << std::endl;
} }
doc->_depth++; doc->_depth++;
} }
void Document::Expat::character_data_handler(void *data, const XML_Char *chars, int len) void Document::Expat::character_data_handler(void *data, const XML_Char *chars, int len)
{ {
Document *doc = (Document *)data; Document *doc = (Document *)data;
Node *nod = doc->root; Node *nod = doc->root;
for (int i = 1; i < doc->_depth; ++i) for (int i = 1; i < doc->_depth; ++i)
{ {
nod = &(nod->children.back()); nod = &(nod->children.back());
} }
int x, y; int x, y;
x = 0; x = 0;
y = len-1; y = len - 1;
while (isspace(chars[y]) && y > 0) --y; while (isspace(chars[y]) && y > 0) --y;
while (isspace(chars[x]) && x < y) ++x; while (isspace(chars[x]) && x < y) ++x;
nod->cdata = std::string(chars, x, y+1); nod->cdata = std::string(chars, x, y + 1);
} }
void Document::Expat::end_element_handler(void *data, const XML_Char *name) void Document::Expat::end_element_handler(void *data, const XML_Char *name)
{ {
Document *doc = (Document *)data; Document *doc = (Document *)data;
//debug_log("xml:%d <- %s", doc->_depth, name); //debug_log("xml:%d <- %s", doc->_depth, name);
doc->_depth--; doc->_depth--;
} }

View file

@ -36,27 +36,29 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
namespace DBus { namespace DBus
{
namespace Xml { namespace Xml
{
class Error : public std::exception class Error : public std::exception
{ {
public: public:
Error(const char *error, int line, int column); Error(const char *error, int line, int column);
~Error() throw() ~Error() throw()
{} {}
const char *what() const throw() const char *what() const throw()
{ {
return _error.c_str(); return _error.c_str();
} }
private: private:
std::string _error; std::string _error;
}; };
class Node; class Node;
@ -65,71 +67,71 @@ class Nodes : public std::vector<Node *>
{ {
public: public:
Nodes operator[](const std::string &key); Nodes operator[](const std::string &key);
Nodes select(const std::string &attr, const std::string &value); Nodes select(const std::string &attr, const std::string &value);
}; };
class Node class Node
{ {
public: public:
typedef std::map<std::string, std::string> Attributes; typedef std::map<std::string, std::string> Attributes;
typedef std::vector<Node> Children; typedef std::vector<Node> Children;
std::string name; std::string name;
std::string cdata; std::string cdata;
Children children; Children children;
Node(std::string &n, Attributes &a) Node(std::string &n, Attributes &a)
: name(n), _attrs(a) : name(n), _attrs(a)
{} {}
Node(const char *n, const char ** a = NULL); Node(const char *n, const char **a = NULL);
Nodes operator[](const std::string &key); Nodes operator[](const std::string &key);
std::string get(const std::string &attribute); std::string get(const std::string &attribute);
void set(const std::string &attribute, std::string value); void set(const std::string &attribute, std::string value);
std::string to_xml() const; std::string to_xml() const;
Node &add(Node child) Node &add(Node child)
{ {
children.push_back(child); children.push_back(child);
return children.back(); return children.back();
} }
private: private:
void _raw_xml(std::string &xml, int &depth) const; void _raw_xml(std::string &xml, int &depth) const;
Attributes _attrs; Attributes _attrs;
}; };
class Document class Document
{ {
public: public:
struct Expat; struct Expat;
Node *root; Node *root;
Document(); Document();
Document(const std::string &xml); Document(const std::string &xml);
~Document(); ~Document();
void from_xml(const std::string &xml); void from_xml(const std::string &xml);
std::string to_xml() const; std::string to_xml() const;
private: private:
int _depth; int _depth;
}; };
} /* namespace Xml */ } /* namespace Xml */

View file

@ -40,9 +40,9 @@ using namespace DBus;
void usage(const char *argv0) void usage(const char *argv0)
{ {
cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]" cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]"
<< endl << endl; << endl << endl;
exit(-1); exit(-1);
} }
/*int char_to_atomic_type(char t) /*int char_to_atomic_type(char t)
@ -61,68 +61,67 @@ void usage(const char *argv0)
}*/ }*/
int main(int argc, char ** argv) int main(int argc, char **argv)
{ {
if (argc < 2) if (argc < 2)
{ {
usage(argv[0]); usage(argv[0]);
} }
bool proxy_mode, adaptor_mode; bool proxy_mode, adaptor_mode;
char *proxy, *adaptor; char *proxy, *adaptor;
proxy_mode = false; proxy_mode = false;
proxy = 0; proxy = 0;
adaptor_mode = false; adaptor_mode = false;
adaptor = 0; adaptor = 0;
for (int a = 1; a < argc; ++a)
{
if (!strncmp(argv[a], "--proxy=", 8))
{
proxy_mode = true;
proxy = argv[a] +8;
}
else
if (!strncmp(argv[a], "--adaptor=", 10))
{
adaptor_mode = true;
adaptor = argv[a] +10;
}
}
if (!proxy_mode && !adaptor_mode) usage(argv[0]); for (int a = 1; a < argc; ++a)
{
if (!strncmp(argv[a], "--proxy=", 8))
{
proxy_mode = true;
proxy = argv[a] + 8;
}
else if (!strncmp(argv[a], "--adaptor=", 10))
{
adaptor_mode = true;
adaptor = argv[a] + 10;
}
}
ifstream xmlfile(argv[1]); if (!proxy_mode && !adaptor_mode) usage(argv[0]);
if (xmlfile.bad()) ifstream xmlfile(argv[1]);
{
cerr << "unable to open file " << argv[1] << endl;
return -1;
}
Xml::Document doc; if (xmlfile.bad())
{
cerr << "unable to open file " << argv[1] << endl;
return -1;
}
try Xml::Document doc;
{
xmlfile >> doc;
//cout << doc.to_xml();
}
catch(Xml::Error &e)
{
cerr << "error parsing " << argv[1] << ": " << e.what() << endl;
return -1;
}
if (!doc.root) try
{ {
cerr << "empty document" << endl; xmlfile >> doc;
return -1; //cout << doc.to_xml();
} }
catch (Xml::Error &e)
{
cerr << "error parsing " << argv[1] << ": " << e.what() << endl;
return -1;
}
if (proxy_mode) generate_proxy(doc, proxy); if (!doc.root)
if (adaptor_mode) generate_adaptor(doc, adaptor); {
cerr << "empty document" << endl;
return -1;
}
return 0; if (proxy_mode) generate_proxy(doc, proxy);
if (adaptor_mode) generate_adaptor(doc, adaptor);
return 0;
} }