Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/tinyxml/ticpp.h @ 2926

Last change on this file since 2926 was 2710, checked in by rgrieder, 16 years ago

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

  • Property svn:eol-style set to native
File size: 48.7 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/**
24@copydoc ticpp
25@file
26@author         Ryan Pusztai
27@author         Ryan Mulder
28@date           04/11/2006
29
30@version        0.04a by edam@waxworlds.org: based Exception based on std::exception; added stream
31                                        << and >> support; added Document::Parse(); bug fix; improved THROW() macro.
32@version        0.04 Added NodeImp class. Also made all the classes inherit from NodeImp.
33@version        0.03 Added Declaration class
34@version        0.02 Added Element class
35@version        0.01 Added Exception class, Document class
36
37@todo add UNKNOWN support. See ticpp::NodeFactory.
38@todo add TYPECOUNT support. See ticpp::NodeFactory.
39@todo Add a quick reference
40*/
41#ifdef TIXML_USE_TICPP
42
43#ifndef TICPP_INCLUDED
44#define TICPP_INCLUDED
45
46#include "tinyxml.h"
47#include <sstream>
48#include <vector>
49#include <memory>
50#include <exception>
51#include <typeinfo>
52
53/**
54@subpage ticpp is a TinyXML wrapper that uses a lot more C++ ideals.
55It throws exceptions, uses templates, is in its own name space, and
56<b>requires</b> STL (Standard Template Library). This is done to ease the use
57of getting values in and out of the xml.
58
59If you don't perfer to use some of the concepts just don't use it.
60It is just a wrapper that extends TinyXML. It doesn't actually change
61any of TinyXML.
62*/
63namespace ticpp
64{
65    /**
66        This is a ticpp exception class
67        */
68        class Exception : public std::exception
69        {
70        public:
71                /**
72                Construct an exception with a message
73                */
74                Exception( const std::string& details );
75                ~Exception() throw();
76
77                /// Override std::exception::what() to return m_details
78                const char* what() const throw();
79
80                std::string m_details; /**< Exception Details */
81        };
82
83        /**
84        This allows you to stream your exceptions in.
85        It will take care of the conversion     and throwing the exception.
86        */
87        #define TICPPTHROW( message )                                                                                   \
88        {                                                                                                                                               \
89                std::ostringstream full_message;                                                                        \
90                std::string file( __FILE__ );                                                                           \
91                file = file.substr( file.find_last_of( "\\/" ) + 1 );                           \
92                full_message << message << " <" << file << "@" << __LINE__ << ">";      \
93                full_message << BuildDetailedErrorString();                                                     \
94                throw Exception( full_message.str() );                                                          \
95        }
96
97        // Forward Declarations for Visitor, and others.
98        class Document;
99        class Element;
100        class Declaration;
101        class StylesheetReference;
102        class Text;
103        class Comment;
104        class Attribute;
105
106        /** Wrapper around TiXmlVisitor */
107        class Visitor : public TiXmlVisitor
108        {
109        public:
110                // Overload the TiXmlVisitor functions, wrap objects, call ticpp::Visitor functions
111                /// @internal
112                virtual bool VisitEnter( const TiXmlDocument& doc );
113                /// @internal
114                virtual bool VisitExit( const TiXmlDocument& doc );
115                /// @internal
116                virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
117                /// @internal
118                virtual bool VisitExit( const TiXmlElement& element );
119                /// @internal
120                virtual bool Visit( const TiXmlDeclaration& declaration );
121                /// @internal
122                virtual bool Visit( const TiXmlStylesheetReference& stylesheet );
123                /// @internal
124                virtual bool Visit( const TiXmlText& text );
125                /// @internal
126                virtual bool Visit( const TiXmlComment& comment );
127
128        public:
129                /// Visit a document.
130                virtual bool VisitEnter( const Document& /*doc*/ )                      { return true; }
131                /// Visit a document.
132                virtual bool VisitExit( const Document& /*doc*/ )                       { return true; }
133
134                /// Visit an element.
135                virtual bool VisitEnter( const Element& /*element*/, const Attribute* /*firstAttribute*/ )      { return true; }
136                /// Visit an element.
137                virtual bool VisitExit( const Element& /*element*/ )            { return true; }
138
139                /// Visit a declaration
140                virtual bool Visit( const Declaration& /*declaration*/ )        { return true; }
141                /// Visit a stylesheet reference
142                virtual bool Visit( const StylesheetReference& /*stylesheet*/ ) { return true; }
143                /// Visit a text node
144                virtual bool Visit( const Text& /*text*/ )                                      { return true; }
145                /// Visit a comment node
146                virtual bool Visit( const Comment& /*comment*/ )                        { return true; }
147        };
148
149        /** Wrapper around TiXmlBase */
150        class Base
151        {
152        public:
153
154                /**
155                Converts any class with a proper overload of the << opertor to a std::string
156                @param value The value to be converted
157                @throws Exception When value cannot be converted to a std::string
158                */
159                template < class T >
160                        std::string ToString( const T& value ) const
161                {
162                        std::stringstream convert;
163                        convert << value;
164                        if ( convert.fail() )
165                        {
166                                TICPPTHROW( "Could not convert value to text" );
167                        }
168                        return convert.str();
169                }
170
171                std::string ToString( const std::string& value ) const
172                {
173                        return value;
174                }
175
176                /**
177                Converts a std::string to any class with a proper overload of the >> opertor
178                @param temp                     The string to be converted
179                @param out      [OUT]   The container for the returned value
180                @throws Exception When temp cannot be converted to the target type
181                */
182                template < class T >
183                        void FromString( const std::string& temp, T* out ) const
184                {
185                        std::istringstream val( temp );
186                        val >> *out;
187
188                        if ( val.fail() )
189                        {
190                                TICPPTHROW( "Could not convert \"" << temp << "\" to target type" );
191                        }
192                }
193
194                /**
195                Specialization for std::string
196                */
197                void FromString( const std::string& temp, std::string* out ) const
198                {
199                        *out = temp;
200                }
201
202                /**
203                Return the position, in the original source file, of this node or attribute.
204                Wrapper around TiXmlBase::Row()
205                */
206                int Row() const
207                {
208                        return GetBasePointer()->Row();
209                }
210
211                /**
212                Return the position, in the original source file, of this node or attribute.
213                Wrapper around TiXmlBase::Row()
214                */
215                int Column() const
216                {
217                        return GetBasePointer()->Column();
218                }
219
220                /**
221                Compare internal TiXml pointers to determine is both are wrappers around the same node
222                */
223                bool operator == ( const Base& rhs ) const
224                {
225                        return ( GetBasePointer() == rhs.GetBasePointer() );
226                }
227               
228                /**
229                Compare internal TiXml pointers to determine is both are wrappers around the same node
230                */
231                bool operator != ( const Base& rhs ) const
232                {
233                        return ( GetBasePointer() != rhs.GetBasePointer() );
234                }
235               
236                /**
237                Builds detailed error string using TiXmlDocument::Error() and others
238                */
239                std::string BuildDetailedErrorString() const
240                {
241                        std::ostringstream full_message;
242                        #ifndef TICPP_NO_RTTI
243                        TiXmlNode* node = dynamic_cast< TiXmlNode* >( GetBasePointer() );
244                        if ( node != 0 )
245                        {
246                                TiXmlDocument* doc = node->GetDocument();
247                                if ( doc != 0 )
248                                {
249                                        if ( doc->Error() )
250                                        {
251                                                full_message    << "\nDescription: " << doc->ErrorDesc()
252                                                                                << "\nFile: " << (strlen( doc->Value() ) > 0 ? doc->Value() : "<unnamed-file>") 
253                                                                                << "\nLine: " << doc->ErrorRow() 
254                                                                                << "\nColumn: " << doc->ErrorCol();
255                                        }
256                                }
257                        }
258                        #endif
259                        return full_message.str();
260                }
261
262                /**
263                Destructor
264                */
265                virtual ~Base()
266                {
267                }
268
269        protected:
270                mutable TiCppRCImp* m_impRC;    /**< Holds status of internal TiXmlPointer - use this to determine if object has been deleted already */
271
272                /**
273                @internal
274                Updates the pointer to the reference counter to point at the counter in the new node.
275
276                @param node TiXmlBase containing the new reference counter
277                */
278                void SetImpRC( TiXmlBase* node )
279                {
280                        m_impRC = node->m_tiRC;
281                }
282
283                void ValidatePointer() const
284                {
285                        if ( m_impRC->IsNull() )
286                        {
287                                TICPPTHROW( "Internal TiXml Pointer is NULL" );
288                        }
289                }               
290
291                /**
292                @internal
293                Get internal TiXmlBase*
294                */
295                virtual TiXmlBase* GetBasePointer() const = 0;
296        };
297
298        /**
299        Wrapper around TiXmlAttribute
300        */
301        class Attribute : public Base
302        {
303        private:
304                TiXmlAttribute* m_tiXmlPointer;
305                TiXmlBase* GetBasePointer() const
306                {
307                        ValidatePointer();
308                        return m_tiXmlPointer;
309                }
310
311        public:
312                /**
313                Construct an empty attribute.
314                */
315                Attribute();
316
317                /**
318                Construct an attribute with @a name and @a value
319
320                @param name The name of the attribute
321                @param value The value of the attribute
322                */
323                Attribute( const std::string& name, const std::string& value );
324
325                /**
326                @internal
327                Construct an attribute with the internal pointer
328
329                @param attribute The internal pointer
330                */
331                Attribute( TiXmlAttribute* attribute );
332
333                /**
334                Get the value of this attribute
335                Uses Base::FromString to convert TiXmlAttribute::ValueStr from a std::string,
336                and puts it in the passed pointer.
337
338                @param value [OUT] A pointer to fill with the value
339                */
340                template < class T >
341                        void GetValue( T* value ) const
342                {
343                        ValidatePointer();
344                        FromString( m_tiXmlPointer->ValueStr(), value );
345                }
346
347                /**
348                Get the value of this attribute.
349                Simple wrapper for TiXmlAttribute::ValueStr.
350
351                @see GetValue
352                */
353                std::string Value() const;
354
355                /**
356                Set the value of this node.
357                Uses Base::ToString to convert value to a std::string, then calls TiXmlAttribute::SetValue.
358
359                @param value The value to set
360                */
361                template < class T >
362                        void SetValue( const T& value )
363                {
364                        ValidatePointer();
365                        m_tiXmlPointer->SetValue( ToString( value ) );
366                }
367
368                /**
369                Get the value of this attribute
370                Uses Base::FromString to convert TiXmlAttribute::Name from a std::string,
371                and puts it in the passed pointer.
372
373                @param name [OUT] A pointer to fill with the name
374                */
375                template < class T >
376                        void GetName( T* name ) const
377                {
378                        ValidatePointer();
379                        FromString( m_tiXmlPointer->Name(), name );
380                }
381
382                /**
383                Get the value of this attribute.
384                Simple wrapper for TiXmlAttribute::Name.
385
386                @see GetName
387                */
388                std::string Name() const;
389
390                /**
391                Set the value of this attribute.
392                Uses Base::ToString to convert @a name to a std::string, then calls TiXmlAttribute::SetName.
393
394                @param name The name to set
395                */
396                template < class T >
397                        void SetName( const T& name )
398                {
399                        ValidatePointer();
400                        m_tiXmlPointer->SetName( ToString( name ) );
401                }
402
403                /**
404                @internal
405                Updates the reference count for the old and new pointers.
406                */
407                void operator=( const Attribute& copy );
408
409                /**
410                @internal
411                Updates the reference count for the old and new pointers.
412                */
413                Attribute( const Attribute& copy );
414
415                /*
416                Decrements reference count.
417                */
418                ~Attribute();
419
420                /**
421                Get the next sibling attribute in the DOM.
422                */
423                Attribute* Next( bool throwIfNoAttribute = true ) const;
424
425                /**
426                Get the previous sibling attribute in the DOM.
427                */
428                Attribute* Previous( bool throwIfNoAttribute = true ) const;
429
430                /**
431                @internal
432                Just for Iterator<>
433
434                @param next [OUT] The pointer to the next valid attribute
435                @return true if there is a next attribute, false if not
436                */
437                void IterateNext( const std::string&, Attribute** next ) const;
438
439                /**
440                @internal
441                Just for Iterator<>
442
443                @param previous [OUT] The pointer to the previous valid attribute
444                @return true if there is a previous attribute, false if not
445                */
446                void IteratePrevious( const std::string&, Attribute** previous ) const;
447
448                /**
449                All TinyXml classes can print themselves to a filestream.
450                */
451                virtual void Print( FILE* file, int depth ) const;
452
453        private:
454
455                /**
456                @internal
457                Sets the internal pointer.
458                Saves a copy of the pointer to the RC object.
459
460                @param newPointer TiXmlAttribute* to set.
461                */
462                void SetTiXmlPointer( TiXmlAttribute* newPointer );
463        };
464
465        /**
466        Wrapper around TiXmlNode
467        */
468        class Node : public Base
469        {
470        public:
471
472                /**
473                Get the value of this node
474                Uses Base::FromString to convert TiXmlNode::ValueStr from a std::string,
475                and puts it in the passed pointer.
476
477                @param value [OUT] A pointer to fill with the value
478                */
479                template < class T >
480                        void GetValue( T* value) const
481                {
482                        FromString( GetTiXmlPointer()->ValueStr(), value );
483                }
484
485                /**
486                Get the value of this node.
487                Simple wrapper for TiXmlNode::ValueStr.
488
489                @see GetValue
490                */
491                std::string Value() const;
492
493                /**
494                Set the value of this node.
495                Uses Base::ToString to convert value to a std::string, then calls TiXmlNode::SetValue.
496
497                @param value The value to set
498                */
499                template < class T >
500                        void SetValue( const T& value )
501                {
502                        GetTiXmlPointer()->SetValue( ToString( value ) );
503                }
504
505                /**
506                Clear all Nodes below this.
507                Simple wrapper for TiXmlNode::Clear.
508                */
509                void Clear();
510
511                /**
512                The Parent of this Node.
513                Simple wrapper for TiXmlNode::Parent.
514
515                @param throwIfNoParent [DEF] If true, throws when Parent = NULL.
516                @return The parent of this node, NULL if there is no Parent.
517                @throws Exception When throwIfNoParent is true, and TiXmlNode::Parent returns Null.
518                */
519                Node* Parent( bool throwIfNoParent = true ) const;
520
521                /**
522                The first child of this node.
523
524                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no children.
525                @return Pointer to child, Null if no children and 'throwIfNoChildren' is false.
526                @throws Exception When throwIfNoChildren is true, and TiXmlNode::FirstChild returns Null.
527
528                @see TiXmlNode::FirstChild
529                */
530                Node* FirstChild( bool throwIfNoChildren = true ) const;
531
532                /**
533                @internal
534                The first child of this node with the matching @a value.
535
536                @overload
537                @param value                            Value to match.
538                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
539
540                @see FirstChild( bool throwIfNoChildren = true )
541                */
542                Node* FirstChild( const char* value, bool throwIfNoChildren = true ) const;
543
544                /**
545                The first child of this node with the matching @a value.
546
547                @overload
548                @param value                            Value to match.
549                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
550
551                @see FirstChild( const char* value, bool throwIfNoChildren = true )
552                */
553                Node* FirstChild( const std::string& value, bool throwIfNoChildren = true ) const;
554
555                /**
556                The last child of this node.
557
558                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no children.
559                @return Pointer to child, Null if no children and 'throwIfNoChildren' is false.
560                @throws Exception When throwIfNoChildren is true, and TiXmlNode::LastChild returns Null.
561
562                @see TiXmlNode::LastChild
563                */
564                Node* LastChild( bool throwIfNoChildren = true ) const;
565
566                /**
567                @internal
568                The last child of this node with the matching @a value.
569
570                @overload
571                @param value                            Value to match.
572                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
573
574                @see LastChild( bool throwIfNoChildren = true )
575                */
576                Node* LastChild( const char* value, bool throwIfNoChildren = true ) const;
577
578                /**
579                The last child of this node with the matching @a value.
580
581                @overload
582                @param value                            Value to match.
583                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
584
585                @see LastChild( const char* value, bool throwIfNoChildren = true )
586                */
587                Node* LastChild( const std::string& value, bool throwIfNoChildren = true ) const;
588
589                /**
590                An alternate way to walk the children of a node.
591                Simple wrapper for TiXmlNode::IterateChildren.
592
593                @param previous The previous Node* that was returned from IterateChildren.
594                @return NULL When there are no more children.
595                */
596                Node* IterateChildren( Node* previous ) const;
597
598                /**
599                This flavor of IterateChildren searches for children with a particular @a value.
600                Simple wrapper for TiXmlNode::IterateChildren.
601
602                @param value    The value you want to search for.
603                @param previous The previous Node* that was returned from IterateChildren.
604                @return NULL When there are no more children.
605                */
606                Node* IterateChildren( const std::string& value, Node* previous ) const;
607
608                /**
609                Adds a child past the LastChild.
610                Throws if you try to insert a document.
611
612                @note This takes a copy of @a addThis so it is not as efficiant as LinkEndChild.
613                @param addThis Node to insert.
614                @throws Exception When TiXmlNode::InsertEndChild returns Null
615
616                @see LinkEndChild
617                @see TiXmlNode::InsertEndChild
618                */
619                Node* InsertEndChild( Node& addThis );
620
621                /**
622                Adds a child past the LastChild.
623                Throws if you try to link a document.
624
625                @param childNode Node to link.
626                @throws Exception When TiXmlNode::LinkEndChild returns Null.
627
628                @see InsertEndChild
629                @see TiXmlNode::LinkEndChild
630                */
631                Node* LinkEndChild( Node* childNode );
632
633                /**
634                Adds a child before the specified child.
635                Throws if you try to insert a document.
636
637                @param beforeThis       Node that will have @a addThis linked before.
638                @param addThis          Node to insert before.
639                @throws Exception When TiXmlNode::InsertBeforeChild returns Null.
640
641                @see InsertAfterChild
642                @see TiXmlNode::InsertBeforeChild
643                */
644                Node* InsertBeforeChild( Node* beforeThis, Node& addThis );
645
646                /**
647                Adds a child after the specified child.
648                Throws if you try to insert a document.
649
650                @param afterThis        Node that will have @a addThis linked after.
651                @param addThis          Node to insert after.
652                @throws Exception When TiXmlNode::InsertAfterChild returns Null.
653
654                @see InsertBeforeChild
655                @see TiXmlNode::InsertAfterChild
656                */
657                Node* InsertAfterChild( Node* afterThis, Node& addThis );
658
659                /**
660                Replace a child of this node.
661                Throws if you try to replace with a document.
662
663                @param replaceThis      Node to replace.
664                @param withThis         Node that is replacing @a replaceThis.
665                @throws Exception When TiXmlNode::ReplaceChild returns Null.
666
667                @see TiXmlNode::ReplaceChild
668                */
669                Node* ReplaceChild( Node* replaceThis, Node& withThis );
670
671                /**
672                Delete a child of this node.
673
674                @param removeThis Node to delete.
675                @throws Exception When removeThis is not a child of this Node.
676
677                @see TiXmlNode::RemoveChild
678                */
679                void RemoveChild( Node* removeThis );
680
681                /**
682                Navigate to a sibling node.
683                Wrapper around TiXmlNode::PreviousSibling.
684
685                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
686                @return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
687                @throws Exception When TiXmlNode::PreviousSibling returns Null and 'throwIfNoSiblings' is true.
688                */
689                Node* PreviousSibling( bool throwIfNoSiblings = true ) const;
690
691                /**
692                Navigate to a sibling node with the given @a value.
693
694                @overload
695                @param value The value of the node to look for.
696                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
697
698                @see PreviousSibling( bool throwIfNoSiblings )
699                */
700                Node* PreviousSibling( const std::string& value, bool throwIfNoSiblings = true ) const;
701
702                /**
703                @internal
704                Navigate to a sibling node with the given @a value.
705
706                @overload
707                @param value The value of the node to look for.
708                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
709
710                @see PreviousSibling( const std::string& value, bool throwIfNoSiblings )
711                */
712                Node* PreviousSibling( const char* value, bool throwIfNoSiblings = true ) const;
713
714                /**
715                Navigate to a sibling node.
716                Wrapper around TiXmlNode::NextSibling.
717
718                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
719                @return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
720                @throws Exception When TiXmlNode::NextSibling returns Null and 'throwIfNoSiblings' is true.
721                */
722                Node* NextSibling( bool throwIfNoSiblings = true ) const;
723
724                /**
725                Navigate to a sibling node with the given @a value.
726
727                @overload
728                @param value The value of the node to look for.
729                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
730
731                @see NextSibling( bool throwIfNoSiblings )
732                */
733                Node* NextSibling( const std::string& value, bool throwIfNoSiblings = true ) const;
734
735                /**
736                @internal
737                Navigate to a sibling node with the given @a value.
738
739                @overload
740                @param value The value of the node to look for.
741                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
742
743                @see NextSibling( const std::string& value, bool throwIfNoSiblings )
744                */
745                Node* NextSibling( const char* value, bool throwIfNoSiblings = true ) const;
746
747                /**
748                @internal
749                Just for Iterator<>
750
751                @param value The value of nodes to iterate through
752                @param next [OUT] The pointer to the first valid node
753                */
754                template < class T >
755                        void IterateFirst( const std::string& value, T** first ) const
756                {
757                        *first = 0;
758                        for( Node* child = FirstChild( value, false ); child; child = child->NextSibling( value, false ) )
759                        {
760                                *first = dynamic_cast< T* >( child );
761                                if ( 0 != *first )
762                                {
763                                        return;
764                                }
765                        }
766                }
767
768                virtual void IterateFirst( const std::string&, Attribute** ) const
769                {
770                        TICPPTHROW( "Attributes can only be iterated with Elements." )
771                }
772
773                /**
774                @internal
775                Just for Iterator<>
776
777                @param value The value of nodes to iterate through
778                @param next [OUT] The pointer to the next valid node
779                */
780                template < class T >
781                        void IterateNext( const std::string& value, T** next ) const
782                {
783                        Node* sibling = NextSibling( value, false );
784                        *next = dynamic_cast< T* >( sibling );
785
786                        while ( ( 0 != sibling ) && ( 0 == *next ) )
787                        {
788                                sibling = sibling->NextSibling( value, false );
789                                *next = dynamic_cast< T* >( sibling );
790                        }
791                }
792
793                /**
794                @internal
795                Just for Iterator<>
796
797                @param value The value of nodes to iterate through
798                @param previous [OUT] The pointer to the previous valid node
799                */
800                template < class T >
801                        void IteratePrevious( const std::string& value, T** previous  ) const
802                {
803                        Node* sibling = PreviousSibling( value, false );
804                        *previous = dynamic_cast< T* >( sibling );
805
806                        while ( ( 0 != sibling ) && ( 0 == *previous ) )
807                        {
808                                sibling = sibling->PreviousSibling( value, false );
809                                *previous = dynamic_cast< T* >( sibling );
810                        }
811                }
812
813                /**
814                Navigate to a sibling element.
815                Wrapper around TiXmlNode::NextSibling.
816
817                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling element.
818                @return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
819                @throws Exception When TiXmlNode::NextSibling returns Null and 'throwIfNoSiblings' is true.
820                */
821                Element* NextSiblingElement( bool throwIfNoSiblings = true ) const;
822
823                /**
824                Navigate to a sibling element with the given @a value.
825
826                @overload
827                @param value The value of the element to look for.
828                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling elements.
829                @see NextSiblingElement( bool throwIfNoSiblings )
830                */
831                Element* NextSiblingElement( const std::string& value, bool throwIfNoSiblings = true ) const;
832
833                /**
834                @internal
835                Navigate to a sibling element with the given @a value.
836
837                @overload
838                @param value The value of the element to look for.
839                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling elements.
840
841                @see NextSiblingElement( const std::string& value, bool throwIfNoSiblings )
842                */
843                Element* NextSiblingElement( const char* value, bool throwIfNoSiblings = true ) const;
844
845                /**
846                The first child element of this node.
847
848                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
849                @return Pointer to child, Null if no element children and 'throwIfNoChildren' is false.
850                @throws Exception When throwIfNoChildren is true, and TiXmlNode::FirstChildElement returns Null.
851
852                @see TiXmlNode::FirstChildElement
853                */
854                Element* FirstChildElement( bool throwIfNoChildren = true ) const;
855
856                /**
857                @internal
858                The first child element of this node with the matching @a value.
859
860                @overload
861                @param value Value to match.
862                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
863
864                @see FirstChildElement( bool throwIfNoChildren = true )
865                */
866                Element* FirstChildElement( const char* value, bool throwIfNoChildren = true ) const;
867
868                /**
869                The first child element of this node with the matching @a value.
870
871                @overload
872                @param value Value to match.
873                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
874
875                @see FirstChildElement( const char* value, bool throwIfNoChildren = true )
876                */
877                Element* FirstChildElement( const std::string& value, bool throwIfNoChildren = true ) const;
878
879                /**
880                Query the type (as TiXmlNode::NodeType ) of this node.
881                */
882                int Type() const;
883
884                /**
885                Return a pointer to the Document this node lives in.
886
887                @param throwIfNoDocument [DEF] If true, will throw an exception if this node is not linked under a Document.
888                @return A pointer to the Document this node lives in, NULL if not linked under a Document, and 'throwIfNoDocument' is false.
889                @throws Exception When this node is not linked under a Document and 'throwIfNoDocument' is true.
890                */
891                Document* GetDocument( bool throwIfNoDocument = true ) const;
892
893                /**
894                Check if this node has no children.
895
896                @return true if this node has no children.
897                */
898                bool NoChildren() const;
899
900                #ifndef TICPP_NO_RTTI
901                /**
902                Pointer conversion ( NOT OBJECT CONVERSION ) - replaces TiXmlNode::ToElement, TiXmlNode::ToDocument, TiXmlNode::ToComment, etc.
903
904                @throws Exception When the target is not an object of class T
905                @warning Some ancient compilers do not support explicit specification of member template arguments, which this depends on ( e.g. VC6 ).
906                */
907                template < class T >
908                        T* To() const
909                {
910                        T* pointer = dynamic_cast< T* >( this );
911                        if ( 0 == pointer )
912                        {
913                                std::string thisType = typeid( this ).name();
914                                std::string targetType = typeid( T ).name();
915                                std::string thatType = typeid( *this ).name();
916                                TICPPTHROW( "The " << thisType.substr( 6 ) << " could not be casted to a " << targetType.substr( 6 )
917                                        << " *, because the target object is not a " << targetType.substr( 6 ) << ". (It is a " << thatType.substr( 6 ) << ")" );
918                        }
919                        return pointer;
920                }
921                #endif
922
923                /**
924                Pointer conversion - replaces TiXmlNode::ToDocument.
925
926                @throws Exception When this node is not a Document.
927                */
928                Document* ToDocument() const;
929
930                /**
931                Pointer conversion - replaces TiXmlNode::ToElement.
932
933                @throws Exception When this node is not a Element.
934                */
935                Element* ToElement() const;
936
937                /**
938                Pointer conversion - replaces TiXmlNode::ToComment.
939
940                @throws Exception When this node is not a Comment.
941                */
942                Comment* ToComment() const;
943
944                /**
945                Pointer conversion - replaces TiXmlNode::ToText.
946
947                @throws Exception When this node is not a Text.
948                */
949                Text* ToText() const;
950
951                /**
952                Pointer conversion - replaces TiXmlNode::ToDeclaration.
953
954                @throws Exception When this node is not a Declaration.
955                */
956                Declaration* ToDeclaration() const;
957
958                /**
959                Pointer conversion - replaces TiXmlNode::ToStylesheetReference.
960
961                @throws Exception When this node is not a StylesheetReference.
962                */
963                StylesheetReference* ToStylesheetReference() const;
964
965                /**
966                Create an exact duplicate of this node and return it.
967
968                @note Using auto_ptr to manage the memory declared on the heap by TiXmlNode::Clone.
969                @code
970                // Now using clone
971                ticpp::Document doc( "C:\\Test.xml" );
972                ticpp::Node* sectionToClone;
973                sectionToClone = doc.FirstChild( "settings" );
974                std::auto_ptr< ticpp::Node > clonedNode = sectionToClone->Clone();
975                // Now you can use the clone.
976                ticpp::Node* node2 = clonedNode->FirstChildElement()->FirstChild();
977                ...
978                // After the variable clonedNode goes out of scope it will automatically be cleaned up.
979                @endcode
980                @return Pointer the duplicate node.
981                */
982                std::auto_ptr< Node > Clone() const;
983
984                /**
985                Accept a hierchical visit the nodes in the TinyXML DOM.
986                @return The boolean returned by the visitor.
987                */
988                bool Accept( TiXmlVisitor* visitor ) const;
989
990                /**
991                Stream input operator.
992                */
993                friend std::istream& operator >>( std::istream& in, Node& base )
994                {
995                        in >> *base.GetTiXmlPointer();
996                        return in;
997                }
998
999                /**
1000                Stream output operator.
1001                */
1002                friend std::ostream& operator <<( std::ostream& out, const Node& base )
1003                {
1004                        out << *base.GetTiXmlPointer();
1005                        return out;
1006                }
1007
1008        protected:
1009                /**
1010                @internal
1011                Allows NodeImp to use Node*'s.
1012                */
1013                virtual TiXmlNode* GetTiXmlPointer() const = 0;
1014
1015                TiXmlBase* GetBasePointer() const
1016                {
1017                        return GetTiXmlPointer();
1018                }
1019
1020                /**
1021                @internal
1022                Constructs the correct child of Node, based on the Type of the TiXmlNode*.
1023                */
1024                Node* NodeFactory( TiXmlNode* tiXmlNode, bool throwIfNull = true, bool rememberSpawnedWrapper = true ) const;
1025
1026        };
1027
1028        /** Iterator for conveniently stepping through Nodes and Attributes.
1029        TinyXML++ introduces iterators:
1030        @code
1031        ticpp::Iterator< ticpp::Node > child;
1032        for ( child = child.begin( parent ); child != child.end(); child++ )
1033        @endcode
1034
1035        Iterators have the added advantage of filtering by type:
1036        @code
1037        // Only iterates through Comment nodes
1038        ticpp::Iterator< ticpp::Comment > child;
1039        for ( child = child.begin( parent ); child != child.end(); child++ )
1040        @endcode
1041
1042        @code
1043        // Only iterates through Element nodes with value "ElementValue"
1044        ticpp::Iterator< ticpp::Element > child( "ElementValue" );
1045        for ( child = child.begin( parent ); child != child.end(); child++ )
1046        @endcode
1047
1048        Finally, Iterators also work with Attributes
1049        @code
1050        ticpp::Iterator< ticpp::Attribute > attribute;
1051        for ( attribute = attribute.begin( element ); attribute != attribute.end(); attribute++ )
1052        @endcode
1053        */
1054        template < class T = Node >
1055                class Iterator
1056        {
1057        private:
1058                T* m_p;                                 /**< Internal Pointer */
1059                std::string m_value;    /**< Value for NextSibling  calls */
1060
1061        public:
1062
1063                /**
1064                For for loop comparisons.
1065                @param parent The parent of the nodes to iterate.
1066                @return The first child of type T.
1067                @code
1068                ticpp::Iterator< ticpp::Node > child;
1069                for ( child = child.begin( parent ); child != child.end(); child++ )
1070                @endcode
1071                */
1072                T* begin( const Node* parent ) const
1073                {
1074                        T* pointer;
1075                        parent->IterateFirst( m_value, &pointer );
1076                        return pointer;
1077                }
1078
1079                /**
1080                For for loop comparisons.
1081                @return NULL
1082                @code
1083                ticpp::Iterator< ticpp::Node > child;
1084                for ( child = child.begin( parent ); child != child.end(); child++ )
1085                @endcode
1086                */
1087                T* end() const
1088                {
1089                        return 0;
1090                }
1091
1092                /** Constructor.
1093                @param value If not empty, this iterator will only visit nodes with matching value.
1094                @code
1095                // Only iterates through Element nodes with value "ElementValue"
1096                ticpp::Iterator< ticpp::Element > child( "ElementValue" );
1097                for ( child = child.begin( parent ); child != child.end(); child++ )
1098                @endcode
1099                */
1100                Iterator( const std::string& value = "" )
1101                        : m_p( 0 ), m_value( value )
1102                {
1103                }
1104
1105                /// Constructor
1106                Iterator( T* node, const std::string& value = "" )
1107                        : m_p( node ), m_value( value )
1108                {
1109                }
1110
1111                /// Constructor
1112                Iterator( const Iterator& it )
1113                        : m_p( it.m_p ), m_value( it.m_value )
1114                {
1115                }
1116
1117                /**
1118                Gets internal pointer.
1119                @return The internal pointer.
1120                */
1121                T* Get() const
1122                {
1123                        return m_p;
1124                }
1125
1126                /** Sets internal pointer */
1127                Iterator& operator=( const Iterator& it )
1128                {
1129                        m_p = it.m_p;
1130                        m_value = it.m_value;
1131                        return *this;
1132                }
1133
1134                /** Sets internal pointer */
1135                Iterator& operator=( T* p )
1136                {
1137                        m_p = p;
1138                        return *this;
1139                }
1140
1141                /** Sets internal pointer to the Next Sibling, or Iterator::END, if there are no more siblings */
1142                Iterator& operator++()
1143                {
1144                        m_p->IterateNext( m_value, &m_p );
1145                        return *this;
1146                }
1147
1148                /** Sets internal pointer to the Next Sibling, or Iterator::END, if there are no more siblings */
1149                Iterator operator++(int)
1150                {
1151                        Iterator tmp(*this);
1152                        ++(*this);
1153                        return tmp;
1154                }
1155
1156                /** Sets internal pointer to the Previous Sibling, or Iterator::END, if there are no prior siblings */
1157                Iterator& operator--()
1158                {
1159                        m_p->IteratePrevious( m_value, &m_p );
1160                        return *this;
1161                }
1162
1163                /** Sets internal pointer to the Previous Sibling, or Iterator::END, if there are no prior siblings */
1164                Iterator operator--(int)
1165                {                       
1166                        Iterator tmp(*this);
1167                        --(*this);
1168                        return tmp;
1169                }
1170
1171                /** Compares internal pointer */
1172                bool operator!=( const T* p ) const
1173                {
1174                        if ( m_p == p )
1175                        {
1176                                return false;
1177                        }
1178                        if ( 0 == m_p || 0 == p )
1179                        {
1180                                return true;
1181                        }
1182                        return *m_p != *p;
1183                }
1184
1185                /** Compares internal pointer */
1186                bool operator!=( const Iterator& it ) const
1187                {
1188                        return operator!=( it.m_p );
1189                }
1190
1191                /** Compares internal pointer* */
1192                bool operator==( T* p ) const
1193                {
1194                        if ( m_p == p )
1195                        {
1196                                return true;
1197                        }
1198                        if ( 0 == m_p || 0 == p )
1199                        {
1200                                return false;
1201                        }
1202                        return *m_p == *p;
1203                }
1204
1205                /** Compares internal pointer */
1206                bool operator==( const Iterator& it ) const
1207                {
1208                        return operator==( it.m_p );
1209                }
1210
1211                /** So Iterator behaves like a STL iterator */
1212                T* operator->() const
1213                {
1214                        return m_p;
1215                }
1216
1217                /** So Iterator behaves like a STL iterator */
1218                T& operator*() const
1219                {
1220                        return *m_p;
1221                }
1222        };
1223
1224        /** Implementation of Node wrapper */
1225        template < class T >
1226                class NodeImp : public Node
1227        {
1228        protected:
1229
1230                T* m_tiXmlPointer;              /**< Internal pointer to the TiXml Class which is being wrapped */
1231
1232    public:
1233                /**
1234                @internal
1235                Gets the internal TinyXML pointer.
1236
1237                @returns The internal TiXmlNode*.
1238                */
1239                TiXmlNode* GetTiXmlPointer() const
1240                {
1241                        ValidatePointer();
1242                        return m_tiXmlPointer;
1243                }
1244    protected:
1245
1246                /**
1247                @internal
1248                Sets the internal pointer.
1249                Saves a copy of the pointer to the RC object.
1250
1251                @param newPointer TiXmlNode* to set.
1252                */
1253                void SetTiXmlPointer( T* newPointer )
1254                {
1255                        m_tiXmlPointer = newPointer;
1256                        SetImpRC( newPointer );
1257                }
1258
1259                /**
1260                @internal
1261                Constructor used by child classes.
1262                */
1263                NodeImp( T* tiXmlPointer )
1264                {
1265                        // Check for NULL pointers
1266                        if ( 0 == tiXmlPointer )
1267                        {
1268                                #ifdef TICPP_NO_RTTI
1269                                        TICPPTHROW( "Can not create TinyXML objext" );
1270                                #else
1271                                        TICPPTHROW( "Can not create a " << typeid( T ).name() );
1272                                #endif
1273                        }
1274                        SetTiXmlPointer( tiXmlPointer );
1275                        m_impRC->IncRef();
1276                }
1277
1278                /**
1279                @internal
1280                Updates the reference count for the old and new pointers.
1281                In addition, the spawnedWrappers must be cleared out before a new TiXml object is loaded in.
1282                */
1283                virtual void operator=( const NodeImp<T>& copy )
1284                {
1285                        // Dropping the reference to the old object
1286                        this->m_impRC->DecRef();
1287
1288                        // Pointing to the new Object
1289                        SetTiXmlPointer( copy.m_tiXmlPointer );
1290
1291                        // The internal tixml pointer changed in the above line
1292                        this->m_impRC->IncRef();
1293                }
1294
1295                /**
1296                @internal
1297                Updates the reference count for the old and new pointers.
1298                In addition, the spawnedWrappers must be cleared out before a new TiXml object is loaded in
1299                */
1300                NodeImp( const NodeImp<T>& copy ) : Node( copy )
1301                {
1302                        // Pointing to the new Object
1303                        SetTiXmlPointer( copy.m_tiXmlPointer );
1304
1305                        // The internal tixml pointer changed in the above line
1306                        this->m_impRC->IncRef();
1307                }
1308
1309        public:
1310
1311                /*
1312                Deletes the spawned wrapper objects.
1313                Decrements reference count.
1314                */
1315                virtual ~NodeImp()
1316                {
1317                        m_impRC->DecRef();
1318                }
1319        };
1320
1321        /** Wrapper around TiXmlComment */
1322        class Comment : public NodeImp< TiXmlComment >
1323        {
1324        public:
1325
1326                /**
1327                Constructor.
1328                */
1329                Comment();
1330
1331                /**
1332                Constructor.
1333                */
1334                Comment( TiXmlComment* comment );
1335
1336                /**
1337                Constructor.
1338                */
1339                Comment( const std::string& comment );
1340        };
1341
1342        /** Wrapper around TiXmlText */
1343        class Text : public NodeImp< TiXmlText >
1344        {
1345        public:
1346
1347                /**
1348                Constructor.
1349                */
1350                Text();
1351
1352                /**
1353                Constructor.
1354                @overload
1355                */
1356                Text( TiXmlText* text );
1357
1358                /**
1359                Constructor.
1360                @overload
1361                */
1362                Text( const std::string& value );
1363
1364                /**
1365                Streams value into a string and creates a Text with it.
1366                Uses ToString to covert the parameter to a string.
1367
1368                @param value The value of the Text node.
1369                @throws Exception
1370
1371                @see TiXmlText
1372        */
1373                template < class T >
1374                        Text( const T& value )
1375                                : NodeImp< TiXmlText >( new TiXmlText( ToString( value ) ) )
1376                {
1377                        m_impRC->InitRef();
1378                }
1379        };
1380
1381        /** Wrapper around TiXmlDocument */
1382        class Document : public NodeImp< TiXmlDocument >
1383        {
1384        public:
1385                /**
1386                Default Constructor.
1387                Create an empty document, that has no name.
1388                */
1389                Document();
1390
1391                /**
1392                Constructor.
1393                */
1394                Document( TiXmlDocument* document );
1395
1396                /**
1397                Constructor.
1398                */
1399                Document( const char* documentName );
1400
1401                /**
1402                Constructor.
1403                Create a document with a name. The name of the document is also the filename of the xml.
1404
1405                @param documentName Name to set in the Document.
1406                */
1407                Document( const std::string& documentName );
1408
1409                /**
1410                Load a file using the current document value. Throws if load is unsuccessful.
1411
1412                @param encoding Sets the documents encoding.
1413                @see TiXmlEncoding
1414                @throws Exception
1415                */
1416                void LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1417
1418                /**
1419                Save a file using the current document value. Throws if it can't save the file.
1420
1421                @throws Exception
1422                */
1423                void SaveFile() const;
1424
1425                /**
1426                Load a file using the given filename. Throws if load is unsuccessful.
1427
1428                @param filename File to load.
1429                @param encoding Sets the documents encoding.
1430                @see TiXmlEncoding
1431                @throws Exception
1432                */
1433                void LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1434
1435                /**
1436                @copydoc Document::LoadFile( const std::string&, TiXmlEncoding )
1437                */
1438                void LoadFile( const char* filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1439
1440                /**
1441                Save a file using the given filename. Throws if it can't save the file.
1442
1443                @param filename File to save.
1444                @throws Exception
1445                */
1446                void SaveFile( const std::string& filename ) const;
1447
1448                /**
1449                Parse the given xml data.
1450
1451                @param xml Xml to parse.
1452                @param throwIfParseError [DEF] If true, throws when there is a parse error.
1453                @param encoding Sets the documents encoding.
1454                @throws Exception
1455                */
1456                void Parse( const std::string& xml, bool throwIfParseError = true, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1457        };
1458
1459        /** Wrapper around TiXmlElement */
1460        class Element : public NodeImp< TiXmlElement >
1461        {
1462        public:
1463                /**
1464                Default Constructor.
1465                */
1466                Element();
1467
1468                /**
1469                Default Constructor. Initializes all the variables.
1470                @param value The value of the element.
1471                */
1472                Element( const std::string& value );
1473
1474                /**
1475                Default Constructor. Initializes all the variables.
1476                @param value The value of the element.
1477                */
1478                Element( const char* value );
1479
1480                /**
1481                Constructor.
1482                */
1483                Element( TiXmlElement* element );
1484
1485                /**
1486                Constructor that allows you to set the element text
1487                @param value The value of the element.
1488                @param text The text to set.
1489                */
1490                template < class T >
1491                        Element( const std::string& value, const T& text )
1492                        : NodeImp< TiXmlElement >( new TiXmlElement( value ) )
1493                {
1494                        m_impRC->InitRef();
1495                        SetText( text );
1496                }
1497
1498                /**
1499                Access the first attribute in this element.
1500
1501                @param throwIfNoAttributes [DEF] If true, throws when there are no attributes
1502                @return The first attribute, NULL if there are none and @a throwIfNoAttributes is true
1503                */
1504                Attribute* FirstAttribute( bool throwIfNoAttributes = true ) const;
1505
1506                /**
1507                Access the last attribute in this element.
1508
1509                @param throwIfNoAttributes [DEF] If true, throws when there are no attributes
1510                @return The last attribute, NULL if there are none and @a throwIfNoAttributes is true
1511                */
1512                Attribute* LastAttribute( bool throwIfNoAttributes = true ) const;
1513
1514                /**
1515                @internal
1516                Just for Iterator<>
1517
1518                @param value The value of nodes to iterate through
1519                @param next [OUT] The pointer to the first valid node
1520                */
1521                void IterateFirst( const std::string&, Attribute** first ) const
1522                {
1523                        *first = 0;
1524                        for( Attribute* child = FirstAttribute( false ); child; child = child->Next( false ) )
1525                        {
1526                                *first = dynamic_cast< Attribute* >( child );
1527                                if ( 0 != *first )
1528                                {
1529                                        return;
1530                                }
1531                        }
1532                }
1533
1534                /**
1535                Sets an attribute of name to a given value.
1536                The attribute will be created if it does not exist, or changed if it does.
1537                Uses ToString to convert the @a value to a string, so there is no need to use any other SetAttribute methods.
1538
1539                @see GetAttribute
1540                */
1541                template < class T >
1542                        void SetAttribute ( const std::string& name, const T& value )
1543                {
1544                        ValidatePointer();
1545                        m_tiXmlPointer->SetAttribute( name, ToString( value ) );
1546                }
1547
1548                /**
1549                Gets the text of an Element.
1550
1551                @param throwIfNotFound  [DEF]   If true, will throw an exception if there is no text in this element
1552                @note This only works if the Text is the FirstChild node
1553                @throws Exception When there is no text and throwIfNotFound is true
1554
1555                @see GetText( T* value, bool throwIfNotFound = false )
1556                @see GetTextOrDefault
1557                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1558                @see TiXmlElement::GetText
1559                */
1560                std::string GetText( bool throwIfNotFound = true ) const
1561                {
1562                        // Get the element's text value as a std::string
1563                        std::string temp;
1564                        if ( !GetTextImp( &temp ) )
1565                        {
1566                                if ( throwIfNotFound )
1567                                {
1568                                        TICPPTHROW( "Text does not exists in the current element" );
1569                                }
1570                        }
1571
1572                        return temp;
1573                }
1574
1575                /**
1576                Gets the text of an Element, if it doesn't exist it will return the defaultValue.
1577
1578                @param defaultValue                     What to put in 'value' if there is no text in this element
1579                @note This only works if the Text is the FirstChild node
1580
1581                @see GetText
1582                @see GetText( T* value, bool throwIfNotFound = false )
1583                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1584                @see TiXmlElement::GetText
1585                */
1586                std::string GetTextOrDefault( const std::string& defaultValue ) const
1587                {
1588                        // Get the element's text value as a std::string
1589                        std::string temp;
1590                        if ( !GetTextImp( &temp ) )
1591                        {
1592                                return defaultValue;
1593                        }
1594
1595                        return temp;
1596                }
1597
1598                /**
1599                Gets the text value of an Element, if it doesn't exist it will return the defaultValue.
1600                Uses FromString to convert the string to the type of choice
1601
1602                @param value            [OUT]   The container for the returned value
1603                @param defaultValue                     What to put in 'value' if there is no text in this element
1604                @note This is different than GetText() in that it will covert the text to what ever type you want.
1605                @note This only works if the Text is the FirstChild node
1606
1607                @see GetText
1608                @see GetText( T* value, bool throwIfNotFound = false )
1609                @see GetTextOrDefault( const std::string& defaultValue )
1610                @see TiXmlElement::GetText
1611                */
1612                template < class T, class DefaultT >
1613                        void GetTextOrDefault( T* value, const DefaultT& defaultValue ) const
1614                {
1615                        // Get the element's text value as a std::string
1616                        std::string temp;
1617                        if ( !GetTextImp( &temp ) )
1618                        {
1619                                // The text value does not exist - set value to the default
1620                                *value = defaultValue;
1621                                return;
1622                        }
1623
1624                        // Stream the value from the string to T
1625                        FromString( temp, value );
1626                }
1627
1628                /**
1629                Gets the text of an Element.
1630                Uses FromString to convert the string to the type of choice.
1631
1632                @param value                    [OUT]   The container for the returned value
1633                @param throwIfNotFound  [DEF]   If true, will throw an exception if there is no text in this element
1634                @note This is different than GetText() in that it will covert the text to what ever type you want
1635                @note This only works if the Text is the FirstChild node
1636                @throws Exception When there is no text and throwIfNotFound is true
1637
1638                @see GetText
1639                @see GetTextOrDefault
1640                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1641                @see TiXmlElement::GetText
1642                */
1643                template< class T >
1644                        void GetText( T* value, bool throwIfNotFound = true ) const
1645                {
1646                        // Get the element's text value as a std::string
1647                        std::string temp;
1648                        if ( !GetTextImp( &temp ) )
1649                        {
1650                                if ( throwIfNotFound )
1651                                {
1652                                        TICPPTHROW( "Text does not exists in the current element" );
1653                                }
1654                                else
1655                                {
1656                                        return;
1657                                }
1658                        }
1659
1660                        // Stream the value from the string to T
1661                        FromString( temp, value );
1662                }
1663
1664                /**
1665                Convenience function to set the text of an element.
1666                Creates a Text node and inserts it as the first child.
1667                Uses ToString to convert the parameter to a string.
1668
1669                @param value The text to set.
1670                */
1671                template < class T >
1672                        void SetText( const T& value )
1673                {
1674                        ValidatePointer();
1675                        std::string temp = ToString( value );
1676
1677                        if ( m_tiXmlPointer->NoChildren() )
1678                        {
1679                                m_tiXmlPointer->LinkEndChild( new TiXmlText( temp ) );
1680                        }
1681                        else
1682                        {
1683                                if ( 0 == m_tiXmlPointer->GetText() )
1684                                {
1685                                        m_tiXmlPointer->InsertBeforeChild( m_tiXmlPointer->FirstChild(), TiXmlText( temp ) );
1686                                }
1687                                else
1688                                {
1689                                        // There already is text, so change it
1690                                        m_tiXmlPointer->FirstChild()->SetValue( temp );
1691                                }
1692                        }
1693                }
1694
1695                /**
1696                Gets an attribute of @a name from an element, if it doesn't exist it will return the defaultValue.
1697                Uses FromString to convert the string to the type of choice.
1698
1699                @param name                     The name of the attribute you are querying.
1700                @param value            [OUT] The container for the returned value.
1701                @param defaultValue     What to put in @a value if there is no attribute in this element.
1702                @throws Exception
1703
1704                @see GetAttribute
1705                */
1706                template < class T, class DefaulT >
1707                        void GetAttributeOrDefault( const std::string& name, T* value, const DefaulT& defaultValue ) const
1708                {
1709                        // Get the attribute's value as a std::string
1710                        std::string temp;
1711                        if ( !GetAttributeImp( name, &temp ) )
1712                        {
1713                                // The attribute does not exist - set value to the default
1714                                *value = defaultValue;
1715                                return;
1716                        }
1717
1718                        // Stream the value from the string to T
1719                        FromString( temp, value );
1720                }
1721
1722                /**
1723                Gets an attribute of @a name from an element, if it doesn't exist it will return the defaultValue.
1724
1725                @param name                     The name of the attribute you are querying.
1726                @param defaultValue     What to put in @a value if there is no attribute in this element.
1727
1728                @see GetAttribute
1729                */
1730                std::string GetAttributeOrDefault( const std::string& name, const std::string& defaultValue ) const;
1731
1732                /**
1733                Returns an attribute of @a name from an element.
1734                Uses FromString to convert the string to the type of choice.
1735
1736                @param name                             The name of the attribute you are querying.
1737                @param throwIfNotFound  [DEF]   If true, will throw an exception if the attribute doesn't exist
1738                @throws Exception When the attribute doesn't exist and throwIfNotFound is true
1739                @see GetAttributeOrDefault
1740                */
1741                template < class T >
1742                        T GetAttribute( const std::string& name, bool throwIfNotFound = true ) const
1743                {
1744                        // Get the attribute's value as a std::string
1745                        std::string temp;
1746                        T value;
1747                        if ( !GetAttributeImp( name, &temp ) )
1748                        {
1749                                if ( throwIfNotFound )
1750                                {
1751                                        TICPPTHROW( "Attribute does not exist" );
1752                                }
1753                        }
1754                        else
1755                        {
1756                                // Stream the value from the string to T
1757                                FromString( temp, &value );
1758                        }
1759
1760                        return value;
1761                }
1762
1763                /**
1764                Gets an attribute of @a name from an element.
1765                Uses FromString to convert the string to the type of choice.
1766
1767                @param name                             The name of the attribute you are querying.
1768                @param value                    [OUT]   The container for the returned value
1769                @param throwIfNotFound  [DEF]   If true, will throw an exception if the attribute doesn't exist
1770                @throws Exception When the attribute doesn't exist and throwIfNotFound is true
1771
1772                @see GetAttributeOrDefault
1773                */
1774                template< class T >
1775                        void GetAttribute( const std::string& name, T* value, bool throwIfNotFound = true ) const
1776                {
1777                        // Get the attribute's value as a std::string
1778                        std::string temp;
1779                        if ( !GetAttributeImp( name, &temp ) )
1780                        {
1781                                if ( throwIfNotFound )
1782                                {
1783                                        TICPPTHROW( "Attribute does not exist" );
1784                                }
1785                                else
1786                                {
1787                                        return;
1788                                }
1789                        }
1790
1791                        // Stream the value from the string to T
1792                        FromString( temp, value );
1793                }
1794
1795                /**
1796                Gets an attribute of @a name from an element.
1797                Returns an empty string if the attribute does not exist.
1798
1799                @param name     The name of the attribute you are querying.
1800                @return The value of the attribute, or an empty string if it does not exist.
1801
1802                @see GetAttributeOrDefault
1803                */
1804                std::string GetAttribute( const std::string& name ) const;
1805
1806                /**
1807                Returns true, if attribute exists
1808
1809                @param name The name of the attribute you are checking.
1810                @return Existence of attribute
1811                */
1812                bool HasAttribute( const std::string& name ) const;
1813
1814                /**
1815                Removes attribute from element.
1816
1817                @param name The name of the attribute to remove.
1818                */
1819                void RemoveAttribute( const std::string& name );
1820
1821        private:
1822
1823                /**
1824                @internal
1825                Implimentation of the GetAttribute and GetAttributeOrDefault template methods.
1826                */
1827                bool GetAttributeImp( const std::string& name, std::string* value ) const;
1828
1829                /**
1830                @internal
1831                Implimentation of the GetText, GetTextOrDefault, GetTextValue, and GetTextValueOrDefault template methods.
1832                */
1833                bool GetTextImp( std::string* value ) const;
1834        };
1835
1836        /** Wrapper around TiXmlDeclaration */
1837        class Declaration : public NodeImp< TiXmlDeclaration >
1838        {
1839        public:
1840                /**
1841                Default Constructor. Construct an empty declaration.
1842                */
1843                Declaration();
1844
1845                /**
1846                Constructor.
1847                */
1848                Declaration( TiXmlDeclaration* declaration );
1849
1850                /**
1851                Constructor.
1852                */
1853                Declaration( const std::string& version, const std::string& encoding, const std::string& standalone );
1854
1855                /**
1856                Version. Will return an empty string if none was found.
1857                */
1858                std::string Version() const;
1859
1860                /**
1861                Encoding. Will return an empty string if none was found.
1862                */
1863                std::string Encoding() const;
1864
1865                /**
1866                StandAlone. Is this a standalone document?
1867                */
1868                std::string Standalone() const;
1869        };
1870
1871        /** Wrapper around TiXmlStylesheetReference */
1872        class StylesheetReference : public NodeImp< TiXmlStylesheetReference >
1873        {
1874        public:
1875                /**
1876                Default Constructor. Construct an empty declaration.
1877                */
1878                StylesheetReference();
1879
1880                /**
1881                Constructor.
1882                */
1883                StylesheetReference( TiXmlStylesheetReference* stylesheetReference );
1884
1885                /**
1886                Constructor.
1887                */
1888                StylesheetReference( const std::string& type, const std::string& href );
1889
1890                /**
1891                Type. Will return an empty string if none was found.
1892                */
1893                std::string Type() const;
1894
1895                /**
1896                Href. Will return an empty string if none was found.
1897                */
1898                std::string Href() const;
1899        };
1900}
1901
1902#endif  // TICPP_INCLUDED
1903
1904#endif // TIXML_USE_TICPP
Note: See TracBrowser for help on using the repository browser.