- 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";
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)
{
cout << "!";
cout << "!";
}
static const size_t THREADS = 3;
@ -37,96 +37,96 @@ DBus::DefaultTimeout *timeout;
void *greeter_thread(void *arg)
{
char idstr[16];
size_t i = (size_t) arg;
char idstr[16];
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)
{
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;
cout << "buffer1: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i)
{
cout << "call1: " << g_client->Hello (str) << endl;
}
char *str = (char *) buffer;
cout << "buffer1: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i)
{
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;
cout << "buffer2: " << str << ", size: " << nbyte <<endl;
for (int i = 0; i < 30 && spin; ++i)
{
cout << "call2: " << g_client->Hello (str) << endl;
}
char *str = (char *) buffer;
cout << "buffer2: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i)
{
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;
cout << "buffer3: " << str << ", size: " << nbyte <<endl;
for (int i = 0; i < 30 && spin; ++i)
{
cout << "call3: " << g_client->Hello (str) << endl;
}
char *str = (char *) buffer;
cout << "buffer3: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i)
{
cout << "call3: " << g_client->Hello(str) << endl;
}
}
int main()
{
size_t i;
size_t i;
signal(SIGTERM, niam);
signal(SIGINT, niam);
signal(SIGTERM, niam);
signal(SIGINT, niam);
DBus::_init_threading();
DBus::_init_threading();
DBus::default_dispatcher = &dispatcher;
// increase DBus-C++ frequency
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);
g_client = &client;
EchoClient client(conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME);
g_client = &client;
pthread_t threads[THREADS];
pthread_t threads[THREADS];
thread_pipe_list[0] = dispatcher.add_pipe (handler1, NULL);
thread_pipe_list[1] = dispatcher.add_pipe (handler2, NULL);
thread_pipe_list[2] = dispatcher.add_pipe (handler3, NULL);
for (i = 0; i < THREADS; ++i)
{
pthread_create(threads+i, NULL, greeter_thread, (void*) i);
}
thread_pipe_list[0] = dispatcher.add_pipe(handler1, NULL);
thread_pipe_list[1] = dispatcher.add_pipe(handler2, NULL);
thread_pipe_list[2] = dispatcher.add_pipe(handler3, NULL);
for (i = 0; i < THREADS; ++i)
{
pthread_create(threads + i, NULL, greeter_thread, (void *) i);
}
dispatcher.enter();
dispatcher.enter();
cout << "terminating" << endl;
cout << "terminating" << endl;
for (i = 0; i < THREADS; ++i)
{
pthread_join(threads[i], NULL);
}
for (i = 0; i < THREADS; ++i)
{
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]);
dispatcher.del_pipe(thread_pipe_list[0]);
dispatcher.del_pipe(thread_pipe_list[1]);
dispatcher.del_pipe(thread_pipe_list[2]);
return 0;
return 0;
}

View file

@ -5,15 +5,15 @@
#include "echo-client-glue.h"
class EchoClient
: public org::freedesktop::DBus::EchoDemo_proxy,
: public org::freedesktop::DBus::EchoDemo_proxy,
public DBus::IntrospectableProxy,
public DBus::ObjectProxy
{
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

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";
EchoServer::EchoServer(DBus::Connection &connection)
: DBus::ObjectAdaptor(connection, ECHO_SERVER_PATH)
: DBus::ObjectAdaptor(connection, ECHO_SERVER_PATH)
{
}
int32_t EchoServer::Random()
{
return rand();
return rand();
}
std::string EchoServer::Hello(const std::string &name)
{
return "Hello " + name + "!";
return "Hello " + name + "!";
}
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)
{
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 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 > info;
char hostname[HOST_NAME_MAX];
std::map< std::string, std::string > info;
char hostname[HOST_NAME_MAX];
gethostname(hostname, sizeof(hostname));
info["hostname"] = hostname;
info["username"] = getlogin();
gethostname(hostname, sizeof(hostname));
info["hostname"] = hostname;
info["username"] = getlogin();
return info;
return info;
}
@ -75,22 +75,22 @@ DBus::BusDispatcher dispatcher;
void niam(int sig)
{
dispatcher.leave();
dispatcher.leave();
}
int main()
{
signal(SIGTERM, niam);
signal(SIGINT, niam);
signal(SIGTERM, niam);
signal(SIGINT, niam);
DBus::default_dispatcher = &dispatcher;
DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SessionBus();
conn.request_name(ECHO_SERVER_NAME);
DBus::Connection conn = DBus::Connection::SessionBus();
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"
class EchoServer
: public org::freedesktop::DBus::EchoDemo_adaptor,
: public org::freedesktop::DBus::EchoDemo_adaptor,
public DBus::IntrospectableAdaptor,
public DBus::ObjectAdaptor
{
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

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";
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)
{
cout << "!";
cout << "!";
}
/*
@ -41,101 +41,101 @@ DBus::Ecore::BusDispatcher dispatcher;
void *greeter_thread(void *arg)
{
char idstr[16];
size_t i = (size_t) arg;
char idstr[16];
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)
{
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;
cout << "buffer1: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i)
{
cout << "call1: " << g_client->Hello (str) << endl;
}
char *str = (char *) buffer;
cout << "buffer1: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i)
{
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;
cout << "buffer2: " << str << ", size: " << nbyte <<endl;
for (int i = 0; i < 30 && spin; ++i)
{
cout << "call2: " << g_client->Hello (str) << endl;
}
char *str = (char *) buffer;
cout << "buffer2: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i)
{
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;
cout << "buffer3: " << str << ", size: " << nbyte <<endl;
for (int i = 0; i < 30 && spin; ++i)
{
cout << "call3: " << g_client->Hello (str) << endl;
}
char *str = (char *) buffer;
cout << "buffer3: " << str << ", size: " << nbyte << endl;
for (int i = 0; i < 30 && spin; ++i)
{
cout << "call3: " << g_client->Hello(str) << endl;
}
}
int main()
{
size_t i;
size_t i;
signal(SIGTERM, niam);
signal(SIGINT, niam);
signal(SIGTERM, niam);
signal(SIGINT, niam);
ecore_init();
//DBus::_init_threading();
//DBus::_init_threading();
DBus::default_dispatcher = &dispatcher;
// increase DBus-C++ frequency
//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);
g_client = &client;
EchoClient client(conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME);
g_client = &client;
pthread_t threads[THREADS];
pthread_t threads[THREADS];
/* thread_pipe_list[0] = dispatcher.add_pipe (handler1, NULL);
thread_pipe_list[1] = dispatcher.add_pipe (handler2, NULL);
thread_pipe_list[2] = dispatcher.add_pipe (handler3, NULL);*/
for (i = 0; i < THREADS; ++i)
{
//pthread_create(threads+i, NULL, greeter_thread, (void*) i);
}
/* thread_pipe_list[0] = dispatcher.add_pipe (handler1, NULL);
thread_pipe_list[1] = dispatcher.add_pipe (handler2, NULL);
thread_pipe_list[2] = dispatcher.add_pipe (handler3, NULL);*/
for (i = 0; i < THREADS; ++i)
{
//pthread_create(threads+i, NULL, greeter_thread, (void*) i);
}
//dispatcher.enter();
//dispatcher.enter();
cout << "terminating" << endl;
cout << "terminating" << endl;
for (i = 0; i < THREADS; ++i)
{
pthread_join(threads[i], NULL);
}
for (i = 0; i < THREADS; ++i)
{
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]);*/
/*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_shutdown();
return 0;
return 0;
}

View file

@ -8,15 +8,15 @@
#include "echo-client-glue.h"
class EchoClient
: public org::freedesktop::DBus::EchoDemo_proxy,
: public org::freedesktop::DBus::EchoDemo_proxy,
public DBus::IntrospectableProxy,
public DBus::ObjectProxy
{
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

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";
EchoServer::EchoServer(DBus::Connection &connection)
: DBus::ObjectAdaptor(connection, ECHO_SERVER_PATH)
: DBus::ObjectAdaptor(connection, ECHO_SERVER_PATH)
{
}
int32_t EchoServer::Random()
{
return rand();
return rand();
}
std::string EchoServer::Hello(const std::string &name)
{
return "Hello " + name + "!";
return "Hello " + name + "!";
}
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)
{
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 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 > info;
char hostname[HOST_NAME_MAX];
std::map< std::string, std::string > info;
char hostname[HOST_NAME_MAX];
gethostname(hostname, sizeof(hostname));
info["hostname"] = hostname;
info["username"] = getlogin();
gethostname(hostname, sizeof(hostname));
info["hostname"] = hostname;
info["username"] = getlogin();
return info;
return info;
}
DBus::Ecore::BusDispatcher dispatcher;
@ -75,25 +75,25 @@ DBus::Ecore::BusDispatcher dispatcher;
void niam(int sig)
{
ecore_main_loop_quit();
ecore_main_loop_quit();
}
int main()
{
signal(SIGTERM, niam);
signal(SIGINT, niam);
signal(SIGTERM, niam);
signal(SIGINT, niam);
ecore_init();
DBus::default_dispatcher = &dispatcher;
DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SessionBus();
conn.request_name(ECHO_SERVER_NAME);
DBus::Connection conn = DBus::Connection::SessionBus();
conn.request_name(ECHO_SERVER_NAME);
EchoServer server(conn);
EchoServer server(conn);
ecore_main_loop_begin();
ecore_shutdown();
return 0;
return 0;
}

View file

@ -8,25 +8,25 @@
#include "echo-server-glue.h"
class EchoServer
: public org::freedesktop::DBus::EchoDemo_adaptor,
: public org::freedesktop::DBus::EchoDemo_adaptor,
public DBus::IntrospectableAdaptor,
public DBus::ObjectAdaptor
{
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

View file

@ -10,62 +10,62 @@
using namespace std;
static const char* DBUS_SERVER_NAME = "org.freedesktop.DBus";
static const char* DBUS_SERVER_PATH = "/org/freedesktop/DBus";
static const char *DBUS_SERVER_NAME = "org.freedesktop.DBus";
static const char *DBUS_SERVER_PATH = "/org/freedesktop/DBus";
typedef vector <string> Names;
DBusBrowser::DBusBrowser( ::DBus::Connection& conn )
: ::DBus::ObjectProxy(conn, DBUS_SERVER_PATH, DBUS_SERVER_NAME)
DBusBrowser::DBusBrowser(::DBus::Connection &conn)
: ::DBus::ObjectProxy(conn, DBUS_SERVER_PATH, DBUS_SERVER_NAME)
{
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;
}
}
}
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;
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(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();
DBusBrowser browser(conn);
DBusBrowser browser(conn);
ecore_main_loop_begin();
ecore_shutdown();
return 0;
return 0;
}

View file

@ -8,21 +8,21 @@
#include "dbus_ecore-glue.h"
class DBusBrowser
: public org::freedesktop::DBus_proxy,
: public org::freedesktop::DBus_proxy,
public DBus::IntrospectableProxy,
public DBus::ObjectProxy
{
public:
DBusBrowser( ::DBus::Connection& conn );
DBusBrowser(::DBus::Connection &conn);
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:

View file

@ -9,131 +9,131 @@ static const char *DBUS_SERVER_NAME = "org.freedesktop.DBus";
static const char *DBUS_SERVER_PATH = "/org/freedesktop/DBus";
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_border_width(5);
set_default_size(400, 500);
set_title("D-Bus Browser");
set_border_width(5);
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)
{
_cb_busnames.append_text(*it);
}
for (Names::iterator it = names.begin(); it != names.end(); ++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);
_tv_inspect.set_model(_tm_inspect);
_tv_inspect.append_column("Node", _records.name);
_tm_inspect = Gtk::TreeStore::create(_records);
_tv_inspect.set_model(_tm_inspect);
_tv_inspect.append_column("Node", _records.name);
_sc_tree.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
_sc_tree.add(_tv_inspect);
_sc_tree.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
_sc_tree.add(_tv_inspect);
_vbox.pack_start(_cb_busnames, Gtk::PACK_SHRINK);
_vbox.pack_start(_sc_tree);
_vbox.pack_start(_cb_busnames, Gtk::PACK_SHRINK);
_vbox.pack_start(_sc_tree);
add(_vbox);
add(_vbox);
show_all_children();
show_all_children();
}
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)
{
cout << name << " lost" << endl;
cout << name << " lost" << endl;
}
void DBusBrowser::NameAcquired(const std::string &name)
{
cout << name << " acquired" << endl;
cout << name << " acquired" << endl;
}
void DBusBrowser::on_select_busname()
{
Glib::ustring busname = _cb_busnames.get_active_text();
if (busname.empty()) return;
Glib::ustring busname = _cb_busnames.get_active_text();
if (busname.empty()) return;
_tm_inspect->clear();
_inspect_append(NULL, "", busname);
_tm_inspect->clear();
_inspect_append(NULL, "", 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::Node &root = *(doc.root);
::DBus::Xml::Document doc(inspector.Introspect());
::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)
{
::DBus::Xml::Node &iface = **ii;
for (::DBus::Xml::Nodes::iterator ii = ifaces.begin(); ii != ifaces.end(); ++ii)
{
::DBus::Xml::Node &iface = **ii;
Gtk::TreeModel::Row i_row = row
? *(_tm_inspect->append(row->children()))
: *(_tm_inspect->append());
i_row[_records.name] = "interface: " + iface.get("name");
Gtk::TreeModel::Row i_row = row
? *(_tm_inspect->append(row->children()))
: *(_tm_inspect->append());
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)
{
Gtk::TreeModel::Row m_row = *(_tm_inspect->append(i_row.children()));
m_row[_records.name] = "method: " + (*im)->get("name");
}
for (::DBus::Xml::Nodes::iterator im = methods.begin(); im != methods.end(); ++im)
{
Gtk::TreeModel::Row m_row = *(_tm_inspect->append(i_row.children()));
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)
{
Gtk::TreeModel::Row s_row = *(_tm_inspect->append(i_row.children()));
s_row[_records.name] = "signal: " + (*is)->get("name");
}
}
for (::DBus::Xml::Nodes::iterator is = signals.begin(); is != signals.end(); ++is)
{
Gtk::TreeModel::Row s_row = *(_tm_inspect->append(i_row.children()));
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)
{
std::string name = (*in)->get("name");
for (::DBus::Xml::Nodes::iterator in = nodes.begin(); in != nodes.end(); ++in)
{
std::string name = (*in)->get("name");
Gtk::TreeModel::Row n_row = row
? *(_tm_inspect->append(row->children()))
: *(_tm_inspect->append());
n_row[_records.name] = name;
Gtk::TreeModel::Row n_row = row
? *(_tm_inspect->append(row->children()))
: *(_tm_inspect->append());
n_row[_records.name] = name;
_inspect_append(&n_row, buspath + "/" + name, busname);
}
_inspect_append(&n_row, buspath + "/" + name, busname);
}
}
DBus::Glib::BusDispatcher dispatcher;
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
// TODO: choose in the GUI
DBus::Connection conn = DBus::Connection::SessionBus();
//DBus::Connection conn = DBus::Connection::SystemBus();
// activate one of both for either system or session bus
// TODO: choose in the GUI
DBus::Connection conn = DBus::Connection::SessionBus();
//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"
class DBusInspector
: public DBus::IntrospectableProxy,
: public DBus::IntrospectableProxy,
public DBus::ObjectProxy
{
public:
DBusInspector(DBus::Connection &conn, const char *path, const char *service)
: DBus::ObjectProxy(conn, path, service)
{}
DBusInspector(DBus::Connection &conn, const char *path, const char *service)
: DBus::ObjectProxy(conn, path, service)
{}
};
class DBusBrowser
: public org::freedesktop::DBus_proxy,
: public org::freedesktop::DBus_proxy,
public DBus::IntrospectableProxy,
public DBus::ObjectProxy,
public Gtk::Window
{
public:
DBusBrowser(::DBus::Connection &);
DBusBrowser(::DBus::Connection &);
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:
class InspectRecord : public Gtk::TreeModel::ColumnRecord
{
public:
class InspectRecord : public Gtk::TreeModel::ColumnRecord
{
public:
InspectRecord() { add(name); }
InspectRecord()
{
add(name);
}
Gtk::TreeModelColumn<Glib::ustring> name;
};
Gtk::TreeModelColumn<Glib::ustring> name;
};
Gtk::VBox _vbox;
Gtk::ScrolledWindow _sc_tree;
Gtk::ComboBoxText _cb_busnames;
Gtk::TreeView _tv_inspect;
Glib::RefPtr<Gtk::TreeStore> _tm_inspect;
InspectRecord _records;
Gtk::VBox _vbox;
Gtk::ScrolledWindow _sc_tree;
Gtk::ComboBoxText _cb_busnames;
Gtk::TreeView _tv_inspect;
Glib::RefPtr<Gtk::TreeStore> _tm_inspect;
InspectRecord _records;
};
#endif//__DEMO_DBUS_BROWSER_H

View file

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

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";
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";
client->Message("message set by property access");
std::cout << "wrote property 'Message'\n";
std::cout << "read property 'Message', value:" << client->Message() << "\n";
std::cout << "read property 'Message', value:" << client->Message() << "\n";
client->Data(1.1);
std::cout << "wrote property 'Data'\n";
client->Data(1.1);
std::cout << "wrote property 'Data'\n";
return NULL;
return NULL;
}
DBus::BusDispatcher dispatcher;
void niam(int sig)
{
dispatcher.leave();
pthread_exit(NULL);
dispatcher.leave();
pthread_exit(NULL);
}
int main()
{
signal(SIGTERM, niam);
signal(SIGINT, niam);
signal(SIGTERM, 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_create(&thread, NULL, test_property_proxy, &client);
pthread_t thread;
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"
class PropsClient
: public org::freedesktop::DBus::PropsGSDemo_proxy,
: public org::freedesktop::DBus::PropsGSDemo_proxy,
public DBus::IntrospectableProxy,
public DBus::PropertiesProxy,
public DBus::ObjectProxy
{
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 MessageChanged(const std::string &message);
void DataChanged(const double& data);
void DataChanged(const double &data);
};
#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";
PropsServer::PropsServer(DBus::Connection &connection)
: DBus::ObjectAdaptor(connection, PROPS_SERVER_PATH)
: DBus::ObjectAdaptor(connection, PROPS_SERVER_PATH)
{
Version = 1;
Message = "default message";
Version = 1;
Message = "default message";
}
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")
{
std::cout << "'Message' has been changed\n";
if (property == "Message")
{
std::cout << "'Message' has been changed\n";
std::string msg = value;
this->MessageChanged(msg);
}
if (property == "Data")
{
std::cout << "'Data' has been changed\n";
std::string msg = value;
this->MessageChanged(msg);
}
if (property == "Data")
{
std::cout << "'Data' has been changed\n";
double data = value;
this->DataChanged(data);
}
double data = value;
this->DataChanged(data);
}
}
DBus::BusDispatcher dispatcher;
void niam(int sig)
{
dispatcher.leave();
dispatcher.leave();
}
int main()
{
signal(SIGTERM, niam);
signal(SIGINT, niam);
signal(SIGTERM, niam);
signal(SIGINT, niam);
DBus::default_dispatcher = &dispatcher;
DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SessionBus();
conn.request_name(PROPS_SERVER_NAME);
DBus::Connection conn = DBus::Connection::SessionBus();
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"
class PropsServer
: public org::freedesktop::DBus::PropsGSDemo_adaptor,
: public org::freedesktop::DBus::PropsGSDemo_adaptor,
public DBus::IntrospectableAdaptor,
public DBus::PropertiesAdaptor,
public DBus::ObjectAdaptor
{
public:
PropsServer(DBus::Connection &connection);
PropsServer(DBus::Connection &connection);
void on_set_property
(DBus::InterfaceAdaptor &interface, const std::string &property, const DBus::Variant &value);
void on_set_property
(DBus::InterfaceAdaptor &interface, const std::string &property, const DBus::Variant &value);
};
#endif//__DEMO_PROPS_SERVER_H

View file

@ -33,11 +33,12 @@
#include "message.h"
#include "pendingcall.h"
namespace DBus {
namespace DBus
{
class Connection;
typedef Slot<bool, const Message&> MessageSlot;
typedef Slot<bool, const Message &> MessageSlot;
typedef std::list<Connection> ConnectionList;
@ -48,419 +49,419 @@ class DXXAPI Connection
{
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.
*
* 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
* 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
* won't find out about it.
*
* Normal API conventions would have the function return a boolean value
* indicating whether the error was set, but that would require blocking always
* to determine the return value.
*
* 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
* specification is the canonical version of this information.
*
* Rules are specified as a string of comma separated key/value pairs. An
* example is "type='signal',sender='org.freedesktop.DBus',
* interface='org.freedesktop.DBus',member='Foo', path='/bar/foo',destination=':452345.34'"
*
* 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.).
* 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
* that sender through regardless of the member.
*
* 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
* 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.
*
* 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.
*
* Currently there is no way to match against non-string arguments.
*
* Matching on interface is tricky because method call messages only optionally
* 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
* method calls should not usually give an interface.
*
* However, signal messages are required to include the interface so when
* 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.
*
* 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
* exist because the D-Bus bus daemon has fixed limits on all resource usage.
*
* \param rule Textual form of match rule.
* \throw Error
*/
void add_match( const char* rule );
/*!
* \brief Adds a match rule to match messages going through the message bus.
*
* 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
* 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
* won't find out about it.
*
* Normal API conventions would have the function return a boolean value
* indicating whether the error was set, but that would require blocking always
* to determine the return value.
*
* 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
* specification is the canonical version of this information.
*
* Rules are specified as a string of comma separated key/value pairs. An
* example is "type='signal',sender='org.freedesktop.DBus',
* interface='org.freedesktop.DBus',member='Foo', path='/bar/foo',destination=':452345.34'"
*
* 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.).
* 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
* that sender through regardless of the member.
*
* 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
* 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.
*
* 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.
*
* Currently there is no way to match against non-string arguments.
*
* Matching on interface is tricky because method call messages only optionally
* 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
* method calls should not usually give an interface.
*
* However, signal messages are required to include the interface so when
* 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.
*
* 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
* exist because the D-Bus bus daemon has fixed limits on all resource usage.
*
* \param rule Textual form of match rule.
* \throw Error
*/
void add_match(const char *rule);
/*!
* \brief Removes a previously-added match rule "by value" (the most
* recently-added identical rule gets removed).
*
* The "rule" argument is the string form of a match rule.
*
* 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().
*
* \param rule Textual form of match rule.
* \throw Error
*/
void remove_match( const char* rule, bool throw_on_error );
/*!
* \brief Removes a previously-added match rule "by value" (the most
* recently-added identical rule gets removed).
*
* The "rule" argument is the string form of a match rule.
*
* 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().
*
* \param rule Textual form of match rule.
* \throw Error
*/
void remove_match(const char *rule, bool throw_on_error);
/*!
* \brief Adds a message filter.
*
* Filters are handlers that are run on all incoming messages, prior to the
* objects registered with ObjectAdaptor::register_obj(). Filters are
* 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
* added during a filter callback won't be run on the message being processed.
*
* \param s The MessageSlot to add.
*/
bool add_filter( MessageSlot& s);
/*!
* \brief Adds a message filter.
*
* Filters are handlers that are run on all incoming messages, prior to the
* objects registered with ObjectAdaptor::register_obj(). Filters are
* 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
* added during a filter callback won't be run on the message being processed.
*
* \param s The MessageSlot to add.
*/
bool add_filter(MessageSlot &s);
/*!
* \brief Removes a previously-added message filter.
*
* 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
* one instance of it will be removed (the most recently-added instance).
*
* \param s The MessageSlot to remove.
*/
void remove_filter( MessageSlot& s);
/*!
* \brief Removes a previously-added message filter.
*
* 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
* one instance of it will be removed (the most recently-added instance).
*
* \param s The MessageSlot to remove.
*/
void remove_filter(MessageSlot &s);
/*!
* \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
* 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 only reason to use this function is to re-implement the equivalent of
* register_bus() yourself. One (probably unusual) reason to do that might
* 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
* register_bus(), instead of messing with this function. There's
* really no point creating pain for yourself by doing things manually.
* (Not sure if this is yet wrapped.)
*
* It's hard to use this function safely on shared connections (created by
* Connection()) in a multithreaded application, because only one
* registration attempt can be sent to the bus. If two threads are both
* sending the registration message, there is no mechanism in libdbus itself
* to avoid sending it twice.
*
* Thus, you need a way to coordinate which thread sends the registration
* 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
* (for example, if some libraries you're using might start libdbus-using
* threads), then you need to avoid using this function on shared connections.
*
* \param n The unique name.
*/
bool unique_name( const char* n );
/*!
* \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
* 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 only reason to use this function is to re-implement the equivalent of
* register_bus() yourself. One (probably unusual) reason to do that might
* 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
* register_bus(), instead of messing with this function. There's
* really no point creating pain for yourself by doing things manually.
* (Not sure if this is yet wrapped.)
*
* It's hard to use this function safely on shared connections (created by
* Connection()) in a multithreaded application, because only one
* registration attempt can be sent to the bus. If two threads are both
* sending the registration message, there is no mechanism in libdbus itself
* to avoid sending it twice.
*
* Thus, you need a way to coordinate which thread sends the registration
* 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
* (for example, if some libraries you're using might start libdbus-using
* threads), then you need to avoid using this function on shared connections.
*
* \param n The unique name.
*/
bool unique_name(const char *n);
/*!
* \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.
* All connections returned by dbus_bus_get() or dbus_bus_get_private() have
* been successfully registered. (Not sure if this is yet wrapped.)
*
* The name remains valid until the connection is freed, and should not be
* freed by the caller.
*
* 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
* responsible for calling unique_name(const char*) if you register by hand
* instead of using register_bus().
*/
const char* unique_name() const;
/*!
* \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.
* All connections returned by dbus_bus_get() or dbus_bus_get_private() have
* been successfully registered. (Not sure if this is yet wrapped.)
*
* The name remains valid until the connection is freed, and should not be
* freed by the caller.
*
* 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
* responsible for calling unique_name(const char*) if you register by hand
* instead of using register_bus().
*/
const char *unique_name() const;
/*!
* \brief Registers a connection with the bus.
*
* 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
* can be obtained using unique_name(void).
*
* This function will block until registration is complete.
*
* If the connection has already registered with the bus (determined by
* checking whether unique_name(void) returns a non-NULL value),
* then this function does nothing.
*
* 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.)
*
* \note Just use dbus_bus_get() or dbus_bus_get_private() instead of
* register_bus() and save yourself some pain. Using register_bus()
* manually is only useful if you have your own custom message bus not found
* in DBusBusType.
*
* 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
* you send the method calls yourself, call unique_name(const char*) with
* the unique bus name you get from the bus.
*
* For shared connections (created with dbus_connection_open()) in a
* multithreaded application, you can't really make the registration calls
* 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
* messages. (TODO: how is this done in the wrapper?)
*
* If you use register_bus() however, there is a lock that keeps both
* apps from registering at the same time.
*
* 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
* the app will respect.
*
* In a single-threaded application you can register by hand instead of using
* 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
* send the registration messages.
*/
bool register_bus();
/*!
* \brief Registers a connection with the bus.
*
* 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
* can be obtained using unique_name(void).
*
* This function will block until registration is complete.
*
* If the connection has already registered with the bus (determined by
* checking whether unique_name(void) returns a non-NULL value),
* then this function does nothing.
*
* 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.)
*
* \note Just use dbus_bus_get() or dbus_bus_get_private() instead of
* register_bus() and save yourself some pain. Using register_bus()
* manually is only useful if you have your own custom message bus not found
* in DBusBusType.
*
* 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
* you send the method calls yourself, call unique_name(const char*) with
* the unique bus name you get from the bus.
*
* For shared connections (created with dbus_connection_open()) in a
* multithreaded application, you can't really make the registration calls
* 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
* messages. (TODO: how is this done in the wrapper?)
*
* If you use register_bus() however, there is a lock that keeps both
* apps from registering at the same time.
*
* 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
* the app will respect.
*
* In a single-threaded application you can register by hand instead of using
* 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
* send the registration messages.
*/
bool register_bus();
/*!
* \brief Gets whether the connection is currently open.
*
* A connection may become disconnected when the remote application closes its
* end, or exits; a connection may also be disconnected with disconnect().
*
* There are not separate states for "closed" and "disconnected," the two
* terms are synonymous.
*
* \return true If the connection is still alive.
*/
bool connected() const;
/*!
* \brief Gets whether the connection is currently open.
*
* A connection may become disconnected when the remote application closes its
* end, or exits; a connection may also be disconnected with disconnect().
*
* There are not separate states for "closed" and "disconnected," the two
* terms are synonymous.
*
* \return true If the connection is still alive.
*/
bool connected() const;
/*!
* \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.
*
* Attempts to send messages after closing a connection are safe, but will
* result in error replies generated locally in libdbus.
*
* 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.
* It's impossible to "reopen" a connection, a new connection must be created.
* This function may result in a call to the DBusDispatchStatusFunction set
* with Private::init(), as the disconnect
* message it generates needs to be dispatched.
*
* 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
* connection.
*
* You may not close a shared connection. Connections created with
* dbus_connection_open() or dbus_bus_get() are shared. These connections are
* owned by libdbus, and applications should only unref them, never close them.
* 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
* 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.
*
* Connections created with dbus_connection_open_private() or
* dbus_bus_get_private() are not kept track of or referenced by libdbus.
* The creator of these connections is responsible for calling
* dbus_connection_close() prior to releasing the last reference, if the
* connection is not already disconnected.
*
* \todo dbus_connection_disconnect() was removed in dbus 0.9x. Maybe this
* function should be renamed to close().
*/
void disconnect();
/*!
* \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.
*
* Attempts to send messages after closing a connection are safe, but will
* result in error replies generated locally in libdbus.
*
* 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.
* It's impossible to "reopen" a connection, a new connection must be created.
* This function may result in a call to the DBusDispatchStatusFunction set
* with Private::init(), as the disconnect
* message it generates needs to be dispatched.
*
* 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
* connection.
*
* You may not close a shared connection. Connections created with
* dbus_connection_open() or dbus_bus_get() are shared. These connections are
* owned by libdbus, and applications should only unref them, never close them.
* 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
* 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.
*
* Connections created with dbus_connection_open_private() or
* dbus_bus_get_private() are not kept track of or referenced by libdbus.
* The creator of these connections is responsible for calling
* dbus_connection_close() prior to releasing the last reference, if the
* connection is not already disconnected.
*
* \todo dbus_connection_disconnect() was removed in dbus 0.9x. Maybe this
* function should be renamed to close().
*/
void disconnect();
/*!
* \brief Set whether _exit() should be called when the connection receives a
* disconnect signal.
*
* The call to _exit() comes after any handlers for the disconnect signal run;
* handlers can cancel the exit by calling this function.
*
* By default, exit_on_disconnect is false; but for message bus connections
* returned from dbus_bus_get() it will be toggled on by default.
*
* \param exit true If _exit() should be called after a disconnect signal.
*/
void exit_on_disconnect( bool exit );
/*!
* \brief Set whether _exit() should be called when the connection receives a
* disconnect signal.
*
* The call to _exit() comes after any handlers for the disconnect signal run;
* handlers can cancel the exit by calling this function.
*
* By default, exit_on_disconnect is false; but for message bus connections
* returned from dbus_bus_get() it will be toggled on by default.
*
* \param exit true If _exit() should be called after a disconnect signal.
*/
void exit_on_disconnect(bool exit);
/*!
* \brief Blocks until the outgoing message queue is empty.
*/
void flush();
/*!
* \brief Blocks until the outgoing message queue is empty.
*/
void flush();
/*!
* \brief Adds a message to the outgoing message queue.
*
* Does not block to write the message to the network; that happens
* asynchronously. To force the message to be written, call
* 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,
* no error will be returned.
*
* 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,
* 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
* Message::serial() or the D-Bus specification.
*
* \param msg The Message to write.
* \param serial Return location for message serial, or NULL if you don't care.
* \return true On success.
*/
bool send( const Message& msg, unsigned int* serial = NULL );
/*!
* \brief Adds a message to the outgoing message queue.
*
* Does not block to write the message to the network; that happens
* asynchronously. To force the message to be written, call
* 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,
* no error will be returned.
*
* 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,
* 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
* Message::serial() or the D-Bus specification.
*
* \param msg The Message to write.
* \param serial Return location for message serial, or NULL if you don't care.
* \return true On success.
*/
bool send(const Message &msg, unsigned int *serial = NULL);
/*!
* \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
* reply are queued up but not processed. This function is used to invoke
* method calls on a remote object.
*
* 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
* 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
* 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.
*
* \warning While this function blocks the calling thread will not be
* processing the incoming message queue. This means you can end up
* 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
* separate thread from the main connection-dispatching thread, or
* use PendingCall to avoid blocking.
*
* \param msg The Message to write.
* \param timeout Timeout in milliseconds (omit for default).
* \throw Error
*/
Message send_blocking( Message& msg, int timeout = -1);
/*!
* \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
* reply are queued up but not processed. This function is used to invoke
* method calls on a remote object.
*
* 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
* 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
* 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.
*
* \warning While this function blocks the calling thread will not be
* processing the incoming message queue. This means you can end up
* 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
* separate thread from the main connection-dispatching thread, or
* use PendingCall to avoid blocking.
*
* \param msg The Message to write.
* \param timeout Timeout in milliseconds (omit for default).
* \throw Error
*/
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);
/*!
* \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 );
void request_name(const char *name, int flags = 0);
unsigned long sender_unix_uid(const char *sender);
unsigned long sender_unix_uid(const char *sender);
/*!
* \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 );
/*!
* \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);
/*!
* \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 );
/*!
* \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();
const std::vector<std::string>& names();
void set_timeout(int timeout);
void set_timeout(int timeout);
int get_timeout();
int get_timeout();
private:
DXXAPILOCAL void init();
DXXAPILOCAL void init();
private:
RefPtrI<Private> _pvt;
int _timeout;
RefPtrI<Private> _pvt;
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 */

View file

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

View file

@ -29,157 +29,158 @@
#include "connection.h"
#include "eventloop.h"
namespace DBus {
namespace DBus
{
class DXXAPI Timeout
{
public:
class Internal;
class Internal;
Timeout(Internal *i);
Timeout(Internal *i);
virtual ~Timeout(){}
virtual ~Timeout() {}
/*!
* \brief Gets the timeout interval.
*
* The handle() should be called each time this interval elapses,
* starting after it elapses once.
*
* 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
* notify you of the change.
*
* return The interval in miliseconds.
*/
int interval() const;
/*!
* \brief Gets the timeout interval.
*
* The handle() should be called each time this interval elapses,
* starting after it elapses once.
*
* 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
* notify you of the change.
*
* return The interval in miliseconds.
*/
int interval() const;
bool enabled() const;
bool enabled() const;
/*!
* \brief Calls the timeout handler for this timeout.
*
* This function should be called when the timeout occurs.
*
* 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
* naturally times out is an adequate response to that problem, but you could
* try to do more if you wanted.
*
* return false If there wasn't enough memory.
*/
bool handle();
/*!
* \brief Calls the timeout handler for this timeout.
*
* This function should be called when the timeout occurs.
*
* 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
* naturally times out is an adequate response to that problem, but you could
* try to do more if you wanted.
*
* return false If there wasn't enough memory.
*/
bool handle();
virtual void toggle() = 0;
virtual void toggle() = 0;
private:
DXXAPILOCAL Timeout(const Timeout &);
DXXAPILOCAL Timeout(const Timeout &);
private:
Internal *_int;
Internal *_int;
};
class DXXAPI Watch
{
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++.
*
* This function calls dbus_watch_get_socket() on win32 and
* dbus_watch_get_unix_fd() on all other systems. (see dbus documentation)
*
* @return The file descriptor.
*/
int descriptor() const;
/*!
* \brief A main loop could poll this descriptor to integrate dbus-c++.
*
* This function calls dbus_watch_get_socket() on win32 and
* dbus_watch_get_unix_fd() on all other systems. (see dbus documentation)
*
* @return The file descriptor.
*/
int descriptor() const;
/*!
* \brief Gets flags from DBusWatchFlags indicating what conditions should be
* monitored on the file descriptor.
*
* 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
* a watch for hangups, errors, and other exceptional conditions.
*
* @return The conditions to watch.
*/
int flags() const;
/*!
* \brief Gets flags from DBusWatchFlags indicating what conditions should be
* monitored on the file descriptor.
*
* 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
* a watch for hangups, errors, and other exceptional conditions.
*
* @return The conditions to watch.
*/
int flags() const;
bool enabled() const;
bool enabled() const;
/*!
* \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.
*
* 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
* 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,
* but nothing more catastrophic should happen.
*
* dbus_watch_handle() cannot be called during the DBusAddWatchFunction, as the
* 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.
*
* @param flags The poll condition using DBusWatchFlags values.
* @return false If there wasn't enough memory.
*/
bool handle(int flags);
/*!
* \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.
*
* 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
* 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,
* but nothing more catastrophic should happen.
*
* dbus_watch_handle() cannot be called during the DBusAddWatchFunction, as the
* 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.
*
* @param flags The poll condition using DBusWatchFlags values.
* @return false If there wasn't enough memory.
*/
bool handle(int flags);
virtual void toggle() = 0;
virtual void toggle() = 0;
private:
DXXAPILOCAL Watch(const Watch &);
DXXAPILOCAL Watch(const Watch &);
private:
Internal *_int;
Internal *_int;
};
class DXXAPI Dispatcher
{
public:
virtual ~Dispatcher()
{}
virtual ~Dispatcher()
{}
void queue_connection(Connection::Private *);
void queue_connection(Connection::Private *);
void dispatch_pending();
bool has_something_to_dispatch();
void dispatch_pending();
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:
void dispatch_pending(Connection::PrivatePList& pending_queue);
void dispatch_pending(Connection::PrivatePList &pending_queue);
DefaultMutex _mutex_p;
DefaultMutex _mutex_p_copy;
DefaultMutex _mutex_p;
DefaultMutex _mutex_p_copy;
Connection::PrivatePList _pending_queue;
Connection::PrivatePList _pending_queue;
};
extern DXXAPI Dispatcher *default_dispatcher;
@ -191,38 +192,38 @@ class DXXAPI Mutex
{
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:
Internal *_int;
Internal *_int;
};
class DXXAPI CondVar
{
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:
Internal *_int;
Internal *_int;
};
typedef Mutex *(*MutexNewFn)();
@ -246,70 +247,70 @@ typedef void (*CondVarWakeAllFn)(CondVar *cv);
void DXXAPI _init_threading();
void DXXAPI _init_threading(
MutexNewFn, MutexFreeFn, MutexLockFn, MutexUnlockFn,
CondVarNewFn, CondVarFreeFn, CondVarWaitFn, CondVarWaitTimeoutFn, CondVarWakeOneFn, CondVarWakeAllFn
MutexNewFn, MutexFreeFn, MutexLockFn, MutexUnlockFn,
CondVarNewFn, CondVarFreeFn, CondVarWaitFn, CondVarWaitTimeoutFn, CondVarWakeOneFn, CondVarWakeAllFn
);
template<class Mx, class Cv>
struct Threading
{
static void init()
{
_init_threading(
mutex_new, mutex_free, mutex_lock, mutex_unlock,
condvar_new, condvar_free, condvar_wait, condvar_wait_timeout, condvar_wake_one, condvar_wake_all
);
}
static void init()
{
_init_threading(
mutex_new, mutex_free, mutex_lock, mutex_unlock,
condvar_new, condvar_free, condvar_wait, condvar_wait_timeout, condvar_wake_one, condvar_wake_all
);
}
static Mutex *mutex_new()
{
return new Mx;
}
static Mutex *mutex_new()
{
return new Mx;
}
static void mutex_free(Mutex *mx)
{
delete mx;
}
static void mutex_free(Mutex *mx)
{
delete mx;
}
static void mutex_lock(Mutex *mx)
{
mx->lock();
}
static void mutex_lock(Mutex *mx)
{
mx->lock();
}
static void mutex_unlock(Mutex *mx)
{
mx->unlock();
}
static void mutex_unlock(Mutex *mx)
{
mx->unlock();
}
static CondVar *condvar_new()
{
return new Cv;
}
static CondVar *condvar_new()
{
return new Cv;
}
static void condvar_free(CondVar *cv)
{
delete cv;
}
static void condvar_free(CondVar *cv)
{
delete cv;
}
static void condvar_wait(CondVar *cv, Mutex *mx)
{
cv->wait(mx);
}
static void condvar_wait(CondVar *cv, Mutex *mx)
{
cv->wait(mx);
}
static bool condvar_wait_timeout(CondVar *cv, Mutex *mx, int timeout)
{
return cv->wait_timeout(mx, timeout);
}
static bool condvar_wait_timeout(CondVar *cv, Mutex *mx, int timeout)
{
return cv->wait_timeout(mx, timeout);
}
static void condvar_wake_one(CondVar *cv)
{
cv->wake_one();
}
static void condvar_wake_one(CondVar *cv)
{
cv->wake_one();
}
static void condvar_wake_all(CondVar *cv)
{
cv->wake_all();
}
static void condvar_wake_all(CondVar *cv)
{
cv->wake_all();
}
};
} /* namespace DBus */

View file

@ -31,9 +31,11 @@
#include "dispatcher.h"
#include "Ecore.h"
namespace DBus {
namespace DBus
{
namespace Ecore {
namespace Ecore
{
class BusDispatcher;
@ -41,70 +43,70 @@ class DXXAPI BusTimeout : public Timeout
{
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:
Ecore_Timer *_etimer;
friend class BusDispatcher;
friend class BusDispatcher;
};
class DXXAPI BusWatch : public Watch
{
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_prepare ( void *data, Ecore_Fd_Handler *fdh);
static Eina_Bool watch_dispatch ( 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_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:
Ecore_Fd_Handler *fd_handler;
Ecore::BusDispatcher *_bd;
friend class BusDispatcher;
friend class BusDispatcher;
};
class DXXAPI BusDispatcher : public Dispatcher
{
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 check ( 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);
private:
};

View file

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

View file

@ -31,7 +31,8 @@
#include "util.h"
#include "eventloop.h"
namespace DBus {
namespace DBus
{
/*
* Glue between the event loop and the DBus library
@ -42,55 +43,55 @@ class Pipe;
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
{
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
{
public:
BusDispatcher();
BusDispatcher();
~BusDispatcher() {}
~BusDispatcher() {}
virtual void enter();
virtual void enter();
virtual void leave();
virtual void leave();
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 void do_iteration();
virtual Timeout *add_timeout(Timeout::Internal *);
virtual Timeout *add_timeout(Timeout::Internal *);
virtual void rem_timeout(Timeout *);
virtual void rem_timeout(Timeout *);
virtual Watch *add_watch(Watch::Internal *);
virtual Watch *add_watch(Watch::Internal *);
virtual void rem_watch(Watch *);
virtual void rem_watch(Watch *);
void watch_ready(DefaultWatch &);
void watch_ready(DefaultWatch &);
void timeout_expired(DefaultTimeout &);
void timeout_expired(DefaultTimeout &);
private:
bool _running;
int _pipe[2];
std::list <Pipe*> pipe_list;
bool _running;
int _pipe[2];
std::list <Pipe *> pipe_list;
};
} /* namespace DBus */

View file

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

View file

@ -30,9 +30,11 @@
#include "api.h"
#include "dispatcher.h"
namespace DBus {
namespace DBus
{
namespace Glib {
namespace Glib
{
class BusDispatcher;
@ -40,80 +42,80 @@ class DXXAPI BusTimeout : public Timeout
{
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:
GMainContext *_ctx;
int _priority;
GSource *_source;
GMainContext *_ctx;
int _priority;
GSource *_source;
friend class BusDispatcher;
friend class BusDispatcher;
};
class DXXAPI BusWatch : public Watch
{
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:
GMainContext *_ctx;
int _priority;
GSource *_source;
GMainContext *_ctx;
int _priority;
GSource *_source;
friend class BusDispatcher;
friend class BusDispatcher;
};
class DXXAPI BusDispatcher : public Dispatcher
{
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:
GMainContext *_ctx;
int _priority;
GSource *_source;
GMainContext *_ctx;
int _priority;
GSource *_source;
};
} /* namespace Glib */

View file

@ -33,15 +33,16 @@
#include "message.h"
namespace DBus {
namespace DBus
{
//todo: this should belong to to properties.h
struct DXXAPI PropertyData
{
bool read;
bool write;
std::string sig;
Variant value;
bool read;
bool write;
std::string sig;
Variant value;
};
typedef std::map<std::string, PropertyData> PropertyTable;
@ -58,18 +59,18 @@ class DXXAPI AdaptorBase
{
public:
virtual const ObjectAdaptor *object() const = 0 ;
virtual const ObjectAdaptor *object() const = 0 ;
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:
virtual const ObjectProxy *object() const = 0 ;
virtual const ObjectProxy *object() const = 0 ;
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;
virtual bool _invoke_method_noreply(CallMessage &call) = 0;
InterfaceProxyTable _interfaces;
InterfaceProxyTable _interfaces;
};
class DXXAPI Interface
{
public:
Interface(const std::string &name);
Interface(const std::string &name);
virtual ~Interface();
virtual ~Interface();
inline const std::string &name() const;
inline const std::string &name() const;
private:
std::string _name;
std::string _name;
};
/*
@ -121,7 +122,7 @@ private:
const std::string &Interface::name() const
{
return _name;
return _name;
}
/*
@ -133,25 +134,25 @@ class DXXAPI InterfaceAdaptor : public Interface, public virtual AdaptorBase
{
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
{
return NULL;
}
virtual IntrospectedInterface *introspect() const
{
return NULL;
}
protected:
MethodTable _methods;
PropertyTable _properties;
MethodTable _methods;
PropertyTable _properties;
};
/*
@ -163,17 +164,17 @@ class DXXAPI InterfaceProxy : public Interface, public virtual ProxyBase
{
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:
SignalTable _signals;
SignalTable _signals;
};
# define register_method(interface, method, callback) \

View file

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

View file

@ -31,7 +31,8 @@
#include "api.h"
#include "util.h"
namespace DBus {
namespace DBus
{
class Message;
class ErrorMessage;
@ -44,175 +45,175 @@ class DXXAPI MessageIter
{
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);
bool append_string(const char *chars);
const char *get_string();
const char *get_string();
bool append_path(const char *chars);
bool append_path(const char *chars);
const char *get_path();
const char *get_path();
bool append_signature(const char *chars);
bool append_signature(const char *chars);
const char *get_signature();
const char *get_signature();
char *signature() const; //returned string must be manually free()'d
char *signature() const; //returned string must be manually free()'d
MessageIter recurse();
MessageIter recurse();
bool append_array(char type, const void *ptr, size_t length);
bool append_array(char type, const void *ptr, size_t length);
int array_type();
int array_type();
int get_array(void *ptr);
int get_array(void *ptr);
bool is_array();
bool is_array();
bool is_dict();
bool is_dict();
MessageIter new_array(const char *sig);
MessageIter new_array(const char *sig);
MessageIter new_variant(const char *sig);
MessageIter new_variant(const char *sig);
MessageIter new_struct();
MessageIter new_struct();
MessageIter new_dict_entry();
MessageIter new_dict_entry();
void close_container(MessageIter &container);
void close_container(MessageIter &container);
void copy_data(MessageIter &to);
void copy_data(MessageIter &to);
Message &msg() const
{
return *_msg;
}
Message &msg() const
{
return *_msg;
}
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:
/* I'm sorry, but don't want to include dbus.h in the public api
*/
unsigned char _iter[sizeof(void *)*3+sizeof(int)*11];
/* I'm sorry, but don't want to include dbus.h in the public api
*/
unsigned char _iter[sizeof(void *) * 3 + sizeof(int) * 11];
Message *_msg;
Message *_msg;
friend class Message;
friend class Message;
};
class DXXAPI Message
{
public:
struct Private;
struct Private;
Message(Private *, bool incref = true);
Message(Private *, bool incref = true);
Message(const Message &m);
Message(const Message &m);
~Message();
~Message();
Message &operator = (const Message &m);
Message &operator = (const Message &m);
Message copy();
Message copy();
int type() const;
int type() const;
int serial() const;
int serial() const;
int reply_serial() const;
int reply_serial() const;
bool reply_serial(int);
bool reply_serial(int);
const char *sender() const;
const char *sender() const;
bool sender(const char *s);
bool sender(const char *s);
const char *destination() const;
const char *destination() const;
bool destination(const char *s);
bool destination(const char *s);
bool is_error() const;
bool is_error() const;
bool is_signal(const char *interface, const char *member) const;
bool is_signal(const char *interface, const char *member) const;
MessageIter reader() const;
MessageIter reader() const;
MessageIter writer();
MessageIter writer();
bool append(int first_type, ...);
bool append(int first_type, ...);
void terminate();
void terminate();
protected:
Message();
Message();
protected:
RefPtrI<Private> _pvt;
RefPtrI<Private> _pvt;
/* classes who need to read `_pvt` directly
*/
friend class ErrorMessage;
friend class ReturnMessage;
friend class MessageIter;
friend class Error;
friend class Connection;
/* classes who need to read `_pvt` directly
*/
friend class ErrorMessage;
friend class ReturnMessage;
friend class MessageIter;
friend class Error;
friend class Connection;
};
/*
@ -222,15 +223,15 @@ class DXXAPI ErrorMessage : public Message
{
public:
ErrorMessage();
ErrorMessage();
ErrorMessage(const Message &, const char *name, const char *message);
ErrorMessage(const Message &, const char *name, const char *message);
const char *name() const;
const char *name() const;
bool name(const char *n);
bool name(const char *n);
bool operator == (const ErrorMessage &) const;
bool operator == (const ErrorMessage &) const;
};
/*
@ -240,25 +241,25 @@ class DXXAPI SignalMessage : public Message
{
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;
};
/*
@ -268,27 +269,27 @@ class DXXAPI CallMessage : public Message
{
public:
CallMessage();
CallMessage();
CallMessage(const char *dest, const char *path, const char *iface, const char *method);
CallMessage(const char *dest, const char *path, const char *iface, const char *method);
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);
const char *signature() const;
const char *signature() const;
bool operator == (const CallMessage &) const;
bool operator == (const CallMessage &) const;
};
/*
@ -298,9 +299,9 @@ class DXXAPI ReturnMessage : public Message
{
public:
ReturnMessage(const CallMessage &callee);
ReturnMessage(const CallMessage &callee);
const char *signature() const;
const char *signature() const;
};
} /* namespace DBus */

View file

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

View file

@ -29,7 +29,8 @@
#include "util.h"
#include "message.h"
namespace DBus {
namespace DBus
{
class Connection;
@ -37,94 +38,94 @@ class DXXAPI PendingCall
{
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.
*
* \return true If a reply has been received.
*/
bool completed();
/*!
* \brief Checks whether the pending call has received a reply yet, or not.
*
* \return true If a reply has been received.
*/
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 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.
*
* The blocking is as with Connection::send_blocking(); it
* does not enter the main loop or process other messages, it simply waits for
* the reply in question.
*
* If the pending call is already completed, this function returns immediately.
*/
void block();
/*!
* \brief Block until the pending call is completed.
*
* The blocking is as with Connection::send_blocking(); it
* does not enter the main loop or process other messages, it simply waits for
* the reply in question.
*
* If the pending call is already completed, this function returns immediately.
*/
void block();
/*!
* \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
* pending call is finalized.
*
* The slot is allocated automatic.
*
* \param data The data to store.
* \throw ErrorNoMemory
*/
void data( void* 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
* pending call is finalized.
*
* The slot is allocated automatic.
*
* \param data The data to store.
* \throw ErrorNoMemory
*/
void data(void *data);
/*!
* \brief Retrieves data previously set with dbus_pending_call_set_data().
*
* The slot must still be allocated (must not have been freed).
*
* \return The data, or NULL if not found.
*/
void *data();
/*!
* \brief Retrieves data previously set with dbus_pending_call_set_data().
*
* The slot must still be allocated (must not have been freed).
*
* \return The data, or NULL if not found.
*/
void *data();
/*!
* \return The data slot.
*/
Slot<void, PendingCall &>& slot();
/*!
* \return The data slot.
*/
Slot<void, PendingCall &>& slot();
/*!
* \brief Gets the reply
*
* 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
* the caller.
*
* \return The reply Message.
* \throw ErrorNoReply
*/
Message steal_reply();
/*!
* \brief Gets the reply
*
* 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
* the caller.
*
* \return The reply Message.
* \throw ErrorNoReply
*/
Message steal_reply();
private:
RefPtrI<Private> _pvt;
RefPtrI<Private> _pvt;
friend struct Private;
friend class Connection;
friend struct Private;
friend class Connection;
};
} /* namespace DBus */

View file

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

View file

@ -29,37 +29,38 @@
#include "types.h"
#include "interface.h"
namespace DBus {
namespace DBus
{
template <typename T>
class PropertyAdaptor
{
public:
PropertyAdaptor() : _data(0)
{}
PropertyAdaptor() : _data(0)
{}
void bind(PropertyData &data)
{
_data = &data;
}
void bind(PropertyData &data)
{
_data = &data;
}
T operator() (void) const
{
return _data->value.operator T();
}
T operator()(void) const
{
return _data->value.operator T();
}
PropertyAdaptor &operator = (const T &t)
{
_data->value.clear();
MessageIter wi = _data->value.writer();
wi << t;
return *this;
}
PropertyAdaptor &operator = (const T &t)
{
_data->value.clear();
MessageIter wi = _data->value.writer();
wi << t;
return *this;
}
private:
PropertyData *_data;
PropertyData *_data;
};
struct IntrospectedInterface;
@ -68,32 +69,32 @@ class DXXAPI PropertiesAdaptor : public InterfaceAdaptor
{
public:
PropertiesAdaptor();
PropertiesAdaptor();
Message Get(const CallMessage &);
Message Get(const CallMessage &);
Message Set(const CallMessage &);
Message Set(const CallMessage &);
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
{
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 */

View file

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

View file

@ -33,7 +33,8 @@
#include "util.h"
#include "dispatcher.h"
namespace DBus {
namespace DBus
{
class Server;
@ -43,30 +44,30 @@ class DXXAPI Server
{
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:
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:
RefPtrI<Private> _pvt;
RefPtrI<Private> _pvt;
};
} /* namespace DBus */

View file

@ -35,30 +35,31 @@
#include "message.h"
#include "error.h"
namespace DBus {
namespace DBus
{
struct DXXAPI Path : public std::string
{
Path() {}
Path(const std::string &s) : std::string(s) {}
Path(const char *c) : std::string(c) {}
Path &operator = (std::string &s)
{
std::string::operator = (s);
return *this;
}
Path() {}
Path(const std::string &s) : std::string(s) {}
Path(const char *c) : std::string(c) {}
Path &operator = (std::string &s)
{
std::string::operator = (s);
return *this;
}
};
struct DXXAPI Signature : public std::string
{
Signature() {}
Signature(const std::string &s) : std::string(s) {}
Signature(const char *c) : std::string(c) {}
Signature &operator = (std::string &s)
{
std::string::operator = (s);
return *this;
}
Signature() {}
Signature(const std::string &s) : std::string(s) {}
Signature(const char *c) : std::string(c) {}
Signature &operator = (std::string &s)
{
std::string::operator = (s);
return *this;
}
};
struct DXXAPI Invalid {};
@ -67,471 +68,580 @@ class DXXAPI Variant
{
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
{
return _msg.reader();
}
MessageIter reader() const
{
return _msg.reader();
}
MessageIter writer()
{
return _msg.writer();
}
MessageIter writer()
{
return _msg.writer();
}
template <typename T>
operator T() const
{
T cast;
MessageIter ri = _msg.reader();
ri >> cast;
return cast;
}
template <typename T>
operator T() const
{
T cast;
MessageIter ri = _msg.reader();
ri >> cast;
return cast;
}
private:
Message _msg;
Message _msg;
};
template <
typename T1,
typename T2 = Invalid,
typename T3 = Invalid,
typename T4 = Invalid,
typename T5 = Invalid,
typename T6 = Invalid,
typename T7 = Invalid,
typename T8 = Invalid,
typename T9 = Invalid,
typename T10 = Invalid,
typename T11 = Invalid,
typename T12 = Invalid,
typename T13 = Invalid,
typename T14 = Invalid,
typename T15 = Invalid,
typename T16 = Invalid // nobody needs more than 16
>
typename T1,
typename T2 = Invalid,
typename T3 = Invalid,
typename T4 = Invalid,
typename T5 = Invalid,
typename T6 = Invalid,
typename T7 = Invalid,
typename T8 = Invalid,
typename T9 = Invalid,
typename T10 = Invalid,
typename T11 = Invalid,
typename T12 = Invalid,
typename T13 = Invalid,
typename T14 = Invalid,
typename T15 = Invalid,
typename T16 = Invalid // nobody needs more than 16
>
struct Struct
{
T1 _1; 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;
T1 _1;
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>
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>
struct type
{
static std::string sig()
{
throw ErrorInvalidArgs("unknown type");
return "";
}
static std::string sig()
{
throw ErrorInvalidArgs("unknown type");
return "";
}
};
template <> struct type<Variant> { static std::string sig(){ return "v"; } };
template <> struct type<uint8_t> { static std::string sig(){ return "y"; } };
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 <> struct type<Variant>
{
static std::string sig()
{
return "v";
}
};
template <> struct type<uint8_t>
{
static std::string sig()
{
return "y";
}
};
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>
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>
struct type< std::map<K,V> >
{ static std::string sig(){ return "a{" + type<K>::sig() + type<V>::sig() + "}"; } };
struct type< std::map<K, V> >
{
static std::string sig()
{
return "a{" + type<K>::sig() + type<V>::sig() + "}";
}
};
template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9,
typename T10,
typename T11,
typename T12,
typename T13,
typename T14,
typename T15,
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> >
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9,
typename T10,
typename T11,
typename T12,
typename T13,
typename T14,
typename T15,
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> >
{
static std::string sig()
{
return "("
+ type<T1>::sig()
+ type<T2>::sig()
+ type<T3>::sig()
+ type<T4>::sig()
+ type<T5>::sig()
+ type<T6>::sig()
+ type<T7>::sig()
+ type<T8>::sig()
+ type<T9>::sig()
+ type<T10>::sig()
+ type<T11>::sig()
+ type<T12>::sig()
+ type<T13>::sig()
+ type<T14>::sig()
+ type<T15>::sig()
+ type<T16>::sig()
+ ")";
}
static std::string sig()
{
return "("
+ type<T1>::sig()
+ type<T2>::sig()
+ type<T3>::sig()
+ type<T4>::sig()
+ type<T5>::sig()
+ type<T6>::sig()
+ type<T7>::sig()
+ type<T8>::sig()
+ type<T9>::sig()
+ type<T10>::sig()
+ type<T11>::sig()
+ type<T12>::sig()
+ type<T13>::sig()
+ type<T14>::sig()
+ type<T15>::sig()
+ type<T16>::sig()
+ ")";
}
};
} /* namespace DBus */
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)
{
iter.append_byte(val);
return iter;
iter.append_byte(val);
return iter;
}
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const bool &val)
{
iter.append_bool(val);
return iter;
iter.append_bool(val);
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);
return iter;
iter.append_int16(val);
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);
return iter;
iter.append_uint16(val);
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);
return iter;
iter.append_int32(val);
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);
return iter;
iter.append_uint32(val);
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);
return iter;
iter.append_int64(val);
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);
return iter;
iter.append_uint64(val);
return iter;
}
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const double &val)
{
iter.append_double(val);
return iter;
iter.append_double(val);
return iter;
}
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::string &val)
{
iter.append_string(val.c_str());
return iter;
iter.append_string(val.c_str());
return iter;
}
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Path &val)
{
iter.append_path(val.c_str());
return iter;
iter.append_path(val.c_str());
return iter;
}
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Signature &val)
{
iter.append_signature(val.c_str());
return iter;
iter.append_signature(val.c_str());
return iter;
}
template<typename E>
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<E>& val)
{
const std::string sig = DBus::type<E>::sig();
DBus::MessageIter ait = iter.new_array(sig.c_str());
const std::string sig = DBus::type<E>::sig();
DBus::MessageIter ait = iter.new_array(sig.c_str());
typename std::vector<E>::const_iterator vit;
for (vit = val.begin(); vit != val.end(); ++vit)
{
ait << *vit;
}
typename std::vector<E>::const_iterator vit;
for (vit = val.begin(); vit != val.end(); ++vit)
{
ait << *vit;
}
iter.close_container(ait);
return iter;
iter.close_container(ait);
return iter;
}
template<>
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<uint8_t>& val)
{
DBus::MessageIter ait = iter.new_array("y");
ait.append_array('y', &val.front(), val.size());
iter.close_container(ait);
return iter;
DBus::MessageIter ait = iter.new_array("y");
ait.append_array('y', &val.front(), val.size());
iter.close_container(ait);
return iter;
}
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() + "}";
DBus::MessageIter ait = iter.new_array(sig.c_str());
const std::string sig = "{" + DBus::type<K>::sig() + DBus::type<V>::sig() + "}";
DBus::MessageIter ait = iter.new_array(sig.c_str());
typename std::map<K,V>::const_iterator mit;
for (mit = val.begin(); mit != val.end(); ++mit)
{
DBus::MessageIter eit = ait.new_dict_entry();
typename std::map<K, V>::const_iterator mit;
for (mit = val.begin(); mit != val.end(); ++mit)
{
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);
return iter;
iter.close_container(ait);
return iter;
}
template <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9,
typename T10,
typename T11,
typename T12,
typename T13,
typename T14,
typename T15,
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)
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9,
typename T10,
typename T11,
typename T12,
typename T13,
typename T14,
typename T15,
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)
{
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._9 << val._10 << val._11 << val._12
<< 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);
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Invalid &)
{
return iter;
return iter;
}
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint8_t &val)
{
val = iter.get_byte();
return ++iter;
val = iter.get_byte();
return ++iter;
}
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, bool &val)
{
val = iter.get_bool();
return ++iter;
val = iter.get_bool();
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();
return ++iter;
val = iter.get_int16();
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();
return ++iter;
val = iter.get_uint16();
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();
return ++iter;
val = iter.get_int32();
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();
return ++iter;
val = iter.get_uint32();
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();
return ++iter;
val = iter.get_int64();
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();
return ++iter;
val = iter.get_uint64();
return ++iter;
}
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, double &val)
{
val = iter.get_double();
return ++iter;
val = iter.get_double();
return ++iter;
}
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::string &val)
{
val = iter.get_string();
return ++iter;
val = iter.get_string();
return ++iter;
}
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Path &val)
{
val = iter.get_path();
return ++iter;
val = iter.get_path();
return ++iter;
}
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Signature &val)
{
val = iter.get_signature();
return ++iter;
val = iter.get_signature();
return ++iter;
}
template<typename E>
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<E>& val)
{
if (!iter.is_array())
throw DBus::ErrorInvalidArgs("array expected");
if (!iter.is_array())
throw DBus::ErrorInvalidArgs("array expected");
DBus::MessageIter ait = iter.recurse();
DBus::MessageIter ait = iter.recurse();
while (!ait.at_end())
{
E elem;
while (!ait.at_end())
{
E elem;
ait >> elem;
ait >> elem;
val.push_back(elem);
}
return ++iter;
val.push_back(elem);
}
return ++iter;
}
template<>
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<uint8_t>& val)
{
if (!iter.is_array())
throw DBus::ErrorInvalidArgs("array expected");
if (!iter.is_array())
throw DBus::ErrorInvalidArgs("array expected");
if (iter.array_type() != 'y')
throw DBus::ErrorInvalidArgs("byte-array expected");
if (iter.array_type() != 'y')
throw DBus::ErrorInvalidArgs("byte-array expected");
DBus::MessageIter ait = iter.recurse();
DBus::MessageIter ait = iter.recurse();
uint8_t *array;
size_t length = ait.get_array(&array);
uint8_t *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>
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())
throw DBus::ErrorInvalidArgs("dictionary value expected");
if (!iter.is_dict())
throw DBus::ErrorInvalidArgs("dictionary value expected");
DBus::MessageIter mit = iter.recurse();
DBus::MessageIter mit = iter.recurse();
while (!mit.at_end())
{
K key; V value;
while (!mit.at_end())
{
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 <
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9,
typename T10,
typename T11,
typename T12,
typename T13,
typename T14,
typename T15,
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)
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9,
typename T10,
typename T11,
typename T12,
typename T13,
typename T14,
typename T15,
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)
{
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._9 >> val._10 >> val._11 >> val._12
>> val._13 >> val._14 >> val._15 >> val._16;
return ++iter;
return ++iter;
}
extern DXXAPI DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Variant &val);

View file

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

View file

@ -42,432 +42,433 @@
using namespace DBus;
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)
: 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()
{
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))
{
std::vector<std::string>::iterator i = names.begin();
if (dbus_connection_get_is_connected(conn))
{
std::vector<std::string>::iterator i = names.begin();
while (i != names.end())
{
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);
++i;
}
dbus_connection_close(conn);
}
dbus_connection_unref(conn);
while (i != names.end())
{
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);
++i;
}
dbus_connection_close(conn);
}
dbus_connection_unref(conn);
}
void Connection::Private::init()
{
dbus_connection_ref(conn);
dbus_connection_ref(conn); //todo: the library has to own another reference
dbus_connection_ref(conn);
dbus_connection_ref(conn); //todo: the library has to own another reference
disconn_filter = new Callback<Connection::Private, bool, const Message &>(
this, &Connection::Private::disconn_filter_function
);
disconn_filter = new Callback<Connection::Private, bool, const Message &>(
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_exit_on_disconnect(conn, false); //why was this set to true??
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??
}
void Connection::Private::detach_server()
{
/* Server::Private *tmp = server;
/* Server::Private *tmp = server;
server = NULL;
server = NULL;
if (tmp)
{
ConnectionList::iterator i;
if (tmp)
{
ConnectionList::iterator i;
for (i = tmp->connections.begin(); i != tmp->connections.end(); ++i)
{
if (i->_pvt.get() == this)
{
tmp->connections.erase(i);
break;
}
}
}*/
for (i = tmp->connections.begin(); i != tmp->connections.end(); ++i)
{
if (i->_pvt.get() == this)
{
tmp->connections.erase(i);
break;
}
}
}*/
}
bool Connection::Private::do_dispatch()
{
debug_log("dispatching on %p", conn);
debug_log("dispatching on %p", conn);
if (!dbus_connection_get_is_connected(conn))
{
debug_log("connection terminated");
if (!dbus_connection_get_is_connected(conn))
{
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)
{
Private *p = static_cast<Private *>(data);
Private *p = static_cast<Private *>(data);
switch (status)
{
case DBUS_DISPATCH_DATA_REMAINS:
debug_log("some dispatching to do on %p", dc);
p->dispatcher->queue_connection(p);
break;
switch (status)
{
case DBUS_DISPATCH_DATA_REMAINS:
debug_log("some dispatching to do on %p", dc);
p->dispatcher->queue_connection(p);
break;
case DBUS_DISPATCH_COMPLETE:
debug_log("all dispatching done on %p", dc);
break;
case DBUS_DISPATCH_COMPLETE:
debug_log("all dispatching done on %p", dc);
break;
case DBUS_DISPATCH_NEED_MEMORY: //uh oh...
debug_log("connection %p needs memory", dc);
break;
}
case DBUS_DISPATCH_NEED_MEMORY: //uh oh...
debug_log("connection %p needs memory", dc);
break;
}
}
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)
? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
return slot && !slot->empty() && slot->call(msg)
? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
bool Connection::Private::disconn_filter_function(const Message &msg)
{
if (msg.is_signal(DBUS_INTERFACE_LOCAL,"Disconnected"))
{
debug_log("%p disconnected by local bus", conn);
dbus_connection_close(conn);
if (msg.is_signal(DBUS_INTERFACE_LOCAL, "Disconnected"))
{
debug_log("%p disconnected by local bus", conn);
dbus_connection_close(conn);
return true;
}
return false;
return true;
}
return false;
}
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()
{
return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS;
return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS;
}
Connection Connection::SystemBus()
{
return Connection(new Private(DBUS_BUS_SYSTEM));
return Connection(new Private(DBUS_BUS_SYSTEM));
}
Connection Connection::SessionBus()
{
return Connection(new Private(DBUS_BUS_SESSION));
return Connection(new Private(DBUS_BUS_SESSION));
}
Connection Connection::ActivationBus()
{
return Connection(new Private(DBUS_BUS_STARTER));
return Connection(new Private(DBUS_BUS_STARTER));
}
Connection::Connection(const char *address, bool priv)
: _timeout(-1)
: _timeout(-1)
{
InternalError e;
DBusConnection *conn = priv
? dbus_connection_open_private(address, e)
: dbus_connection_open(address, e);
InternalError e;
DBusConnection *conn = priv
? dbus_connection_open_private(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)
: _pvt(p), _timeout(-1)
: _pvt(p), _timeout(-1)
{
setup(default_dispatcher);
setup(default_dispatcher);
}
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()
{
dbus_connection_unref(_pvt->conn);
dbus_connection_unref(_pvt->conn);
}
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(
_pvt->conn,
Dispatcher::Private::on_add_watch,
Dispatcher::Private::on_rem_watch,
Dispatcher::Private::on_toggle_watch,
dispatcher,
0
);
dbus_connection_set_watch_functions(
_pvt->conn,
Dispatcher::Private::on_add_watch,
Dispatcher::Private::on_rem_watch,
Dispatcher::Private::on_toggle_watch,
dispatcher,
0
);
dbus_connection_set_timeout_functions(
_pvt->conn,
Dispatcher::Private::on_add_timeout,
Dispatcher::Private::on_rem_timeout,
Dispatcher::Private::on_toggle_timeout,
dispatcher,
0
);
dbus_connection_set_timeout_functions(
_pvt->conn,
Dispatcher::Private::on_add_timeout,
Dispatcher::Private::on_rem_timeout,
Dispatcher::Private::on_toggle_timeout,
dispatcher,
0
);
return prev;
return prev;
}
bool Connection::operator == (const Connection &c) const
{
return _pvt->conn == c._pvt->conn;
return _pvt->conn == c._pvt->conn;
}
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);
if (e) throw(e);
return r;
return r;
}
bool Connection::connected() const
{
return dbus_connection_get_is_connected(_pvt->conn);
return dbus_connection_get_is_connected(_pvt->conn);
}
void Connection::disconnect()
{
// 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)
{
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)
{
return dbus_bus_set_unique_name(_pvt->conn, n);
return dbus_bus_set_unique_name(_pvt->conn, n);
}
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()
{
dbus_connection_flush(_pvt->conn);
dbus_connection_flush(_pvt->conn);
}
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,
bool throw_on_error)
bool throw_on_error)
{
InternalError e;
InternalError e;
dbus_bus_remove_match(_pvt->conn, rule, e);
dbus_bus_remove_match(_pvt->conn, rule, e);
debug_log("%s: removed match rule %s", unique_name(), rule);
debug_log("%s: removed match rule %s", unique_name(), rule);
if (e) {
if (throw_on_error)
throw Error(e);
else
debug_log("DBus::Connection::remove_match: %s (%s).",
static_cast<DBusError*>(e)->message,
static_cast<DBusError*>(e)->name);
}
if (e)
{
if (throw_on_error)
throw Error(e);
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)
{
debug_log("%s: adding filter", unique_name());
return dbus_connection_add_filter(_pvt->conn, Private::message_filter_stub, &s, NULL);
debug_log("%s: adding filter", unique_name());
return dbus_connection_add_filter(_pvt->conn, Private::message_filter_stub, &s, NULL);
}
void Connection::remove_filter(MessageSlot &s)
{
debug_log("%s: removing filter", unique_name());
dbus_connection_remove_filter(_pvt->conn, Private::message_filter_stub, &s);
debug_log("%s: removing filter", unique_name());
dbus_connection_remove_filter(_pvt->conn, Private::message_filter_stub, &s);
}
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)
{
DBusMessage *reply;
InternalError e;
DBusMessage *reply;
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 (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 (e) throw Error(e);
return Message(new Message::Private(reply), false);
return Message(new Message::Private(reply), false);
}
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))
{
throw ErrorNoMemory("Unable to start asynchronous call");
}
return PendingCall(new PendingCall::Private(pending));
if (!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout))
{
throw ErrorNoMemory("Unable to start asynchronous call");
}
return PendingCall(new PendingCall::Private(pending));
}
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:
* Think about giving back the 'ret' value. Some people on the list
* requested about this...
*/
int ret = dbus_bus_request_name(_pvt->conn, name, flags, e);
/*
* TODO:
* Think about giving back the 'ret' value. Some people on the list
* requested about this...
*/
int ret = dbus_bus_request_name(_pvt->conn, name, flags, e);
if (ret == -1)
{
if (e) throw Error(e);
}
if (ret == -1)
{
if (e) throw Error(e);
}
// this->remove_match("destination");
if (name)
{
_pvt->names.push_back(name);
std::string match = "destination='" + _pvt->names.back() + "'";
add_match(match.c_str());
}
if (name)
{
_pvt->names.push_back(name);
std::string match = "destination='" + _pvt->names.back() + "'";
add_match(match.c_str());
}
}
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)
{
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()
{
return _pvt->names;
return _pvt->names;
}
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)
{
_timeout=timeout;
_timeout = timeout;
}
int Connection::get_timeout()
{
return _timeout;
return _timeout;
}

View file

@ -38,37 +38,38 @@
#include <string>
namespace DBus {
namespace DBus
{
struct DXXAPILOCAL Connection::Private
{
DBusConnection * conn;
DBusConnection *conn;
std::vector<std::string> names;
std::vector<std::string> names;
Dispatcher *dispatcher;
bool do_dispatch();
Dispatcher *dispatcher;
bool do_dispatch();
MessageSlot disconn_filter;
bool disconn_filter_function(const Message &);
MessageSlot disconn_filter;
bool disconn_filter_function(const Message &);
Server::Private *server;
void detach_server();
Server::Private *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();
bool has_something_to_dispatch();
DBusDispatchStatus dispatch_status();
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 */

View file

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

View file

@ -38,64 +38,64 @@ DBus::Dispatcher *DBus::default_dispatcher = NULL;
using namespace DBus;
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
{
return dbus_timeout_get_interval((DBusTimeout *)_int);
return dbus_timeout_get_interval((DBusTimeout *)_int);
}
bool Timeout::enabled() const
{
return dbus_timeout_get_enabled((DBusTimeout *)_int);
return dbus_timeout_get_enabled((DBusTimeout *)_int);
}
bool Timeout::handle()
{
return dbus_timeout_handle((DBusTimeout *)_int);
return dbus_timeout_handle((DBusTimeout *)_int);
}
/*
*/
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
{
#if HAVE_WIN32
return dbus_watch_get_socket((DBusWatch*)_int);
return dbus_watch_get_socket((DBusWatch *)_int);
#else
// 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) || \
// 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) || \
(DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MAJOR > 1) || \
(DBUS_VERSION_MAJOR > 1)
return dbus_watch_get_unix_fd((DBusWatch*)_int);
#else
return dbus_watch_get_fd((DBusWatch*)_int);
#endif
return dbus_watch_get_unix_fd((DBusWatch *)_int);
#else
return dbus_watch_get_fd((DBusWatch *)_int);
#endif
#endif
}
int Watch::flags() const
{
return dbus_watch_get_flags((DBusWatch *)_int);
return dbus_watch_get_flags((DBusWatch *)_int);
}
bool Watch::enabled() const
{
return dbus_watch_get_enabled((DBusWatch *)_int);
return dbus_watch_get_enabled((DBusWatch *)_int);
}
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
_mutex_p.lock();
_pending_queue.push_back(cp);
_mutex_p.unlock();
_mutex_p.lock();
_pending_queue.push_back(cp);
_mutex_p.unlock();
}
bool Dispatcher::has_something_to_dispatch()
{
_mutex_p.lock();
bool has_something = false;
for(Connection::PrivatePList::iterator it = _pending_queue.begin();
it != _pending_queue.end() && !has_something;
++it)
{
has_something = (*it)->has_something_to_dispatch();
}
_mutex_p.lock();
bool has_something = false;
for (Connection::PrivatePList::iterator it = _pending_queue.begin();
it != _pending_queue.end() && !has_something;
++it)
{
has_something = (*it)->has_something_to_dispatch();
}
_mutex_p.unlock();
return has_something;
_mutex_p.unlock();
return has_something;
}
void Dispatcher::dispatch_pending()
{
while (1)
{
_mutex_p.lock();
if (_pending_queue.empty())
{
_mutex_p.unlock();
break;
}
while (1)
{
_mutex_p.lock();
if (_pending_queue.empty())
{
_mutex_p.unlock();
break;
}
Connection::PrivatePList pending_queue_copy(_pending_queue);
_mutex_p.unlock();
Connection::PrivatePList pending_queue_copy(_pending_queue);
_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!
_mutex_p.lock();
//only push_back on list is mandatory!
_mutex_p.lock();
Connection::PrivatePList::iterator i, j;
i = _pending_queue.begin();
size_t counter = 0;
while (counter < copy_elem_num && i != _pending_queue.end())
{
j = i;
++j;
_pending_queue.erase(i);
i = j;
++counter;
}
Connection::PrivatePList::iterator i, j;
i = _pending_queue.begin();
size_t counter = 0;
while (counter < copy_elem_num && i != _pending_queue.end())
{
j = i;
++j;
_pending_queue.erase(i);
i = j;
++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();
while (pending_queue.size() > 0)
{
Connection::PrivatePList::iterator i, j;
_mutex_p_copy.lock();
while (pending_queue.size() > 0)
{
Connection::PrivatePList::iterator i, j;
i = pending_queue.begin();
i = pending_queue.begin();
while (i != pending_queue.end())
{
j = i;
while (i != pending_queue.end())
{
j = i;
++j;
++j;
if ((*i)->do_dispatch())
pending_queue.erase(i);
else
debug_log("dispatch_pending_private: do_dispatch error");
if ((*i)->do_dispatch())
pending_queue.erase(i);
else
debug_log("dispatch_pending_private: do_dispatch error");
i = j;
}
}
_mutex_p_copy.unlock();
i = j;
}
}
_mutex_p_copy.unlock();
}
void DBus::_init_threading()
{
#ifdef DBUS_HAS_THREADS_INIT_DEFAULT
dbus_threads_init_default();
dbus_threads_init_default();
#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
}
void DBus::_init_threading(
MutexNewFn m1,
MutexFreeFn m2,
MutexLockFn m3,
MutexUnlockFn m4,
CondVarNewFn c1,
CondVarFreeFn c2,
CondVarWaitFn c3,
CondVarWaitTimeoutFn c4,
CondVarWakeOneFn c5,
CondVarWakeAllFn c6
MutexNewFn m1,
MutexFreeFn m2,
MutexLockFn m3,
MutexUnlockFn m4,
CondVarNewFn c1,
CondVarFreeFn c2,
CondVarWaitFn c3,
CondVarWaitTimeoutFn c4,
CondVarWakeOneFn c5,
CondVarWakeAllFn c6
)
{
#ifndef DBUS_HAS_RECURSIVE_MUTEX
DBusThreadFunctions functions = {
DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK|
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
(DBusMutexNewFunction) m1,
(DBusMutexFreeFunction) m2,
(DBusMutexLockFunction) m3,
(DBusMutexUnlockFunction) m4,
(DBusCondVarNewFunction) c1,
(DBusCondVarFreeFunction) c2,
(DBusCondVarWaitFunction) c3,
(DBusCondVarWaitTimeoutFunction) c4,
(DBusCondVarWakeOneFunction) c5,
(DBusCondVarWakeAllFunction) c6
};
DBusThreadFunctions functions =
{
DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
(DBusMutexNewFunction) m1,
(DBusMutexFreeFunction) m2,
(DBusMutexLockFunction) m3,
(DBusMutexUnlockFunction) m4,
(DBusCondVarNewFunction) c1,
(DBusCondVarFreeFunction) c2,
(DBusCondVarWaitFunction) c3,
(DBusCondVarWaitTimeoutFunction) c4,
(DBusCondVarWakeOneFunction) c5,
(DBusCondVarWakeAllFunction) c6
};
#else
DBusThreadFunctions functions = {
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK|
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
0, 0, 0, 0,
(DBusCondVarNewFunction) c1,
(DBusCondVarFreeFunction) c2,
(DBusCondVarWaitFunction) c3,
(DBusCondVarWaitTimeoutFunction) c4,
(DBusCondVarWakeOneFunction) c5,
(DBusCondVarWakeAllFunction) c6,
(DBusRecursiveMutexNewFunction) m1,
(DBusRecursiveMutexFreeFunction) m2,
(DBusRecursiveMutexLockFunction) m3,
(DBusRecursiveMutexUnlockFunction) m4
};
DBusThreadFunctions functions =
{
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
0, 0, 0, 0,
(DBusCondVarNewFunction) c1,
(DBusCondVarFreeFunction) c2,
(DBusCondVarWaitFunction) c3,
(DBusCondVarWaitTimeoutFunction) c4,
(DBusCondVarWakeOneFunction) c5,
(DBusCondVarWakeAllFunction) c6,
(DBusRecursiveMutexNewFunction) m1,
(DBusRecursiveMutexFreeFunction) m2,
(DBusRecursiveMutexLockFunction) m3,
(DBusRecursiveMutexUnlockFunction) m4
};
#endif//DBUS_HAS_RECURSIVE_MUTEX
dbus_threads_init(&functions);
dbus_threads_init(&functions);
}

View file

@ -35,21 +35,22 @@
#include "internalerror.h"
namespace DBus {
namespace DBus
{
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 */

View file

@ -33,120 +33,120 @@ using namespace DBus;
Dispatcher *gdispatcher = NULL;
Ecore::BusTimeout::BusTimeout( Timeout::Internal* ti)
: Timeout(ti)
Ecore::BusTimeout::BusTimeout(Timeout::Internal *ti)
: Timeout(ti)
{
if (Timeout::enabled())
{
_enable();
_enable();
}
}
Ecore::BusTimeout::~BusTimeout()
{
_disable();
_disable();
}
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();
}
else
else
{
_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()
{
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()
{
debug_log("Ecore::BusTimeout::_disable()");
ecore_timer_del (_etimer);
ecore_timer_del(_etimer);
}
Ecore::BusWatch::BusWatch( Watch::Internal* wi)
: Watch(wi), fd_handler (NULL), _bd (NULL)
Ecore::BusWatch::BusWatch(Watch::Internal *wi)
: Watch(wi), fd_handler(NULL), _bd(NULL)
{
if (Watch::enabled())
{
_enable();
_enable();
}
}
Ecore::BusWatch::~BusWatch()
{
_disable();
_disable();
}
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();
else _disable();
if (Watch::enabled()) _enable();
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)
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_READ);
if (w->flags() & DBUS_WATCH_WRITABLE)
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_WRITE);
if (w->flags() & DBUS_WATCH_READABLE)
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_READ);
if (w->flags() & DBUS_WATCH_WRITABLE)
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_WRITE);
w->handle(flags);
w->_bd->dispatch_pending();
return 1;
return 1;
}
void Ecore::BusWatch::_enable()
{
debug_log("Ecore::BusWatch::_enable()");
fd_handler = ecore_main_fd_handler_add (descriptor(),
(Ecore_Fd_Handler_Flags) (ECORE_FD_READ | ECORE_FD_WRITE),
watch_dispatch, this,
NULL, NULL);
fd_handler = ecore_main_fd_handler_add(descriptor(),
(Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_WRITE),
watch_dispatch, this,
NULL, NULL);
}
void Ecore::BusWatch::_disable()
{
if (fd_handler)
{
ecore_main_fd_handler_del (fd_handler);
ecore_main_fd_handler_del(fd_handler);
fd_handler = NULL;
}
}
void Ecore::BusWatch::data (Ecore::BusDispatcher *bd)
void Ecore::BusWatch::data(Ecore::BusDispatcher *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;
}
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);
w->data (this);
Ecore::BusWatch *w = new Ecore::BusWatch(wi);
w->data(this);
debug_log("ecore: added watch %p (%s) fd=%d flags=%d",
w, w->enabled() ? "on":"off", w->descriptor(), w->flags()
);
return w;
debug_log("ecore: added watch %p (%s) fd=%d flags=%d",
w, w->enabled() ? "on" : "off", w->descriptor(), w->flags()
);
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()
: _int(new InternalError)
: _int(new InternalError)
{}
Error::Error(InternalError &i)
: _int(new InternalError(i))
: _int(new InternalError(i))
{}
Error::Error(const char *name, const char *message)
: _int(new InternalError)
: _int(new InternalError)
{
set(name, message);
set(name, message);
}
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()
@ -64,26 +64,26 @@ Error::~Error() throw()
const char *Error::name() const
{
return _int->error.name;
return _int->error.name;
}
const char *Error::message() const
{
return _int->error.message;
return _int->error.message;
}
bool Error::is_set() const
{
return *(_int);
return *(_int);
}
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()
{
return _int->error.message;
return _int->error.message;
}

View file

@ -43,182 +43,182 @@ using namespace DBus;
using namespace std;
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()
{
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)
: 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)
flags |= POLLIN;
if (Watch::flags() & DBUS_WATCH_WRITABLE)
flags |= POLLOUT;
if (Watch::flags() & DBUS_WATCH_READABLE)
flags |= POLLIN;
if (Watch::flags() & DBUS_WATCH_WRITABLE)
flags |= POLLOUT;
DefaultWatch::flags(flags);
DefaultWatch::enabled(Watch::enabled());
DefaultWatch::flags(flags);
DefaultWatch::enabled(Watch::enabled());
}
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() :
_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)
int ret = pipe(_pipe);
if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());
int ret = pipe(_pipe);
if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());
_fdunlock[0] = _pipe[0];
_fdunlock[1] = _pipe[1];
_fdunlock[0] = _pipe[0];
_fdunlock[1] = _pipe[1];
}
void BusDispatcher::enter()
{
debug_log("entering dispatcher %p", this);
debug_log("entering dispatcher %p", this);
_running = true;
_running = true;
while (_running)
{
do_iteration();
while (_running)
{
do_iteration();
for (std::list <Pipe*>::iterator p_it = pipe_list.begin ();
p_it != pipe_list.end ();
++p_it)
{
Pipe* read_pipe = *p_it;
for (std::list <Pipe *>::iterator p_it = pipe_list.begin();
p_it != pipe_list.end();
++p_it)
{
Pipe *read_pipe = *p_it;
char buffer[1024]; // TODO: should be max pipe size
unsigned int 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()
{
_running = false;
_running = false;
int ret = write(_fdunlock[1],"exit",strlen("exit"));
if (ret == -1) throw Error("WriteError:errno", toString(errno).c_str());
int ret = write(_fdunlock[1], "exit", strlen("exit"));
if (ret == -1) throw Error("WriteError:errno", toString(errno).c_str());
close(_fdunlock[1]);
close(_fdunlock[0]);
close(_fdunlock[1]);
close(_fdunlock[0]);
}
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_list.push_back (new_pipe);
Pipe *new_pipe = new Pipe(handler, data);
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);
delete pipe;
pipe_list.remove(pipe);
delete pipe;
}
void BusDispatcher::do_iteration()
{
dispatch_pending();
dispatch();
dispatch_pending();
dispatch();
}
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->data(bt);
bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &>(this, &BusDispatcher::timeout_expired);
bt->data(bt);
debug_log("added timeout %p (%s) (%d millies)",
bt,
((Timeout*)bt)->enabled() ? "on":"off",
((Timeout*)bt)->interval()
);
debug_log("added timeout %p (%s) (%d millies)",
bt,
((Timeout *)bt)->enabled() ? "on" : "off",
((Timeout *)bt)->interval()
);
return bt;
return bt;
}
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)
{
BusWatch *bw = new BusWatch(wi, this);
BusWatch *bw = new BusWatch(wi, this);
bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready);
bw->data(bw);
bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready);
bw->data(bw);
debug_log("added watch %p (%s) fd=%d flags=%d",
bw, ((Watch *)bw)->enabled() ? "on":"off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());
debug_log("added watch %p (%s) fd=%d flags=%d",
bw, ((Watch *)bw)->enabled() ? "on" : "off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());
return bw;
return bw;
}
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)
{
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)
{
BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());
BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());
debug_log("watch %p ready, flags=%d state=%d",
watch, ((Watch *)watch)->flags(), watch->state()
);
debug_log("watch %p ready, flags=%d state=%d",
watch, ((Watch *)watch)->flags(), watch->state()
);
int flags = 0;
int flags = 0;
if (watch->state() & POLLIN)
flags |= DBUS_WATCH_READABLE;
if (watch->state() & POLLOUT)
flags |= DBUS_WATCH_WRITABLE;
if (watch->state() & POLLHUP)
flags |= DBUS_WATCH_HANGUP;
if (watch->state() & POLLERR)
flags |= DBUS_WATCH_ERROR;
if (watch->state() & POLLIN)
flags |= DBUS_WATCH_READABLE;
if (watch->state() & POLLOUT)
flags |= DBUS_WATCH_WRITABLE;
if (watch->state() & POLLHUP)
flags |= DBUS_WATCH_HANGUP;
if (watch->state() & POLLERR)
flags |= DBUS_WATCH_ERROR;
watch->handle(flags);
watch->handle(flags);
}

View file

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

View file

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

View file

@ -33,7 +33,7 @@
using namespace DBus;
Interface::Interface(const std::string &name)
: _name(name)
: _name(name)
{}
Interface::~Interface()
@ -41,129 +41,129 @@ Interface::~Interface()
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)
: 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)
{
const char *name = msg.member();
const char *name = msg.member();
MethodTable::iterator mi = _methods.find(name);
if (mi != _methods.end())
{
return mi->second.call(msg);
}
else
{
return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name);
}
MethodTable::iterator mi = _methods.find(name);
if (mi != _methods.end())
{
return mi->second.call(msg);
}
else
{
return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name);
}
}
void InterfaceAdaptor::emit_signal(const SignalMessage &sig)
{
SignalMessage &sig2 = const_cast<SignalMessage &>(sig);
SignalMessage &sig2 = const_cast<SignalMessage &>(sig);
if (sig2.interface() == NULL)
sig2.interface(name().c_str());
if (sig2.interface() == NULL)
sig2.interface(name().c_str());
_emit_signal(sig2);
_emit_signal(sig2);
}
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->second.read)
throw ErrorAccessDenied("property is not readable");
if (pti != _properties.end())
{
if (!pti->second.read)
throw ErrorAccessDenied("property is not readable");
return &(pti->second.value);
}
return NULL;
return &(pti->second.value);
}
return NULL;
}
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->second.write)
throw ErrorAccessDenied("property is not writeable");
if (pti != _properties.end())
{
if (!pti->second.write)
throw ErrorAccessDenied("property is not writeable");
Signature sig = value.signature();
Signature sig = value.signature();
if (pti->second.sig != sig)
throw ErrorInvalidSignature("property expects a different type");
if (pti->second.sig != sig)
throw ErrorInvalidSignature("property expects a different type");
pti->second.value = value;
return;
}
throw ErrorFailed("requested property not found");
pti->second.value = value;
return;
}
throw ErrorFailed("requested property not found");
}
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)
: 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)
{
const char *name = msg.member();
const char *name = msg.member();
SignalTable::iterator si = _signals.find(name);
if (si != _signals.end())
{
si->second.call(msg);
// Here we always return false because there might be
// another InterfaceProxy listening for the same signal.
// This way we instruct libdbus-1 to go on dispatching
// the signal.
return false;
}
else
{
return false;
}
SignalTable::iterator si = _signals.find(name);
if (si != _signals.end())
{
si->second.call(msg);
// Here we always return false because there might be
// another InterfaceProxy listening for the same signal.
// This way we instruct libdbus-1 to go on dispatching
// the signal.
return false;
}
else
{
return false;
}
}
Message InterfaceProxy::invoke_method(const CallMessage &call)
{
CallMessage &call2 = const_cast<CallMessage &>(call);
CallMessage &call2 = const_cast<CallMessage &>(call);
if (call.interface() == NULL)
call2.interface(name().c_str());
if (call.interface() == NULL)
call2.interface(name().c_str());
return _invoke_method(call2);
return _invoke_method(call2);
}
bool InterfaceProxy::invoke_method_noreply(const CallMessage &call)
{
CallMessage &call2 = const_cast<CallMessage &>(call);
CallMessage &call2 = const_cast<CallMessage &>(call);
if (call.interface() == NULL)
call2.interface(name().c_str());
if (call.interface() == NULL)
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>
namespace DBus {
namespace DBus
{
struct DXXAPI InternalError
{
DBusError error;
DBusError error;
InternalError()
{
dbus_error_init(&error);
}
InternalError()
{
dbus_error_init(&error);
}
explicit InternalError(DBusError *e)
{
dbus_error_init(&error);
dbus_move_error(e, &error);
}
explicit InternalError(DBusError *e)
{
dbus_error_init(&error);
dbus_move_error(e, &error);
}
InternalError(const InternalError &ie)
{
dbus_error_init(&error);
dbus_move_error(const_cast<DBusError *>(&(ie.error)), &error);
}
InternalError(const InternalError &ie)
{
dbus_error_init(&error);
dbus_move_error(const_cast<DBusError *>(&(ie.error)), &error);
}
~InternalError()
{
dbus_error_free(&error);
}
~InternalError()
{
dbus_error_free(&error);
}
operator DBusError *()
{
return &error;
}
operator DBusError *()
{
return &error;
}
operator bool()
{
return dbus_error_is_set(&error);
}
operator bool()
{
return dbus_error_is_set(&error);
}
};
} /* namespace DBus */

View file

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

View file

@ -40,447 +40,447 @@ using namespace DBus;
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()
{
return type() == DBUS_TYPE_INVALID;
return type() == DBUS_TYPE_INVALID;
}
bool MessageIter::has_next()
{
return dbus_message_iter_has_next((DBusMessageIter *)&_iter);
return dbus_message_iter_has_next((DBusMessageIter *)&_iter);
}
MessageIter &MessageIter::operator ++()
{
dbus_message_iter_next((DBusMessageIter *)&_iter);
return (*this);
dbus_message_iter_next((DBusMessageIter *)&_iter);
return (*this);
}
MessageIter MessageIter::operator ++(int)
{
MessageIter copy(*this);
++(*this);
return copy;
MessageIter copy(*this);
++(*this);
return copy;
}
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)
{
if (type() != type_id)
throw ErrorInvalidArgs("type mismatch");
if (type() != type_id)
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)
{
return append_basic(DBUS_TYPE_BYTE, &b);
return append_basic(DBUS_TYPE_BYTE, &b);
}
unsigned char MessageIter::get_byte()
{
unsigned char b;
get_basic(DBUS_TYPE_BYTE, &b);
return b;
unsigned char b;
get_basic(DBUS_TYPE_BYTE, &b);
return b;
}
bool MessageIter::append_bool(bool b)
{
dbus_bool_t db = b;
return append_basic(DBUS_TYPE_BOOLEAN, &db);
dbus_bool_t db = b;
return append_basic(DBUS_TYPE_BOOLEAN, &db);
}
bool MessageIter::get_bool()
{
dbus_bool_t db;
get_basic(DBUS_TYPE_BOOLEAN, &db);
return (bool)db;
dbus_bool_t db;
get_basic(DBUS_TYPE_BOOLEAN, &db);
return (bool)db;
}
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 i;
get_basic(DBUS_TYPE_INT16, &i);
return i;
signed short i;
get_basic(DBUS_TYPE_INT16, &i);
return i;
}
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 u;
get_basic(DBUS_TYPE_UINT16, &u);
return u;
unsigned short u;
get_basic(DBUS_TYPE_UINT16, &u);
return u;
}
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 i;
get_basic(DBUS_TYPE_INT32, &i);
return i;
signed int i;
get_basic(DBUS_TYPE_INT32, &i);
return i;
}
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 u;
get_basic(DBUS_TYPE_UINT32, &u);
return u;
unsigned int u;
get_basic(DBUS_TYPE_UINT32, &u);
return u;
}
signed long long MessageIter::get_int64()
{
signed long long i;
get_basic(DBUS_TYPE_INT64, &i);
return i;
signed long long i;
get_basic(DBUS_TYPE_INT64, &i);
return 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 u;
get_basic(DBUS_TYPE_UINT64, &u);
return u;
unsigned long long u;
get_basic(DBUS_TYPE_UINT64, &u);
return 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 d;
get_basic(DBUS_TYPE_DOUBLE, &d);
return d;
double d;
get_basic(DBUS_TYPE_DOUBLE, &d);
return 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)
{
return append_basic(DBUS_TYPE_STRING, &chars);
return append_basic(DBUS_TYPE_STRING, &chars);
}
const char *MessageIter::get_string()
{
char *chars;
get_basic(DBUS_TYPE_STRING, &chars);
return chars;
char *chars;
get_basic(DBUS_TYPE_STRING, &chars);
return 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()
{
char *chars;
get_basic(DBUS_TYPE_OBJECT_PATH, &chars);
return chars;
char *chars;
get_basic(DBUS_TYPE_OBJECT_PATH, &chars);
return 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()
{
char *chars;
get_basic(DBUS_TYPE_SIGNATURE, &chars);
return chars;
char *chars;
get_basic(DBUS_TYPE_SIGNATURE, &chars);
return chars;
}
MessageIter MessageIter::recurse()
{
MessageIter iter(msg());
dbus_message_iter_recurse((DBusMessageIter *)&_iter, (DBusMessageIter *)&(iter._iter));
return iter;
MessageIter iter(msg());
dbus_message_iter_recurse((DBusMessageIter *)&_iter, (DBusMessageIter *) & (iter._iter));
return iter;
}
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)
{
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()
{
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 length;
dbus_message_iter_get_fixed_array((DBusMessageIter *)&_iter, ptr, &length);
return length;
int length;
dbus_message_iter_get_fixed_array((DBusMessageIter *)&_iter, ptr, &length);
return length;
}
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()
{
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 arr(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *)&(arr._iter)
);
return arr;
MessageIter arr(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *) & (arr._iter)
);
return arr;
}
MessageIter MessageIter::new_variant(const char *sig)
{
MessageIter var(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *)&(var._iter)
);
return var;
MessageIter var(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *) & (var._iter)
);
return var;
}
MessageIter MessageIter::new_struct()
{
MessageIter stu(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *)&(stu._iter)
);
return stu;
MessageIter stu(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *) & (stu._iter)
);
return stu;
}
MessageIter MessageIter::new_dict_entry()
{
MessageIter ent(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *)&(ent._iter)
);
return ent;
MessageIter ent(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *) & (ent._iter)
);
return ent;
}
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)
{
switch (typecode)
{
case 'y':
case 'b':
case 'n':
case 'q':
case 'i':
case 'u':
case 'x':
case 't':
case 'd':
case 's':
case 'o':
case 'g':
return true;
default:
return false;
}
switch (typecode)
{
case 'y':
case 'b':
case 'n':
case 'q':
case 'i':
case 'u':
case 'x':
case 't':
case 'd':
case 's':
case 'o':
case 'g':
return true;
default:
return false;
}
}
void MessageIter::copy_data(MessageIter &to)
{
for (MessageIter &from = *this; !from.at_end(); ++from)
{
if (is_basic_type(from.type()))
{
debug_log("copying basic type: %c", from.type());
for (MessageIter &from = *this; !from.at_end(); ++from)
{
if (is_basic_type(from.type()))
{
debug_log("copying basic type: %c", from.type());
unsigned char value[8];
from.get_basic(from.type(), &value);
to.append_basic(from.type(), &value);
}
else
{
MessageIter from_container = from.recurse();
char *sig = from_container.signature();
unsigned char value[8];
from.get_basic(from.type(), &value);
to.append_basic(from.type(), &value);
}
else
{
MessageIter from_container = from.recurse();
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());
dbus_message_iter_open_container
(
(DBusMessageIter *)&(to._iter),
from.type(),
from.type() == DBUS_TYPE_VARIANT ? NULL : sig,
(DBusMessageIter *)&(to_container._iter)
);
MessageIter to_container(to.msg());
dbus_message_iter_open_container
(
(DBusMessageIter *) & (to._iter),
from.type(),
from.type() == DBUS_TYPE_VARIANT ? NULL : sig,
(DBusMessageIter *) & (to_container._iter)
);
from_container.copy_data(to_container);
to.close_container(to_container);
free(sig);
}
}
from_container.copy_data(to_container);
to.close_container(to_container);
free(sig);
}
}
}
/*
*/
Message::Message()
: _pvt(new Private)
: _pvt(new Private)
{
}
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)
: _pvt(m._pvt)
: _pvt(m._pvt)
{
dbus_message_ref(_pvt->msg);
dbus_message_ref(_pvt->msg);
}
Message::~Message()
{
dbus_message_unref(_pvt->msg);
dbus_message_unref(_pvt->msg);
}
Message &Message::operator = (const Message &m)
{
if (&m != this)
{
dbus_message_unref(_pvt->msg);
_pvt = m._pvt;
dbus_message_ref(_pvt->msg);
}
return *this;
if (&m != this)
{
dbus_message_unref(_pvt->msg);
_pvt = m._pvt;
dbus_message_ref(_pvt->msg);
}
return *this;
}
Message Message::copy()
{
Private *pvt = new Private(dbus_message_copy(_pvt->msg));
return Message(pvt);
Private *pvt = new Private(dbus_message_copy(_pvt->msg));
return Message(pvt);
}
bool Message::append(int first_type, ...)
{
va_list vl;
va_start(vl, first_type);
va_list vl;
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);
return b;
va_end(vl);
return b;
}
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
{
return dbus_message_get_type(_pvt->msg);
return dbus_message_get_type(_pvt->msg);
}
int Message::serial() const
{
return dbus_message_get_serial(_pvt->msg);
return dbus_message_get_serial(_pvt->msg);
}
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)
{
return dbus_message_set_reply_serial(_pvt->msg, s);
return dbus_message_set_reply_serial(_pvt->msg, s);
}
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)
{
return dbus_message_set_sender(_pvt->msg, s);
return dbus_message_set_sender(_pvt->msg, s);
}
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)
{
return dbus_message_set_destination(_pvt->msg, s);
return dbus_message_set_destination(_pvt->msg, s);
}
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
{
return dbus_message_is_signal(_pvt->msg, interface, member);
return dbus_message_is_signal(_pvt->msg, interface, member);
}
MessageIter Message::writer()
{
MessageIter iter(*this);
dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *)&(iter._iter));
return iter;
MessageIter iter(*this);
dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *) & (iter._iter));
return iter;
}
MessageIter Message::reader() const
{
MessageIter iter(const_cast<Message &>(*this));
dbus_message_iter_init(_pvt->msg, (DBusMessageIter *)&(iter._iter));
return iter;
MessageIter iter(const_cast<Message &>(*this));
dbus_message_iter_init(_pvt->msg, (DBusMessageIter *) & (iter._iter));
return iter;
}
/*
@ -488,27 +488,27 @@ MessageIter Message::reader() const
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)
{
_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
{
return dbus_message_is_error(_pvt->msg, m.name());
return dbus_message_is_error(_pvt->msg, m.name());
}
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)
{
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)
{
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
member(name);
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
member(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
{
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
{
return dbus_message_get_interface(_pvt->msg);
return dbus_message_get_interface(_pvt->msg);
}
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
{
return dbus_message_get_member(_pvt->msg);
return dbus_message_get_member(_pvt->msg);
}
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
{
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;
dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ?
return p;
char **p;
dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ?
return 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()
{
_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)
{
_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
{
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
{
return dbus_message_get_interface(_pvt->msg);
return dbus_message_get_interface(_pvt->msg);
}
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
{
return dbus_message_get_member(_pvt->msg);
return dbus_message_get_member(_pvt->msg);
}
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
{
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;
dbus_message_get_path_decomposed(_pvt->msg, &p);
return p;
char **p;
dbus_message_get_path_decomposed(_pvt->msg, &p);
return 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
{
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)
{
_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
{
return dbus_message_get_signature(_pvt->msg);
return dbus_message_get_signature(_pvt->msg);
}

View file

@ -34,17 +34,18 @@
#include <dbus/dbus.h>
namespace DBus {
namespace DBus
{
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 */

View file

@ -40,7 +40,7 @@
using namespace DBus;
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)
{
debug_log("%s: %d millies", __PRETTY_FUNCTION__, new_timeout);
if(new_timeout < 0 && new_timeout != -1)
throw ErrorInvalidArgs("Bad timeout, cannot set it");
_default_timeout = new_timeout;
debug_log("%s: %d millies", __PRETTY_FUNCTION__, new_timeout);
if (new_timeout < 0 && new_timeout != -1)
throw ErrorInvalidArgs("Bad timeout, cannot set it");
_default_timeout = new_timeout;
}
struct ObjectAdaptor::Private
{
static void unregister_function_stub(DBusConnection *, void *);
static DBusHandlerResult message_function_stub(DBusConnection *, DBusMessage *, void *);
static void unregister_function_stub(DBusConnection *, void *);
static DBusHandlerResult message_function_stub(DBusConnection *, DBusMessage *, void *);
};
static DBusObjectPathVTable _vtable =
{
ObjectAdaptor::Private::unregister_function_stub,
ObjectAdaptor::Private::message_function_stub,
NULL, NULL, NULL, NULL
ObjectAdaptor::Private::unregister_function_stub,
ObjectAdaptor::Private::message_function_stub,
NULL, NULL, NULL, NULL
};
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)
{
ObjectAdaptor *o = static_cast<ObjectAdaptor *>(data);
ObjectAdaptor *o = static_cast<ObjectAdaptor *>(data);
if (o)
{
Message msg(new Message::Private(dmsg));
if (o)
{
Message msg(new Message::Private(dmsg));
debug_log("in object %s", o->path().c_str());
debug_log(" got message #%d from %s to %s",
msg.serial(),
msg.sender(),
msg.destination()
);
debug_log("in object %s", o->path().c_str());
debug_log(" got message #%d from %s to %s",
msg.serial(),
msg.sender(),
msg.destination()
);
return o->handle_message(msg)
? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
else
{
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
return o->handle_message(msg)
? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
else
{
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
}
typedef std::map<Path, ObjectAdaptor *> ObjectAdaptorTable;
@ -104,282 +104,282 @@ static ObjectAdaptorTable _adaptor_table;
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())
return ati->second;
if (ati != _adaptor_table.end())
return ati->second;
return NULL;
return NULL;
}
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())
{
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
ali.push_back(ati->second);
while (ati != _adaptor_table.end())
{
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
ali.push_back(ati->second);
++ati;
}
++ati;
}
return ali;
return ali;
}
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())
{
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
{
std::string p = ati->second->path().substr(plen);
p = p.substr(0,p.find('/'));
ali.push_back(p);
}
++ati;
}
while (ati != _adaptor_table.end())
{
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
{
std::string p = ati->second->path().substr(plen);
p = p.substr(0, p.find('/'));
ali.push_back(p);
}
++ati;
}
ali.sort();
ali.unique();
ali.sort();
ali.unique();
return ali;
return ali;
}
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()
{
unregister_obj(false);
unregister_obj(false);
}
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))
{
throw ErrorNoMemory("unable to register object path");
}
if (!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this))
{
throw ErrorNoMemory("unable to register object path");
}
_adaptor_table[path()] = this;
_adaptor_table[path()] = this;
}
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)
{
sig.path(path().c_str());
sig.path(path().c_str());
conn().send(sig);
conn().send(sig);
}
struct ReturnLaterError
{
const Tag *tag;
const Tag *tag;
};
bool ObjectAdaptor::handle_message(const Message &msg)
{
switch (msg.type())
{
case DBUS_MESSAGE_TYPE_METHOD_CALL:
{
const CallMessage &cmsg = reinterpret_cast<const CallMessage &>(msg);
const char *member = cmsg.member();
const char *interface = cmsg.interface();
switch (msg.type())
{
case DBUS_MESSAGE_TYPE_METHOD_CALL:
{
const CallMessage &cmsg = reinterpret_cast<const CallMessage &>(msg);
const char *member = cmsg.member();
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);
if (ii)
{
try
{
Message ret = ii->dispatch_method(cmsg);
conn().send(ret);
}
catch(Error &e)
{
ErrorMessage em(cmsg, e.name(), e.message());
conn().send(em);
}
catch(ReturnLaterError &rle)
{
_continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag);
}
return true;
}
else
{
return false;
}
}
default:
{
return false;
}
}
InterfaceAdaptor *ii = find_interface(interface);
if (ii)
{
try
{
Message ret = ii->dispatch_method(cmsg);
conn().send(ret);
}
catch (Error &e)
{
ErrorMessage em(cmsg, e.name(), e.message());
conn().send(em);
}
catch (ReturnLaterError &rle)
{
_continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag);
}
return true;
}
else
{
return false;
}
}
default:
{
return false;
}
}
}
void ObjectAdaptor::return_later(const Tag *tag)
{
ReturnLaterError rle = { tag };
throw rle;
ReturnLaterError rle = { tag };
throw rle;
}
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)
{
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)
{
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)
: _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)
: Object(conn, path, service)
: Object(conn, path, service)
{
register_obj();
register_obj();
}
ObjectProxy::~ObjectProxy()
{
unregister_obj(false);
unregister_obj(false);
}
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);
conn().add_filter(_filtered);
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while (ii != _interfaces.end())
{
std::string im = "type='signal',interface='"+ii->first+"',path='"+path()+"'";
conn().add_match(im.c_str());
++ii;
}
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while (ii != _interfaces.end())
{
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)
{
debug_log("unregistering remote object %s", path().c_str());
debug_log("unregistering remote object %s", path().c_str());
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while (ii != _interfaces.end())
{
std::string im = "type='signal',interface='"+ii->first+"',path='"+path()+"'";
conn().remove_match(im.c_str(), throw_on_error);
++ii;
}
conn().remove_filter(_filtered);
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while (ii != _interfaces.end())
{
std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
conn().remove_match(im.c_str(), throw_on_error);
++ii;
}
conn().remove_filter(_filtered);
}
Message ObjectProxy::_invoke_method(CallMessage &call)
{
if (call.path() == NULL)
call.path(path().c_str());
if (call.path() == NULL)
call.path(path().c_str());
if (call.destination() == NULL)
call.destination(service().c_str());
if (call.destination() == NULL)
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)
{
if (call.path() == NULL)
call.path(path().c_str());
if (call.path() == NULL)
call.path(path().c_str());
if (call.destination() == NULL)
call.destination(service().c_str());
if (call.destination() == NULL)
call.destination(service().c_str());
return conn().send(call);
return conn().send(call);
}
bool ObjectProxy::handle_message(const Message &msg)
{
switch (msg.type())
{
case DBUS_MESSAGE_TYPE_SIGNAL:
{
const SignalMessage &smsg = reinterpret_cast<const SignalMessage &>(msg);
const char *interface = smsg.interface();
const char *member = smsg.member();
const char *objpath = smsg.path();
switch (msg.type())
{
case DBUS_MESSAGE_TYPE_SIGNAL:
{
const SignalMessage &smsg = reinterpret_cast<const SignalMessage &>(msg);
const char *interface = smsg.interface();
const char *member = smsg.member();
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",
member, interface, msg.sender(), objpath);
debug_log("filtered signal %s(in %s) from %s to object %s",
member, interface, msg.sender(), objpath);
InterfaceProxy *ii = find_interface(interface);
if (ii)
{
return ii->dispatch_signal(smsg);
}
else
{
return false;
}
}
default:
{
return false;
}
}
InterfaceProxy *ii = find_interface(interface);
if (ii)
{
return ii->dispatch_signal(smsg);
}
else
{
return false;
}
}
default:
{
return false;
}
}
}

View file

@ -36,107 +36,107 @@
using namespace DBus;
PendingCall::Private::Private(DBusPendingCall *dpc)
: call(dpc), dataslot(-1)
: call(dpc), dataslot(-1)
{
if (!dbus_pending_call_allocate_data_slot(&dataslot))
{
throw ErrorNoMemory("Unable to allocate data slot");
}
if (!dbus_pending_call_allocate_data_slot(&dataslot))
{
throw ErrorNoMemory("Unable to allocate data slot");
}
}
PendingCall::Private::~Private()
{
if (dataslot != -1)
{
dbus_pending_call_allocate_data_slot(&dataslot);
}
if (dataslot != -1)
{
dbus_pending_call_allocate_data_slot(&dataslot);
}
}
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);
pvt->slot(pc);
PendingCall pc(pvt);
pvt->slot(pc);
}
PendingCall::PendingCall(PendingCall::Private *p)
: _pvt(p)
: _pvt(p)
{
if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL))
{
throw ErrorNoMemory("Unable to initialize pending call");
}
if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL))
{
throw ErrorNoMemory("Unable to initialize pending call");
}
}
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()
{
dbus_pending_call_unref(_pvt->call);
dbus_pending_call_unref(_pvt->call);
}
PendingCall &PendingCall::operator = (const PendingCall &c)
{
if (&c != this)
{
dbus_pending_call_unref(_pvt->call);
_pvt = c._pvt;
dbus_pending_call_ref(_pvt->call);
}
return *this;
if (&c != this)
{
dbus_pending_call_unref(_pvt->call);
_pvt = c._pvt;
dbus_pending_call_ref(_pvt->call);
}
return *this;
}
bool PendingCall::completed()
{
return dbus_pending_call_get_completed(_pvt->call);
return dbus_pending_call_get_completed(_pvt->call);
}
void PendingCall::cancel()
{
dbus_pending_call_cancel(_pvt->call);
dbus_pending_call_cancel(_pvt->call);
}
void PendingCall::block()
{
dbus_pending_call_block(_pvt->call);
dbus_pending_call_block(_pvt->call);
}
void PendingCall::data(void *p)
{
if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
{
throw ErrorNoMemory("Unable to initialize data slot");
}
if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
{
throw ErrorNoMemory("Unable to initialize data slot");
}
}
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()
{
return _pvt->slot;
return _pvt->slot;
}
Message PendingCall::steal_reply()
{
DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call);
if (!dmsg)
{
dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call);
DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call);
if (!dmsg)
{
dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call);
if (callComplete)
throw ErrorNoReply("No reply available");
else
throw ErrorNoReply("Call not complete");
}
if (callComplete)
throw ErrorNoReply("No reply available");
else
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>
namespace DBus {
namespace DBus
{
struct DXXAPILOCAL PendingCall::Private
{
DBusPendingCall *call;
int dataslot;
Slot<void, PendingCall &> slot;
DBusPendingCall *call;
int dataslot;
Slot<void, PendingCall &> slot;
Private(DBusPendingCall *);
Private(DBusPendingCall *);
~Private();
~Private();
static void notify_stub(DBusPendingCall *dpc, void *data);
static void notify_stub(DBusPendingCall *dpc, void *data);
};
} /* 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) :
_handler(handler),
_fd_write (0),
_fd_read (0),
_fd_write(0),
_fd_read(0),
_data(data)
{
int fd[2];
if(pipe(fd) == 0)
if (pipe(fd) == 0)
{
_fd_read = fd[0];
_fd_write = fd[1];
@ -56,23 +56,23 @@ Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), c
}
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)
{
// 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
::write(_fd_write, buffer, nbytes);
::write(_fd_write, buffer, nbytes);
}
ssize_t Pipe::read(void *buffer, unsigned int &nbytes)
{
// first read the size from the pipe...
::read(_fd_read, &nbytes, sizeof (nbytes));
::read(_fd_read, &nbytes, sizeof(nbytes));
//ssize_t size = 0;
return ::read(_fd_read, buffer, nbytes);
@ -80,5 +80,5 @@ ssize_t Pipe::read(void *buffer, unsigned int &nbytes)
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";
PropertiesAdaptor::PropertiesAdaptor()
: InterfaceAdaptor(properties_name)
: InterfaceAdaptor(properties_name)
{
register_method(PropertiesAdaptor, Get, Get);
register_method(PropertiesAdaptor, Set, Set);
register_method(PropertiesAdaptor, Get, Get);
register_method(PropertiesAdaptor, Set, Set);
}
Message PropertiesAdaptor::Get(const CallMessage &call)
{
MessageIter ri = call.reader();
MessageIter ri = call.reader();
std::string iface_name;
std::string property_name;
std::string iface_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)
throw ErrorFailed("requested interface not found");
if (!interface)
throw ErrorFailed("requested interface not found");
Variant *value = interface->get_property(property_name);
Variant *value = interface->get_property(property_name);
if (!value)
throw ErrorFailed("requested property not found");
if (!value)
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;
return reply;
wi << *value;
return reply;
}
Message PropertiesAdaptor::Set(const CallMessage &call)
{
MessageIter ri = call.reader();
MessageIter ri = call.reader();
std::string iface_name;
std::string property_name;
Variant value;
std::string iface_name;
std::string property_name;
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)
throw ErrorFailed("requested interface not found");
if (!interface)
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[] =
{
{ "interface_name", "s", true },
{ "property_name", "s", true },
{ "value", "v", false },
{ 0, 0, 0 }
};
static IntrospectedArgument Set_args[] =
{
{ "interface_name", "s", true },
{ "property_name", "s", true },
{ "value", "v", true },
{ 0, 0, 0 }
};
static IntrospectedMethod Properties_methods[] =
{
{ "Get", Get_args },
{ "Set", Set_args },
{ 0, 0 }
};
static IntrospectedMethod Properties_signals[] =
{
{ 0, 0 }
};
static IntrospectedProperty Properties_properties[] =
{
{ 0, 0, 0, 0 }
};
static IntrospectedInterface Properties_interface =
{
properties_name,
Properties_methods,
Properties_signals,
Properties_properties
};
return &Properties_interface;
static IntrospectedArgument Get_args[] =
{
{ "interface_name", "s", true },
{ "property_name", "s", true },
{ "value", "v", false },
{ 0, 0, 0 }
};
static IntrospectedArgument Set_args[] =
{
{ "interface_name", "s", true },
{ "property_name", "s", true },
{ "value", "v", true },
{ 0, 0, 0 }
};
static IntrospectedMethod Properties_methods[] =
{
{ "Get", Get_args },
{ "Set", Set_args },
{ 0, 0 }
};
static IntrospectedMethod Properties_signals[] =
{
{ 0, 0 }
};
static IntrospectedProperty Properties_properties[] =
{
{ 0, 0, 0, 0 }
};
static IntrospectedInterface Properties_interface =
{
properties_name,
Properties_methods,
Properties_signals,
Properties_properties
};
return &Properties_interface;
}
PropertiesProxy::PropertiesProxy()
: InterfaceProxy(properties_name)
: InterfaceProxy(properties_name)
{
}
Variant PropertiesProxy::Get(const std::string &iface, const std::string &property)
{
//todo
Variant v;
return v;
Variant v;
return v;
}
void PropertiesProxy::Set(const std::string &iface, const std::string &property, const Variant &value)

View file

@ -36,7 +36,7 @@
using namespace DBus;
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)
{
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)
{
InternalError e;
DBusServer *server = dbus_server_listen(address, e);
InternalError 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)
@ -81,49 +81,49 @@ Server::Server(const Server &s)
*/
Server::~Server()
{
dbus_server_unref(_pvt->server);
dbus_server_unref(_pvt->server);
}
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(
_pvt->server,
Dispatcher::Private::on_add_watch,
Dispatcher::Private::on_rem_watch,
Dispatcher::Private::on_toggle_watch,
dispatcher,
0
);
dbus_server_set_watch_functions(
_pvt->server,
Dispatcher::Private::on_add_watch,
Dispatcher::Private::on_rem_watch,
Dispatcher::Private::on_toggle_watch,
dispatcher,
0
);
dbus_server_set_timeout_functions(
_pvt->server,
Dispatcher::Private::on_add_timeout,
Dispatcher::Private::on_rem_timeout,
Dispatcher::Private::on_toggle_timeout,
dispatcher,
0
);
dbus_server_set_timeout_functions(
_pvt->server,
Dispatcher::Private::on_add_timeout,
Dispatcher::Private::on_rem_timeout,
Dispatcher::Private::on_toggle_timeout,
dispatcher,
0
);
_pvt->dispatcher = dispatcher;
_pvt->dispatcher = dispatcher;
return prev;
return prev;
}
bool Server::operator == (const Server &s) const
{
return _pvt->server == s._pvt->server;
return _pvt->server == s._pvt->server;
}
bool Server::listening() const
{
return dbus_server_get_is_connected(_pvt->server);
return dbus_server_get_is_connected(_pvt->server);
}
void Server::disconnect()
{
dbus_server_disconnect(_pvt->server);
dbus_server_disconnect(_pvt->server);
}

View file

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

View file

@ -37,70 +37,70 @@
using namespace DBus;
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)
: _msg(CallMessage())
: _msg(CallMessage())
{
MessageIter vi = it.recurse();
MessageIter mi = _msg.writer();
vi.copy_data(mi);
MessageIter vi = it.recurse();
MessageIter mi = _msg.writer();
vi.copy_data(mi);
}
Variant &Variant::operator = (const Variant &v)
{
if (&v != this)
{
_msg = v._msg;
}
return *this;
if (&v != this)
{
_msg = v._msg;
}
return *this;
}
void Variant::clear()
{
CallMessage empty;
_msg = empty;
CallMessage empty;
_msg = empty;
}
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)
{
const Signature sig = val.signature();
const Signature sig = val.signature();
MessageIter rit = val.reader();
MessageIter wit = iter.new_variant(sig.c_str());
MessageIter rit = val.reader();
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)
{
if (iter.type() != DBUS_TYPE_VARIANT)
throw ErrorInvalidArgs("variant type expected");
if (iter.type() != DBUS_TYPE_VARIANT)
throw ErrorInvalidArgs("variant type expected");
val.clear();
val.clear();
MessageIter vit = iter.recurse();
MessageIter mit = val.writer();
MessageIter vit = iter.recurse();
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_cond_t clientCondition = PTHREAD_COND_INITIALIZER;
TestApp::TestApp ()
TestApp::TestApp()
{
testList.push_back ("test1");
testList.push_back ("testByte");
testList.push_back("test1");
testList.push_back("testByte");
cout << "initialize DBus..." << endl;
initDBus ();
initDBus();
}
void TestApp::initDBus ()
void TestApp::initDBus()
{
DBus::_init_threading();
@ -39,68 +39,68 @@ void TestApp::initDBus ()
DBus::Connection conn = DBus::Connection::SessionBus();
TestAppIntro testComIntro (conn, clientCondition, testResult);
TestAppIntro testComIntro(conn, clientCondition, testResult);
g_testComIntro = &testComIntro;
cout << "Start server..." << endl;
TestAppIntroProvider testComProviderIntro (conn, &testComIntro);
conn.request_name ("DBusCpp.Test.Com.Intro");
TestAppIntroProvider testComProviderIntro(conn, &testComIntro);
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;
pthread_create (&testThread, NULL, TestApp::testThreadRunner, &conn);
pthread_create(&testThread, NULL, TestApp::testThreadRunner, &conn);
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 ();
tl_it != testList.end ();
for (std::list <std::string>::const_iterator tl_it = testList.begin();
tl_it != testList.end();
++tl_it)
{
const string &testString = *tl_it;
cout << "write to pipe" << endl;
mTestToDBusPipe->write (testString.c_str (), testString.length () + 1);
mTestToDBusPipe->write(testString.c_str(), testString.length() + 1);
struct timespec abstime;
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += 1;
pthread_mutex_lock (&clientMutex);
if (pthread_cond_timedwait (&clientCondition, &clientMutex, &abstime) == ETIMEDOUT)
pthread_mutex_lock(&clientMutex);
if (pthread_cond_timedwait(&clientCondition, &clientMutex, &abstime) == ETIMEDOUT)
{
cout << "client timeout!" << endl;
testResult = false;
}
pthread_mutex_unlock (&clientMutex);
pthread_mutex_unlock(&clientMutex);
}
cout << "leave!" << endl;
dispatcher.leave ();
dispatcher.leave();
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 << "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,14 +13,14 @@
class TestApp
{
public:
TestApp ();
TestApp();
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
pthread_t testThread;

View file

@ -15,24 +15,24 @@ class TestAppIntro :
public DBus::ObjectProxy
{
public:
TestAppIntro (DBus::Connection& connection, pthread_cond_t &condition, bool &testResult) :
DBus::ObjectProxy (connection, "/DBusCpp/Test/Com/Intro", "DBusCpp.Test.Com.Intro"),
mCondition (condition),
mTestResult (testResult)
TestAppIntro(DBus::Connection &connection, pthread_cond_t &condition, bool &testResult) :
DBus::ObjectProxy(connection, "/DBusCpp/Test/Com/Intro", "DBusCpp.Test.Com.Intro"),
mCondition(condition),
mTestResult(testResult)
{}
void test1Result ()
void test1Result()
{
cout << "Test1Result" << endl;
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;
pthread_cond_signal (&mCondition);
pthread_cond_signal(&mCondition);
}
private:

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
#include <dbuscxx_test_generator-server.h>
int main (int argc, char **argv)
int main(int argc, char **argv)
{
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\
";
void underscorize(string &str)
{
for (unsigned int i = 0; i < str.length(); ++i)
{
if (!isalpha(str[i]) && !isdigit(str[i])) str[i] = '_';
}
}
void underscorize(string &str)
{
for (unsigned int i = 0; i < str.length(); ++i)
{
if (!isalpha(str[i]) && !isdigit(str[i])) str[i] = '_';
}
}
string stub_name(string name)
{
underscorize(name);
string stub_name(string name)
{
underscorize(name);
return "_" + name + "_stub";
}
return "_" + name + "_stub";
}
const char *atomic_type_to_string(char t)
{
static struct { char type; const char *name; } atos[] =
{
{ 'y', "uint8_t" },
{ 'b', "bool" },
{ 'n', "int16_t" },
{ 'q', "uint16_t" },
{ 'i', "int32_t" },
{ 'u', "uint32_t" },
{ 'x', "int64_t" },
{ 't', "uint64_t" },
{ 'd', "double" },
{ 's', "std::string" },
{ 'o', "::DBus::Path" },
{ 'g', "::DBus::Signature" },
{ 'v', "::DBus::Variant" },
{ '\0', "" }
};
int i;
const char *atomic_type_to_string(char t)
{
static struct
{
char type;
const char *name;
} atos[] =
{
{ 'y', "uint8_t" },
{ 'b', "bool" },
{ 'n', "int16_t" },
{ 'q', "uint16_t" },
{ 'i', "int32_t" },
{ 'u', "uint32_t" },
{ 'x', "int64_t" },
{ 't', "uint64_t" },
{ 'd', "double" },
{ 's', "std::string" },
{ 'o', "::DBus::Path" },
{ 'g', "::DBus::Signature" },
{ 'v', "::DBus::Variant" },
{ '\0', "" }
};
int i;
for (i = 0; atos[i].type; ++i)
{
if (atos[i].type == t) break;
}
return atos[i].name;
}
for (i = 0; atos[i].type; ++i)
{
if (atos[i].type == t) break;
}
return atos[i].name;
}
static void _parse_signature(const string &signature, string &type, unsigned int &i, bool only_once = false)
{
/*cout << "signature: " << signature << endl;
cout << "type: " << type << endl;
cout << "i: " << i << ", signature[i]: " << signature[i] << endl;*/
static void _parse_signature(const string &signature, string &type, unsigned int &i, bool only_once = false)
{
/*cout << "signature: " << signature << endl;
cout << "type: " << type << 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 += " >";
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;
}
case '(':
{
type += "std::vector< ::DBus::Struct< ";
++i;
_parse_signature(signature, type, i);
type += " > >";
break;
}
default:
{
type += "std::vector< ";
_parse_signature(signature, type, i, true);
break;
}
default:
{
type += "std::vector< ";
_parse_signature(signature, type, i, true);
type += " >";
type += " >";
break;
}
}
break;
}
case '(':
{
type += "::DBus::Struct< ";
++i;
break;
}
}
break;
}
case '(':
{
type += "::DBus::Struct< ";
++i;
_parse_signature(signature, type, i);
_parse_signature(signature, type, i);
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;
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;
}
}
if (only_once)
return;
if (only_once)
return;
if (i+1 < signature.length() && signature[i+1] != ')' && signature[i+1] != '}')
{
type += ", ";
}
}
}
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;
}
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
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;
os << std::setw(w) << std::setprecision(p) << thing;

View file

@ -34,46 +34,46 @@ static char *service;
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(SIGINT, niam);
signal(SIGALRM, niam);
signal(SIGTERM, niam);
signal(SIGINT, niam);
signal(SIGALRM, niam);
if (argc == 1)
{
std::cerr << std::endl << "Usage: " << argv[0] << " [--system] <object_path> [<destination>]" << std::endl << std::endl;
}
else
{
if (strcmp(argv[1], "--system"))
{
systembus = false;
path = argv[1];
service = argc > 2 ? argv[2] : 0;
}
else
{
systembus = true;
path = argv[2];
service = argc > 3 ? argv[3] : 0;
}
if (argc == 1)
{
std::cerr << std::endl << "Usage: " << argv[0] << " [--system] <object_path> [<destination>]" << std::endl << std::endl;
}
else
{
if (strcmp(argv[1], "--system"))
{
systembus = false;
path = argv[1];
service = argc > 2 ? argv[2] : 0;
}
else
{
systembus = true;
path = argv[2];
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:
IntrospectedObject(DBus::Connection &conn, const char *path, const char *service)
: DBus::ObjectProxy(conn, path, service)
{}
IntrospectedObject(DBus::Connection &conn, const char *path, const char *service)
: DBus::ObjectProxy(conn, path, service)
{}
};
#endif//__DBUSXX_TOOLS_INTROSPECT_H

View file

@ -28,16 +28,16 @@
std::istream &operator >> (std::istream &in, DBus::Xml::Document &doc)
{
std::stringbuf xmlbuf;
in.get(xmlbuf, '\0');
doc.from_xml(xmlbuf.str());
std::stringbuf xmlbuf;
in.get(xmlbuf, '\0');
doc.from_xml(xmlbuf.str());
return in;
return in;
}
std::ostream &operator << (std::ostream &out, const DBus::Xml::Document &doc)
{
return out << doc.to_xml();
return out << doc.to_xml();
}
using namespace DBus;
@ -45,209 +45,209 @@ using namespace DBus::Xml;
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)
: name(n)
Node::Node(const char *n, const char **a)
: name(n)
{
if (a)
for (int i = 0; a[i]; i += 2)
{
_attrs[a[i]] = a[i+1];
if (a)
for (int i = 0; a[i]; i += 2)
{
_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 result;
Nodes result;
for (iterator i = begin(); i != end(); ++i)
{
Nodes part = (**i)[key];
for (iterator i = begin(); i != end(); ++i)
{
Nodes part = (**i)[key];
result.insert(result.end(), part.begin(), part.end());
}
return result;
result.insert(result.end(), part.begin(), part.end());
}
return result;
}
Nodes Nodes::select(const std::string &attr, const std::string &value)
{
Nodes result;
Nodes result;
for (iterator i = begin(); i != end(); ++i)
{
if ((*i)->get(attr) == value)
result.insert(result.end(), *i);
}
return result;
for (iterator i = begin(); i != end(); ++i)
{
if ((*i)->get(attr) == value)
result.insert(result.end(), *i);
}
return result;
}
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)
{
if (i->name == key)
result.push_back(&(*i));
}
return result;
for (Children::iterator i = children.begin(); i != children.end(); ++i)
{
if (i->name == key)
result.push_back(&(*i));
}
return result;
}
std::string Node::get(const std::string &attribute)
{
if (_attrs.find(attribute) != _attrs.end())
return _attrs[attribute];
else
return "";
if (_attrs.find(attribute) != _attrs.end())
return _attrs[attribute];
else
return "";
}
void Node::set(const std::string &attribute, std::string value)
{
if (value.length())
_attrs[attribute] = value;
else
_attrs.erase(value);
if (value.length())
_attrs[attribute] = value;
else
_attrs.erase(value);
}
std::string Node::to_xml() const
{
std::string xml;
int depth = 0;
std::string xml;
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
{
xml.append(depth *2, ' ');
xml.append("<"+name);
xml.append(depth * 2, ' ');
xml.append("<" + name);
for (Attributes::const_iterator i = _attrs.begin(); i != _attrs.end(); ++i)
{
xml.append(" "+i->first+"=\""+i->second+"\"");
}
for (Attributes::const_iterator i = _attrs.begin(); i != _attrs.end(); ++i)
{
xml.append(" " + i->first + "=\"" + i->second + "\"");
}
if (cdata.length() == 0 && children.size() == 0)
{
xml.append("/>\n");
}
else
{
xml.append(">");
if (cdata.length() == 0 && children.size() == 0)
{
xml.append("/>\n");
}
else
{
xml.append(">");
if (cdata.length())
{
xml.append(cdata);
}
if (cdata.length())
{
xml.append(cdata);
}
if (children.size())
{
xml.append("\n");
depth++;
if (children.size())
{
xml.append("\n");
depth++;
for (Children::const_iterator i = children.begin(); i != children.end(); ++i)
{
i->_raw_xml(xml, depth);
}
for (Children::const_iterator i = children.begin(); i != children.end(); ++i)
{
i->_raw_xml(xml, depth);
}
depth--;
xml.append(depth *2, ' ');
}
xml.append("</"+name+">\n");
}
depth--;
xml.append(depth * 2, ' ');
}
xml.append("</" + name + ">\n");
}
}
Document::Document()
: root(0), _depth(0)
: root(0), _depth(0)
{
}
Document::Document(const std::string &xml)
: root(0), _depth(0)
: root(0), _depth(0)
{
from_xml(xml);
from_xml(xml);
}
Document::~Document()
{
delete root;
delete root;
}
struct Document::Expat
{
static void start_doctype_decl_handler(
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 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 end_element_handler(void *data, const XML_Char *name);
static void start_doctype_decl_handler(
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 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 end_element_handler(void *data, const XML_Char *name);
};
void Document::from_xml(const std::string &xml)
{
_depth = 0;
delete root;
root = 0;
_depth = 0;
delete root;
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(
parser,
Document::Expat::start_doctype_decl_handler,
Document::Expat::end_doctype_decl_handler
);
XML_SetDoctypeDeclHandler(
parser,
Document::Expat::start_doctype_decl_handler,
Document::Expat::end_doctype_decl_handler
);
XML_SetElementHandler(
parser,
Document::Expat::start_element_handler,
Document::Expat::end_element_handler
);
XML_SetElementHandler(
parser,
Document::Expat::start_element_handler,
Document::Expat::end_element_handler
);
XML_SetCharacterDataHandler(
parser,
Document::Expat::character_data_handler
);
XML_SetCharacterDataHandler(
parser,
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)
{
const char *error = XML_ErrorString(XML_GetErrorCode(parser));
int line = XML_GetCurrentLineNumber(parser);
int column = XML_GetCurrentColumnNumber(parser);
if (status == XML_STATUS_ERROR)
{
const char *error = XML_ErrorString(XML_GetErrorCode(parser));
int line = XML_GetCurrentLineNumber(parser);
int column = XML_GetCurrentColumnNumber(parser);
XML_ParserFree(parser);
XML_ParserFree(parser);
throw Error(error, line, column);
}
else
{
XML_ParserFree(parser);
}
throw Error(error, line, column);
}
else
{
XML_ParserFree(parser);
}
}
std::string Document::to_xml() const
{
return root->to_xml();
return root->to_xml();
}
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)
{
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)
{
doc->root = new Node(name, atts);
}
else
{
Node::Children *cld = &(doc->root->children);
if (!doc->root)
{
doc->root = new Node(name, atts);
}
else
{
Node::Children *cld = &(doc->root->children);
for (int i = 1; i < doc->_depth; ++i)
{
cld = &(cld->back().children);
}
cld->push_back(Node(name, atts));
for (int i = 1; i < doc->_depth; ++i)
{
cld = &(cld->back().children);
}
cld->push_back(Node(name, atts));
//std::cerr << doc->to_xml() << std::endl;
}
doc->_depth++;
//std::cerr << doc->to_xml() << std::endl;
}
doc->_depth++;
}
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)
{
nod = &(nod->children.back());
}
int x, y;
for (int i = 1; i < doc->_depth; ++i)
{
nod = &(nod->children.back());
}
int x, y;
x = 0;
y = len-1;
x = 0;
y = len - 1;
while (isspace(chars[y]) && y > 0) --y;
while (isspace(chars[x]) && x < y) ++x;
while (isspace(chars[y]) && y > 0) --y;
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)
{
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 <sstream>
namespace DBus {
namespace DBus
{
namespace Xml {
namespace Xml
{
class Error : public std::exception
{
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()
{
return _error.c_str();
}
const char *what() const throw()
{
return _error.c_str();
}
private:
std::string _error;
std::string _error;
};
class Node;
@ -65,71 +67,71 @@ class Nodes : public std::vector<Node *>
{
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
{
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 cdata;
Children children;
std::string name;
std::string cdata;
Children children;
Node(std::string &n, Attributes &a)
: name(n), _attrs(a)
{}
Node(std::string &n, Attributes &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)
{
children.push_back(child);
return children.back();
}
Node &add(Node child)
{
children.push_back(child);
return children.back();
}
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
{
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:
int _depth;
int _depth;
};
} /* namespace Xml */

View file

@ -40,9 +40,9 @@ using namespace DBus;
void usage(const char *argv0)
{
cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]"
<< endl << endl;
exit(-1);
cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]"
<< endl << endl;
exit(-1);
}
/*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)
{
usage(argv[0]);
}
if (argc < 2)
{
usage(argv[0]);
}
bool proxy_mode, adaptor_mode;
char *proxy, *adaptor;
bool proxy_mode, adaptor_mode;
char *proxy, *adaptor;
proxy_mode = false;
proxy = 0;
proxy_mode = false;
proxy = 0;
adaptor_mode = false;
adaptor = 0;
adaptor_mode = false;
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;
}
}
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]);
if (!proxy_mode && !adaptor_mode) usage(argv[0]);
ifstream xmlfile(argv[1]);
ifstream xmlfile(argv[1]);
if (xmlfile.bad())
{
cerr << "unable to open file " << argv[1] << endl;
return -1;
}
if (xmlfile.bad())
{
cerr << "unable to open file " << argv[1] << endl;
return -1;
}
Xml::Document doc;
Xml::Document doc;
try
{
xmlfile >> doc;
//cout << doc.to_xml();
}
catch(Xml::Error &e)
{
cerr << "error parsing " << argv[1] << ": " << e.what() << endl;
return -1;
}
try
{
xmlfile >> doc;
//cout << doc.to_xml();
}
catch (Xml::Error &e)
{
cerr << "error parsing " << argv[1] << ": " << e.what() << endl;
return -1;
}
if (!doc.root)
{
cerr << "empty document" << endl;
return -1;
}
if (!doc.root)
{
cerr << "empty document" << endl;
return -1;
}
if (proxy_mode) generate_proxy(doc, proxy);
if (adaptor_mode) generate_adaptor(doc, adaptor);
if (proxy_mode) generate_proxy(doc, proxy);
if (adaptor_mode) generate_adaptor(doc, adaptor);
return 0;
return 0;
}