* Enabled the symbol visibility feature from gcc 4, reduces binary size and dynamic loading speed

* A lot of fixes to keep compatibility with older (0.6x) versions of libdbus
* Moved the xml handling code from the library to the code generator
* Rewrote the routine to generate introspection data
* Autojunk cleanup



git-svn-id: http://dev.openwengo.org/svn/openwengo/wengophone-ng/branches/wengophone-dbus-api/libs/dbus@12019 30a43799-04e7-0310-8b2b-ea0d24f86d0e
This commit is contained in:
pdurante 2007-07-23 18:31:49 +00:00
parent a8f5e819bd
commit 7c420f87cd
36 changed files with 287 additions and 172 deletions

View file

@ -1,6 +1,5 @@
AM_CPPFLAGS = \
$(dbus_CFLAGS) \
$(xml_CFLAGS) \
$(glib_CFLAGS) \
-I$(top_srcdir)/include
@ -28,16 +27,16 @@ HEADER_FILES = \
$(HEADER_DIR)/debug.h \
$(HEADER_DIR)/util.h \
$(HEADER_DIR)/refptr_impl.h \
$(HEADER_DIR)/xml.h \
$(HEADER_DIR)/introspection.h \
$(HEADER_DIR)/api.h \
$(GLIB_H)
lib_includedir=$(includedir)/dbus-c++-1/dbus-c++/
lib_include_HEADERS = $(HEADER_FILES)
lib_LTLIBRARIES = libdbus-c++-1.la
libdbus_c___1_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 $(GLIB_CPP)
libdbus_c___1_la_LIBADD = $(dbus_LIBS) $(xml_LIBS) $(glib_LIBS)
libdbus_c___1_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp eventloop.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 $(GLIB_CPP)
libdbus_c___1_la_LIBADD = $(dbus_LIBS) $(glib_LIBS)
MAINTAINERCLEANFILES = \
Makefile.in

View file

@ -40,7 +40,7 @@
namespace DBus {
struct Connection::Private
struct DXXAPILOCAL Connection::Private
{
DBusConnection* conn;

View file

@ -28,12 +28,12 @@
#include <cstdio>
#include <stdlib.h>
static int debug_env = -1;
static void _debug_log_default(const char* format, ...)
{
#ifdef DEBUG
static int debug_env = -1;
if(debug_env < 0) debug_env = getenv("DBUSXX_VERBOSE") ? 1 : 0;
if(debug_env)

View file

@ -168,10 +168,12 @@ void Dispatcher::dispatch_pending()
}
}
#ifdef DBUS_HAS_THREADS_INIT_DEFAULT
void DBus::_init_threading()
{
dbus_threads_init_default();
}
#endif//DBUS_HAS_THREADS_INIT_DEFAULT
void DBus::_init_threading(
MutexNewFn m1,

View file

@ -37,7 +37,7 @@
namespace DBus {
struct Dispatcher::Private
struct DXXAPILOCAL Dispatcher::Private
{
static dbus_bool_t on_add_watch( DBusWatch* watch, void* data );

View file

@ -55,6 +55,10 @@ Error::Error( Message& m )
dbus_set_error_from_message(&(_int->error), m._pvt->msg);
}
Error::~Error() throw()
{
}
const char* Error::name() const
{
return _int->error.name;

View file

@ -35,7 +35,7 @@
namespace DBus {
struct InternalError
struct DXXAPI InternalError
{
DBusError error;

View file

@ -25,10 +25,11 @@
#include <dbus-c++/introspection.h>
#include <dbus-c++/object.h>
#include <dbus-c++/message.h>
#include <dbus-c++/xml.h>
#include <dbus/dbus.h>
#include <sstream>
using namespace DBus;
static const char* introspectable_name = "org.freedesktop.DBus.Introspectable";
@ -42,8 +43,14 @@ IntrospectableAdaptor::IntrospectableAdaptor()
Message IntrospectableAdaptor::Introspect( const CallMessage& call )
{
debug_log("requested introspection data");
Xml::Node iroot("node");
std::ostringstream xml;
xml << DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE;
const std::string path = object()->path();
xml << "<node name=\"" << path << "\">";
InterfaceAdaptorTable::const_iterator iti;
@ -54,71 +61,72 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
IntrospectedInterface* const intro = iti->second->introspect();
if(intro)
{
Xml::Node& iface = iroot.add(Xml::Node("interface"));
iface.set("name", intro->name);
xml << "<interface 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);
xml << "<property name=\"" << p->name << "\""
<< " type=\"" << p->type << "\""
<< " access=\"" << access << "\"/>";
}
for(const IntrospectedMethod* m = intro->methods; m->args; ++m)
{
Xml::Node& method = iface.add(Xml::Node("method"));
method.set("name", m->name);
xml << "<method name=\"" << m->name << "\">";
for(const IntrospectedArgument* a = m->args; a->type; ++a)
{
Xml::Node& arg = method.add(Xml::Node("arg"));
if(a->name) arg.set("name", a->name);
arg.set("direction", a->in ? "in" : "out");
arg.set("type", a->type);
xml << "<arg direction=\"" << (a->in ? "in" : "out") << "\""
<< " type=\"" << a->type << "\"";
if(a->name) xml << " name=\"" << a->name << "\"";
xml << "/>";
}
xml << "</method>";
}
for(const IntrospectedMethod* m = intro->signals; m->args; ++m)
{
Xml::Node& method = iface.add(Xml::Node("signal"));
method.set("name", m->name);
xml << "<signal name=\"" << m->name << "\">";
for(const IntrospectedArgument* a = m->args; a->type; ++a)
{
Xml::Node& arg = method.add(Xml::Node("arg"));
if(a->name) arg.set("name", a->name);
arg.set("type", a->type);
xml << "<arg type=\"" << a->type << "\"";
if(a->name) xml << " name=\"" << a->name << "\"";
xml << "/>";
}
xml << "</signal>";
}
xml << "</interface>";
}
}
const std::string parent = object()->path();
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(parent + '/');
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/');
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);
std::string name = (*oci)->path().substr(path.length()+1);
name.substr(name.find('/'));
subnode.set("name", name);
xml << "<node name=\"" << name << "\"/>";
}
std::string xml = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + iroot.to_xml();
xml << "</node>";
ReturnMessage reply(call);
MessageIter wi = reply.writer();
wi.append_string(xml.c_str());
wi.append_string(xml.str().c_str());
return reply;
}

View file

@ -36,7 +36,7 @@
namespace DBus {
struct Message::Private
struct DXXAPILOCAL Message::Private
{
DBusMessage* msg;

View file

@ -36,7 +36,7 @@
namespace DBus {
struct PendingCall::Private
struct DXXAPILOCAL PendingCall::Private
{
DBusPendingCall* call;
int dataslot;

View file

@ -37,7 +37,7 @@
namespace DBus {
struct Server::Private
struct DXXAPILOCAL Server::Private
{
DBusServer* server;

View file

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