- 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

@ -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 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 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);
void request_name( const char* name, int flags = 0 );
unsigned long sender_unix_uid(const char *sender);
/*!
* \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 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 );
void request_name(const char *name, int flags = 0);
/*!
* \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 );
unsigned long sender_unix_uid(const char *sender);
const std::vector<std::string>& names();
void set_timeout(int timeout);
int get_timeout();
/*!
* \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);
const std::vector<std::string>& names();
void set_timeout(int 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(Message &);
Error(const char *name, const char *message);
~Error() throw();
Error(Message &);
const char *what() const throw();
~Error() throw();
const char *name() const;
const char *what() const throw();
const char *message() const;
const char *name() const;
void set(const char *name, const char *message);
// parameters MUST be static strings
const char *message() const;
bool is_set() const;
void set(const char *name, const char *message);
// parameters MUST be static strings
operator bool() const
{
return is_set();
}
bool is_set() const;
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,9 +31,10 @@
#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();
virtual void enter();
~BusDispatcher() {}
virtual void leave();
virtual void enter();
virtual void leave();
virtual Pipe *add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data);
virtual void del_pipe (Pipe *pipe);
virtual void do_iteration();
virtual void del_pipe(Pipe *pipe);
virtual Timeout *add_timeout(Timeout::Internal *);
virtual void do_iteration();
virtual void rem_timeout(Timeout *);
virtual Timeout *add_timeout(Timeout::Internal *);
virtual Watch *add_watch(Watch::Internal *);
virtual void rem_timeout(Timeout *);
virtual void rem_watch(Watch *);
virtual Watch *add_watch(Watch::Internal *);
void watch_ready(DefaultWatch &);
virtual void rem_watch(Watch *);
void timeout_expired(DefaultTimeout &);
void watch_ready(DefaultWatch &);
void timeout_expired(DefaultTimeout &);
private:
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;
DefaultMainLoop *_disp;
void *_data;
friend class DefaultMainLoop;
DefaultMainLoop *_disp;
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 bool _invoke_method_noreply(CallMessage &call) = 0;
virtual Message _invoke_method(CallMessage &) = 0;
InterfaceProxyTable _interfaces;
virtual bool _invoke_method_noreply(CallMessage &call) = 0;
InterfaceProxyTable _interfaces;
};
class DXXAPI Interface
{
public:
Interface(const std::string &name);
virtual ~Interface();
inline const std::string &name() const;
Interface(const std::string &name);
virtual ~Interface();
inline const std::string &name() const;
private:
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) \
@ -185,7 +186,7 @@ protected:
InterfaceAdaptor::_properties[ #variable ].write = can_write; \
InterfaceAdaptor::_properties[ #variable ].sig = type; \
variable.bind(InterfaceAdaptor::_properties[ #variable ]);
# define connect_signal(interface, signal, callback) \
InterfaceProxy::_signals[ #signal ] = \
new ::DBus::Callback< interface, void, const ::DBus::SignalMessage &>(this, & interface :: 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();
bool append_string(const char *chars);
double get_double();
const char *get_string();
bool append_string(const char *chars);
bool append_path(const char *chars);
const char *get_string();
const char *get_path();
bool append_path(const char *chars);
bool append_signature(const char *chars);
const char *get_path();
const char *get_signature();
bool append_signature(const char *chars);
char *signature() const; //returned string must be manually free()'d
MessageIter recurse();
const char *get_signature();
bool append_array(char type, const void *ptr, size_t length);
char *signature() const; //returned string must be manually free()'d
int array_type();
MessageIter recurse();
int get_array(void *ptr);
bool append_array(char type, const void *ptr, size_t length);
bool is_array();
int array_type();
bool is_dict();
int get_array(void *ptr);
MessageIter new_array(const char *sig);
bool is_array();
MessageIter new_variant(const char *sig);
bool is_dict();
MessageIter new_struct();
MessageIter new_array(const char *sig);
MessageIter new_dict_entry();
MessageIter new_variant(const char *sig);
void close_container(MessageIter &container);
MessageIter new_struct();
void copy_data(MessageIter &to);
MessageIter new_dict_entry();
Message &msg() const
{
return *_msg;
}
void close_container(MessageIter &container);
void copy_data(MessageIter &to);
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;
Message(Private *, bool incref = true);
struct Private;
Message(const Message &m);
Message(Private *, bool incref = true);
~Message();
Message(const Message &m);
Message &operator = (const Message &m);
~Message();
Message copy();
Message &operator = (const Message &m);
int type() const;
Message copy();
int serial() const;
int type() const;
int reply_serial() const;
int serial() const;
bool reply_serial(int);
int reply_serial() const;
const char *sender() const;
bool reply_serial(int);
bool sender(const char *s);
const char *sender() const;
const char *destination() const;
bool sender(const char *s);
bool destination(const char *s);
const char *destination() const;
bool is_error() const;
bool destination(const char *s);
bool is_signal(const char *interface, const char *member) const;
bool is_error() const;
MessageIter reader() const;
bool is_signal(const char *interface, const char *member) const;
MessageIter writer();
MessageIter reader() const;
bool append(int first_type, ...);
MessageIter writer();
void terminate();
bool append(int first_type, ...);
void terminate();
protected:
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;
};
/*
@ -221,16 +222,16 @@ friend class Connection;
class DXXAPI ErrorMessage : public Message
{
public:
ErrorMessage();
ErrorMessage(const Message &, const char *name, const char *message);
ErrorMessage();
const char *name() const;
ErrorMessage(const Message &, const char *name, const char *message);
bool name(const char *n);
const char *name() const;
bool operator == (const ErrorMessage &) const;
bool name(const char *n);
bool operator == (const ErrorMessage &) const;
};
/*
@ -240,25 +241,25 @@ class DXXAPI SignalMessage : public Message
{
public:
SignalMessage(const char *name);
SignalMessage(const char *name);
SignalMessage(const char *path, const char *interface, const char *name);
SignalMessage(const char *path, const char *interface, const char *name);
const char *interface() const;
const char *interface() const;
bool interface(const char *i);
bool interface(const char *i);
const char *member() const;
const char *member() const;
bool member(const char *m);
bool member(const char *m);
const char *path() const;
const char *path() const;
char ** path_split() const;
char **path_split() const;
bool path(const char *p);
bool path(const char *p);
bool operator == (const SignalMessage &) const;
bool operator == (const SignalMessage &) const;
};
/*
@ -267,28 +268,28 @@ public:
class DXXAPI CallMessage : public Message
{
public:
CallMessage();
CallMessage(const char *dest, const char *path, const char *iface, const char *method);
CallMessage();
const char *interface() const;
CallMessage(const char *dest, const char *path, const char *iface, const char *method);
bool interface(const char *i);
const char *interface() const;
const char *member() const;
bool interface(const char *i);
bool member(const char *m);
const char *member() const;
const char *path() const;
bool member(const char *m);
char ** path_split() const;
const char *path() const;
bool path(const char *p);
char **path_split() const;
const char *signature() const;
bool path(const char *p);
bool operator == (const CallMessage &) const;
const char *signature() const;
bool operator == (const CallMessage &) const;
};
/*
@ -297,10 +298,10 @@ public:
class DXXAPI ReturnMessage : public Message
{
public:
ReturnMessage(const CallMessage &callee);
const char *signature() const;
ReturnMessage(const CallMessage &callee);
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 Connection &conn();
inline const std::string &service() const;
void set_timeout(int new_timeout = -1);
inline Connection &conn();
inline int get_timeout() const;
void set_timeout(int new_timeout = -1);
inline int get_timeout() const;
private:
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 &);
bool _invoke_method_noreply(CallMessage &call);
Message _invoke_method(CallMessage &);
bool handle_message(const Message &);
bool _invoke_method_noreply(CallMessage &call);
void register_obj();
void unregister_obj(bool throw_on_error = true);
bool handle_message(const Message &);
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 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 Checks whether the pending call has received a reply yet, or not.
*
* \return true If a reply has been received.
*/
bool completed();
/*!
* \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 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 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 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 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 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);
/*!
* \return The data slot.
*/
Slot<void, PendingCall &>& slot();
/*!
* \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 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();
/*!
* \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();
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();
private:
void(*_handler)(const void *data, void *buffer, unsigned int nbyte);
int _fd_write;
int _fd_read;
const void *_data;
// allow construction only in BusDispatcher
Pipe (void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data);
~Pipe () {};
/*!
* 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();
friend class BusDispatcher;
private:
void(*_handler)(const void *data, void *buffer, unsigned int nbyte);
int _fd_write;
int _fd_read;
const void *_data;
// allow construction only in BusDispatcher
Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data);
~Pipe() {};
friend class BusDispatcher;
};
} /* namespace DBus */

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,474 +68,583 @@ 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>
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> >
{
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()
+ ")";
}
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()
+ ")";
}
};
} /* 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);
#endif//__DBUSXX_TYPES_H

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;
return __ptr;
}
T *operator ->() const
{
if (__cnt.noref()) return 0;
T *get() const
{
if (__cnt.noref()) return 0;
return __ptr;
}
return __ptr;
}
T *get() const
{
if (__cnt.noref()) return 0;
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;
return __ptr;
}
T *operator ->() const
{
if (__cnt.noref()) return 0;
T *get() const
{
if (__cnt.noref()) return 0;
return __ptr;
}
return __ptr;
}
T *get() const
{
if (__cnt.noref()) return 0;
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,28 +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())
{
return _cb->call(param);
}
// TODO: think about return type in this case
// this assert should help me to find the use case where it's needed...
//assert (false);
}
R call(P param) const
{
if (!empty())
R operator()(P param) const
{
if (!empty())
{
return _cb->call(param);
}
@ -254,46 +243,59 @@ 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;
}
R call(P param) const
{
if (!empty())
{
return _cb->call(param);
}
// TODO: think about return type in this case
// this assert should help me to find the use case where it's needed...
//assert (false);
}
bool empty() const
{
return _cb.get() == 0;
}
private:
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 */