Initial commit.
This commit is contained in:
commit
59c6161fdb
134 changed files with 4751 additions and 0 deletions
380
src/web/xml/XmlParser.cpp
Normal file
380
src/web/xml/XmlParser.cpp
Normal file
|
@ -0,0 +1,380 @@
|
|||
#include "XmlParser.h"
|
||||
#include "StringUtils.h"
|
||||
#include <iostream>
|
||||
|
||||
using LS = XmlParser::LineState;
|
||||
using DS = XmlParser::DocumentState;
|
||||
|
||||
XmlParser::XmlParser()
|
||||
: mDocument(XmlDocument::Create()),
|
||||
mDocumentState(XmlParser::DocumentState::Await_Prolog),
|
||||
mLineState(XmlParser::LineState::Await_Tag_Open)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void XmlParser::ProcessLine(const std::string& input)
|
||||
{
|
||||
for(std::size_t idx; 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:
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
onElementTagEnd();
|
||||
}
|
||||
else if(mDocumentState == DS::Close_Element)
|
||||
{
|
||||
if(mWorkingElement->GetTagName() == mWorkingTagName)
|
||||
{
|
||||
mDocumentState = DS::Await_Element;
|
||||
mLineState = LS::Await_Tag_Open;
|
||||
if(mParentElement)
|
||||
{
|
||||
mWorkingElement = mParentElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::OnTextStart(char c)
|
||||
{
|
||||
mWorkingText = c;
|
||||
mLineState = LS::Await_Text_End;
|
||||
}
|
||||
|
||||
void XmlParser::OnTextEnd()
|
||||
{
|
||||
mWorkingElement->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)
|
||||
{
|
||||
mWorkingProlog = XmlProlog::Create(mWorkingTagName);
|
||||
mLineState = LS::Await_Attribute_Name;
|
||||
}
|
||||
else if(mDocumentState == DS::Build_Element)
|
||||
{
|
||||
auto new_element = XmlElement::Create(mWorkingTagName);
|
||||
mParentElement = mWorkingElement;
|
||||
mWorkingElement = new_element;
|
||||
|
||||
if(!mDocument->GetRoot())
|
||||
{
|
||||
mDocument->SetRoot(mWorkingElement);
|
||||
}
|
||||
mLineState = LS::Await_Attribute_Name;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlParser::OnAttributeNameStart(char c)
|
||||
{
|
||||
mWorkingAttributeName = c;
|
||||
mLineState = LS::Await_Attribute_Name_End;
|
||||
}
|
||||
|
||||
void XmlParser::OnAttributeNameEnd()
|
||||
{
|
||||
mWorkingAttribute = XmlAttribute::Create(mWorkingAttributeName);
|
||||
if(mDocumentState == DS::Build_Prolog)
|
||||
{
|
||||
mWorkingProlog->AddAttribute(mWorkingAttribute);
|
||||
}
|
||||
else if(mDocumentState == DS::Build_Element)
|
||||
{
|
||||
mWorkingElement->AddAttribute(mWorkingAttribute);
|
||||
}
|
||||
mLineState = LS::Await_Attribute_Value;
|
||||
}
|
||||
|
||||
void XmlParser::OnAttributeValueStart()
|
||||
{
|
||||
mWorkingAttributeValue = "";
|
||||
mLineState = LS::Await_Attribute_Value_End;
|
||||
}
|
||||
|
||||
void XmlParser::OnAttributeValueEnd()
|
||||
{
|
||||
mWorkingAttribute->SetValue(mWorkingAttributeValue);
|
||||
mLineState = LS::Await_Attribute_Name;
|
||||
}
|
||||
|
||||
void XmlParser::OnStartProlog()
|
||||
{
|
||||
mDocumentState = DS::Build_Prolog;
|
||||
mLineState = LS::Await_Tag_Name_End;
|
||||
}
|
||||
|
||||
void XmlParser::onFinishProlog()
|
||||
{
|
||||
mWorkingProlog->Update();
|
||||
mDocument->SetProlog(mWorkingProlog);
|
||||
mWorkingProlog = nullptr;
|
||||
mDocumentState = DS::Await_Element;
|
||||
mLineState = LS::Await_Tag_Open;
|
||||
}
|
||||
|
||||
XmlDocumentPtr XmlParser::GetDocument() const
|
||||
{
|
||||
return mDocument;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue