Initial revision
[lsystem3d.git] / lsystem3d / src / xmlstructure.cpp
diff --git a/lsystem3d/src/xmlstructure.cpp b/lsystem3d/src/xmlstructure.cpp
new file mode 100644 (file)
index 0000000..b7466c0
--- /dev/null
@@ -0,0 +1,231 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D 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 General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#include <string>
+
+#include <libxml++/document.h>
+#include <libxml++/nodes/element.h>
+#include <libxml++/nodes/node.h>
+#include <libxml++/parsers/domparser.h>
+
+#include <glibmm/stringutils.h>
+
+#include "xmlstructure.h"
+
+using namespace std;
+
+
+
+/**
+ * Constructor
+ */
+XMLStructure::XMLStructure()
+{
+    _rootElement = NULL;
+    _activeElement = NULL;
+    _activeDocument = NULL;
+    _activeChildInList = NULL;
+}
+
+
+
+/**
+ * Destructor
+ */
+XMLStructure::~XMLStructure()
+{
+    delete _activeDocument;
+}
+
+
+
+/**
+ * Create new document with root node
+ * @param rootName name of root
+ */
+void XMLStructure::createDocumentWithRoot(string rootName)
+{
+    delete _activeDocument;
+    _activeDocument = new xmlpp::Document;
+    
+    _rootElement = _activeDocument->create_root_node(rootName);
+}
+
+
+
+/**
+ * Add new child to root
+ * @param name name of child
+ */
+void XMLStructure::addChildToRoot(string name)
+{
+    _activeElement = _rootElement->add_child(name);
+}
+
+
+
+/**
+ * Add a string as content of current child
+ * @param text the text
+ */
+void XMLStructure::addString(string text)
+{
+    _activeElement->add_child_text(text);
+}
+
+
+
+/**
+ * Add a number as content of current child
+ * @param value the number
+ */
+void XMLStructure::addNumber(double value)
+{
+    // convert double -> string
+    string numberAsString = Glib::Ascii::dtostr(value);
+    
+    addString(numberAsString);
+}
+
+
+
+/**
+ * Add attribute to current child
+ * @param name name of attribute
+ * @param value value of attribute
+ */
+void XMLStructure::addAttribute(string name, string value)
+{
+    _activeElement->set_attribute(name, value);
+}
+
+
+
+/**
+ * Save document to file
+ * @param path path to file
+ */
+void XMLStructure::saveToDisk(string path)
+{
+    _activeDocument->write_to_file_formatted(path);
+}
+
+
+
+/**
+ * Load document from file
+ * @param path path to file
+ */
+void XMLStructure::loadFromDisk(string path)
+{
+    // TODO: validate?
+    //_parser.set_validate(true);
+    
+    _parser.parse_file(path);
+        
+    _rootElement = _parser.get_document()->get_root_node();
+}
+
+
+
+/**
+ * Find all children with the specified name
+ * @param name name of children
+ * @return true if found, else false
+ */
+bool XMLStructure::findChild(string name)
+{
+    _activeList = _rootElement->get_children(name);
+    _activeChildInList = _activeList.begin();
+    
+    return !_activeList.empty();
+}
+
+
+
+/**
+ * Find next child in current search result list
+ * @return true if found, else false
+ */
+bool XMLStructure::findNextChild()
+{
+    _activeChildInList++;
+    
+    bool endOfList = false;
+    
+    // last child?
+    if (_activeChildInList == _activeList.end())
+    {
+        _activeChildInList--;
+        endOfList = true;
+    }
+    
+    return !endOfList;
+}
+
+
+
+/**
+ * Get content of current child as a string
+ * @return the string
+ */
+string XMLStructure::getString()
+{
+    // the child
+    xmlpp::Node *child = (*_activeChildInList)->get_children().front();
+    
+    // its content
+    string content = dynamic_cast<xmlpp::ContentNode*>(child)->get_content();
+    
+    return content;
+}
+
+
+
+/**
+ * Get content of current child as a number
+ * @return the number
+ */
+double XMLStructure::getNumber()
+{
+    // convert string -> double
+    double number = Glib::Ascii::strtod(getString());
+
+    return number;
+}
+
+
+
+/**
+ * Get attribute value of current child
+ * @param name name of attribute
+ * @return the value
+ */
+string XMLStructure::getAttribute(string name)
+{
+    // the child
+    xmlpp::Element *child = dynamic_cast<xmlpp::Element*>(*_activeChildInList);
+    
+    // its attribute value
+    string attributeValue = child->get_attribute(name)->get_value();
+    
+    return attributeValue;
+}