1 /*
2 http://code.google.com/p/ticpp/
3 Copyright (c) 2006 Ryan Pusztai, Ryan Mulder
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy of
6 this software and associated documentation files (the "Software"), to deal in
7 the Software without restriction, including without limitation the rights to
8 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 the Software, and to permit persons to whom the Software is furnished to do so,
10 subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in all
13 copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 */
22 #define TIXML_USE_TICPP
23 #ifdef TIXML_USE_TICPP
24
25 #include "ticpp.h"
26 #include "ticpprc.h"
27 #include "tinyxml.h"
28 #include <sstream>
29
30 using namespace ticpp;
31
32 // In the following Visitor functions, casting away const should be safe, as the
33 // object can only be referred to by a const &
VisitEnter(const TiXmlDocument & doc)34 bool Visitor::VisitEnter(const TiXmlDocument& doc) {
35 return VisitEnter(Document(const_cast< TiXmlDocument* >(&doc)));
36 }
37
VisitExit(const TiXmlDocument & doc)38 bool Visitor::VisitExit(const TiXmlDocument& doc) {
39 return VisitEnter(Document(const_cast< TiXmlDocument* >(&doc)));
40 }
41
VisitEnter(const TiXmlElement & element,const TiXmlAttribute * firstAttribute)42 bool Visitor::VisitEnter(const TiXmlElement& element,
43 const TiXmlAttribute* firstAttribute) {
44 if (0 != firstAttribute) {
45 Attribute attribute(const_cast< TiXmlAttribute* >(firstAttribute));
46 return VisitEnter(Element(const_cast< TiXmlElement* >(&element)), &attribute);
47 } else {
48 return VisitEnter(Element(const_cast< TiXmlElement* >(&element)), 0);
49 }
50 }
51
VisitExit(const TiXmlElement & element)52 bool Visitor::VisitExit(const TiXmlElement& element) {
53 return VisitExit(Element(const_cast< TiXmlElement* >(&element)));
54 }
55
Visit(const TiXmlDeclaration & declaration)56 bool Visitor::Visit(const TiXmlDeclaration& declaration) {
57 return Visit(Declaration(const_cast< TiXmlDeclaration* >(&declaration)));
58 }
59
Visit(const TiXmlStylesheetReference & stylesheet)60 bool Visitor::Visit(const TiXmlStylesheetReference& stylesheet) {
61 return Visit(
62 StylesheetReference(const_cast< TiXmlStylesheetReference* >(&stylesheet)));
63 }
64
Visit(const TiXmlText & text)65 bool Visitor::Visit(const TiXmlText& text) {
66 return Visit(Text(const_cast< TiXmlText* >(&text)));
67 }
68
Visit(const TiXmlComment & comment)69 bool Visitor::Visit(const TiXmlComment& comment) {
70 return Visit(Comment(const_cast< TiXmlComment* >(&comment)));
71 }
72
Visit(const TiXmlUnknown & x)73 bool Visitor::Visit(const TiXmlUnknown& x) { return TiXmlVisitor::Visit(x); }
74
Attribute()75 Attribute::Attribute() {
76 SetTiXmlPointer(new TiXmlAttribute());
77 m_impRC->InitRef();
78 }
79
Attribute(TiXmlAttribute * attribute)80 Attribute::Attribute(TiXmlAttribute* attribute) {
81 SetTiXmlPointer(attribute);
82 m_impRC->IncRef();
83 }
84
Attribute(const std::string & name,const std::string & value)85 Attribute::Attribute(const std::string& name, const std::string& value) {
86 SetTiXmlPointer(new TiXmlAttribute(name, value));
87 m_impRC->InitRef();
88 }
89
operator =(const Attribute & copy)90 void Attribute::operator=(const Attribute& copy) {
91 // Dropping the reference to the old object
92 this->m_impRC->DecRef();
93
94 // Pointing to the new Object
95 SetTiXmlPointer(copy.m_tiXmlPointer);
96
97 // The internal tixml pointer changed in the above line
98 this->m_impRC->IncRef();
99 }
100
Attribute(const Attribute & copy)101 Attribute::Attribute(const Attribute& copy)
102 : Base() {
103 // Dropping the reference to the old object
104 this->m_impRC->DecRef();
105
106 // Pointing to the new Object
107 SetTiXmlPointer(copy.m_tiXmlPointer);
108
109 // The internal tixml pointer changed in the above line
110 this->m_impRC->IncRef();
111 }
112
~Attribute()113 Attribute::~Attribute() { m_impRC->DecRef(); }
114
Value() const115 std::string Attribute::Value() const {
116 ValidatePointer();
117 return m_tiXmlPointer->ValueStr();
118 }
119
Name() const120 std::string Attribute::Name() const {
121 ValidatePointer();
122 return m_tiXmlPointer->Name();
123 }
124
Next(bool throwIfNoAttribute) const125 Attribute* Attribute::Next(bool throwIfNoAttribute) const {
126 ValidatePointer();
127 TiXmlAttribute* attribute = m_tiXmlPointer->Next();
128
129 if (0 == attribute) {
130 if (throwIfNoAttribute) {
131 TICPPTHROW("No more attributes found")
132 } else {
133 return 0;
134 }
135 }
136
137 Attribute* temp = new Attribute(attribute);
138 attribute->m_spawnedWrappers.push_back(temp);
139
140 return temp;
141 }
142
Previous(bool throwIfNoAttribute) const143 Attribute* Attribute::Previous(bool throwIfNoAttribute) const {
144 ValidatePointer();
145 TiXmlAttribute* attribute = m_tiXmlPointer->Previous();
146
147 if (0 == attribute) {
148 if (throwIfNoAttribute) {
149 TICPPTHROW("No more attributes found")
150 } else {
151 return 0;
152 }
153 }
154
155 Attribute* temp = new Attribute(attribute);
156 attribute->m_spawnedWrappers.push_back(temp);
157
158 return temp;
159 }
160
IterateNext(const std::string &,Attribute ** next) const161 void Attribute::IterateNext(const std::string&, Attribute** next) const {
162 *next = Next(false);
163 }
164
IteratePrevious(const std::string &,Attribute ** previous) const165 void Attribute::IteratePrevious(const std::string&, Attribute** previous) const {
166 *previous = Previous(false);
167 }
168
Print(FILE * file,int depth) const169 void Attribute::Print(FILE* file, int depth) const {
170 ValidatePointer();
171 m_tiXmlPointer->Print(file, depth);
172 }
173
SetTiXmlPointer(TiXmlAttribute * newPointer)174 void Attribute::SetTiXmlPointer(TiXmlAttribute* newPointer) {
175 m_tiXmlPointer = newPointer;
176 SetImpRC(newPointer);
177 }
178
179 //*****************************************************************************
180
NodeFactory(TiXmlNode * tiXmlNode,bool throwIfNull,bool rememberSpawnedWrapper) const181 Node* Node::NodeFactory(TiXmlNode* tiXmlNode,
182 bool throwIfNull,
183 bool rememberSpawnedWrapper) const {
184 if (0 == tiXmlNode) {
185 if (throwIfNull) {
186 TICPPTHROW("tiXmlNode is nullptr")
187 } else {
188 return 0;
189 }
190 }
191
192 Node* temp;
193
194 switch (tiXmlNode->Type()) {
195 case TiXmlNode::DOCUMENT:
196 temp = new Document(tiXmlNode->ToDocument());
197 break;
198
199 case TiXmlNode::ELEMENT:
200 temp = new Element(tiXmlNode->ToElement());
201 break;
202
203 case TiXmlNode::COMMENT:
204 temp = new Comment(tiXmlNode->ToComment());
205 break;
206
207 case TiXmlNode::TEXT:
208 temp = new Text(tiXmlNode->ToText());
209 break;
210
211 case TiXmlNode::DECLARATION:
212 temp = new Declaration(tiXmlNode->ToDeclaration());
213 break;
214
215 case TiXmlNode::STYLESHEETREFERENCE:
216 temp = new StylesheetReference(tiXmlNode->ToStylesheetReference());
217 break;
218
219 default:
220 TICPPTHROW("Type is unsupported")
221 }
222
223 if (rememberSpawnedWrapper) {
224 tiXmlNode->m_spawnedWrappers.push_back(temp);
225 }
226
227 return temp;
228 }
229
Value() const230 std::string Node::Value() const { return GetTiXmlPointer()->ValueStr(); }
231
Clear()232 void Node::Clear() { GetTiXmlPointer()->Clear(); }
233
Parent(bool throwIfNoParent) const234 Node* Node::Parent(bool throwIfNoParent) const {
235 TiXmlNode* parent = GetTiXmlPointer()->Parent();
236
237 if ((0 == parent) && throwIfNoParent) {
238 TICPPTHROW("No parent exists");
239 }
240
241 return NodeFactory(parent, false);
242 }
243
FirstChild(bool throwIfNoChildren) const244 Node* Node::FirstChild(bool throwIfNoChildren) const {
245 return FirstChild("", throwIfNoChildren);
246 }
247
FirstChild(const std::string & value,bool throwIfNoChildren) const248 Node* Node::FirstChild(const std::string& value, bool throwIfNoChildren) const {
249 return FirstChild(value.c_str(), throwIfNoChildren);
250 }
251
FirstChild(const char * value,bool throwIfNoChildren) const252 Node* Node::FirstChild(const char* value, bool throwIfNoChildren) const {
253 TiXmlNode* childNode;
254
255 if (0 == strlen(value)) {
256 childNode = GetTiXmlPointer()->FirstChild();
257 } else {
258 childNode = GetTiXmlPointer()->FirstChild(value);
259 }
260
261 if ((0 == childNode) && throwIfNoChildren) {
262 TICPPTHROW("Child with the value of \"" << value << "\" not found");
263 }
264
265 return NodeFactory(childNode, false);
266 }
267
LastChild(bool throwIfNoChildren) const268 Node* Node::LastChild(bool throwIfNoChildren) const {
269 return LastChild("", throwIfNoChildren);
270 }
271
LastChild(const std::string & value,bool throwIfNoChildren) const272 Node* Node::LastChild(const std::string& value, bool throwIfNoChildren) const {
273 return LastChild(value.c_str(), throwIfNoChildren);
274 }
275
LastChild(const char * value,bool throwIfNoChildren) const276 Node* Node::LastChild(const char* value, bool throwIfNoChildren) const {
277 TiXmlNode* childNode;
278
279 if (0 == strlen(value)) {
280 childNode = GetTiXmlPointer()->LastChild();
281 } else {
282 childNode = GetTiXmlPointer()->LastChild(value);
283 }
284
285 if ((0 == childNode) && throwIfNoChildren) {
286 TICPPTHROW("Child with the value of \"" << value << "\" not found");
287 }
288
289 return NodeFactory(childNode, false);
290 }
291
IterateChildren(Node * previous) const292 Node* Node::IterateChildren(Node* previous) const {
293 TiXmlNode* pointer;
294
295 if (0 == previous) {
296 pointer = GetTiXmlPointer()->IterateChildren(0);
297 } else {
298 pointer = GetTiXmlPointer()->IterateChildren(previous->GetTiXmlPointer());
299 }
300
301 return NodeFactory(pointer, false);
302 }
303
IterateChildren(const std::string & value,Node * previous) const304 Node* Node::IterateChildren(const std::string& value, Node* previous) const {
305 TiXmlNode* pointer;
306
307 if (0 == previous) {
308 pointer = GetTiXmlPointer()->IterateChildren(value, 0);
309 } else {
310 pointer =
311 GetTiXmlPointer()->IterateChildren(value, previous->GetTiXmlPointer());
312 }
313
314 return NodeFactory(pointer, false);
315 }
316
InsertEndChild(Node & addThis)317 Node* Node::InsertEndChild(Node& addThis) {
318 if (addThis.Type() == TiXmlNode::DOCUMENT) {
319 TICPPTHROW("Node is a Document and can't be inserted");
320 }
321
322 TiXmlNode* pointer =
323 GetTiXmlPointer()->InsertEndChild(*addThis.GetTiXmlPointer());
324
325 if (0 == pointer) {
326 TICPPTHROW("Node can't be inserted");
327 }
328
329 return NodeFactory(pointer);
330 }
331
LinkEndChild(Node * childNode)332 Node* Node::LinkEndChild(Node* childNode) {
333 if (childNode->Type() == TiXmlNode::DOCUMENT) {
334 TICPPTHROW("Node is a Document and can't be linked");
335 }
336
337 // Increment reference count when adding to the tree
338 childNode->m_impRC->IncRef();
339
340 if (0 == GetTiXmlPointer()->LinkEndChild(childNode->GetTiXmlPointer())) {
341 TICPPTHROW("Node can't be linked");
342 }
343
344 return childNode;
345 }
346
InsertBeforeChild(Node * beforeThis,Node & addThis)347 Node* Node::InsertBeforeChild(Node* beforeThis, Node& addThis) {
348 if (addThis.Type() == TiXmlNode::DOCUMENT) {
349 TICPPTHROW("Node is a Document and can't be inserted");
350 }
351
352 // Increment reference count when adding to the tree
353 addThis.m_impRC->IncRef();
354
355 TiXmlNode* pointer = GetTiXmlPointer()->InsertBeforeChild(
356 beforeThis->GetTiXmlPointer(), *addThis.GetTiXmlPointer());
357
358 if (0 == pointer) {
359 TICPPTHROW("Node can't be inserted");
360 }
361
362 return NodeFactory(pointer);
363 }
364
InsertAfterChild(Node * afterThis,Node & addThis)365 Node* Node::InsertAfterChild(Node* afterThis, Node& addThis) {
366 if (addThis.Type() == TiXmlNode::DOCUMENT) {
367 TICPPTHROW("Node is a Document and can't be inserted");
368 }
369
370 // Increment reference count when adding to the tree
371 addThis.m_impRC->IncRef();
372
373 TiXmlNode* pointer = GetTiXmlPointer()->InsertAfterChild(
374 afterThis->GetTiXmlPointer(), *addThis.GetTiXmlPointer());
375
376 if (0 == pointer) {
377 TICPPTHROW("Node can't be inserted");
378 }
379
380 return NodeFactory(pointer);
381 }
382
ReplaceChild(Node * replaceThis,Node & withThis)383 Node* Node::ReplaceChild(Node* replaceThis, Node& withThis) {
384 if (withThis.Type() == TiXmlNode::DOCUMENT) {
385 TICPPTHROW("Node is a Document and can't be inserted");
386 }
387
388 // Increment reference count when adding to the tree
389 withThis.m_impRC->IncRef();
390
391 TiXmlNode* pointer = GetTiXmlPointer()->ReplaceChild(
392 replaceThis->GetTiXmlPointer(), *withThis.GetTiXmlPointer());
393
394 if (0 == pointer) {
395 TICPPTHROW("Node can't be inserted");
396 }
397
398 return NodeFactory(pointer);
399 }
400
RemoveChild(Node * removeThis)401 void Node::RemoveChild(Node* removeThis) {
402 if (!GetTiXmlPointer()->RemoveChild(removeThis->GetTiXmlPointer())) {
403 TICPPTHROW("Node to remove (" << removeThis->Value()
404 << ") is not a child of this Node ("
405 << Value()
406 << ")")
407 }
408 }
409
PreviousSibling(bool throwIfNoSiblings) const410 Node* Node::PreviousSibling(bool throwIfNoSiblings) const {
411 return PreviousSibling("", throwIfNoSiblings);
412 }
413
PreviousSibling(const std::string & value,bool throwIfNoSiblings) const414 Node* Node::PreviousSibling(const std::string& value,
415 bool throwIfNoSiblings) const {
416 return PreviousSibling(value.c_str(), throwIfNoSiblings);
417 }
418
PreviousSibling(const char * value,bool throwIfNoSiblings) const419 Node* Node::PreviousSibling(const char* value, bool throwIfNoSiblings) const {
420 TiXmlNode* sibling;
421
422 if (0 == strlen(value)) {
423 sibling = GetTiXmlPointer()->PreviousSibling();
424 } else {
425 sibling = GetTiXmlPointer()->PreviousSibling(value);
426 }
427
428 if ((0 == sibling) && throwIfNoSiblings) {
429 TICPPTHROW("No Siblings found with value, '" << value
430 << "', Prior to this Node ("
431 << Value()
432 << ")")
433 }
434
435 return NodeFactory(sibling, false);
436 }
437
NextSibling(bool throwIfNoSiblings) const438 Node* Node::NextSibling(bool throwIfNoSiblings) const {
439 return NextSibling("", throwIfNoSiblings);
440 }
441
NextSibling(const std::string & value,bool throwIfNoSiblings) const442 Node* Node::NextSibling(const std::string& value, bool throwIfNoSiblings) const {
443 return NextSibling(value.c_str(), throwIfNoSiblings);
444 }
445
NextSibling(const char * value,bool throwIfNoSiblings) const446 Node* Node::NextSibling(const char* value, bool throwIfNoSiblings) const {
447 TiXmlNode* sibling;
448
449 if (0 == strlen(value)) {
450 sibling = GetTiXmlPointer()->NextSibling();
451 } else {
452 sibling = GetTiXmlPointer()->NextSibling(value);
453 }
454
455 if ((0 == sibling) && throwIfNoSiblings) {
456 TICPPTHROW("No Siblings found with value, '" << value << "', After this Node ("
457 << Value()
458 << ")")
459 }
460
461 return NodeFactory(sibling, false);
462 }
463
NextSiblingElement(bool throwIfNoSiblings) const464 Element* Node::NextSiblingElement(bool throwIfNoSiblings) const {
465 return NextSiblingElement("", throwIfNoSiblings);
466 }
467
NextSiblingElement(const std::string & value,bool throwIfNoSiblings) const468 Element* Node::NextSiblingElement(const std::string& value,
469 bool throwIfNoSiblings) const {
470 return NextSiblingElement(value.c_str(), throwIfNoSiblings);
471 }
472
NextSiblingElement(const char * value,bool throwIfNoSiblings) const473 Element* Node::NextSiblingElement(const char* value,
474 bool throwIfNoSiblings) const {
475 TiXmlElement* sibling;
476
477 if (0 == strlen(value)) {
478 sibling = GetTiXmlPointer()->NextSiblingElement();
479 } else {
480 sibling = GetTiXmlPointer()->NextSiblingElement(value);
481 }
482
483 if (0 == sibling) {
484 if (throwIfNoSiblings) {
485 TICPPTHROW("No Element Siblings found with value, '"
486 << value
487 << "', After this Node ("
488 << Value()
489 << ")")
490 } else {
491 return 0;
492 }
493 }
494
495 Element* temp = new Element(sibling);
496 sibling->m_spawnedWrappers.push_back(temp);
497
498 return temp;
499 }
500
FirstChildElement(bool throwIfNoChildren) const501 Element* Node::FirstChildElement(bool throwIfNoChildren) const {
502 return FirstChildElement("", throwIfNoChildren);
503 }
504
FirstChildElement(const std::string & value,bool throwIfNoChildren) const505 Element* Node::FirstChildElement(const std::string& value,
506 bool throwIfNoChildren) const {
507 return FirstChildElement(value.c_str(), throwIfNoChildren);
508 }
509
FirstChildElement(const char * value,bool throwIfNoChildren) const510 Element* Node::FirstChildElement(const char* value, bool throwIfNoChildren) const {
511 TiXmlElement* element;
512
513 if (0 == strlen(value)) {
514 element = GetTiXmlPointer()->FirstChildElement();
515 } else {
516 element = GetTiXmlPointer()->FirstChildElement(value);
517 }
518
519 if (0 == element) {
520 if (throwIfNoChildren) {
521 TICPPTHROW("Element (" << Value()
522 << ") does NOT contain a child with the value of '"
523 << value
524 << "'")
525 } else {
526 return 0;
527 }
528 }
529
530 Element* temp = new Element(element);
531 element->m_spawnedWrappers.push_back(temp);
532
533 return temp;
534 }
535
Type() const536 int Node::Type() const { return GetTiXmlPointer()->Type(); }
537
GetDocument(bool throwIfNoDocument) const538 Document* Node::GetDocument(bool throwIfNoDocument) const {
539 TiXmlDocument* doc = GetTiXmlPointer()->GetDocument();
540
541 if (0 == doc) {
542 if (throwIfNoDocument) {
543 TICPPTHROW("This node (" << Value() << ") is not linked under a document")
544 } else {
545 return 0;
546 }
547 }
548
549 Document* temp = new Document(doc);
550 doc->m_spawnedWrappers.push_back(temp);
551
552 return temp;
553 }
554
NoChildren() const555 bool Node::NoChildren() const { return GetTiXmlPointer()->NoChildren(); }
556
ToDocument() const557 Document* Node::ToDocument() const {
558 TiXmlDocument* doc = GetTiXmlPointer()->ToDocument();
559
560 if (0 == doc) {
561 TICPPTHROW("This node (" << Value() << ") is not a Document")
562 }
563
564 Document* temp = new Document(doc);
565 doc->m_spawnedWrappers.push_back(temp);
566
567 return temp;
568 }
569
ToElement() const570 Element* Node::ToElement() const {
571 TiXmlElement* doc = GetTiXmlPointer()->ToElement();
572
573 if (0 == doc) {
574 TICPPTHROW("This node (" << Value() << ") is not a Element")
575 }
576
577 Element* temp = new Element(doc);
578 doc->m_spawnedWrappers.push_back(temp);
579
580 return temp;
581 }
582
ToComment() const583 Comment* Node::ToComment() const {
584 TiXmlComment* doc = GetTiXmlPointer()->ToComment();
585
586 if (0 == doc) {
587 TICPPTHROW("This node (" << Value() << ") is not a Comment")
588 }
589
590 Comment* temp = new Comment(doc);
591 doc->m_spawnedWrappers.push_back(temp);
592
593 return temp;
594 }
595
ToText() const596 Text* Node::ToText() const {
597 TiXmlText* doc = GetTiXmlPointer()->ToText();
598
599 if (0 == doc) {
600 TICPPTHROW("This node (" << Value() << ") is not a Text")
601 }
602
603 Text* temp = new Text(doc);
604 doc->m_spawnedWrappers.push_back(temp);
605
606 return temp;
607 }
608
ToDeclaration() const609 Declaration* Node::ToDeclaration() const {
610 TiXmlDeclaration* doc = GetTiXmlPointer()->ToDeclaration();
611
612 if (0 == doc) {
613 TICPPTHROW("This node (" << Value() << ") is not a Declaration")
614 }
615
616 Declaration* temp = new Declaration(doc);
617 doc->m_spawnedWrappers.push_back(temp);
618
619 return temp;
620 }
621
ToStylesheetReference() const622 StylesheetReference* Node::ToStylesheetReference() const {
623 TiXmlStylesheetReference* doc = GetTiXmlPointer()->ToStylesheetReference();
624
625 if (0 == doc) {
626 TICPPTHROW("This node (" << Value() << ") is not a StylesheetReference")
627 }
628
629 StylesheetReference* temp = new StylesheetReference(doc);
630 doc->m_spawnedWrappers.push_back(temp);
631
632 return temp;
633 }
634
Clone() const635 std::unique_ptr< Node > Node::Clone() const {
636 TiXmlNode* node = GetTiXmlPointer()->Clone();
637
638 if (0 == node) {
639 TICPPTHROW("Node could not be cloned");
640 }
641
642 std::unique_ptr< Node > temp(NodeFactory(node, false, false));
643
644 // Take ownership of the memory from TiXml
645 temp->m_impRC->InitRef();
646
647 return temp;
648 }
649
Accept(TiXmlVisitor * visitor) const650 bool Node::Accept(TiXmlVisitor* visitor) const {
651 return GetTiXmlPointer()->Accept(visitor);
652 }
653
654 //*****************************************************************************
655
Comment()656 Comment::Comment()
657 : NodeImp< TiXmlComment >(new TiXmlComment()) {
658 m_impRC->InitRef();
659 }
660
Comment(TiXmlComment * comment)661 Comment::Comment(TiXmlComment* comment)
662 : NodeImp< TiXmlComment >(comment) {}
663
Comment(const std::string & comment)664 Comment::Comment(const std::string& comment)
665 : NodeImp< TiXmlComment >(new TiXmlComment()) {
666 m_impRC->InitRef();
667 m_tiXmlPointer->SetValue(comment);
668 }
669
670 //*****************************************************************************
671
Text()672 Text::Text()
673 : NodeImp< TiXmlText >(new TiXmlText("")) {
674 m_impRC->InitRef();
675 }
676
Text(const std::string & value)677 Text::Text(const std::string& value)
678 : NodeImp< TiXmlText >(new TiXmlText(value)) {
679 m_impRC->InitRef();
680 }
681
Text(TiXmlText * text)682 Text::Text(TiXmlText* text)
683 : NodeImp< TiXmlText >(text) {}
684
685 //*****************************************************************************
686
Document()687 Document::Document()
688 : NodeImp< TiXmlDocument >(new TiXmlDocument()) {
689 m_impRC->InitRef();
690 }
691
Document(TiXmlDocument * document)692 Document::Document(TiXmlDocument* document)
693 : NodeImp< TiXmlDocument >(document) {}
694
Document(const char * documentName)695 Document::Document(const char* documentName)
696 : NodeImp< TiXmlDocument >(new TiXmlDocument(documentName)) {
697 m_impRC->InitRef();
698 }
699
Document(const std::string & documentName)700 Document::Document(const std::string& documentName)
701 : NodeImp< TiXmlDocument >(new TiXmlDocument(documentName)) {
702 m_impRC->InitRef();
703 }
704
LoadFile(TiXmlEncoding encoding)705 void Document::LoadFile(TiXmlEncoding encoding) {
706 if (!m_tiXmlPointer->LoadFile(encoding)) {
707 TICPPTHROW("Couldn't load " << m_tiXmlPointer->Value());
708 }
709 }
710
SaveFile() const711 void Document::SaveFile() const {
712 if (!m_tiXmlPointer->SaveFile()) {
713 TICPPTHROW("Couldn't save " << m_tiXmlPointer->Value());
714 }
715 }
716
LoadFile(const std::string & filename,TiXmlEncoding encoding)717 void Document::LoadFile(const std::string& filename, TiXmlEncoding encoding) {
718 if (!m_tiXmlPointer->LoadFile(filename.c_str(), encoding)) {
719 TICPPTHROW("Couldn't load " << filename);
720 }
721 }
722
LoadFile(const char * filename,TiXmlEncoding encoding)723 void Document::LoadFile(const char* filename, TiXmlEncoding encoding) {
724 if (!m_tiXmlPointer->LoadFile(filename, encoding)) {
725 TICPPTHROW("Couldn't load " << filename);
726 }
727 }
728
SaveFile(const std::string & filename) const729 void Document::SaveFile(const std::string& filename) const {
730 if (!m_tiXmlPointer->SaveFile(filename.c_str())) {
731 TICPPTHROW("Couldn't save " << filename);
732 }
733 }
734
Parse(const std::string & xml,bool throwIfParseError,TiXmlEncoding encoding)735 void Document::Parse(const std::string& xml,
736 bool throwIfParseError,
737 TiXmlEncoding encoding) {
738 m_tiXmlPointer->Parse(xml.c_str(), 0, encoding);
739
740 if (throwIfParseError && m_tiXmlPointer->Error()) {
741 TICPPTHROW("Error parsing xml.");
742 }
743 }
744
745 //*****************************************************************************
746
Element()747 Element::Element()
748 : NodeImp< TiXmlElement >(new TiXmlElement(
749 "DefaultValueCausedByCreatingAnElementWithNoParameters")) {
750 m_impRC->InitRef();
751 }
752
Element(const std::string & value)753 Element::Element(const std::string& value)
754 : NodeImp< TiXmlElement >(new TiXmlElement(value)) {
755 m_impRC->InitRef();
756 }
757
Element(const char * value)758 Element::Element(const char* value)
759 : NodeImp< TiXmlElement >(new TiXmlElement(value)) {
760 m_impRC->InitRef();
761 }
762
Element(TiXmlElement * element)763 Element::Element(TiXmlElement* element)
764 : NodeImp< TiXmlElement >(element) {}
765
FirstAttribute(bool throwIfNoAttributes) const766 Attribute* Element::FirstAttribute(bool throwIfNoAttributes) const {
767 ValidatePointer();
768 TiXmlAttribute* attribute = m_tiXmlPointer->FirstAttribute();
769
770 if ((0 == attribute) && throwIfNoAttributes) {
771 TICPPTHROW("This Element (" << Value() << ") has no attributes")
772 }
773
774 if (0 == attribute) {
775 if (throwIfNoAttributes) {
776 TICPPTHROW("Element (" << Value() << ") has no attributes")
777 } else {
778 return 0;
779 }
780 }
781
782 Attribute* temp = new Attribute(attribute);
783 attribute->m_spawnedWrappers.push_back(temp);
784
785 return temp;
786 }
787
LastAttribute(bool throwIfNoAttributes) const788 Attribute* Element::LastAttribute(bool throwIfNoAttributes) const {
789 ValidatePointer();
790 TiXmlAttribute* attribute = m_tiXmlPointer->LastAttribute();
791
792 if ((0 == attribute) && throwIfNoAttributes) {
793 TICPPTHROW("This Element (" << Value() << ") has no attributes")
794 }
795
796 if (0 == attribute) {
797 if (throwIfNoAttributes) {
798 TICPPTHROW("Element (" << Value() << ") has no attributes")
799 } else {
800 return 0;
801 }
802 }
803
804 Attribute* temp = new Attribute(attribute);
805 attribute->m_spawnedWrappers.push_back(temp);
806
807 return temp;
808 }
809
GetAttributeOrDefault(const std::string & name,const std::string & defaultValue) const810 std::string Element::GetAttributeOrDefault(const std::string& name,
811 const std::string& defaultValue) const {
812 std::string value;
813
814 if (!GetAttributeImp(name, &value)) {
815 return defaultValue;
816 }
817
818 return value;
819 }
820
GetAttribute(const std::string & name) const821 std::string Element::GetAttribute(const std::string& name) const {
822 return GetAttributeOrDefault(name, std::string());
823 }
824
HasAttribute(const std::string & name) const825 bool Element::HasAttribute(const std::string& name) const {
826 ValidatePointer();
827 return (0 != m_tiXmlPointer->Attribute(name.c_str()));
828 }
829
RemoveAttribute(const std::string & name)830 void Element::RemoveAttribute(const std::string& name) {
831 ValidatePointer();
832 m_tiXmlPointer->RemoveAttribute(name.c_str());
833 }
834
GetAttributeImp(const std::string & name,std::string * value) const835 bool Element::GetAttributeImp(const std::string& name, std::string* value) const {
836 ValidatePointer();
837
838 // Get value from TinyXML, if the attribute exists
839 const char* retVal = m_tiXmlPointer->Attribute(name.c_str());
840
841 // TinyXML returns nullptr if the attribute doesn't exist
842 if (0 == retVal) {
843 return false;
844 } else {
845 *value = retVal;
846 return true;
847 }
848 }
849
GetTextImp(std::string * value) const850 bool Element::GetTextImp(std::string* value) const {
851 ValidatePointer();
852
853 // Get value from TinyXML, if the attribute exists
854 const char* retVal = m_tiXmlPointer->GetText();
855
856 // TinyXML returns nullptr if the attribute doesn't exist
857 if (0 == retVal) {
858 return false;
859 } else {
860 *value = retVal;
861 return true;
862 }
863 }
864
865 //*****************************************************************************
866
Declaration()867 Declaration::Declaration()
868 : NodeImp< TiXmlDeclaration >(new TiXmlDeclaration()) {
869 m_impRC->InitRef();
870 }
871
Declaration(TiXmlDeclaration * declaration)872 Declaration::Declaration(TiXmlDeclaration* declaration)
873 : NodeImp< TiXmlDeclaration >(declaration) {}
874
Declaration(const std::string & version,const std::string & encoding,const std::string & standalone)875 Declaration::Declaration(const std::string& version,
876 const std::string& encoding,
877 const std::string& standalone)
878 : NodeImp< TiXmlDeclaration >(
879 new TiXmlDeclaration(version, encoding, standalone)) {
880 m_impRC->InitRef();
881 }
882
Version() const883 std::string Declaration::Version() const { return m_tiXmlPointer->Version(); }
884
Encoding() const885 std::string Declaration::Encoding() const { return m_tiXmlPointer->Encoding(); }
886
Standalone() const887 std::string Declaration::Standalone() const {
888 return m_tiXmlPointer->Standalone();
889 }
890
891 //*****************************************************************************
892
StylesheetReference()893 StylesheetReference::StylesheetReference()
894 : NodeImp< TiXmlStylesheetReference >(new TiXmlStylesheetReference()) {
895 m_impRC->InitRef();
896 }
897
StylesheetReference(TiXmlStylesheetReference * stylesheetReference)898 StylesheetReference::StylesheetReference(
899 TiXmlStylesheetReference* stylesheetReference)
900 : NodeImp< TiXmlStylesheetReference >(stylesheetReference) {}
901
StylesheetReference(const std::string & type,const std::string & href)902 StylesheetReference::StylesheetReference(const std::string& type,
903 const std::string& href)
904 : NodeImp< TiXmlStylesheetReference >(
905 new TiXmlStylesheetReference(type, href)) {
906 m_impRC->InitRef();
907 }
908
Type() const909 std::string StylesheetReference::Type() const { return m_tiXmlPointer->Type(); }
910
Href() const911 std::string StylesheetReference::Href() const { return m_tiXmlPointer->Href(); }
912
913 //*****************************************************************************
914
Exception(const std::string & details)915 Exception::Exception(const std::string& details)
916 : m_details(details) {}
917
~Exception()918 Exception::~Exception() throw() {}
919
what() const920 const char* Exception::what() const throw() { return m_details.c_str(); }
921
922 //*****************************************************************************
923
TiCppRC()924 TiCppRC::TiCppRC() {
925 // Spawn reference counter for this object
926 m_tiRC = new TiCppRCImp(this);
927 }
928
DeleteSpawnedWrappers()929 void TiCppRC::DeleteSpawnedWrappers() {
930 std::vector< Base* >::reverse_iterator wrapper;
931
932 for (wrapper = m_spawnedWrappers.rbegin(); wrapper != m_spawnedWrappers.rend();
933 ++wrapper) {
934 delete *wrapper;
935 }
936
937 m_spawnedWrappers.clear();
938 }
939
~TiCppRC()940 TiCppRC::~TiCppRC() {
941 DeleteSpawnedWrappers();
942
943 // Set pointer held by reference counter to nullptr
944 this->m_tiRC->Nullify();
945
946 // Decrement reference - so reference counter will delete itself if necessary
947 this->m_tiRC->DecRef();
948 }
949
950 //*****************************************************************************
951
TiCppRCImp(TiCppRC * tiCppRC)952 TiCppRCImp::TiCppRCImp(TiCppRC* tiCppRC)
953 : m_count(1)
954 , m_tiCppRC(tiCppRC) {}
955
IncRef()956 void TiCppRCImp::IncRef() { m_count++; }
957
DecRef()958 void TiCppRCImp::DecRef() {
959 m_count--;
960
961 if (0 == m_count) {
962 delete m_tiCppRC;
963 delete this;
964 }
965 }
966
InitRef()967 void TiCppRCImp::InitRef() { m_count = 1; }
968
Nullify()969 void TiCppRCImp::Nullify() { m_tiCppRC = 0; }
970
Get()971 TiCppRC* TiCppRCImp::Get() { return m_tiCppRC; }
972
IsNull()973 bool TiCppRCImp::IsNull() { return 0 == m_tiCppRC; }
974
975 #endif // TIXML_USE_TICPP
976