mirror of
https://github.com/edubart/otclient.git
synced 2025-12-20 23:47:12 +01:00
make otml simpler and easier to use, improve error handling/exceptions
This commit is contained in:
@@ -2,157 +2,86 @@
|
||||
#include "otmlemitter.h"
|
||||
#include "otmldocument.h"
|
||||
|
||||
OTMLNode::OTMLNode()
|
||||
OTMLNodePtr OTMLNode::create(std::string tag, bool unique)
|
||||
{
|
||||
m_unique = false;
|
||||
OTMLNodePtr node(new OTMLNode);
|
||||
node->setTag(tag);
|
||||
node->setUnique(unique);
|
||||
return node;
|
||||
}
|
||||
|
||||
std::string OTMLNode::tag() const
|
||||
OTMLNodePtr OTMLNode::create(std::string tag, std::string value)
|
||||
{
|
||||
return m_tag;
|
||||
OTMLNodePtr node(new OTMLNode);
|
||||
node->setTag(tag);
|
||||
node->setValue(value);
|
||||
node->setUnique(true);
|
||||
return node;
|
||||
}
|
||||
|
||||
std::string OTMLNode::value() const
|
||||
bool OTMLNode::hasChildren() const
|
||||
{
|
||||
// ~ is an alias for no value
|
||||
if(m_value == "~")
|
||||
return fw::empty_string;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
int OTMLNode::size() const
|
||||
{
|
||||
return m_childNodes.size();
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::parent() const
|
||||
{
|
||||
return m_parent.lock();
|
||||
}
|
||||
|
||||
const OTMLNodeList& OTMLNode::childNodes() const
|
||||
{
|
||||
return m_childNodes;
|
||||
}
|
||||
|
||||
std::string OTMLNode::source() const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
bool OTMLNode::hasTag() const
|
||||
{
|
||||
return !m_tag.empty();
|
||||
}
|
||||
|
||||
bool OTMLNode::hasValue() const
|
||||
{
|
||||
return (!m_value.empty() && m_value != "~");
|
||||
}
|
||||
|
||||
bool OTMLNode::hasChildNodes() const
|
||||
{
|
||||
return size() > 0;
|
||||
}
|
||||
|
||||
bool OTMLNode::hasChild(const std::string& childTag) const
|
||||
{
|
||||
return !!get(childTag);
|
||||
}
|
||||
|
||||
bool OTMLNode::hasChild(int index) const
|
||||
{
|
||||
return !!get(index);
|
||||
}
|
||||
|
||||
bool OTMLNode::isUnique() const
|
||||
{
|
||||
return m_unique;
|
||||
}
|
||||
|
||||
void OTMLNode::setTag(std::string tag)
|
||||
{
|
||||
m_tag = tag;
|
||||
|
||||
// valued nodes that has tags are always unique
|
||||
if(!m_value.empty() && hasTag())
|
||||
setUnique();
|
||||
}
|
||||
|
||||
void OTMLNode::setValue(const std::string& value)
|
||||
{
|
||||
m_value = value;
|
||||
|
||||
// valued nodes that has tags are always unique
|
||||
if(!m_value.empty() && hasTag())
|
||||
setUnique();
|
||||
}
|
||||
|
||||
void OTMLNode::setParent(const OTMLNodePtr& parent)
|
||||
{
|
||||
m_parent = parent;
|
||||
}
|
||||
|
||||
void OTMLNode::setUnique(bool unique)
|
||||
{
|
||||
m_unique = unique;
|
||||
}
|
||||
|
||||
void OTMLNode::setSource(const std::string& source)
|
||||
{
|
||||
m_source = source;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::at(const std::string& childTag)
|
||||
{
|
||||
for(const OTMLNodePtr& child : m_childNodes) {
|
||||
if(child->tag() == childTag)
|
||||
return child;
|
||||
int count = 0;
|
||||
for(const OTMLNodePtr& child : m_children) {
|
||||
if(!child->isNull())
|
||||
count++;
|
||||
}
|
||||
throw OTMLException(shared_from_this(), fw::mkstr("child node with tag '", childTag, "' not found"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::at(int childIndex)
|
||||
{
|
||||
if(childIndex < size() && childIndex >= 0)
|
||||
return m_childNodes[childIndex];
|
||||
throw OTMLException(shared_from_this(), fw::mkstr("child node at index '", childIndex, "' not found"));
|
||||
return nullptr;
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::get(const std::string& childTag) const
|
||||
{
|
||||
for(const OTMLNodePtr& child : m_childNodes) {
|
||||
if(child->tag() == childTag)
|
||||
for(const OTMLNodePtr& child : m_children) {
|
||||
if(child->tag() == childTag && !child->isNull())
|
||||
return child;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::get(int childIndex) const
|
||||
OTMLNodePtr OTMLNode::getIndex(int childIndex) const
|
||||
{
|
||||
if(childIndex < size() && childIndex >= 0)
|
||||
return m_childNodes[childIndex];
|
||||
return m_children[childIndex];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::at(const std::string& childTag)
|
||||
{
|
||||
OTMLNodePtr res;
|
||||
for(const OTMLNodePtr& child : m_children) {
|
||||
if(child->tag() == childTag && !child->isNull()) {
|
||||
res = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!res)
|
||||
throw OTMLException(shared_from_this(), fw::mkstr("child node with tag '", childTag, "' not found"));
|
||||
return res;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::atIndex(int childIndex)
|
||||
{
|
||||
if(childIndex >= size() || childIndex < 0)
|
||||
throw OTMLException(shared_from_this(), fw::mkstr("child node with index '", childIndex, "' not found"));
|
||||
return m_children[childIndex];
|
||||
}
|
||||
|
||||
void OTMLNode::addChild(const OTMLNodePtr& newChild)
|
||||
{
|
||||
// replace is needed when the tag is marked as unique
|
||||
if(newChild->hasTag()) {
|
||||
for(OTMLNodePtr node : m_childNodes) {
|
||||
for(const OTMLNodePtr& node : m_children) {
|
||||
if(node->tag() == newChild->tag() && (node->isUnique() || newChild->isUnique())) {
|
||||
newChild->setUnique();
|
||||
newChild->setUnique(true);
|
||||
replaceChild(node, newChild);
|
||||
|
||||
// remove any other child with the same tag
|
||||
auto it = m_childNodes.begin();
|
||||
while(it != m_childNodes.end()) {
|
||||
auto it = m_children.begin();
|
||||
while(it != m_children.end()) {
|
||||
OTMLNodePtr node = (*it);
|
||||
if(node != newChild && node->tag() == newChild->tag()) {
|
||||
node->setParent(nullptr);
|
||||
it = m_childNodes.erase(it);
|
||||
it = m_children.erase(it);
|
||||
} else
|
||||
++it;
|
||||
}
|
||||
@@ -161,60 +90,67 @@ void OTMLNode::addChild(const OTMLNodePtr& newChild)
|
||||
}
|
||||
}
|
||||
|
||||
m_childNodes.push_back(newChild);
|
||||
m_children.push_back(newChild);
|
||||
newChild->setParent(shared_from_this());
|
||||
}
|
||||
|
||||
bool OTMLNode::removeChild(const OTMLNodePtr& oldChild)
|
||||
{
|
||||
for(auto it = m_childNodes.begin(); it != m_childNodes.end(); ++it) {
|
||||
if((*it) == oldChild) {
|
||||
m_childNodes.erase(it);
|
||||
oldChild->setParent(nullptr);
|
||||
return true;
|
||||
}
|
||||
auto it = std::find(m_children.begin(), m_children.end(), oldChild);
|
||||
if(it != m_children.end()) {
|
||||
m_children.erase(it);
|
||||
oldChild->setParent(nullptr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OTMLNode::replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newChild)
|
||||
{
|
||||
for(auto it = m_childNodes.begin(); it != m_childNodes.end(); ++it) {
|
||||
if((*it) == oldChild) {
|
||||
oldChild->setParent(nullptr);
|
||||
newChild->setParent(shared_from_this());
|
||||
it = m_childNodes.erase(it);
|
||||
m_childNodes.insert(it, newChild);
|
||||
return true;
|
||||
}
|
||||
auto it = std::find(m_children.begin(), m_children.end(), oldChild);
|
||||
if(it != m_children.end()) {
|
||||
oldChild->setParent(nullptr);
|
||||
newChild->setParent(shared_from_this());
|
||||
it = m_children.erase(it);
|
||||
m_children.insert(it, newChild);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OTMLNode::clear()
|
||||
{
|
||||
m_childNodes.clear();
|
||||
}
|
||||
|
||||
void OTMLNode::merge(const OTMLNodePtr& node)
|
||||
{
|
||||
for(const OTMLNodePtr& child : node->childNodes()) {
|
||||
OTMLNodePtr newNode(new OTMLNode);
|
||||
newNode->setUnique(child->isUnique());
|
||||
newNode->setTag(child->tag());
|
||||
newNode->setValue(child->value());
|
||||
addChild(newNode);
|
||||
newNode->merge(child);
|
||||
}
|
||||
for(const OTMLNodePtr& child : node->m_children)
|
||||
addChild(child->clone());
|
||||
setTag(node->tag());
|
||||
setSource(node->source());
|
||||
}
|
||||
|
||||
void OTMLNode::clear()
|
||||
{
|
||||
for(const OTMLNodePtr& child : m_children)
|
||||
child->setParent(nullptr);
|
||||
m_children.clear();
|
||||
}
|
||||
|
||||
OTMLNodeList OTMLNode::children() const
|
||||
{
|
||||
OTMLNodeList children;
|
||||
for(const OTMLNodePtr& child : m_children)
|
||||
if(!child->isNull())
|
||||
children.push_back(child);
|
||||
return children;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::clone() const
|
||||
{
|
||||
OTMLNodePtr myClone(new OTMLNode);
|
||||
myClone->setTag(tag());
|
||||
myClone->setValue(value());
|
||||
myClone->setUnique(isUnique());
|
||||
for(OTMLNodePtr child : childNodes())
|
||||
myClone->setTag(m_tag);
|
||||
myClone->setValue(m_value);
|
||||
myClone->setUnique(m_unique);
|
||||
myClone->setNull(m_null);
|
||||
myClone->setSource(m_source);
|
||||
for(const OTMLNodePtr& child : m_children)
|
||||
myClone->addChild(child->clone());
|
||||
return myClone;
|
||||
}
|
||||
@@ -223,3 +159,4 @@ std::string OTMLNode::emit()
|
||||
{
|
||||
return OTMLEmitter::emitNode(shared_from_this(), 0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user