major D-Bus code update

git-svn-id: http://dev.openwengo.org/svn/openwengo/wengophone-ng/branches/wengophone-dbus-api/libs/dbus@7715 30a43799-04e7-0310-8b2b-ea0d24f86d0e
This commit is contained in:
pdurante 2006-09-23 23:25:34 +00:00
parent acfeb85b87
commit 42ea920aeb
41 changed files with 958 additions and 1506 deletions

View file

@ -4,9 +4,10 @@ AM_CPPFLAGS = -DDBUS_API_SUBJECT_TO_CHANGE
HEADER_DIR = $(top_srcdir)/include/dbus-c++
HEADER_FILES = \
$(HEADER_DIR)/config.h \
$(HEADER_DIR)/dbus-c++.h \
$(HEADER_DIR)/dbus.h \
$(HEADER_DIR)/types.h \
$(HEADER_DIR)/connection.h \
$(HEADER_DIR)/property.h \
$(HEADER_DIR)/debug.h \
$(HEADER_DIR)/error.h \
$(HEADER_DIR)/interface.h \
@ -26,5 +27,5 @@ lib_includedir=$(includedir)/dbus-c++-0.3/dbus-c++
lib_include_HEADERS = $(HEADER_FILES)
lib_LTLIBRARIES = libdbus-c++-0.3.la
libdbus_c___0_3_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp eventloop.cpp xml.cpp types.cpp connection.cpp connection_p.h dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h
libdbus_c___0_3_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp eventloop.cpp xml.cpp types.cpp connection.cpp connection_p.h property.cpp dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h
libdbus_c___0_3_la_LIBADD = $(dbus_LIBS) $(xml_LIBS)

View file

@ -62,8 +62,8 @@ libdbus_c___0_3_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
am__objects_1 =
am_libdbus_c___0_3_la_OBJECTS = $(am__objects_1) interface.lo \
object.lo introspection.lo debug.lo eventloop.lo xml.lo \
types.lo connection.lo dispatcher.lo pendingcall.lo error.lo \
message.lo server.lo
types.lo connection.lo property.lo dispatcher.lo \
pendingcall.lo error.lo message.lo server.lo
libdbus_c___0_3_la_OBJECTS = $(am_libdbus_c___0_3_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include/dbus-c++
depcomp = $(SHELL) $(top_srcdir)/depcomp
@ -202,9 +202,10 @@ AM_CPPFLAGS = -DDBUS_API_SUBJECT_TO_CHANGE
HEADER_DIR = $(top_srcdir)/include/dbus-c++
HEADER_FILES = \
$(HEADER_DIR)/config.h \
$(HEADER_DIR)/dbus-c++.h \
$(HEADER_DIR)/dbus.h \
$(HEADER_DIR)/types.h \
$(HEADER_DIR)/connection.h \
$(HEADER_DIR)/property.h \
$(HEADER_DIR)/debug.h \
$(HEADER_DIR)/error.h \
$(HEADER_DIR)/interface.h \
@ -223,7 +224,7 @@ HEADER_FILES = \
lib_includedir = $(includedir)/dbus-c++-0.3/dbus-c++
lib_include_HEADERS = $(HEADER_FILES)
lib_LTLIBRARIES = libdbus-c++-0.3.la
libdbus_c___0_3_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp eventloop.cpp xml.cpp types.cpp connection.cpp connection_p.h dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h
libdbus_c___0_3_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp eventloop.cpp xml.cpp types.cpp connection.cpp connection_p.h property.cpp dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h
libdbus_c___0_3_la_LIBADD = $(dbus_LIBS) $(xml_LIBS)
all: all-am
@ -304,6 +305,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pendingcall.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/property.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/types.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml.Plo@am__quote@

View file

@ -307,7 +307,7 @@ PendingCall Connection::send_async( Message& msg, int timeout )
if(!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout))
{
throw Error(DBUS_ERROR_NO_MEMORY, "Unable to start asynchronous call");
throw ErrorNoMemory("Unable to start asynchronous call");
}
return PendingCall(new PendingCall::Private(pending));
}

View file

@ -55,17 +55,17 @@ Error::Error( Message& m )
dbus_set_error_from_message(&(_int->error), m._pvt->msg);
}
const char* Error::name()
const char* Error::name() const
{
return _int->error.name;
}
const char* Error::message()
const char* Error::message() const
{
return _int->error.message;
}
bool Error::is_set()
bool Error::is_set() const
{
return *(_int);
}

View file

@ -111,8 +111,9 @@ void EepleMainLoop::dispatch()
int wait_min = 10000;
Timeouts::iterator ti = _timeouts.begin();
for(;ti != _timeouts.end(); ++ti)
Timeouts::iterator ti;
for(ti = _timeouts.begin(); ti != _timeouts.end(); ++ti)
{
if((*ti)->enabled() && (*ti)->interval() < wait_min)
wait_min = (*ti)->interval();
@ -151,7 +152,9 @@ void EepleMainLoop::dispatch()
for(int j = 0; j < nfd; ++j)
{
for(Watches::iterator wi = _watches.begin(); wi != _watches.end();)
Watches::iterator wi;
for(wi = _watches.begin(); wi != _watches.end();)
{
Watches::iterator tmp = wi;
++tmp;

View file

@ -29,44 +29,29 @@
using namespace DBus;
Message IfaceTracker::rinvoke_method( CallMessage& msg )
{
return ErrorMessage(msg, DBUS_ERROR_NOT_SUPPORTED, "there are no proxies in a InterfaceAdaptor");
}
Interface::Interface( const char* name )
: _name(name)
{
register_interface(name);
}
Interface::Interface( const std::string& name )
: _name(name)
{}
Interface::~Interface()
{}
InterfaceAdaptor* AdaptorBase::find_interface( const std::string& name )
{
//unregister_interface(name); //not needed
InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name);
return ii != _interfaces.end() ? ii->second : NULL;
}
Message Interface::invoke_method( const CallMessage& )
InterfaceAdaptor::InterfaceAdaptor( const std::string& name )
: Interface(name)
{
throw Error(DBUS_ERROR_NOT_SUPPORTED, "");
}
bool Interface::dispatch_signal( const SignalMessage& )
{
throw Error(DBUS_ERROR_NOT_SUPPORTED, "");
}
void Interface::register_interface( const char* name )
{
debug_log("registering interface %s",name);
debug_log("adding interface %s", name.c_str());
_interfaces[name] = this;
}
InterfaceAdaptor::InterfaceAdaptor( const char* name )
: Interface(name)
{}
Message InterfaceAdaptor::invoke_method( const CallMessage& msg )
Message InterfaceAdaptor::dispatch_method( const CallMessage& msg )
{
const char* name = msg.member();
@ -85,13 +70,53 @@ void InterfaceAdaptor::emit_signal( const SignalMessage& sig )
{
SignalMessage& sig2 = const_cast<SignalMessage&>(sig);
sig2.interface( iname().c_str() );
remit_signal(sig2);
sig2.interface( name().c_str() );
_emit_signal(sig2);
}
InterfaceProxy::InterfaceProxy( const char* name )
: Interface(name)
{}
Variant* InterfaceAdaptor::get_property( const std::string& name )
{
PropertyTable::iterator pti = _properties.find(name);
if( pti != _properties.end() )
{
if( !pti->second.read )
throw ErrorAccessDenied("property is not readable");
return &(pti->second.value);
}
return NULL;
}
bool InterfaceAdaptor::set_property( const std::string& name, Variant& value )
{
PropertyTable::iterator pti = _properties.find(name);
if( pti != _properties.end() )
{
if( !pti->second.write )
throw ErrorAccessDenied("property is not writeable");
pti->second.value = value;
return true;
}
return false;
}
InterfaceProxy* ProxyBase::find_interface( const std::string& name )
{
InterfaceProxyTable::const_iterator ii = _interfaces.find(name);
return ii != _interfaces.end() ? ii->second : NULL;
}
InterfaceProxy::InterfaceProxy( const std::string& name )
: Interface(name)
{
debug_log("adding interface %s", name.c_str());
_interfaces[name] = this;
}
bool InterfaceProxy::dispatch_signal( const SignalMessage& msg )
{
@ -113,6 +138,6 @@ Message InterfaceProxy::invoke_method( const CallMessage& call )
{
CallMessage& call2 = const_cast<CallMessage&>(call);
call2.interface( iname().c_str() );
return rinvoke_method(call2);
call2.interface( name().c_str() );
return _invoke_method(call2);
}

View file

@ -23,6 +23,7 @@
#include <dbus-c++/introspection.h>
#include <dbus-c++/object.h>
#include <dbus-c++/message.h>
#include <dbus-c++/xml.h>
@ -44,7 +45,7 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
Xml::Node iroot("node");
InterfaceTable::const_iterator iti;
InterfaceAdaptorTable::const_iterator iti;
for(iti = _interfaces.begin(); iti != _interfaces.end(); ++iti)
{
@ -56,6 +57,20 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
Xml::Node& iface = iroot.add(Xml::Node("interface"));
iface.set("name", intro->name);
for(const IntrospectedProperty* p = intro->properties; p->name; ++p)
{
Xml::Node& property = iface.add(Xml::Node("property"));
property.set("name", p->name);
property.set("type", p->type);
std::string access;
if(p->read) access += "read";
if(p->write) access += "write";
property.set("access", access);
}
for(const IntrospectedMethod* m = intro->methods; m->args; ++m)
{
Xml::Node& method = iface.add(Xml::Node("method"));
@ -84,10 +99,25 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
}
}
}
const std::string parent = object()->path();
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(parent + '/');
ObjectAdaptorPList::const_iterator oci;
for(oci = children.begin(); oci != children.end(); ++oci)
{
Xml::Node& subnode = iroot.add(Xml::Node("node"));
std::string name = (*oci)->path().substr(parent.length()+1);
name.substr(name.find('/'));
subnode.set("name", name);
}
std::string xml = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + iroot.to_xml();
ReturnMessage reply(call);
MessageIter wi = reply.w_iter();
MessageIter wi = reply.writer();
wi.append_string(xml.c_str());
return reply;
}
@ -108,9 +138,16 @@ IntrospectedInterface* const IntrospectableAdaptor::introspect() const
{
{ 0, 0 }
};
static IntrospectedProperty Introspectable_properties[] =
{
{ 0, 0, 0, 0 }
};
static IntrospectedInterface Introspectable_interface =
{
introspectable_name, Introspectable_methods, Introspectable_signals
introspectable_name,
Introspectable_methods,
Introspectable_signals,
Introspectable_properties
};
return &Introspectable_interface;
}
@ -127,7 +164,7 @@ std::string IntrospectableProxy::Introspect()
DBus::Message ret = invoke_method(call);
DBus::MessageIter ri = ret.r_iter();
DBus::MessageIter ri = ret.reader();
const char* str = ri.get_string();
return str;

View file

@ -67,7 +67,7 @@ bool MessageIter::append_basic( int type_id, void* value )
void MessageIter::get_basic( int type_id, void* ptr )
{
if(type() != type_id)
throw Error(DBUS_ERROR_INVALID_ARGS, "type mismatch");
throw ErrorInvalidArgs("type mismatch");
dbus_message_iter_get_basic((DBusMessageIter*)_iter, ptr);
}
@ -287,11 +287,11 @@ MessageIter MessageIter::new_variant( const char* sig )
return var;
}
MessageIter MessageIter::new_struct( const char* sig )
MessageIter MessageIter::new_struct()
{
MessageIter stu(msg());
dbus_message_iter_open_container(
(DBusMessageIter*)_iter, DBUS_TYPE_STRUCT, sig, (DBusMessageIter*)&(stu._iter)
(DBusMessageIter*)_iter, DBUS_TYPE_STRUCT, 0, (DBusMessageIter*)&(stu._iter)
);
return stu;
}
@ -301,6 +301,56 @@ void MessageIter::close_container( MessageIter& container )
dbus_message_iter_close_container((DBusMessageIter*)&_iter, (DBusMessageIter*)&(container._iter));
}
void MessageIter::copy_data( MessageIter& to )
{
for(MessageIter from = *this; from.at_end(); ++from)
{
switch(from.type())
{
case DBUS_TYPE_BYTE:
case DBUS_TYPE_BOOLEAN:
case DBUS_TYPE_INT16:
case DBUS_TYPE_UINT16:
case DBUS_TYPE_INT32:
case DBUS_TYPE_UINT32:
case DBUS_TYPE_INT64:
case DBUS_TYPE_UINT64:
case DBUS_TYPE_DOUBLE:
case DBUS_TYPE_STRING:
case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_SIGNATURE:
{
unsigned char value[8];
from.get_basic(from.type(), &value);
to.append_basic(from.type(), &value);
break;
}
case DBUS_TYPE_ARRAY:
case DBUS_TYPE_VARIANT:
case DBUS_TYPE_STRUCT:
case DBUS_TYPE_DICT_ENTRY:
{
MessageIter from_container = from.recurse();
char* sig = from_container.signature();
MessageIter to_container(to.msg());
dbus_message_iter_open_container
(
(DBusMessageIter*)&(to._iter),
from.type(),
sig,
(DBusMessageIter*)&(to_container._iter)
);
from_container.copy_data(to_container);
to.close_container(to_container);
free(sig);
break;
}
}
}
}
/*
*/
@ -398,14 +448,14 @@ bool Message::is_signal( const char* interface, const char* member ) const
return dbus_message_is_signal(_pvt->msg, interface, member);
}
MessageIter Message::w_iter()
MessageIter Message::writer()
{
MessageIter iter(*this);
dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter*)&(iter._iter));
return iter;
}
MessageIter Message::r_iter() const
MessageIter Message::reader() const
{
MessageIter iter(const_cast<Message&>(*this));
dbus_message_iter_init(_pvt->msg, (DBusMessageIter*)&(iter._iter));

View file

@ -26,6 +26,7 @@
#include <dbus-c++/object.h>
#include "internalerror.h"
#include <map>
#include <dbus/dbus.h>
#include "message_p.h"
@ -33,7 +34,7 @@
using namespace DBus;
Object::Object( Connection& conn, const char* path, const char* service )
Object::Object( Connection& conn, const Path& path, const char* service )
: _conn(conn), _path(path), _service(service ? service : "")
{
}
@ -57,7 +58,7 @@ static DBusObjectPathVTable _vtable =
void ObjectAdaptor::Private::unregister_function_stub( DBusConnection* conn, void* data )
{
// XXX: what do we have to do here ?
//TODO: what do we have to do here ?
}
DBusHandlerResult ObjectAdaptor::Private::message_function_stub( DBusConnection*, DBusMessage* dmsg, void* data )
@ -85,7 +86,39 @@ DBusHandlerResult ObjectAdaptor::Private::message_function_stub( DBusConnection*
}
}
ObjectAdaptor::ObjectAdaptor( Connection& conn, const char* path )
typedef std::map<Path, ObjectAdaptor*> ObjectAdaptorTable;
static ObjectAdaptorTable _adaptor_table;
ObjectAdaptor* ObjectAdaptor::from_path( const Path& path )
{
ObjectAdaptorTable::iterator ati = _adaptor_table.find(path);
if(ati != _adaptor_table.end())
return ati->second;
return NULL;
}
ObjectAdaptorPList ObjectAdaptor::from_path_prefix( const std::string& prefix )
{
ObjectAdaptorPList ali;
ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
size_t plen = prefix.length();
while(ati != _adaptor_table.end())
{
if(!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
ali.push_back(ati->second);
++ati;
}
return ali;
}
ObjectAdaptor::ObjectAdaptor( Connection& conn, const Path& path )
: Object(conn, path, conn.unique_name())
{
register_obj();
@ -102,11 +135,11 @@ void ObjectAdaptor::register_obj()
if(!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this))
{
throw Error(DBUS_ERROR_NO_MEMORY,"unable to register object path");
throw ErrorNoMemory("unable to register object path");
}
else
{
InterfaceTable::const_iterator ii = _interfaces.begin();
InterfaceAdaptorTable::const_iterator ii = _interfaces.begin();
while( ii != _interfaces.end() )
{
std::string im = "type='method_call',interface='"+ii->first+"'";
@ -114,15 +147,19 @@ void ObjectAdaptor::register_obj()
++ii;
}
}
_adaptor_table[path()] = this;
}
void ObjectAdaptor::unregister_obj()
{
_adaptor_table.erase(path());
debug_log("unregistering local object %s", path().c_str());
dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str());
InterfaceTable::const_iterator ii = _interfaces.begin();
InterfaceAdaptorTable::const_iterator ii = _interfaces.begin();
while( ii != _interfaces.end() )
{
std::string im = "type='method_call',interface='"+ii->first+"'";
@ -131,7 +168,7 @@ void ObjectAdaptor::unregister_obj()
}
}
void ObjectAdaptor::remit_signal( SignalMessage& sig )
void ObjectAdaptor::_emit_signal( SignalMessage& sig )
{
sig.path(path().c_str());
@ -150,17 +187,17 @@ bool ObjectAdaptor::handle_message( const Message& msg )
case DBUS_MESSAGE_TYPE_METHOD_CALL:
{
const CallMessage& cmsg = reinterpret_cast<const CallMessage&>(msg);
const char* member = cmsg.member();
const char* interface = cmsg.interface();
const char* member = cmsg.member();
const char* interface = cmsg.interface();
debug_log(" invoking method %s.%s", interface, member);
InterfaceTable::const_iterator ii = _interfaces.find(interface);
if( ii != _interfaces.end() )
InterfaceAdaptor* ii = find_interface(interface);
if( ii )
{
try
{
Message ret = ii->second->invoke_method(cmsg);
Message ret = ii->dispatch_method(cmsg);
conn().send(ret);
}
catch(Error& e)
@ -170,7 +207,7 @@ bool ObjectAdaptor::handle_message( const Message& msg )
}
catch(WontReturnException& wre)
{
_deferred_returns[wre.tag] = new DeferredReturn(conn(), cmsg, wre.tag);
_continuations[wre.tag] = new Continuation(conn(), cmsg, wre.tag);
}
return true;
}
@ -193,45 +230,45 @@ void ObjectAdaptor::return_later( const void* tag )
throw wre;
}
void ObjectAdaptor::return_now( DeferredReturn* ret )
void ObjectAdaptor::return_now( Continuation* ret )
{
ret->_conn.send(ret->_return);
DeferredReturnMap::iterator di = _deferred_returns.find(ret->_tag);
ContinuationMap::iterator di = _continuations.find(ret->_tag);
delete di->second;
_deferred_returns.erase(di);
_continuations.erase(di);
}
void ObjectAdaptor::return_error( DeferredReturn* ret, Error& error )
void ObjectAdaptor::return_error( Continuation* ret, const Error error )
{
ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message()));
DeferredReturnMap::iterator di = _deferred_returns.find(ret->_tag);
ContinuationMap::iterator di = _continuations.find(ret->_tag);
delete di->second;
_deferred_returns.erase(di);
_continuations.erase(di);
}
ObjectAdaptor::DeferredReturn* ObjectAdaptor::find_return( const void* tag )
ObjectAdaptor::Continuation* ObjectAdaptor::find_continuation( const void* tag )
{
DeferredReturnMap::iterator di = _deferred_returns.find(tag);
ContinuationMap::iterator di = _continuations.find(tag);
return di != _deferred_returns.end() ? di->second : NULL;
return di != _continuations.end() ? di->second : NULL;
}
ObjectAdaptor::DeferredReturn::DeferredReturn( Connection& conn, const CallMessage& call, const void* tag )
ObjectAdaptor::Continuation::Continuation( Connection& conn, const CallMessage& call, const void* tag )
: _conn(conn), _call(call), _return(_call), _tag(tag)
{
_writer = _return.w_iter(); //todo: verify
_writer = _return.writer(); //todo: verify
}
/*
*/
ObjectProxy::ObjectProxy( Connection& conn, const char* path, const char* service )
ObjectProxy::ObjectProxy( Connection& conn, const Path& path, const char* service )
: Object(conn, path, service)
{
register_obj();
@ -250,7 +287,7 @@ void ObjectProxy::register_obj()
conn().add_filter(_filtered);
InterfaceTable::const_iterator ii = _interfaces.begin();
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while( ii != _interfaces.end() )
{
std::string im = "type='signal',interface='"+ii->first+"'";
@ -266,7 +303,7 @@ void ObjectProxy::unregister_obj()
{
debug_log("unregistering remote object %s", path().c_str());
InterfaceTable::const_iterator ii = _interfaces.begin();
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while( ii != _interfaces.end() )
{
std::string im = "type='signal',interface='"+ii->first+"'";
@ -279,7 +316,7 @@ void ObjectProxy::unregister_obj()
conn().remove_filter(_filtered);
}
Message ObjectProxy::rinvoke_method( CallMessage& call )
Message ObjectProxy::_invoke_method( CallMessage& call )
{
call.path(path().c_str());
call.destination(service().c_str());
@ -299,10 +336,10 @@ bool ObjectProxy::handle_message( const Message& msg )
debug_log("filtered signal %s(in %s) from remote object %s", member, interface, msg.sender());
InterfaceTable::const_iterator ii = _interfaces.find(interface);
if( ii != _interfaces.end() )
InterfaceProxy* ii = find_interface(interface);
if( ii )
{
return ii->second->dispatch_signal(smsg);
return ii->dispatch_signal(smsg);
}
else
{
@ -313,14 +350,14 @@ bool ObjectProxy::handle_message( const Message& msg )
{
debug_log("filtered method return from remote object %s", msg.sender());
//TODO:
//TODO?
return false;
}
case DBUS_MESSAGE_TYPE_ERROR:
{
debug_log("filtered error from remote object %s", msg.sender());
//TODO:
//TODO?
return false;
}
default:

View file

@ -31,12 +31,12 @@
using namespace DBus;
PendingCall::Private::Private( DBusPendingCall* pc )
: call(pc), dataslot(-1)
PendingCall::Private::Private( DBusPendingCall* dpc )
: call(dpc), dataslot(-1)
{
if(!dbus_pending_call_allocate_data_slot(&dataslot))
{
throw Error(DBUS_ERROR_NO_MEMORY, "Unable to allocate data slot");
throw ErrorNoMemory("Unable to allocate data slot");
}
}
@ -60,7 +60,7 @@ PendingCall::PendingCall( PendingCall::Private* p )
{
if(!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, this, NULL))
{
throw Error(DBUS_ERROR_NO_MEMORY, "Unable to initialize pending call");
throw ErrorNoMemory("Unable to initialize pending call");
}
}
@ -94,7 +94,7 @@ void PendingCall::data( void* p )
{
if(!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
{
throw Error(DBUS_ERROR_NO_MEMORY, "Unable to initialize data slot");
throw ErrorNoMemory("Unable to initialize data slot");
}
}

151
src/property.cpp Normal file
View file

@ -0,0 +1,151 @@
/*
*
* D-Bus++ - C++ bindings for DBus
*
* Copyright (C) 2005-2006 Paolo Durante <shackan@gmail.com>
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <dbus-c++/property.h>
#include <dbus-c++/introspection.h>
using namespace DBus;
static const char* properties_name = "org.freedesktop.DBus.Properties";
PropertiesAdaptor::PropertiesAdaptor()
: InterfaceAdaptor(properties_name)
{
register_method(PropertiesAdaptor, Get, Get);
register_method(PropertiesAdaptor, Set, Set);
}
Message PropertiesAdaptor::Get( const CallMessage& call )
{
MessageIter ri = call.reader();
String iface_name;
String property_name;
ri >> iface_name >> property_name;
InterfaceAdaptor* interface = (InterfaceAdaptor*) find_interface(iface_name);
if(!interface)
throw ErrorFailed("requested interface not found");
Variant* value = interface->get_property(property_name);
if(!value)
throw ErrorFailed("requested property not found");
on_get_property(*interface, property_name, *value);
ReturnMessage reply(call);
MessageIter wi = reply.writer();
wi << *value;
return reply;
}
Message PropertiesAdaptor::Set( const CallMessage& call )
{
MessageIter ri = call.reader();
String iface_name;
String property_name;
Variant value;
ri >> iface_name >> property_name >> value;
InterfaceAdaptor* interface = (InterfaceAdaptor*) find_interface(iface_name);
if(!interface)
throw ErrorFailed("requested interface not found");
on_set_property(*interface, property_name, value);
if(!interface->set_property(property_name, value))
throw ErrorFailed("requested property not found");
ReturnMessage reply(call);
return reply;
}
IntrospectedInterface* const PropertiesAdaptor::introspect() const
{
static IntrospectedArgument Get_args[] =
{
{ "interface_name", "s", true },
{ "property_name", "s", true },
{ "value", "v", false },
{ 0, 0, 0 }
};
static IntrospectedArgument Set_args[] =
{
{ "interface_name", "s", true },
{ "property_name", "s", true },
{ "value", "v", true },
{ 0, 0, 0 }
};
static IntrospectedMethod Properties_methods[] =
{
{ "Get", Get_args },
{ "Set", Set_args },
{ 0, 0 }
};
static IntrospectedMethod Properties_signals[] =
{
{ 0, 0 }
};
static IntrospectedProperty Properties_properties[] =
{
{ 0, 0, 0, 0 }
};
static IntrospectedInterface Properties_interface =
{
properties_name,
Properties_methods,
Properties_signals,
Properties_properties
};
return &Properties_interface;
}
PropertiesProxy::PropertiesProxy()
: InterfaceProxy(properties_name)
{
}
Variant PropertiesProxy::Get( const String& iface, const String& property )
{
//todo
Variant v;
return v;
}
void PropertiesProxy::Set( const String& iface, const String& property, const Variant& value )
{
//todo
}

View file

@ -33,15 +33,16 @@
using namespace DBus;
Variant::Variant()
: _msg(CallMessage()), // dummy message used as temporary storage for variant data
_it(_msg.w_iter())
: _msg(CallMessage()) // dummy message used as temporary storage for variant data
{
}
Variant::Variant( MessageIter& it )
: _msg(it.msg()),
_it(it.recurse())
: _msg(CallMessage())
{
MessageIter vi = it.recurse();
MessageIter mi = _msg.writer();
vi.copy_data(mi);
}
Variant& Variant::operator = ( const Variant& v )
@ -49,118 +50,35 @@ Variant& Variant::operator = ( const Variant& v )
if(&v != this)
{
_msg = v._msg;
_it = v._it;
_signature = v._signature;
}
return *this;
}
const char* Variant::signature() const
void Variant::clear()
{
char* sigbuf = _it.signature();
CallMessage empty;
_msg = empty;
}
_signature = sigbuf;
const Signature Variant::signature() const
{
char* sigbuf = reader().signature();
Signature signature = sigbuf;
free(sigbuf);
return _signature.c_str();
return signature;
}
MessageIter& operator << ( MessageIter& iter, const Variant& val )
{
const char* sig = val.signature();
const Signature sig = val.signature();
MessageIter rit = val.iter();
MessageIter wit = iter.new_variant(sig);
MessageIter rit = val.reader();
MessageIter wit = iter.new_variant(sig.c_str());
for(size_t i = 0; i < strlen(sig); ++i)
{
switch(sig[i])
{
case 'b':
{
Bool b; rit >> b; wit << b;
break;
}
case 'y':
{
Byte y; rit >> y; wit << y;
break;
}
case 'n':
{
Int16 n; rit >> n; wit << n;
break;
}
case 'q':
{
UInt16 q; rit >> q; wit << q;
break;
}
case 'i':
{
Int32 i; rit >> i; wit << i;
break;
}
case 'u':
{
UInt32 u; rit >> u; wit << u;
break;
}
case 'x':
{
Int64 x; rit >> x; wit << x;
break;
}
case 't':
{
UInt64 t; rit >> t; wit << t;
break;
}
case 'd':
{
Double d; rit >> d; wit << d;
break;
}
case 's':
{
String s; rit >> s; wit << s;
break;
}
case 'o':
{
Path o; rit >> o; wit << o;
break;
}
case 'g':
{
Signature g; rit >> g; wit << g;
break;
}
case 'a':
{
break;
}
case '(':
{
break;
}
case ')':
{
break;
}
case '{':
{
break;
}
case '}':
{
break;
}
}
}
//TODO: implement marshaling of compound types
rit.copy_data(wit);
iter.close_container(wit);