* 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:
parent
a8f5e819bd
commit
7c420f87cd
36 changed files with 287 additions and 172 deletions
315
tools/xml.cpp
Normal file
315
tools/xml.cpp
Normal file
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
*
|
||||
* 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 "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--;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue