Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/external/tinyxml/ticpp.cpp @ 8116

Last change on this file since 8116 was 5781, checked in by rgrieder, 15 years ago

Reverted trunk again. We might want to find a way to delete these revisions again (x3n's changes are still available as diff in the commit mails).

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