|
@@ -3,7 +3,7 @@
|
|
|
* Company: Lynar Studios
|
|
|
* E-Mail: webmaster@lynarstudios.com
|
|
|
* Created: 2020-11-26
|
|
|
- * Changed: 2023-02-24
|
|
|
+ * Changed: 2023-05-16
|
|
|
*
|
|
|
* */
|
|
|
|
|
@@ -27,6 +27,7 @@ using std::move;
|
|
|
using std::pair;
|
|
|
using std::shared_ptr;
|
|
|
using std::string;
|
|
|
+using std::string_view;
|
|
|
|
|
|
XmlParser::XmlParser(const shared_ptr<XmlDocument> &_document) : Class("XmlParser")
|
|
|
{
|
|
@@ -36,7 +37,7 @@ XmlParser::XmlParser(const shared_ptr<XmlDocument> &_document) : Class("XmlParse
|
|
|
|
|
|
XmlParser::~XmlParser() noexcept = default;
|
|
|
|
|
|
-shared_ptr<XmlDocument> XmlParser::getDocument()
|
|
|
+shared_ptr<XmlDocument> XmlParser::getDocument() const
|
|
|
{
|
|
|
return this->document;
|
|
|
}
|
|
@@ -77,14 +78,14 @@ void XmlParser::_assignDocument(const shared_ptr<XmlDocument> &_document)
|
|
|
this->document = _document;
|
|
|
}
|
|
|
|
|
|
-bool XmlParser::_contains(const string &_text, const string &_searchText)
|
|
|
+bool XmlParser::_contains(string_view _text, string_view _searchText)
|
|
|
{
|
|
|
return _text.find(_searchText) != string::npos;
|
|
|
}
|
|
|
|
|
|
shared_ptr<XmlDeclaration> XmlParser::_createDeclaration(const list<pair<string, string>> &_attributes)
|
|
|
{
|
|
|
- shared_ptr<XmlDeclaration> declaration = make_shared<XmlDeclaration>("1.0");
|
|
|
+ auto declaration = make_shared<XmlDeclaration>("1.0");
|
|
|
pair<string, string> attribute = XmlParser::_findAttribute(_attributes, "version");
|
|
|
|
|
|
if (!attribute.first.empty())
|
|
@@ -109,29 +110,29 @@ shared_ptr<XmlDeclaration> XmlParser::_createDeclaration(const list<pair<string,
|
|
|
return declaration;
|
|
|
}
|
|
|
|
|
|
-shared_ptr<XmlNode> XmlParser::_createNode(const list<pair<string, string>> &_attributes, const string &_name)
|
|
|
+shared_ptr<XmlNode> XmlParser::_createNode(const list<pair<string, string>> &_attributes, string_view _name)
|
|
|
{
|
|
|
- shared_ptr<XmlNode> node = make_shared<XmlNode>(_name);
|
|
|
+ auto node = make_shared<XmlNode>(string{_name});
|
|
|
shared_ptr<XmlAttribute> attribute{};
|
|
|
|
|
|
- for (const auto &parsedAttribute : _attributes)
|
|
|
+ for (const auto &[attributeName, attributeValue] : _attributes)
|
|
|
{
|
|
|
- attribute = make_shared<XmlAttribute>(parsedAttribute.first);
|
|
|
- attribute->setValue(parsedAttribute.second);
|
|
|
+ attribute = make_shared<XmlAttribute>(attributeName);
|
|
|
+ attribute->setValue(attributeValue);
|
|
|
node->addAttributeToEnd(attribute);
|
|
|
}
|
|
|
|
|
|
return node;
|
|
|
}
|
|
|
|
|
|
-bool XmlParser::_endsWith(const string &_text, const string &_ending)
|
|
|
+bool XmlParser::_endsWith(string_view _text, string_view _ending)
|
|
|
{
|
|
|
return _text.rfind(_ending) == (_text.size() - _ending.size());
|
|
|
}
|
|
|
|
|
|
pair<string, string> XmlParser::_findAttribute(const list<pair<string, string>> &_attributes, const string &_name)
|
|
|
{
|
|
|
- const auto &iterator = find_if(_attributes.begin(), _attributes.end(), [_name](const pair<string, string> &_attribute) { return _attribute.first == _name; });
|
|
|
+ const auto &iterator = find_if(_attributes.begin(), _attributes.end(), [&_name](const pair<string, string> &_attribute) { return _attribute.first == _name; });
|
|
|
return iterator != _attributes.end() ? *iterator : pair<string, string>{};
|
|
|
}
|
|
|
|
|
@@ -158,12 +159,11 @@ size_t XmlParser::_findAttributeEndPosition(const byte_field &_data)
|
|
|
return position;
|
|
|
}
|
|
|
|
|
|
-byte_field XmlParser::_getNextTagString(const byte_field &_data, string::size_type _index)
|
|
|
+byte_field XmlParser::_getNextTagString(string_view _data, string::size_type _index)
|
|
|
{
|
|
|
byte_field tag{};
|
|
|
- size_t closingCharacterPosition = _index + _data.substr(_index).find('>');
|
|
|
|
|
|
- if (closingCharacterPosition != string::npos)
|
|
|
+ if (size_t closingCharacterPosition = _index + _data.substr(_index).find('>'); closingCharacterPosition != string::npos)
|
|
|
{
|
|
|
tag = _data.substr(_index, (closingCharacterPosition - _index) + 1);
|
|
|
}
|
|
@@ -171,7 +171,7 @@ byte_field XmlParser::_getNextTagString(const byte_field &_data, string::size_ty
|
|
|
return tag;
|
|
|
}
|
|
|
|
|
|
-void XmlParser::_isClosingTag(const byte_field &_data, string::size_type _index)
|
|
|
+void XmlParser::_isClosingTag(string_view _data, string::size_type _index)
|
|
|
{
|
|
|
if (this->mode == XmlParseMode::XML_PARSE_MODE_ANALYZE && _data.substr(_index, 2) == "</")
|
|
|
{
|
|
@@ -179,7 +179,7 @@ void XmlParser::_isClosingTag(const byte_field &_data, string::size_type _index)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void XmlParser::_isDeclaration(const byte_field &_data, string::size_type _index)
|
|
|
+void XmlParser::_isDeclaration(string_view _data, string::size_type _index)
|
|
|
{
|
|
|
if (_data.substr(_index, 5) == "<?xml")
|
|
|
{
|
|
@@ -187,7 +187,7 @@ void XmlParser::_isDeclaration(const byte_field &_data, string::size_type _index
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void XmlParser::_isOpeningTag(const byte_field &_data, string::size_type _index)
|
|
|
+void XmlParser::_isOpeningTag(string_view _data, string::size_type _index)
|
|
|
{
|
|
|
if (this->mode == XmlParseMode::XML_PARSE_MODE_ANALYZE && _data.substr(_index, 1) == "<")
|
|
|
{
|
|
@@ -206,7 +206,7 @@ void XmlParser::_isValue(const byte_field &_data, string::size_type _index)
|
|
|
{
|
|
|
string value{_data.substr(_index, end)};
|
|
|
|
|
|
- if (!XmlParser::_contains(value, "\n") && !XmlParser::_contains(value, "\r\n"))
|
|
|
+ if (!XmlParser::_contains(string_view{value}, string_view{"\n"}) && !XmlParser::_contains(string_view{value}, string_view{"\r\n"}))
|
|
|
{
|
|
|
this->mode = XmlParseMode::XML_PARSE_MODE_VALUE;
|
|
|
}
|
|
@@ -267,46 +267,11 @@ void XmlParser::_parse(const byte_field &_data)
|
|
|
{
|
|
|
for (string::size_type index = 0; index < _data.size(); index++)
|
|
|
{
|
|
|
- switch (this->mode)
|
|
|
- {
|
|
|
- case XmlParseMode::XML_PARSE_MODE_ANALYZE:
|
|
|
- {
|
|
|
- this->_analyze(_data, index);
|
|
|
- }
|
|
|
- break;
|
|
|
- case XmlParseMode::XML_PARSE_MODE_DECLARATION:
|
|
|
- {
|
|
|
- --index;
|
|
|
- index = this->_parseDeclaration(_data, index);
|
|
|
- this->mode = XmlParseMode::XML_PARSE_MODE_ANALYZE;
|
|
|
- }
|
|
|
- break;
|
|
|
- case XmlParseMode::XML_PARSE_MODE_OPENING_TAG:
|
|
|
- {
|
|
|
- --index;
|
|
|
- index = XmlParser::_parseOpeningTag(_data, index);
|
|
|
- this->mode = XmlParseMode::XML_PARSE_MODE_ANALYZE;
|
|
|
- }
|
|
|
- break;
|
|
|
- case XmlParseMode::XML_PARSE_MODE_VALUE:
|
|
|
- {
|
|
|
- --index;
|
|
|
- index = XmlParser::_parseValue(_data, index);
|
|
|
- this->mode = XmlParseMode::XML_PARSE_MODE_ANALYZE;
|
|
|
- }
|
|
|
- break;
|
|
|
- case XmlParseMode::XML_PARSE_MODE_CLOSING_TAG:
|
|
|
- {
|
|
|
- --index;
|
|
|
- index = XmlParser::_parseClosingTag(_data, index);
|
|
|
- this->mode = XmlParseMode::XML_PARSE_MODE_ANALYZE;
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
+ index = this->_parseMode(index, _data);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pair<string, string> XmlParser::_parseAttribute(const byte_field &_data)
|
|
|
+pair<string, string> XmlParser::_parseAttribute(string_view _data)
|
|
|
{
|
|
|
pair<string, string> parsedAttribute{};
|
|
|
parsedAttribute.first = _data.substr(0, _data.find('='));
|
|
@@ -329,7 +294,7 @@ list<pair<string, string>> XmlParser::_parseAttributes(byte_field _data)
|
|
|
position = _data.find(' ') + 1;
|
|
|
} while (_data[position] == ' ');
|
|
|
|
|
|
- if (_data.size() <= 3 && XmlParser::_endsWith(string{_data}, ">"))
|
|
|
+ if (_data.size() <= 3 && XmlParser::_endsWith(string_view{_data}, ">"))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
@@ -349,7 +314,7 @@ size_t XmlParser::_parseClosingTag(const byte_field &_data, string::size_type _i
|
|
|
return tagString.empty() ? _index : _index + (tagString.size() - 1);
|
|
|
}
|
|
|
|
|
|
-size_t XmlParser::_parseDeclaration(const byte_field &_data, string::size_type _index)
|
|
|
+size_t XmlParser::_parseDeclaration(const byte_field &_data, string::size_type _index) const
|
|
|
{
|
|
|
string tagString = XmlParser::_getNextTagString(_data, _index);
|
|
|
bool isValidTagString = !tagString.empty();
|
|
@@ -363,6 +328,50 @@ size_t XmlParser::_parseDeclaration(const byte_field &_data, string::size_type _
|
|
|
return !isValidTagString ? _index : _index + (tagString.size() - 1);
|
|
|
}
|
|
|
|
|
|
+string::size_type XmlParser::_parseMode(string::size_type _index, const byte_field &_data)
|
|
|
+{
|
|
|
+ string::size_type index = _index;
|
|
|
+
|
|
|
+ switch (this->mode)
|
|
|
+ {
|
|
|
+ case XmlParseMode::XML_PARSE_MODE_ANALYZE:
|
|
|
+ {
|
|
|
+ this->_analyze(_data, index);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case XmlParseMode::XML_PARSE_MODE_DECLARATION:
|
|
|
+ {
|
|
|
+ --index;
|
|
|
+ index = this->_parseDeclaration(_data, index);
|
|
|
+ this->mode = XmlParseMode::XML_PARSE_MODE_ANALYZE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case XmlParseMode::XML_PARSE_MODE_OPENING_TAG:
|
|
|
+ {
|
|
|
+ --index;
|
|
|
+ index = XmlParser::_parseOpeningTag(_data, index);
|
|
|
+ this->mode = XmlParseMode::XML_PARSE_MODE_ANALYZE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case XmlParseMode::XML_PARSE_MODE_VALUE:
|
|
|
+ {
|
|
|
+ --index;
|
|
|
+ index = XmlParser::_parseValue(_data, index);
|
|
|
+ this->mode = XmlParseMode::XML_PARSE_MODE_ANALYZE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case XmlParseMode::XML_PARSE_MODE_CLOSING_TAG:
|
|
|
+ {
|
|
|
+ --index;
|
|
|
+ index = XmlParser::_parseClosingTag(_data, index);
|
|
|
+ this->mode = XmlParseMode::XML_PARSE_MODE_ANALYZE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return index;
|
|
|
+}
|
|
|
+
|
|
|
size_t XmlParser::_parseOpeningTag(const byte_field &_data, string::size_type _index)
|
|
|
{
|
|
|
string tagString{XmlParser::_getNextTagString(_data, _index)};
|
|
@@ -387,7 +396,7 @@ size_t XmlParser::_parseOpeningTag(const byte_field &_data, string::size_type _i
|
|
|
return !isValidTagString ? _index : _index + (tagString.size() - 1);
|
|
|
}
|
|
|
|
|
|
-byte_field XmlParser::_parseTagName(const byte_field &_data)
|
|
|
+string_view XmlParser::_parseTagName(string_view _data)
|
|
|
{
|
|
|
string::size_type position = _data.find(' ');
|
|
|
|
|
@@ -399,10 +408,10 @@ byte_field XmlParser::_parseTagName(const byte_field &_data)
|
|
|
return _data.substr(1, position - 1);
|
|
|
}
|
|
|
|
|
|
-size_t XmlParser::_parseValue(const byte_field &_data, string::size_type _index)
|
|
|
+size_t XmlParser::_parseValue(string_view _data, string::size_type _index)
|
|
|
{
|
|
|
- byte_field value = _data.substr(_index, _data.substr(_index).find('<'));
|
|
|
- this->parseParameters.back().getNode()->setValue(value);
|
|
|
+ string_view value = _data.substr(_index, _data.substr(_index).find('<'));
|
|
|
+ this->parseParameters.back().getNode()->setValue(string{value});
|
|
|
|
|
|
return _index + (value.size() - 1);
|
|
|
}
|