diff --git a/MiniEngine_Xml.cpp b/MiniEngine_Xml.cpp new file mode 100644 index 0000000..7056b96 --- /dev/null +++ b/MiniEngine_Xml.cpp @@ -0,0 +1,382 @@ +#include "MiniEngine_Xml.h" +#include "rapidxml/rapidxml_print.hpp" +#include "rapidxml/rapidxml_utils.hpp" +#include + +namespace MiniEngine +{ + +namespace XML +{ + +void Attribute::_set(XAttr* pattr) +{ + _pattr=pattr; +} + +XAttr* Attribute::_get() const +{ + return _pattr; +} + +void Attribute::_clear() +{ + _pattr=nullptr; +} + +void Attribute::_setdoc(Document* pDoc) +{ + _pdoc=pDoc; +} + +Attribute::Attribute() +{ + _pattr=nullptr; + _pdoc=nullptr; +} + +Attribute::Attribute(XAttr* pAttr) +{ + _pattr=pAttr; + _pdoc=nullptr; +} + +std::string Attribute::getName() const +{ + return std::string(getNameRaw()); +} + +std::string Attribute::getValue() const +{ + return std::string(getValueRaw()); +} + +char* Attribute::getNameRaw() const +{ + return _pattr->name(); +} + +char* Attribute::getValueRaw() const +{ + return _pattr->value(); +} + +bool Attribute::hasPrevAttr() const +{ + return _pattr->previous_attribute()!=nullptr; +} + +bool Attribute::hasNextAttr() const +{ + return _pattr->next_attribute()!=nullptr; +} + +Attribute Attribute::getPrevAttr() const +{ + return Attribute(_pattr->previous_attribute()); +} + +Attribute Attribute::getNextAttr() const +{ + return Attribute(_pattr->next_attribute()); +} + + + +Node::Node() +{ + _pnode=nullptr; + _pdoc=nullptr; +} + +Node::Node(XNode* expNode) +{ + _pnode=expNode; + _pdoc=nullptr; +} + + + +void Node::_set(XNode* node) +{ + _pnode=node; +} + +XNode* Node::_get() const +{ + return _pnode; +} + +void Node::_clear() +{ + _pnode=nullptr; +} + +void Node::_setdoc(Document* pDoc) +{ + _pdoc=pDoc; +} + +std::string Node::getName() const +{ + return std::string(getNameRaw()); +} + +std::string Node::getValue() const +{ + return std::string(getValueRaw()); +} + +char* Node::getNameRaw() const +{ + return _pnode->name(); +} + +char* Node::getValueRaw() const +{ + return _pnode->value(); +} + + +Node& Node::push_front(const Node& node) +{ + _pnode->prepend_node(node._pnode); + return *this; +} + +Node& Node::push_back(const Node& node) +{ + _pnode->append_node(node._pnode); + return *this; +} + +Node& Node::insert(const Node& where, const Node& val) +{ + _pnode->insert_node(where._pnode,val._pnode); + return *this; +} + +Node& Node::remove_first_node() +{ + _pnode->remove_first_node(); + return *this; +} + +Node& Node::remove_last_node() +{ + _pnode->remove_last_node(); + return *this; +} + +Node& Node::remove_node(const Node& todelete) +{ + _pnode->remove_node(todelete._pnode); + return *this; +} + +Node& Node::remove_all_node() +{ + _pnode->remove_all_nodes(); + return *this; +} + +Node& Node::push_front(const Attribute& attr) +{ + _pnode->prepend_attribute(attr._get()); + return *this; +} + +Node& Node::push_back(const Attribute& attr) +{ + _pnode->append_attribute(attr._get()); + return *this; +} + +Node& Node::insert(const Attribute& where, const Attribute& val) +{ + _pnode->insert_attribute(where._get(),val._get()); + return *this; +} + +Node& Node::remove_first_attr() +{ + _pnode->remove_first_attribute(); + return *this; +} + +Node& Node::remove_last_attr() +{ + _pnode->remove_last_attribute(); + return *this; +} + +Node& Node::remove_attr(const Attribute& todelete) +{ + _pnode->remove_attribute(todelete._get()); + return *this; +} + +Node& Node::remove_all_attr() +{ + _pnode->remove_all_attributes(); + return *this; +} + +bool Node::operator==(const Node& node) +{ + return _pnode==node._pnode && _pdoc==node._pdoc; +} + +bool Node::hasPrevNode() const +{ + return _pnode->previous_sibling()!=nullptr; +} + +bool Node::hasNextNode() const +{ + return _pnode->next_sibling()!=nullptr; +} + +bool Node::hasParentNode() const +{ + return _pnode->parent()!=nullptr; +} + +Node Node::getPrevNode() const +{ + return Node(_pnode->previous_sibling()); +} + +Node Node::getNextNode() const +{ + return Node(_pnode->next_sibling()); +} + +Node Node::getPrevNode(const std::string& name) const +{ + return Node(_pnode->previous_sibling(name.c_str())); +} + +Node Node::getNextNode(const std::string& name) const +{ + return Node(_pnode->next_sibling(name.c_str())); +} + +Node Node::getParentNode() const +{ + return Node(_pnode->parent()); +} + +bool Node::valid() +{ + return _pnode!=nullptr && _pdoc!=nullptr; +} + + +Node Node::getChild() const +{ + return _pnode->first_node(); +} + +Node Node::getChild(const std::string& nodename) const +{ + return _pnode->first_node(nodename.c_str()); +} + + +Document::Document() +{ + _is_ready=false; +} + +Document::Document(const std::string& filename) +{ + if(loadFrom(filename,false)!=0) + { + _is_ready=false; + } + else + { + _is_ready=true; + } +} + +int Document::loadFrom(const std::string& filename, bool clearCurrent) +{ + std::ifstream ifs(filename); + if(!ifs) + { + /// File Read Error. + return -1; + } + rapidxml::file<> infilereader(ifs); + if(clearCurrent) + { + _doc.clear(); + } + _doc.parse<0>(infilereader.data()); + return 0; +} + +int Document::saveTo(const std::string& filename) +{ + std::string ans; + rapidxml::print(std::back_inserter(ans),_doc,0); + + std::ofstream ofs(filename); + + if(!ofs) return -1; + + ofs< + +namespace MiniEngine +{ + +namespace XML +{ + +typedef rapidxml::xml_node<> XNode; +typedef rapidxml::xml_attribute<> XAttr; +typedef rapidxml::xml_document<> XDoc; + +/// Fwd Decl +class Document; + +class Attribute +{ +public: + void _set(XAttr*); + XAttr* _get() const; + void _clear(); + void _setdoc(Document*); + + Attribute(); + Attribute(XAttr*); + + std::string getName() const; + std::string getValue() const; + + char* getNameRaw() const; + char* getValueRaw() const; + + bool hasPrevAttr() const; + bool hasNextAttr() const; + Attribute getPrevAttr() const; + Attribute getNextAttr() const; + Attribute getPrevAttr(const std::string& name) const; + Attribute getNextAttr(const std::string& name) const; + +private: + XAttr* _pattr; + Document* _pdoc; +}; + +class Node +{ +public: + void _set(XNode*); + XNode* _get() const; + void _clear(); + void _setdoc(Document*); + + Node(); + Node(XNode*); + + std::string getName() const; + std::string getValue() const; + + char* getNameRaw() const; + char* getValueRaw() const; + + Node& push_front(const Node&); + Node& push_back(const Node&); + Node& insert(const Node& where,const Node& val); + + Node& remove_first_node(); + Node& remove_last_node(); + Node& remove_node(const Node& todelete); + Node& remove_all_node(); + + Node& push_front(const Attribute&); + Node& push_back(const Attribute&); + Node& insert(const Attribute& where,const Attribute& val); + + Node& remove_first_attr(); + Node& remove_last_attr(); + Node& remove_attr(const Attribute& todelete); + Node& remove_all_attr(); + + bool operator == (const Node& node); + + bool hasPrevNode() const; + bool hasNextNode() const; + bool hasParentNode() const; + Node getPrevNode() const; + Node getNextNode() const; + Node getParentNode() const; + Node getPrevNode(const std::string& name) const; + Node getNextNode(const std::string& name) const; + + Node getChild() const; + Node getChild(const std::string& nodename) const; + + bool valid(); + +private: + XNode* _pnode; + Document* _pdoc; +}; + +class Document +{ +public: + Document(); + Document(const std::string& filename); + int loadFrom(const std::string& filename,bool clearCurrent=true); + int saveTo(const std::string& filename); + bool ready(); + Node newNode(const std::string& name,const std::string& value); + Attribute newAttr(const std::string& name,const std::string& value); + Node cloneNode(const Node&); + void clear(); + +protected: + char* _allocate_string(const std::string& str); + char* _allocate_string(const char* pstr,int sz); +private: + XDoc _doc; + bool _is_ready; +}; + + + +}/// End of namespace MiniEngine::XML + +}/// End of namespace MiniEngine + diff --git a/rapidxml/rapidxml_print.hpp b/rapidxml/rapidxml_print.hpp index d03d5f5..718db5f 100644 --- a/rapidxml/rapidxml_print.hpp +++ b/rapidxml/rapidxml_print.hpp @@ -28,10 +28,10 @@ namespace rapidxml //! \cond internal namespace internal { - + /////////////////////////////////////////////////////////////////////////// // Internal character operations - + // Copy characters from given range to given output iterator template inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out) @@ -40,7 +40,7 @@ namespace rapidxml *out++ = *begin++; return out; } - + // Copy characters from given range to given output iterator and expand // characters into references (< > ' " &) template @@ -59,17 +59,17 @@ namespace rapidxml case Ch('<'): *out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';'); break; - case Ch('>'): + case Ch('>'): *out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';'); break; - case Ch('\''): + case Ch('\''): *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';'); break; - case Ch('"'): + case Ch('"'): *out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';'); break; - case Ch('&'): - *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';'); + case Ch('&'): + *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';'); break; default: *out++ = *begin; // No expansion, copy character @@ -101,7 +101,41 @@ namespace rapidxml /////////////////////////////////////////////////////////////////////////// // Internal printing operations - + + /// Forward Declaration : Fix Compile Bug in MinGW + template + inline OutIt print_node(OutIt out, const xml_node *node, int flags, int indent); + + template + inline OutIt print_children(OutIt out, const xml_node *node, int flags, int indent); + + template + inline OutIt print_attributes(OutIt out, const xml_node *node, int flags); + + template + inline OutIt print_data_node(OutIt out, const xml_node *node, int flags, int indent); + + template + inline OutIt print_cdata_node(OutIt out, const xml_node *node, int flags, int indent); + + template + inline OutIt print_element_node(OutIt out, const xml_node *node, int flags, int indent); + + template + inline OutIt print_declaration_node(OutIt out, const xml_node *node, int flags, int indent); + + template + inline OutIt print_comment_node(OutIt out, const xml_node *node, int flags, int indent); + + template + inline OutIt print_doctype_node(OutIt out, const xml_node *node, int flags, int indent); + + template + inline OutIt print_pi_node(OutIt out, const xml_node *node, int flags, int indent); + + + + // Print node template inline OutIt print_node(OutIt out, const xml_node *node, int flags, int indent) @@ -119,12 +153,12 @@ namespace rapidxml case node_element: out = print_element_node(out, node, flags, indent); break; - + // Data case node_data: out = print_data_node(out, node, flags, indent); break; - + // CDATA case node_cdata: out = print_cdata_node(out, node, flags, indent); @@ -139,7 +173,7 @@ namespace rapidxml case node_comment: out = print_comment_node(out, node, flags, indent); break; - + // Doctype case node_doctype: out = print_doctype_node(out, node, flags, indent); @@ -155,7 +189,7 @@ namespace rapidxml assert(0); break; } - + // If indenting not disabled, add line break after node if (!(flags & print_no_indenting)) *out = Ch('\n'), ++out; @@ -163,8 +197,8 @@ namespace rapidxml // Return modified iterator return out; } - - // Print children of the node + + // Print children of the node template inline OutIt print_children(OutIt out, const xml_node *node, int flags, int indent) { @@ -249,7 +283,7 @@ namespace rapidxml *out = Ch('<'), ++out; out = copy_chars(node->name(), node->name() + node->name_size(), out); out = print_attributes(out, node, flags); - + // If node is childless if (node->value_size() == 0 && !node->first_node()) { @@ -308,11 +342,11 @@ namespace rapidxml // Print attributes out = print_attributes(out, node, flags); - + // Print declaration end *out = Ch('?'), ++out; *out = Ch('>'), ++out; - + return out; } @@ -384,7 +418,7 @@ namespace rapidxml //! \param node Node to be printed. Pass xml_document to print entire document. //! \param flags Flags controlling how XML is printed. //! \return Output iterator pointing to position immediately after last character of printed text. - template + template inline OutIt print(OutIt out, const xml_node &node, int flags = 0) { return internal::print_node(out, &node, flags, 0); @@ -397,7 +431,7 @@ namespace rapidxml //! \param node Node to be printed. Pass xml_document to print entire document. //! \param flags Flags controlling how XML is printed. //! \return Output stream. - template + template inline std::basic_ostream &print(std::basic_ostream &out, const xml_node &node, int flags = 0) { print(std::ostream_iterator(out), node, flags); @@ -408,7 +442,7 @@ namespace rapidxml //! \param out Output stream to print to. //! \param node Node to be printed. //! \return Output stream. - template + template inline std::basic_ostream &operator <<(std::basic_ostream &out, const xml_node &node) { return print(out, node);