Otclient  14/8/2020
otmlnode.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "otmlnode.h"
24 #include "otmlemitter.h"
25 #include "otmldocument.h"
26 
27 OTMLNodePtr OTMLNode::create(std::string tag, bool unique)
28 {
29  OTMLNodePtr node(new OTMLNode);
30  node->setTag(tag);
31  node->setUnique(unique);
32  return node;
33 }
34 
35 OTMLNodePtr OTMLNode::create(std::string tag, std::string value)
36 {
37  OTMLNodePtr node(new OTMLNode);
38  node->setTag(tag);
39  node->setValue(value);
40  node->setUnique(true);
41  return node;
42 }
43 
45 {
46  int count = 0;
47  for(const OTMLNodePtr& child : m_children) {
48  if(!child->isNull())
49  count++;
50  }
51  return count > 0;
52 }
53 
54 OTMLNodePtr OTMLNode::get(const std::string& childTag)
55 {
56  for(const OTMLNodePtr& child : m_children) {
57  if(child->tag() == childTag && !child->isNull())
58  return child;
59  }
60  return nullptr;
61 }
62 
64 {
65  if(childIndex < size() && childIndex >= 0)
66  return m_children[childIndex];
67  return nullptr;
68 }
69 
70 OTMLNodePtr OTMLNode::at(const std::string& childTag)
71 {
72  OTMLNodePtr res;
73  for(const OTMLNodePtr& child : m_children) {
74  if(child->tag() == childTag && !child->isNull()) {
75  res = child;
76  break;
77  }
78  }
79  if(!res)
80  throw OTMLException(asOTMLNode(), stdext::format("child node with tag '%s' not found", childTag));
81  return res;
82 }
83 
85 {
86  if(childIndex >= size() || childIndex < 0)
87  throw OTMLException(asOTMLNode(), stdext::format("child node with index '%d' not found", childIndex));
88  return m_children[childIndex];
89 }
90 
91 void OTMLNode::addChild(const OTMLNodePtr& newChild)
92 {
93  // replace is needed when the tag is marked as unique
94  if(newChild->hasTag()) {
95  for(const OTMLNodePtr& node : m_children) {
96  if(node->tag() == newChild->tag() && (node->isUnique() || newChild->isUnique())) {
97  newChild->setUnique(true);
98 
99  if(node->hasChildren() && newChild->hasChildren()) {
100  OTMLNodePtr tmpNode = node->clone();
101  tmpNode->merge(newChild);
102  newChild->copy(tmpNode);
103  }
104 
105  replaceChild(node, newChild);
106 
107  // remove any other child with the same tag
108  auto it = m_children.begin();
109  while(it != m_children.end()) {
110  OTMLNodePtr node = (*it);
111  if(node != newChild && node->tag() == newChild->tag()) {
112  it = m_children.erase(it);
113  } else
114  ++it;
115  }
116  return;
117  }
118  }
119  }
120 
121  m_children.push_back(newChild);
122 }
123 
124 bool OTMLNode::removeChild(const OTMLNodePtr& oldChild)
125 {
126  auto it = std::find(m_children.begin(), m_children.end(), oldChild);
127  if(it != m_children.end()) {
128  m_children.erase(it);
129  return true;
130  }
131  return false;
132 }
133 
134 bool OTMLNode::replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newChild)
135 {
136  auto it = std::find(m_children.begin(), m_children.end(), oldChild);
137  if(it != m_children.end()) {
138  it = m_children.erase(it);
139  m_children.insert(it, newChild);
140  return true;
141  }
142  return false;
143 }
144 
145 void OTMLNode::copy(const OTMLNodePtr& node)
146 {
147  setTag(node->tag());
148  setValue(node->rawValue());
149  setUnique(node->isUnique());
150  setNull(node->isNull());
151  setSource(node->source());
152  clear();
153  for(const OTMLNodePtr& child : node->m_children)
154  addChild(child->clone());
155 }
156 
157 void OTMLNode::merge(const OTMLNodePtr& node)
158 {
159  for(const OTMLNodePtr& child : node->m_children)
160  addChild(child->clone());
161  setTag(node->tag());
162  setSource(node->source());
163 }
164 
166 {
167  m_children.clear();
168 }
169 
171 {
173  for(const OTMLNodePtr& child : m_children)
174  if(!child->isNull())
175  children.push_back(child);
176  return children;
177 }
178 
180 {
181  OTMLNodePtr myClone(new OTMLNode);
182  myClone->setTag(m_tag);
183  myClone->setValue(m_value);
184  myClone->setUnique(m_unique);
185  myClone->setNull(m_null);
186  myClone->setSource(m_source);
187  for(const OTMLNodePtr& child : m_children)
188  myClone->addChild(child->clone());
189  return myClone;
190 }
191 
192 std::string OTMLNode::emit()
193 {
194  return OTMLEmitter::emitNode(asOTMLNode(), 0);
195 }
OTMLNode::setTag
void setTag(const std::string &tag)
Definition: otmlnode.h:50
OTMLNode::setSource
void setSource(const std::string &source)
Definition: otmlnode.h:54
OTMLNode::source
std::string source()
Definition: otmlnode.h:38
OTMLNode
Definition: otmlnode.h:28
OTMLException
All OTML errors throw this exception.
Definition: otmlexception.h:29
OTMLNode::hasChildren
bool hasChildren()
Definition: otmlnode.cpp:44
OTMLNode::m_null
bool m_null
Definition: otmlnode.h:102
OTMLNode::removeChild
bool removeChild(const OTMLNodePtr &oldChild)
Definition: otmlnode.cpp:124
OTMLNode::m_children
OTMLNodeList m_children
Definition: otmlnode.h:97
OTMLNode::children
OTMLNodeList children()
Definition: otmlnode.cpp:170
OTMLEmitter::emitNode
static std::string emitNode(const OTMLNodePtr &node, int currentDepth=-1)
Emits a node and it's children to a std::string.
Definition: otmlemitter.cpp:26
stdext::format
std::string format()
Definition: format.h:82
OTMLNode::addChild
void addChild(const OTMLNodePtr &newChild)
Definition: otmlnode.cpp:91
OTMLNode::replaceChild
bool replaceChild(const OTMLNodePtr &oldChild, const OTMLNodePtr &newChild)
Definition: otmlnode.cpp:134
otmldocument.h
OTMLNode::isUnique
bool isUnique()
Definition: otmlnode.h:41
OTMLNode::setNull
void setNull(bool null)
Definition: otmlnode.h:52
OTMLNode::tag
std::string tag()
Definition: otmlnode.h:36
OTMLNode::setUnique
void setUnique(bool unique)
Definition: otmlnode.h:53
OTMLNode::emit
virtual std::string emit()
Definition: otmlnode.cpp:192
OTMLNode::getIndex
OTMLNodePtr getIndex(int childIndex)
Definition: otmlnode.cpp:63
OTMLNode::value
T value()
Definition: otmlnode.h:122
OTMLNode::rawValue
std::string rawValue()
Definition: otmlnode.h:39
OTMLNode::clone
OTMLNodePtr clone()
Definition: otmlnode.cpp:179
OTMLNode::setValue
void setValue(const std::string &value)
Definition: otmlnode.h:51
OTMLNodeList
std::vector< OTMLNodePtr > OTMLNodeList
Definition: declarations.h:35
OTMLNode::size
int size()
Definition: otmlnode.h:37
OTMLNode::get
OTMLNodePtr get(const std::string &childTag)
Definition: otmlnode.cpp:54
OTMLNode::m_value
std::string m_value
Definition: otmlnode.h:99
OTMLNode::hasTag
bool hasTag()
Definition: otmlnode.h:44
OTMLNode::asOTMLNode
OTMLNodePtr asOTMLNode()
Definition: otmlnode.h:92
OTMLNode::m_source
std::string m_source
Definition: otmlnode.h:100
otmlnode.h
stdext::shared_object_ptr< OTMLNode >
OTMLNode::merge
void merge(const OTMLNodePtr &node)
Definition: otmlnode.cpp:157
OTMLNode::copy
void copy(const OTMLNodePtr &node)
Definition: otmlnode.cpp:145
OTMLNode::isNull
bool isNull()
Definition: otmlnode.h:42
otmlemitter.h
OTMLNode::m_tag
std::string m_tag
Definition: otmlnode.h:98
OTMLNode::clear
void clear()
Definition: otmlnode.cpp:165
OTMLNode::m_unique
bool m_unique
Definition: otmlnode.h:101
OTMLNode::atIndex
OTMLNodePtr atIndex(int childIndex)
Definition: otmlnode.cpp:84
OTMLNode::at
OTMLNodePtr at(const std::string &childTag)
Definition: otmlnode.cpp:70
OTMLNode::create
static OTMLNodePtr create(std::string tag="", bool unique=false)
Definition: otmlnode.cpp:27