Start working on build system.
This commit is contained in:
parent
4b308f6c32
commit
521486be62
88 changed files with 1065 additions and 349 deletions
43
src/base/core/serialization/xml/XmlDocument.cpp
Normal file
43
src/base/core/serialization/xml/XmlDocument.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "XmlDocument.h"
|
||||
|
||||
#include "XmlProlog.h"
|
||||
#include "XmlElement.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
XmlDocument::XmlDocument()
|
||||
:mProlog(XmlProlog::Create("xml"))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
XmlDocument::~XmlDocument()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
XmlDocumentPtr XmlDocument::Create()
|
||||
{
|
||||
return std::make_unique<XmlDocument>();
|
||||
}
|
||||
|
||||
void XmlDocument::setProlog(XmlPrologPtr prolog)
|
||||
{
|
||||
mProlog = std::move(prolog);
|
||||
}
|
||||
|
||||
XmlProlog* XmlDocument::getProlog() const
|
||||
{
|
||||
return mProlog.get();
|
||||
}
|
||||
|
||||
void XmlDocument::setRoot(XmlElementPtr root)
|
||||
{
|
||||
mRoot = std::move(root);
|
||||
}
|
||||
|
||||
XmlElement* XmlDocument::getRoot() const
|
||||
{
|
||||
return mRoot.get();
|
||||
}
|
||||
|
31
src/base/core/serialization/xml/XmlDocument.h
Normal file
31
src/base/core/serialization/xml/XmlDocument.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "XmlElement.h"
|
||||
#include "XmlProlog.h"
|
||||
|
||||
class XmlElement;
|
||||
class XmlProlog;
|
||||
using XmlPrologPtr = std::unique_ptr<XmlProlog>;
|
||||
using XmlElementPtr = std::unique_ptr<XmlElement>;
|
||||
|
||||
class XmlDocument
|
||||
{
|
||||
public:
|
||||
XmlDocument();
|
||||
virtual ~XmlDocument();
|
||||
|
||||
static std::unique_ptr<XmlDocument> Create();
|
||||
|
||||
XmlProlog* getProlog() const;
|
||||
XmlElement* getRoot() const;
|
||||
|
||||
void setProlog(XmlPrologPtr prolog);
|
||||
void setRoot(XmlElementPtr root);
|
||||
private:
|
||||
XmlPrologPtr mProlog;
|
||||
XmlElementPtr mRoot;
|
||||
};
|
||||
|
||||
using XmlDocumentPtr = std::unique_ptr<XmlDocument>;
|
409
src/base/core/serialization/xml/XmlParser.cpp
Normal file
409
src/base/core/serialization/xml/XmlParser.cpp
Normal file
|
@ -0,0 +1,409 @@
|
|||
#include "XmlParser.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
#include "XmlDocument.h"
|
||||
#include "XmlElement.h"
|
||||
#include "XmlAttribute.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using LS = XmlParser::LineState;
|
||||
using DS = XmlParser::DocumentState;
|
||||
|
||||
XmlParser::XmlParser()
|
||||
: mDocumentState(XmlParser::DocumentState::Await_Prolog),
|
||||
mLineState(XmlParser::LineState::Await_Tag_Open),
|
||||
mDocument(XmlDocument::Create()),
|
||||
mWorkingElements()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void XmlParser::processLine(const std::string& input)
|
||||
{
|
||||
for (std::size_t idx=0; idx<input.size(); idx++)
|
||||
{
|
||||
switch (input[idx])
|
||||
{
|
||||
case StringUtils::LEFT_BRACKET:
|
||||
onLeftBracket();
|
||||
break;
|
||||
case StringUtils::RIGHT_BRACKET:
|
||||
onRightBracket();
|
||||
break;
|
||||
case StringUtils::QUESTION_MARK:
|
||||
onQuestionMark();
|
||||
break;
|
||||
case StringUtils::FORWARD_SLASH:
|
||||
onForwardSlash();
|
||||
break;
|
||||
case StringUtils::EQUALS:
|
||||
onEquals();
|
||||
break;
|
||||
case StringUtils::DOUBLE_QUOTE:
|
||||
onDoubleQuote();
|
||||
break;
|
||||
default:
|
||||
onChar(input[idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onChar(char c)
|
||||
{
|
||||
if(StringUtils::isAlphaNumeric(c))
|
||||
{
|
||||
onAlphaNumeric(c);
|
||||
}
|
||||
else if(StringUtils::isSpace(c))
|
||||
{
|
||||
onSpace(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
onNonAlphaNumeric(c);
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onAlphaNumeric(char c)
|
||||
{
|
||||
switch(mLineState)
|
||||
{
|
||||
case LS::Await_Tag_Open:
|
||||
onTextStart(c);
|
||||
break;
|
||||
case LS::Await_Tag_Follower:
|
||||
case LS::Await_Tag_Name:
|
||||
{
|
||||
onTagNameStart(c);
|
||||
break;
|
||||
}
|
||||
case LS::Await_Tag_Name_End:
|
||||
{
|
||||
mWorkingTagName.push_back(c);
|
||||
break;
|
||||
}
|
||||
case LS::Await_Attribute_Name:
|
||||
{
|
||||
onAttributeNameStart(c);
|
||||
break;
|
||||
}
|
||||
case LS::Await_Attribute_Name_End:
|
||||
{
|
||||
mWorkingAttributeName.push_back(c);
|
||||
break;
|
||||
}
|
||||
case LS::Await_Attribute_Value:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case LS::Await_Attribute_Value_End:
|
||||
{
|
||||
mWorkingAttributeValue.push_back(c);
|
||||
break;
|
||||
}
|
||||
case LS::Await_Text_End:
|
||||
{
|
||||
mWorkingText.push_back(c);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onNonAlphaNumeric(char c)
|
||||
{
|
||||
switch(mLineState)
|
||||
{
|
||||
case LS::Await_Tag_Name_End:
|
||||
{
|
||||
mWorkingTagName.push_back(c);
|
||||
break;
|
||||
}
|
||||
case LS::Await_Attribute_Name_End:
|
||||
{
|
||||
mWorkingAttributeName.push_back(c);
|
||||
break;
|
||||
}
|
||||
case LS::Await_Attribute_Value_End:
|
||||
{
|
||||
mWorkingAttributeValue.push_back(c);
|
||||
break;
|
||||
}
|
||||
case LS::Await_Text_End:
|
||||
{
|
||||
mWorkingText.push_back(c);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onSpace(char c)
|
||||
{
|
||||
switch(mLineState)
|
||||
{
|
||||
case LS::Await_Tag_Name_End:
|
||||
onTagNameEnd();
|
||||
break;
|
||||
case LS::Await_Attribute_Name_End:
|
||||
onAttributeNameEnd();
|
||||
break;
|
||||
case LS::Await_Text_End:
|
||||
mWorkingText.push_back(c);
|
||||
break;
|
||||
case LS::Await_Attribute_Value_End:
|
||||
mWorkingAttributeValue.push_back(c);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onLeftBracket()
|
||||
{
|
||||
switch(mLineState)
|
||||
{
|
||||
case LS::Await_Tag_Open:
|
||||
{
|
||||
onTagOpen();
|
||||
break;
|
||||
}
|
||||
case LS::Await_Text_End:
|
||||
{
|
||||
onTextEnd();
|
||||
onTagOpen();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
onNonAlphaNumeric(StringUtils::LEFT_BRACKET);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onRightBracket()
|
||||
{
|
||||
switch(mLineState)
|
||||
{
|
||||
case LS::Await_Tag_Name_End:
|
||||
case LS::Await_Attribute_Name:
|
||||
case LS::Await_Attribute_Name_End:
|
||||
case LS::Await_Attribute_Value:
|
||||
case LS::Await_Tag_Inline_Close:
|
||||
{
|
||||
onTagClose();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
onNonAlphaNumeric(StringUtils::RIGHT_BRACKET);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onQuestionMark()
|
||||
{
|
||||
if(mLineState == LS::Await_Tag_Follower)
|
||||
{
|
||||
if(mDocumentState == DS::Await_Prolog)
|
||||
{
|
||||
onStartProlog();
|
||||
}
|
||||
}
|
||||
else if(mDocumentState != DS::Build_Prolog)
|
||||
{
|
||||
onNonAlphaNumeric(StringUtils::QUESTION_MARK);
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onForwardSlash()
|
||||
{
|
||||
if (mLineState == LS::Await_Tag_Follower)
|
||||
{
|
||||
if (mDocumentState == DS::Await_Element || mDocumentState == DS::Build_Element)
|
||||
{
|
||||
mDocumentState = DS::Close_Element;
|
||||
}
|
||||
}
|
||||
else if(mLineState == LS::Await_Attribute_Name)
|
||||
{
|
||||
mLineState = LS::Await_Tag_Inline_Close;
|
||||
}
|
||||
else
|
||||
{
|
||||
onNonAlphaNumeric(StringUtils::FORWARD_SLASH);
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onEquals()
|
||||
{
|
||||
if(mLineState == LS::Await_Attribute_Name_End)
|
||||
{
|
||||
onAttributeNameEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
onNonAlphaNumeric(StringUtils::EQUALS);
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onDoubleQuote()
|
||||
{
|
||||
if(mLineState == LS::Await_Attribute_Value)
|
||||
{
|
||||
onAttributeValueStart();
|
||||
}
|
||||
else if(mLineState == LS::Await_Attribute_Value_End)
|
||||
{
|
||||
onAttributeValueEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onTagOpen()
|
||||
{
|
||||
mLineState = LS::Await_Tag_Follower;
|
||||
}
|
||||
|
||||
void XmlParser::onTagClose()
|
||||
{
|
||||
if(mDocumentState == DS::Build_Prolog)
|
||||
{
|
||||
onFinishProlog();
|
||||
}
|
||||
else if(mDocumentState == DS::Build_Element)
|
||||
{
|
||||
if(mLineState == LS::Await_Tag_Name_End)
|
||||
{
|
||||
onTagNameEnd();
|
||||
}
|
||||
else if (mLineState == LS::Await_Tag_Inline_Close)
|
||||
{
|
||||
if (!mWorkingElements.empty())
|
||||
{
|
||||
mWorkingElements.pop();
|
||||
}
|
||||
}
|
||||
onElementTagEnd();
|
||||
}
|
||||
else if(mDocumentState == DS::Close_Element)
|
||||
{
|
||||
mDocumentState = DS::Await_Element;
|
||||
mLineState = LS::Await_Tag_Open;
|
||||
if (!mWorkingElements.empty())
|
||||
{
|
||||
mWorkingElements.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onTextStart(char c)
|
||||
{
|
||||
mWorkingText = c;
|
||||
mLineState = LS::Await_Text_End;
|
||||
}
|
||||
|
||||
void XmlParser::onTextEnd()
|
||||
{
|
||||
mWorkingElements.top()->setText(mWorkingText);
|
||||
}
|
||||
|
||||
void XmlParser::onElementTagEnd()
|
||||
{
|
||||
mDocumentState = DS::Await_Element;
|
||||
mLineState = LS::Await_Tag_Open;
|
||||
}
|
||||
|
||||
void XmlParser::onTagNameStart(char c)
|
||||
{
|
||||
mWorkingTagName = c;
|
||||
mLineState = LS::Await_Tag_Name_End;
|
||||
if(mDocumentState != DS::Build_Prolog && mDocumentState != DS::Close_Element)
|
||||
{
|
||||
mDocumentState = DS::Build_Element;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onTagNameEnd()
|
||||
{
|
||||
if(mDocumentState == DS::Build_Prolog)
|
||||
{
|
||||
mDocument->getProlog()->setTagName(mWorkingTagName);
|
||||
mLineState = LS::Await_Attribute_Name;
|
||||
}
|
||||
else if(mDocumentState == DS::Build_Element)
|
||||
{
|
||||
auto new_element = XmlElement::Create(mWorkingTagName);
|
||||
auto working_element = new_element.get();
|
||||
|
||||
if (!mDocument->getRoot())
|
||||
{
|
||||
mDocument->setRoot(std::move(new_element));
|
||||
}
|
||||
else
|
||||
{
|
||||
mWorkingElements.top()->addChild(std::move(new_element));
|
||||
}
|
||||
mWorkingElements.push(working_element);
|
||||
mLineState = LS::Await_Attribute_Name;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::onAttributeNameStart(char c)
|
||||
{
|
||||
mWorkingAttributeName = c;
|
||||
mLineState = LS::Await_Attribute_Name_End;
|
||||
}
|
||||
|
||||
void XmlParser::onAttributeNameEnd()
|
||||
{
|
||||
auto attribute = XmlAttribute::Create(mWorkingAttributeName);
|
||||
if(mDocumentState == DS::Build_Prolog)
|
||||
{
|
||||
mDocument->getProlog()->addAttribute(std::move(attribute));
|
||||
}
|
||||
else if(mDocumentState == DS::Build_Element)
|
||||
{
|
||||
mWorkingElements.top()->addAttribute(std::move(attribute));
|
||||
}
|
||||
mLineState = LS::Await_Attribute_Value;
|
||||
}
|
||||
|
||||
void XmlParser::onAttributeValueStart()
|
||||
{
|
||||
mWorkingAttributeValue = "";
|
||||
mLineState = LS::Await_Attribute_Value_End;
|
||||
}
|
||||
|
||||
void XmlParser::onAttributeValueEnd()
|
||||
{
|
||||
if(mDocumentState == DS::Build_Prolog)
|
||||
{
|
||||
mDocument->getProlog()->getAttribute(mWorkingAttributeName)->setValue(mWorkingAttributeValue);
|
||||
}
|
||||
else if(mDocumentState == DS::Build_Element)
|
||||
{
|
||||
mWorkingElements.top()->getAttribute(mWorkingAttributeName)->setValue(mWorkingAttributeValue);
|
||||
}
|
||||
mLineState = LS::Await_Attribute_Name;
|
||||
}
|
||||
|
||||
void XmlParser::onStartProlog()
|
||||
{
|
||||
mDocumentState = DS::Build_Prolog;
|
||||
mLineState = LS::Await_Tag_Name_End;
|
||||
}
|
||||
|
||||
void XmlParser::onFinishProlog()
|
||||
{
|
||||
mDocument->getProlog()->update();
|
||||
mDocumentState = DS::Await_Element;
|
||||
mLineState = LS::Await_Tag_Open;
|
||||
}
|
||||
|
||||
XmlDocumentPtr XmlParser::getDocument()
|
||||
{
|
||||
return std::move(mDocument);
|
||||
}
|
102
src/base/core/serialization/xml/XmlParser.h
Normal file
102
src/base/core/serialization/xml/XmlParser.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <stack>
|
||||
#include <memory>
|
||||
|
||||
class XmlDocument;
|
||||
using XmlDocumentPtr = std::unique_ptr<XmlDocument>;
|
||||
|
||||
class XmlElement;
|
||||
|
||||
class XmlParser
|
||||
{
|
||||
public:
|
||||
enum class DocumentState
|
||||
{
|
||||
Await_Prolog,
|
||||
Build_Prolog,
|
||||
Await_Element,
|
||||
Build_Element,
|
||||
Close_Element
|
||||
};
|
||||
|
||||
enum class LineState
|
||||
{
|
||||
Await_Tag_Open,
|
||||
Await_Tag_Follower,
|
||||
Await_Tag_Name,
|
||||
Await_Tag_Name_End,
|
||||
Await_Tag_Inline_Close,
|
||||
Await_Attribute_Name,
|
||||
Await_Attribute_Name_End,
|
||||
Await_Attribute_Value,
|
||||
Await_Attribute_Value_End,
|
||||
Await_Text_End
|
||||
};
|
||||
|
||||
public:
|
||||
XmlParser();
|
||||
|
||||
void processLine(const std::string& input);
|
||||
|
||||
XmlDocumentPtr getDocument();
|
||||
|
||||
private:
|
||||
void onLeftBracket();
|
||||
|
||||
void onRightBracket();
|
||||
|
||||
void onQuestionMark();
|
||||
|
||||
void onForwardSlash();
|
||||
|
||||
void onChar(char c);
|
||||
|
||||
void onSpace(char c);
|
||||
|
||||
void onAlphaNumeric(char c);
|
||||
|
||||
void onNonAlphaNumeric(char c);
|
||||
|
||||
void onEquals();
|
||||
|
||||
void onDoubleQuote();
|
||||
|
||||
void onTagOpen();
|
||||
|
||||
void onTagNameStart(char c);
|
||||
|
||||
void onTagNameEnd();
|
||||
|
||||
void onTagClose();
|
||||
|
||||
void onTextStart(char c);
|
||||
|
||||
void onTextEnd();
|
||||
|
||||
void onAttributeNameStart(char c);
|
||||
|
||||
void onAttributeNameEnd();
|
||||
|
||||
void onAttributeValueStart();
|
||||
|
||||
void onAttributeValueEnd();
|
||||
|
||||
void onStartProlog();
|
||||
|
||||
void onFinishProlog();
|
||||
|
||||
void onElementTagEnd();
|
||||
|
||||
private:
|
||||
DocumentState mDocumentState;
|
||||
LineState mLineState;
|
||||
XmlDocumentPtr mDocument;
|
||||
std::stack<XmlElement*> mWorkingElements;
|
||||
|
||||
std::string mWorkingAttributeName;
|
||||
std::string mWorkingTagName;
|
||||
std::string mWorkingAttributeValue;
|
||||
std::string mWorkingText;
|
||||
};
|
24
src/base/core/serialization/xml/XmlWriter.cpp
Normal file
24
src/base/core/serialization/xml/XmlWriter.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "XmlWriter.h"
|
||||
|
||||
#include "XmlDocument.h"
|
||||
#include "XmlAttribute.h"
|
||||
|
||||
std::string XmlWriter::toString(XmlDocument* document)
|
||||
{
|
||||
std::string content;
|
||||
if (auto prolog = document->getProlog())
|
||||
{
|
||||
content += "<?xml";
|
||||
for (const auto& [key, attribute] : prolog->getAttributes())
|
||||
{
|
||||
content += " " + attribute->getName() + "=\"" + attribute->getValue() + "\"";
|
||||
}
|
||||
content += "?>\n";
|
||||
}
|
||||
|
||||
if (auto root = document->getRoot())
|
||||
{
|
||||
content += root->toString();
|
||||
}
|
||||
return content;
|
||||
}
|
14
src/base/core/serialization/xml/XmlWriter.h
Normal file
14
src/base/core/serialization/xml/XmlWriter.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class XmlDocument;
|
||||
class XmlElement;
|
||||
|
||||
class XmlWriter
|
||||
{
|
||||
public:
|
||||
XmlWriter() = default;
|
||||
|
||||
std::string toString(XmlDocument* document);
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
#include "XmlAttribute.h"
|
||||
|
||||
XmlAttribute::XmlAttribute(const std::string& name)
|
||||
: mName(name),
|
||||
mValue()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
XmlAttributePtr XmlAttribute::Create(const std::string& name)
|
||||
{
|
||||
return std::make_unique<XmlAttribute>(name);
|
||||
}
|
||||
|
||||
const std::string& XmlAttribute::getName() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
const std::string& XmlAttribute::getValue() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
void XmlAttribute::setValue(const std::string& value)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
23
src/base/core/serialization/xml/xml-elements/XmlAttribute.h
Normal file
23
src/base/core/serialization/xml/xml-elements/XmlAttribute.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class XmlAttribute
|
||||
{
|
||||
public:
|
||||
XmlAttribute(const std::string& name);
|
||||
|
||||
static std::unique_ptr<XmlAttribute> Create(const std::string& name);
|
||||
|
||||
const std::string& getName() const;
|
||||
|
||||
const std::string& getValue() const;
|
||||
|
||||
void setValue(const std::string& value);
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mValue;
|
||||
};
|
||||
|
||||
using XmlAttributePtr = std::unique_ptr<XmlAttribute>;
|
140
src/base/core/serialization/xml/xml-elements/XmlElement.cpp
Normal file
140
src/base/core/serialization/xml/xml-elements/XmlElement.cpp
Normal file
|
@ -0,0 +1,140 @@
|
|||
#include "XmlElement.h"
|
||||
|
||||
#include "XmlAttribute.h"
|
||||
|
||||
XmlElement::XmlElement(const std::string& tagName)
|
||||
: mTagName(tagName),
|
||||
mChildren()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
XmlElement::~XmlElement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
XmlElementPtr XmlElement::Create(const std::string& tagName)
|
||||
{
|
||||
return std::make_unique<XmlElement>(tagName);
|
||||
}
|
||||
|
||||
void XmlElement::setTagName(const std::string& tagName)
|
||||
{
|
||||
mTagName = tagName;
|
||||
}
|
||||
|
||||
void XmlElement::addChild(XmlElementPtr child)
|
||||
{
|
||||
mChildren.push_back(std::move(child));
|
||||
}
|
||||
|
||||
void XmlElement::addAttribute(XmlAttributePtr attribute)
|
||||
{
|
||||
mAttributes[attribute->getName()] = std::move(attribute);
|
||||
}
|
||||
|
||||
void XmlElement::addAttribute(const std::string& name, const std::string& value)
|
||||
{
|
||||
auto attr = std::make_unique<XmlAttribute>(name);
|
||||
attr->setValue(value);
|
||||
addAttribute(std::move(attr));
|
||||
}
|
||||
|
||||
const std::string& XmlElement::getTagName() const
|
||||
{
|
||||
return mTagName;
|
||||
}
|
||||
|
||||
const std::string& XmlElement::getText() const
|
||||
{
|
||||
return mText;
|
||||
}
|
||||
|
||||
void XmlElement::setText(const std::string& text)
|
||||
{
|
||||
mText = text;
|
||||
}
|
||||
|
||||
XmlElement* XmlElement::getFirstChildWithTagName(const std::string& tag)
|
||||
{
|
||||
for(auto& child : mChildren)
|
||||
{
|
||||
if (child->getTagName() == tag)
|
||||
{
|
||||
return child.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool XmlElement::hasAttribute(const std::string& attribute) const
|
||||
{
|
||||
return (bool)(getAttribute(attribute));
|
||||
}
|
||||
|
||||
XmlAttribute* XmlElement::getAttribute(const std::string& attributeName) const
|
||||
{
|
||||
if (auto iter = mAttributes.find(attributeName); iter != mAttributes.end())
|
||||
{
|
||||
return iter->second.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, XmlAttributePtr>& XmlElement::getAttributes() const
|
||||
{
|
||||
return mAttributes;
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<XmlElement> >& XmlElement::getChildren() const
|
||||
{
|
||||
return mChildren;
|
||||
}
|
||||
|
||||
std::string XmlElement::toString(unsigned depth, bool keepInline) const
|
||||
{
|
||||
const auto prefix = std::string(2*depth, ' ');
|
||||
|
||||
std::string line_ending = keepInline ? "" : "\n";
|
||||
|
||||
auto content = prefix + "<" + getTagName();
|
||||
for (const auto& [key, attribute] : getAttributes())
|
||||
{
|
||||
content += " " + attribute->getName() + "=\"" + attribute->getValue() + "\"";
|
||||
}
|
||||
|
||||
const auto num_children = mChildren.size();
|
||||
if (num_children == 0 && getText().empty())
|
||||
{
|
||||
content += "/>" + line_ending;
|
||||
return content;
|
||||
}
|
||||
else
|
||||
{
|
||||
content += ">";
|
||||
}
|
||||
|
||||
if (!getText().empty())
|
||||
{
|
||||
content += getText();
|
||||
}
|
||||
|
||||
if (num_children>0)
|
||||
{
|
||||
content += line_ending;
|
||||
}
|
||||
|
||||
for(const auto& child : mChildren)
|
||||
{
|
||||
content += child->toString(depth+1, keepInline);
|
||||
}
|
||||
if (num_children>0)
|
||||
{
|
||||
content += prefix;
|
||||
}
|
||||
|
||||
content += "</" + getTagName() + ">" + line_ending;
|
||||
return content;
|
||||
}
|
47
src/base/core/serialization/xml/xml-elements/XmlElement.h
Normal file
47
src/base/core/serialization/xml/xml-elements/XmlElement.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class XmlAttribute;
|
||||
using XmlAttributePtr = std::unique_ptr<XmlAttribute>;
|
||||
|
||||
class XmlElement
|
||||
{
|
||||
public:
|
||||
XmlElement(const std::string& tagName);
|
||||
virtual ~XmlElement();
|
||||
|
||||
static std::unique_ptr<XmlElement> Create(const std::string& tagName);
|
||||
|
||||
void addAttribute(XmlAttributePtr attribute);
|
||||
void addAttribute(const std::string& name, const std::string& value);
|
||||
void addChild(std::unique_ptr<XmlElement> child);
|
||||
|
||||
const std::string& getTagName() const;
|
||||
const std::string& getText() const;
|
||||
|
||||
bool hasAttribute(const std::string& attribute) const;
|
||||
XmlAttribute* getAttribute(const std::string& attribute) const;
|
||||
const std::unordered_map<std::string, XmlAttributePtr>& getAttributes() const;
|
||||
|
||||
const std::vector<std::unique_ptr<XmlElement> >& getChildren() const;
|
||||
|
||||
XmlElement* getFirstChildWithTagName(const std::string& tag);
|
||||
|
||||
void setText(const std::string& text);
|
||||
void setTagName(const std::string& tagName);
|
||||
|
||||
virtual std::string toString(unsigned depth = 0, bool keepInline = false) const;
|
||||
|
||||
protected:
|
||||
std::string mTagName;
|
||||
std::string mText;
|
||||
|
||||
std::unordered_map<std::string, XmlAttributePtr> mAttributes;
|
||||
std::vector<std::unique_ptr<XmlElement> > mChildren;
|
||||
};
|
||||
|
||||
using XmlElementPtr = std::unique_ptr<XmlElement>;
|
55
src/base/core/serialization/xml/xml-elements/XmlProlog.cpp
Normal file
55
src/base/core/serialization/xml/xml-elements/XmlProlog.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include "XmlProlog.h"
|
||||
|
||||
#include "XmlAttribute.h"
|
||||
|
||||
XmlProlog::XmlProlog(const std::string& tagName)
|
||||
: XmlElement(tagName),
|
||||
mVersion(XmlProlog::Version::V1_0),
|
||||
mEncoding(XmlProlog::Encoding::UTF8)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
XmlPrologPtr XmlProlog::Create(const std::string& tagName)
|
||||
{
|
||||
return std::make_unique<XmlProlog>(tagName);
|
||||
}
|
||||
|
||||
XmlProlog::Encoding XmlProlog::getEncoding() const
|
||||
{
|
||||
return mEncoding;
|
||||
}
|
||||
|
||||
XmlProlog::Version XmlProlog::getVersion() const
|
||||
{
|
||||
return mVersion;
|
||||
}
|
||||
|
||||
void XmlProlog::setEncoding(const std::string& encoding)
|
||||
{
|
||||
if(encoding == "UTF-8")
|
||||
{
|
||||
mEncoding = XmlProlog::Encoding::UTF8;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlProlog::setVersion(const std::string& version)
|
||||
{
|
||||
if(version == "1.0")
|
||||
{
|
||||
mVersion = XmlProlog::Version::V1_0;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlProlog::update()
|
||||
{
|
||||
if(const auto version = getAttribute("version"))
|
||||
{
|
||||
setVersion(version->getValue());
|
||||
}
|
||||
|
||||
if(const auto encoding = getAttribute("encoding"))
|
||||
{
|
||||
setEncoding(encoding->getValue());
|
||||
}
|
||||
}
|
36
src/base/core/serialization/xml/xml-elements/XmlProlog.h
Normal file
36
src/base/core/serialization/xml/xml-elements/XmlProlog.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include "XmlElement.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class XmlProlog : public XmlElement
|
||||
{
|
||||
public:
|
||||
enum class Version{
|
||||
V1_0
|
||||
};
|
||||
|
||||
enum class Encoding{
|
||||
UTF8
|
||||
};
|
||||
|
||||
public:
|
||||
XmlProlog(const std::string& tagName);
|
||||
|
||||
static std::unique_ptr<XmlProlog> Create(const std::string& tagName);
|
||||
|
||||
Encoding getEncoding() const;
|
||||
Version getVersion() const;
|
||||
|
||||
void setEncoding(const std::string& encoding);
|
||||
void setVersion(const std::string& version);
|
||||
void update();
|
||||
|
||||
private:
|
||||
Version mVersion;
|
||||
Encoding mEncoding;
|
||||
};
|
||||
|
||||
using XmlPrologPtr = std::unique_ptr<XmlProlog>;
|
Loading…
Add table
Add a link
Reference in a new issue