diff options
author | Peter Williams <peter@newton.cx> | 2015-12-19 21:32:26 -0500 |
---|---|---|
committer | Peter Williams <peter@newton.cx> | 2015-12-19 21:32:26 -0500 |
commit | f9e8eb77314653f6d0a9b93c3534d46ffcd37e75 (patch) | |
tree | e6a9f1e40448440545e93054c307a72bdad9821f | |
parent | 12269b4bda2739c7264699e9059245b698ebb79a (diff) | |
download | dbus-c++-f9e8eb77314653f6d0a9b93c3534d46ffcd37e75.tar.gz |
examples/glib: fix 'make dist'
The reference to a source file in $(top_srcdir) was causing issues for the
"make dist" stage. I feel like the easiest solution is just to copy the
relevant file, though I suppose I could've just killed the example.
-rw-r--r-- | examples/glib/Makefile.am | 2 | ||||
-rw-r--r-- | examples/glib/xml.cpp | 313 |
2 files changed, 314 insertions, 1 deletions
diff --git a/examples/glib/Makefile.am b/examples/glib/Makefile.am index 8904690..c7017e8 100644 --- a/examples/glib/Makefile.am +++ b/examples/glib/Makefile.am @@ -6,7 +6,7 @@ if HAVE_GTKMM noinst_PROGRAMS = dbus-browser endif -dbus_browser_SOURCES = dbus-glue.h dbus-browser.h dbus-browser.cpp $(top_srcdir)/tools/xml.cpp +dbus_browser_SOURCES = dbus-glue.h dbus-browser.h dbus-browser.cpp xml.cpp dbus_browser_LDADD = $(top_builddir)/src/integration/glib/libdbus-c++-glib-1.la \ $(top_builddir)/src/libdbus-c++-1.la $(gtkmm_LIBS) diff --git a/examples/glib/xml.cpp b/examples/glib/xml.cpp new file mode 100644 index 0000000..d3cc3ab --- /dev/null +++ b/examples/glib/xml.cpp @@ -0,0 +1,313 @@ +/* + * + * 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 <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--; +} + |