Merge branch 'mingw-dev-xml-parser' into mingw-dev

Provide XML Parsing
This commit is contained in:
Kirigaya Kazuto 2017-05-21 10:20:08 +08:00
commit 6c4f1c345d
3 changed files with 566 additions and 21 deletions

382
MiniEngine_Xml.cpp Normal file
View File

@ -0,0 +1,382 @@
#include "MiniEngine_Xml.h"
#include "rapidxml/rapidxml_print.hpp"
#include "rapidxml/rapidxml_utils.hpp"
#include <fstream>
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<<ans;
return 0;
}
bool Document::ready()
{
return _is_ready;
}
Node Document::newNode(const std::string& name,const std::string& value)
{
Node node;
node._set(_doc.allocate_node(rapidxml::node_type::node_element,
_allocate_string(name),_allocate_string(value)));
node._setdoc(this);
return node;
}
Attribute Document::newAttr(const std::string& name,const std::string& value)
{
Attribute attr;
attr._set(_doc.allocate_attribute(_allocate_string(name),_allocate_string(value)));
attr._setdoc(this);
return attr;
}
Node Document::cloneNode(const Node& node)
{
return Node(_doc.clone_node(node._get()));
}
void Document::clear()
{
return _doc.clear();
}
//protected
char* Document::_allocate_string(const std::string& str)
{
return _doc.allocate_string(str.c_str(),str.size());
}
//protected
char* Document::_allocate_string(const char* source,int sz)
{
return _doc.allocate_string(source,sz);
}
}/// End of namespace MiniEngine::XML
}/// End of namespace MiniEngine

129
MiniEngine_Xml.h Normal file
View File

@ -0,0 +1,129 @@
#pragma once
#include "rapidxml/rapidxml.hpp"
#include <string>
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

View File

@ -102,6 +102,40 @@ namespace rapidxml
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Internal printing operations // Internal printing operations
/// Forward Declaration : Fix Compile Bug in MinGW
template<class OutIt, class Ch>
inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags);
template<class OutIt, class Ch>
inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
template<class OutIt, class Ch>
inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
// Print node // Print node
template<class OutIt, class Ch> template<class OutIt, class Ch>
inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent) inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)