Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib2/src/external/tinyxml/ticpp.h @ 8617

Last change on this file since 8617 was 8285, checked in by rgrieder, 14 years ago

Merged revisions 8098 - 8277 from kicklib to kicklib2.

  • Property svn:eol-style set to native
File size: 49.1 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( const 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, const 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, const 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, const 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                 * @param documentName Name to set in the Document.
1405                 * @note LoadFile() needs to be called to actually load the data from the file specified by documentName
1406                 *               SaveFile() needs to be called to save data to file specified by documentName.
1407                 */
1408                Document( const std::string& documentName );
1409
1410                /**
1411                Load a file using the current document value. Throws if load is unsuccessful.
1412
1413                @param encoding Sets the documents encoding.
1414                @see TiXmlEncoding
1415                @throws Exception
1416                */
1417                void LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1418
1419                /**
1420                Save a file using the current document value. Throws if it can't save the file.
1421
1422                @throws Exception
1423                */
1424                void SaveFile() const;
1425
1426                /**
1427                Load a file using the given filename. Throws if load is unsuccessful.
1428
1429                @param filename File to load.
1430                @param encoding Sets the documents encoding.
1431                @see TiXmlEncoding
1432                @throws Exception
1433                */
1434                void LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1435
1436                /**
1437                @copydoc Document::LoadFile( const std::string&, TiXmlEncoding )
1438                */
1439                void LoadFile( const char* filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1440
1441                /**
1442                Save a file using the given filename. Throws if it can't save the file.
1443
1444                @param filename File to save.
1445                @throws Exception
1446                */
1447                void SaveFile( const std::string& filename ) const;
1448
1449                /**
1450                Parse the given xml data.
1451
1452                @param xml Xml to parse.
1453                @param throwIfParseError [DEF] If true, throws when there is a parse error.
1454                @param encoding Sets the documents encoding.
1455                @throws Exception
1456                */
1457                void Parse( const std::string& xml, bool throwIfParseError = true, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1458        };
1459
1460        /** Wrapper around TiXmlElement */
1461        class Element : public NodeImp< TiXmlElement >
1462        {
1463        public:
1464                /**
1465                Default Constructor.
1466                */
1467                Element();
1468
1469                /**
1470                Default Constructor. Initializes all the variables.
1471                @param value The value of the element.
1472                */
1473                Element( const std::string& value );
1474
1475                /**
1476                Default Constructor. Initializes all the variables.
1477                @param value The value of the element.
1478                */
1479                Element( const char* value );
1480
1481                /**
1482                Constructor.
1483                */
1484                Element( TiXmlElement* element );
1485
1486                /**
1487                Constructor that allows you to set the element text
1488                @param value The value of the element.
1489                @param text The text to set.
1490                */
1491                template < class T >
1492                        Element( const std::string& value, const T& text )
1493                        : NodeImp< TiXmlElement >( new TiXmlElement( value ) )
1494                {
1495                        m_impRC->InitRef();
1496                        SetText( text );
1497                }
1498
1499                /**
1500                Access the first attribute in this element.
1501
1502                @param throwIfNoAttributes [DEF] If true, throws when there are no attributes
1503                @return The first attribute, NULL if there are none and @a throwIfNoAttributes is true
1504                */
1505                Attribute* FirstAttribute( bool throwIfNoAttributes = true ) const;
1506
1507                /**
1508                Access the last attribute in this element.
1509
1510                @param throwIfNoAttributes [DEF] If true, throws when there are no attributes
1511                @return The last attribute, NULL if there are none and @a throwIfNoAttributes is true
1512                */
1513                Attribute* LastAttribute( bool throwIfNoAttributes = true ) const;
1514
1515                /**
1516                @internal
1517                Just for Iterator<>
1518
1519                @param value The value of nodes to iterate through
1520                @param next [OUT] The pointer to the first valid node
1521                */
1522                void IterateFirst( const std::string&, Attribute** first ) const
1523                {
1524                        *first = 0;
1525                        for( Attribute* child = FirstAttribute( false ); child; child = child->Next( false ) )
1526                        {
1527                                *first = dynamic_cast< Attribute* >( child );
1528                                if ( 0 != *first )
1529                                {
1530                                        return;
1531                                }
1532                        }
1533                }
1534
1535                /**
1536                Sets an attribute of name to a given value.
1537                The attribute will be created if it does not exist, or changed if it does.
1538                Uses ToString to convert the @a value to a string, so there is no need to use any other SetAttribute methods.
1539
1540                @see GetAttribute
1541                */
1542                template < class T >
1543                        void SetAttribute ( const std::string& name, const T& value )
1544                {
1545                        ValidatePointer();
1546                        m_tiXmlPointer->SetAttribute( name, ToString( value ) );
1547                }
1548
1549                /**
1550                Gets the text of an Element.
1551
1552                @param throwIfNotFound  [DEF]   If true, will throw an exception if there is no text in this element
1553                @note This only works if the Text is the FirstChild node
1554                @throws Exception When there is no text and throwIfNotFound is true
1555
1556                @see GetText( T* value, bool throwIfNotFound = false )
1557                @see GetTextOrDefault
1558                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1559                @see TiXmlElement::GetText
1560                */
1561                std::string GetText( bool throwIfNotFound = true ) const
1562                {
1563                        // Get the element's text value as a std::string
1564                        std::string temp;
1565                        if ( !GetTextImp( &temp ) )
1566                        {
1567                                if ( throwIfNotFound )
1568                                {
1569                                        TICPPTHROW( "Text does not exists in the current element" );
1570                                }
1571                        }
1572
1573                        return temp;
1574                }
1575
1576                /**
1577                Gets the text of an Element, if it doesn't exist it will return the defaultValue.
1578
1579                @param defaultValue                     What to put in 'value' if there is no text in this element
1580                @note This only works if the Text is the FirstChild node
1581
1582                @see GetText
1583                @see GetText( T* value, bool throwIfNotFound = false )
1584                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1585                @see TiXmlElement::GetText
1586                */
1587                std::string GetTextOrDefault( const std::string& defaultValue ) const
1588                {
1589                        // Get the element's text value as a std::string
1590                        std::string temp;
1591                        if ( !GetTextImp( &temp ) )
1592                        {
1593                                return defaultValue;
1594                        }
1595
1596                        return temp;
1597                }
1598
1599                /**
1600                Gets the text value of an Element, if it doesn't exist it will return the defaultValue.
1601                Uses FromString to convert the string to the type of choice
1602
1603                @param value            [OUT]   The container for the returned value
1604                @param defaultValue                     What to put in 'value' if there is no text in this element
1605                @note This is different than GetText() in that it will covert the text to what ever type you want.
1606                @note This only works if the Text is the FirstChild node
1607
1608                @see GetText
1609                @see GetText( T* value, bool throwIfNotFound = false )
1610                @see GetTextOrDefault( const std::string& defaultValue )
1611                @see TiXmlElement::GetText
1612                */
1613                template < class T, class DefaultT >
1614                        void GetTextOrDefault( T* value, const DefaultT& defaultValue ) const
1615                {
1616                        // Get the element's text value as a std::string
1617                        std::string temp;
1618                        if ( !GetTextImp( &temp ) )
1619                        {
1620                                // The text value does not exist - set value to the default
1621                                *value = defaultValue;
1622                                return;
1623                        }
1624
1625                        // Stream the value from the string to T
1626                        FromString( temp, value );
1627                }
1628
1629                /**
1630                Gets the text of an Element.
1631                Uses FromString to convert the string to the type of choice.
1632
1633                @param value                    [OUT]   The container for the returned value
1634                @param throwIfNotFound  [DEF]   If true, will throw an exception if there is no text in this element
1635                @note This is different than GetText() in that it will covert the text to what ever type you want
1636                @note This only works if the Text is the FirstChild node
1637                @throws Exception When there is no text and throwIfNotFound is true
1638
1639                @see GetText
1640                @see GetTextOrDefault
1641                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1642                @see TiXmlElement::GetText
1643                */
1644                template< class T >
1645                        void GetText( T* value, bool throwIfNotFound = true ) const
1646                {
1647                        // Get the element's text value as a std::string
1648                        std::string temp;
1649                        if ( !GetTextImp( &temp ) )
1650                        {
1651                                if ( throwIfNotFound )
1652                                {
1653                                        TICPPTHROW( "Text does not exists in the current element" );
1654                                }
1655                                else
1656                                {
1657                                        return;
1658                                }
1659                        }
1660
1661                        // Stream the value from the string to T
1662                        FromString( temp, value );
1663                }
1664
1665                /**
1666                Convenience function to set the text of an element.
1667                Creates a Text node and inserts it as the first child.
1668                Uses ToString to convert the parameter to a string.
1669
1670                @param value The text to set.
1671                */
1672                template < class T >
1673                        void SetText( const T& value )
1674                {
1675                        ValidatePointer();
1676                        std::string temp = ToString( value );
1677
1678                        if ( m_tiXmlPointer->NoChildren() )
1679                        {
1680                                m_tiXmlPointer->LinkEndChild( new TiXmlText( temp ) );
1681                        }
1682                        else
1683                        {
1684                                if ( 0 == m_tiXmlPointer->GetText() )
1685                                {
1686                                        m_tiXmlPointer->InsertBeforeChild( m_tiXmlPointer->FirstChild(), TiXmlText( temp ) );
1687                                }
1688                                else
1689                                {
1690                                        // There already is text, so change it
1691                                        m_tiXmlPointer->FirstChild()->SetValue( temp );
1692                                }
1693                        }
1694                }
1695
1696                /**
1697                Gets an attribute of @a name from an element, if it doesn't exist it will return the defaultValue.
1698                Uses FromString to convert the string to the type of choice.
1699
1700                @param name                     The name of the attribute you are querying.
1701                @param value            [OUT] The container for the returned value.
1702                @param defaultValue     What to put in @a value if there is no attribute in this element.
1703                @throws Exception
1704
1705                @see GetAttribute
1706                */
1707                template < class T, class DefaulT >
1708                        void GetAttributeOrDefault( const std::string& name, T* value, const DefaulT& defaultValue ) const
1709                {
1710                        // Get the attribute's value as a std::string
1711                        std::string temp;
1712                        if ( !GetAttributeImp( name, &temp ) )
1713                        {
1714                                // The attribute does not exist - set value to the default
1715                                *value = defaultValue;
1716                                return;
1717                        }
1718
1719                        // Stream the value from the string to T
1720                        FromString( temp, value );
1721                }
1722
1723                /**
1724                Gets an attribute of @a name from an element, if it doesn't exist it will return the defaultValue.
1725
1726                @param name                     The name of the attribute you are querying.
1727                @param defaultValue     What to put in @a value if there is no attribute in this element.
1728
1729                @see GetAttribute
1730                */
1731                std::string GetAttributeOrDefault( const std::string& name, const std::string& defaultValue ) const;
1732
1733                /**
1734                Returns an attribute of @a name from an element.
1735                Uses FromString to convert the string to the type of choice.
1736
1737                @param name                             The name of the attribute you are querying.
1738                @param throwIfNotFound  [DEF]   If true, will throw an exception if the attribute doesn't exist
1739                @throws Exception When the attribute doesn't exist and throwIfNotFound is true
1740                @see GetAttributeOrDefault
1741                */
1742                template < class T >
1743                        T GetAttribute( const std::string& name, bool throwIfNotFound = true ) const
1744                {
1745                        // Get the attribute's value as a std::string
1746                        std::string temp;
1747                        T value;
1748                        if ( !GetAttributeImp( name, &temp ) )
1749                        {
1750                                if ( throwIfNotFound )
1751                                {
1752                                        const std::string error( std::string( "Attribute '" ) + name + std::string( "' does not exist" ) );
1753                                        TICPPTHROW( error );
1754                                }
1755                        }
1756                        else
1757                        {
1758                                // Stream the value from the string to T
1759                                FromString( temp, &value );
1760                        }
1761
1762                        return value;
1763                }
1764
1765                /**
1766                Gets an attribute of @a name from an element.
1767                Uses FromString to convert the string to the type of choice.
1768
1769                @param name                             The name of the attribute you are querying.
1770                @param value                    [OUT]   The container for the returned value
1771                @param throwIfNotFound  [DEF]   If true, will throw an exception if the attribute doesn't exist
1772                @throws Exception When the attribute doesn't exist and throwIfNotFound is true
1773
1774                @see GetAttributeOrDefault
1775                */
1776                template< class T >
1777                        void GetAttribute( const std::string& name, T* value, bool throwIfNotFound = true ) const
1778                {
1779                        // Get the attribute's value as a std::string
1780                        std::string temp;
1781                        if ( !GetAttributeImp( name, &temp ) )
1782                        {
1783                                if ( throwIfNotFound )
1784                                {
1785                                        const std::string error( std::string( "Attribute '" ) + name + std::string( "' does not exist" ) );
1786                                        TICPPTHROW( error );
1787                                }
1788                                else
1789                                {
1790                                        return;
1791                                }
1792                        }
1793
1794                        // Stream the value from the string to T
1795                        FromString( temp, value );
1796                }
1797
1798                /**
1799                Gets an attribute of @a name from an element.
1800                Returns an empty string if the attribute does not exist.
1801
1802                @param name     The name of the attribute you are querying.
1803                @return The value of the attribute, or an empty string if it does not exist.
1804
1805                @see GetAttributeOrDefault
1806                */
1807                std::string GetAttribute( const std::string& name ) const;
1808
1809                /**
1810                Returns true, if attribute exists
1811
1812                @param name The name of the attribute you are checking.
1813                @return Existence of attribute
1814                */
1815                bool HasAttribute( const std::string& name ) const;
1816
1817                /**
1818                Removes attribute from element.
1819
1820                @param name The name of the attribute to remove.
1821                */
1822                void RemoveAttribute( const std::string& name );
1823
1824        private:
1825
1826                /**
1827                @internal
1828                Implimentation of the GetAttribute and GetAttributeOrDefault template methods.
1829                */
1830                bool GetAttributeImp( const std::string& name, std::string* value ) const;
1831
1832                /**
1833                @internal
1834                Implimentation of the GetText, GetTextOrDefault, GetTextValue, and GetTextValueOrDefault template methods.
1835                */
1836                bool GetTextImp( std::string* value ) const;
1837        };
1838
1839        /** Wrapper around TiXmlDeclaration */
1840        class Declaration : public NodeImp< TiXmlDeclaration >
1841        {
1842        public:
1843                /**
1844                Default Constructor. Construct an empty declaration.
1845                */
1846                Declaration();
1847
1848                /**
1849                Constructor.
1850                */
1851                Declaration( TiXmlDeclaration* declaration );
1852
1853                /**
1854                Constructor.
1855                */
1856                Declaration( const std::string& version, const std::string& encoding, const std::string& standalone );
1857
1858                /**
1859                Version. Will return an empty string if none was found.
1860                */
1861                std::string Version() const;
1862
1863                /**
1864                Encoding. Will return an empty string if none was found.
1865                */
1866                std::string Encoding() const;
1867
1868                /**
1869                StandAlone. Is this a standalone document?
1870                */
1871                std::string Standalone() const;
1872        };
1873
1874        /** Wrapper around TiXmlStylesheetReference */
1875        class StylesheetReference : public NodeImp< TiXmlStylesheetReference >
1876        {
1877        public:
1878                /**
1879                Default Constructor. Construct an empty declaration.
1880                */
1881                StylesheetReference();
1882
1883                /**
1884                Constructor.
1885                */
1886                StylesheetReference( TiXmlStylesheetReference* stylesheetReference );
1887
1888                /**
1889                Constructor.
1890                */
1891                StylesheetReference( const std::string& type, const std::string& href );
1892
1893                /**
1894                Type. Will return an empty string if none was found.
1895                */
1896                std::string Type() const;
1897
1898                /**
1899                Href. Will return an empty string if none was found.
1900                */
1901                std::string Href() const;
1902        };
1903}
1904
1905#endif  // TICPP_INCLUDED
1906
1907#endif // TIXML_USE_TICPP
Note: See TracBrowser for help on using the repository browser.