source: rrlib_xml/tNode.cpp

tip
Last change on this file was 69:b9bd564ea70c, checked in by Max Reichardt <mreichardt@…>, 3 years ago

Fixes compiler warnings that appear with additional non-default warning options enabled

File size: 10.7 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    rrlib/xml/tNode.cpp
23 *
24 * \author  Tobias Foehst
25 *
26 * \date    2010-06-24
27 *
28 */
29//----------------------------------------------------------------------
30#include "rrlib/xml/tNode.h"
31
32//----------------------------------------------------------------------
33// External includes (system with <>, local with "")
34//----------------------------------------------------------------------
35#include <cstring>
36
37//----------------------------------------------------------------------
38// Internal includes with ""
39//----------------------------------------------------------------------
40
41//----------------------------------------------------------------------
42// Debugging
43//----------------------------------------------------------------------
44#include <cassert>
45
46//----------------------------------------------------------------------
47// Namespace usage
48//----------------------------------------------------------------------
49
50//----------------------------------------------------------------------
51// Namespace declaration
52//----------------------------------------------------------------------
53namespace rrlib
54{
55namespace xml
56{
57
58//----------------------------------------------------------------------
59// Forward declarations / typedefs / enums
60//----------------------------------------------------------------------
61
62//----------------------------------------------------------------------
63// Const values
64//----------------------------------------------------------------------
65
66//----------------------------------------------------------------------
67// Implementation
68//----------------------------------------------------------------------
69
70//----------------------------------------------------------------------
71// tNode destructor
72//----------------------------------------------------------------------
73tNode::~tNode()
74{
75  static_assert(sizeof(tNode) == sizeof(xmlNode), "Do not add any variables or virtual methods to tNode!");
76}
77
78//----------------------------------------------------------------------
79// tNode IsInSubtreeOf
80//----------------------------------------------------------------------
81bool tNode::IsInSubtreeOf(const tNode &node) const
82{
83  const tNode *current_node = this;
84  do
85  {
86    if (current_node == &node)
87    {
88      return true;
89    }
90  }
91  while ((current_node = reinterpret_cast<tNode *>(current_node->parent)));
92  return false;
93}
94
95//----------------------------------------------------------------------
96// tNode Name
97//----------------------------------------------------------------------
98const std::string tNode::Name() const
99{
100  return reinterpret_cast<const char *>(this->name);
101}
102
103//----------------------------------------------------------------------
104// tNode Parent
105//----------------------------------------------------------------------
106tNode &tNode::Parent()
107{
108  if (!this->parent || this->parent->type != XML_ELEMENT_NODE)
109  {
110    throw tException("Node has no parent!");
111  }
112  return reinterpret_cast<tNode &>(*this->parent);
113}
114
115//----------------------------------------------------------------------
116// tNode ChildrenEnd
117//----------------------------------------------------------------------
118const tNode::iterator &tNode::ChildrenEnd()
119{
120  static iterator end;
121  return end;
122}
123
124const tNode::const_iterator &tNode::ChildrenEnd() const
125{
126  static const_iterator end;
127  return end;
128}
129
130//----------------------------------------------------------------------
131// tNode FirstChild
132//----------------------------------------------------------------------
133tNode &tNode::FirstChild()
134{
135  if (!this->HasChildren())
136  {
137    throw tException("Node has no children!");
138  }
139  return *this->ChildrenBegin();
140}
141
142//----------------------------------------------------------------------
143// tNode AddChildNode
144//----------------------------------------------------------------------
145tNode &tNode::AddChildNode(const std::string &name, const std::string &content)
146{
147  const char* c = (content.length() == 0) ? NULL : content.c_str();
148  return reinterpret_cast<tNode &>(*xmlNewChild(this, 0, reinterpret_cast<const xmlChar *>(name.c_str()), reinterpret_cast<const xmlChar *>(c)));
149}
150
151tNode &tNode::AddChildNode(tNode &node, bool copy)
152{
153  tNode *child = &node;
154  if (copy)
155  {
156    child = reinterpret_cast<tNode *>(xmlDocCopyNode(child, this->doc, 1));
157  }
158  if (child->doc != this->doc)
159  {
160    xmlUnlinkNode(child);
161  }
162  if (this->IsInSubtreeOf(*child))
163  {
164    assert(!copy);
165    throw tException("Cannot add node as child to its own subtree without copying!");
166  }
167  xmlAddChild(this, child);
168  return *child;
169}
170
171//----------------------------------------------------------------------
172// tNode RemoveChildNode
173//----------------------------------------------------------------------
174void tNode::RemoveChildNode(tNode &node)
175{
176  iterator it = std::find(this->ChildrenBegin(), this->ChildrenEnd(), node);
177  if (it == this->ChildrenEnd())
178  {
179    throw tException("Given node is not a child of this!");
180  }
181  it->FreeNode();
182}
183
184//----------------------------------------------------------------------
185// tNode NextSiblingsEnd
186//----------------------------------------------------------------------
187const tNode::iterator &tNode::NextSiblingsEnd()
188{
189  static iterator end;
190  return end;
191}
192
193const tNode::const_iterator &tNode::NextSiblingsEnd() const
194{
195  static const_iterator end;
196  return end;
197}
198
199//----------------------------------------------------------------------
200// tNode NextSibling
201//----------------------------------------------------------------------
202tNode &tNode::NextSibling()
203{
204  if (!this->HasNextSibling())
205  {
206    throw tException("Node has no sibling!");
207  }
208  return *this->NextSiblingsBegin();
209}
210
211//----------------------------------------------------------------------
212// tNode AddNextSibling
213//----------------------------------------------------------------------
214tNode &tNode::AddNextSibling(const std::string &name, const std::string &content)
215{
216  tNode *sibling = reinterpret_cast<tNode *>(xmlNewNode(0, reinterpret_cast<const xmlChar *>(name.c_str())));
217  if (content != "")
218  {
219    xmlNodeSetContentLen(sibling, reinterpret_cast<const xmlChar *>(content.c_str()), content.length());
220  }
221  return reinterpret_cast<tNode &>(*xmlAddNextSibling(this, sibling));
222}
223
224tNode &tNode::AddNextSibling(tNode &node, bool copy)
225{
226  tNode *sibling = &node;
227  if (copy)
228  {
229    sibling = reinterpret_cast<tNode *>(xmlDocCopyNode(sibling, this->doc, 1));
230  }
231  if (sibling->doc != this->doc)
232  {
233    xmlUnlinkNode(sibling);
234  }
235  if (this->IsInSubtreeOf(*sibling))
236  {
237    assert(!copy);
238    throw tException("Cannot add node as sibling in its own subtree without copying!");
239  }
240  xmlAddNextSibling(this, sibling);
241  return *sibling;
242}
243
244//----------------------------------------------------------------------
245// tNode GetTextContent
246//----------------------------------------------------------------------
247const std::string tNode::GetTextContent() const
248{
249  xmlChar *content = xmlNodeGetContent(const_cast<tNode *>(this));
250  std::string result(reinterpret_cast<const char *>(content));
251  xmlFree(content);
252  return result;
253}
254
255//----------------------------------------------------------------------
256// tNode AddTextContent
257//----------------------------------------------------------------------
258void tNode::AddTextContent(const std::string &content)
259{
260  xmlNodeAddContentLen(this, reinterpret_cast<const xmlChar *>(content.c_str()), content.length());
261}
262
263//----------------------------------------------------------------------
264// tNode SetContent
265//----------------------------------------------------------------------
266void tNode::SetContent(const std::string &content)
267{
268  xmlNodeSetContentLen(this, reinterpret_cast<const xmlChar *>(content.c_str()), content.length());
269}
270
271//----------------------------------------------------------------------
272// tNode RemoveTextContent
273//----------------------------------------------------------------------
274void tNode::RemoveTextContent()
275{
276  std::vector<tNode *> nodes_to_delete;
277  for (xmlNodePtr child_node = this->children; child_node; child_node = child_node->next)
278  {
279    if (xmlNodeIsText(child_node))
280    {
281      nodes_to_delete.push_back(reinterpret_cast<tNode *>(child_node));
282    }
283  }
284  for (std::vector<tNode *>::iterator it = nodes_to_delete.begin(); it != nodes_to_delete.end(); ++it)
285  {
286    (*it)->FreeNode();
287  }
288}
289
290//----------------------------------------------------------------------
291// tNode SetStringAttribute
292//----------------------------------------------------------------------
293void tNode::SetStringAttribute(const std::string &name, const std::string &value, bool create)
294{
295  if (!this->HasAttribute(name))
296  {
297    if (create)
298    {
299      xmlNewProp(this, reinterpret_cast<const xmlChar *>(name.c_str()), reinterpret_cast<const xmlChar *>(value.c_str()));
300      return;
301    }
302    throw tException("Attribute `" + name + "' does not exist in this node and creation was disabled!");
303  }
304  xmlSetProp(this, reinterpret_cast<const xmlChar *>(name.c_str()), reinterpret_cast<const xmlChar *>(value.c_str()));
305}
306
307//----------------------------------------------------------------------
308// tNode RemoveAttribute
309//----------------------------------------------------------------------
310void tNode::RemoveAttribute(const std::string &name)
311{
312  xmlAttrPtr attr = xmlHasProp(this, reinterpret_cast<const xmlChar *>(name.c_str()));
313  if (attr)
314  {
315    xmlRemoveProp(attr);
316  }
317}
318
319//----------------------------------------------------------------------
320// tNode GetXMLDump
321//----------------------------------------------------------------------
322const std::string tNode::GetXMLDump(bool format) const
323{
324  xmlBufferPtr buffer = xmlBufferCreate();
325  xmlNodeDump(buffer, this->doc, const_cast<tNode *>(this), 0, format);
326  std::string result(reinterpret_cast<const char *>(buffer->content));
327  xmlBufferFree(buffer);
328  return result;
329}
330
331//----------------------------------------------------------------------
332// End of namespace declaration
333//----------------------------------------------------------------------
334}
335}
Note: See TracBrowser for help on using the repository browser.