Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/buildsystem/src/tinyxml/ticpp.h @ 2138

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

Added #define TIXML_USE_TICPP to the ticpp and tinyxml headers.
All the other changes (missing include, const, public & protected qualifiers, verbose errors) have been fixed by ticpp anyway.

  • Property svn:eol-style set to native
File size: 48.7 KB
Line 
1#define TIXML_USE_TICPP
2
3/*
4http://code.google.com/p/ticpp/
5Copyright (c) 2006 Ryan Pusztai, Ryan Mulder
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of
8this software and associated documentation files (the "Software"), to deal in
9the Software without restriction, including without limitation the rights to
10use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11the Software, and to permit persons to whom the Software is furnished to do so,
12subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*/
24
25/**
26@copydoc ticpp
27@file
28@author         Ryan Pusztai
29@author         Ryan Mulder
30@date           04/11/2006
31
32@version        0.04a by edam@waxworlds.org: based Exception based on std::exception; added stream
33                                        << and >> support; added Document::Parse(); bug fix; improved THROW() macro.
34@version        0.04 Added NodeImp class. Also made all the classes inherit from NodeImp.
35@version        0.03 Added Declaration class
36@version        0.02 Added Element class
37@version        0.01 Added Exception class, Document class
38
39@todo add UNKNOWN support. See ticpp::NodeFactory.
40@todo add TYPECOUNT support. See ticpp::NodeFactory.
41@todo Add a quick reference
42*/
43#ifdef TIXML_USE_TICPP
44
45#ifndef TICPP_INCLUDED
46#define TICPP_INCLUDED
47
48#include "tinyxml.h"
49#include <sstream>
50#include <vector>
51#include <memory>
52#include <exception>
53#include <typeinfo>
54
55/**
56@subpage ticpp is a TinyXML wrapper that uses a lot more C++ ideals.
57It throws exceptions, uses templates, is in its own name space, and
58<b>requires</b> STL (Standard Template Library). This is done to ease the use
59of getting values in and out of the xml.
60
61If you don't perfer to use some of the concepts just don't use it.
62It is just a wrapper that extends TinyXML. It doesn't actually change
63any of TinyXML.
64*/
65namespace ticpp
66{
67    /**
68        This is a ticpp exception class
69        */
70        class Exception : public std::exception
71        {
72        public:
73                /**
74                Construct an exception with a message
75                */
76                Exception( const std::string& details );
77                ~Exception() throw();
78
79                /// Override std::exception::what() to return m_details
80                const char* what() const throw();
81
82                std::string m_details; /**< Exception Details */
83        };
84
85        /**
86        This allows you to stream your exceptions in.
87        It will take care of the conversion     and throwing the exception.
88        */
89        #define TICPPTHROW( message )                                                                                   \
90        {                                                                                                                                               \
91                std::ostringstream full_message;                                                                        \
92                std::string file( __FILE__ );                                                                           \
93                file = file.substr( file.find_last_of( "\\/" ) + 1 );                           \
94                full_message << message << " <" << file << "@" << __LINE__ << ">";      \
95                full_message << BuildDetailedErrorString();                                                     \
96                throw Exception( full_message.str() );                                                          \
97        }
98
99        // Forward Declarations for Visitor, and others.
100        class Document;
101        class Element;
102        class Declaration;
103        class StylesheetReference;
104        class Text;
105        class Comment;
106        class Attribute;
107
108        /** Wrapper around TiXmlVisitor */
109        class Visitor : public TiXmlVisitor
110        {
111        public:
112                // Overload the TiXmlVisitor functions, wrap objects, call ticpp::Visitor functions
113                /// @internal
114                virtual bool VisitEnter( const TiXmlDocument& doc );
115                /// @internal
116                virtual bool VisitExit( const TiXmlDocument& doc );
117                /// @internal
118                virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
119                /// @internal
120                virtual bool VisitExit( const TiXmlElement& element );
121                /// @internal
122                virtual bool Visit( const TiXmlDeclaration& declaration );
123                /// @internal
124                virtual bool Visit( const TiXmlStylesheetReference& stylesheet );
125                /// @internal
126                virtual bool Visit( const TiXmlText& text );
127                /// @internal
128                virtual bool Visit( const TiXmlComment& comment );
129
130        public:
131                /// Visit a document.
132                virtual bool VisitEnter( const Document& /*doc*/ )                      { return true; }
133                /// Visit a document.
134                virtual bool VisitExit( const Document& /*doc*/ )                       { return true; }
135
136                /// Visit an element.
137                virtual bool VisitEnter( const Element& /*element*/, const Attribute* /*firstAttribute*/ )      { return true; }
138                /// Visit an element.
139                virtual bool VisitExit( const Element& /*element*/ )            { return true; }
140
141                /// Visit a declaration
142                virtual bool Visit( const Declaration& /*declaration*/ )        { return true; }
143                /// Visit a stylesheet reference
144                virtual bool Visit( const StylesheetReference& /*stylesheet*/ ) { return true; }
145                /// Visit a text node
146                virtual bool Visit( const Text& /*text*/ )                                      { return true; }
147                /// Visit a comment node
148                virtual bool Visit( const Comment& /*comment*/ )                        { return true; }
149        };
150
151        /** Wrapper around TiXmlBase */
152        class Base
153        {
154        public:
155
156                /**
157                Converts any class with a proper overload of the << opertor to a std::string
158                @param value The value to be converted
159                @throws Exception When value cannot be converted to a std::string
160                */
161                template < class T >
162                        std::string ToString( const T& value ) const
163                {
164                        std::stringstream convert;
165                        convert << value;
166                        if ( convert.fail() )
167                        {
168                                TICPPTHROW( "Could not convert value to text" );
169                        }
170                        return convert.str();
171                }
172
173                std::string ToString( const std::string& value ) const
174                {
175                        return value;
176                }
177
178                /**
179                Converts a std::string to any class with a proper overload of the >> opertor
180                @param temp                     The string to be converted
181                @param out      [OUT]   The container for the returned value
182                @throws Exception When temp cannot be converted to the target type
183                */
184                template < class T >
185                        void FromString( const std::string& temp, T* out ) const
186                {
187                        std::istringstream val( temp );
188                        val >> *out;
189
190                        if ( val.fail() )
191                        {
192                                TICPPTHROW( "Could not convert \"" << temp << "\" to target type" );
193                        }
194                }
195
196                /**
197                Specialization for std::string
198                */
199                void FromString( const std::string& temp, std::string* out ) const
200                {
201                        *out = temp;
202                }
203
204                /**
205                Return the position, in the original source file, of this node or attribute.
206                Wrapper around TiXmlBase::Row()
207                */
208                int Row() const
209                {
210                        return GetBasePointer()->Row();
211                }
212
213                /**
214                Return the position, in the original source file, of this node or attribute.
215                Wrapper around TiXmlBase::Row()
216                */
217                int Column() const
218                {
219                        return GetBasePointer()->Column();
220                }
221
222                /**
223                Compare internal TiXml pointers to determine is both are wrappers around the same node
224                */
225                bool operator == ( const Base& rhs ) const
226                {
227                        return ( GetBasePointer() == rhs.GetBasePointer() );
228                }
229               
230                /**
231                Compare internal TiXml pointers to determine is both are wrappers around the same node
232                */
233                bool operator != ( const Base& rhs ) const
234                {
235                        return ( GetBasePointer() != rhs.GetBasePointer() );
236                }
237               
238                /**
239                Builds detailed error string using TiXmlDocument::Error() and others
240                */
241                std::string BuildDetailedErrorString() const
242                {
243                        std::ostringstream full_message;
244                        #ifndef TICPP_NO_RTTI
245                        TiXmlNode* node = dynamic_cast< TiXmlNode* >( GetBasePointer() );
246                        if ( node != 0 )
247                        {
248                                TiXmlDocument* doc = node->GetDocument();
249                                if ( doc != 0 )
250                                {
251                                        if ( doc->Error() )
252                                        {
253                                                full_message    << "\nDescription: " << doc->ErrorDesc()
254                                                                                << "\nFile: " << (strlen( doc->Value() ) > 0 ? doc->Value() : "<unnamed-file>") 
255                                                                                << "\nLine: " << doc->ErrorRow() 
256                                                                                << "\nColumn: " << doc->ErrorCol();
257                                        }
258                                }
259                        }
260                        #endif
261                        return full_message.str();
262                }
263
264                /**
265                Destructor
266                */
267                virtual ~Base()
268                {
269                }
270
271        protected:
272                mutable TiCppRCImp* m_impRC;    /**< Holds status of internal TiXmlPointer - use this to determine if object has been deleted already */
273
274                /**
275                @internal
276                Updates the pointer to the reference counter to point at the counter in the new node.
277
278                @param node TiXmlBase containing the new reference counter
279                */
280                void SetImpRC( TiXmlBase* node )
281                {
282                        m_impRC = node->m_tiRC;
283                }
284
285                void ValidatePointer() const
286                {
287                        if ( m_impRC->IsNull() )
288                        {
289                                TICPPTHROW( "Internal TiXml Pointer is NULL" );
290                        }
291                }               
292
293                /**
294                @internal
295                Get internal TiXmlBase*
296                */
297                virtual TiXmlBase* GetBasePointer() const = 0;
298        };
299
300        /**
301        Wrapper around TiXmlAttribute
302        */
303        class Attribute : public Base
304        {
305        private:
306                TiXmlAttribute* m_tiXmlPointer;
307                TiXmlBase* GetBasePointer() const
308                {
309                        ValidatePointer();
310                        return m_tiXmlPointer;
311                }
312
313        public:
314                /**
315                Construct an empty attribute.
316                */
317                Attribute();
318
319                /**
320                Construct an attribute with @a name and @a value
321
322                @param name The name of the attribute
323                @param value The value of the attribute
324                */
325                Attribute( const std::string& name, const std::string& value );
326
327                /**
328                @internal
329                Construct an attribute with the internal pointer
330
331                @param attribute The internal pointer
332                */
333                Attribute( TiXmlAttribute* attribute );
334
335                /**
336                Get the value of this attribute
337                Uses Base::FromString to convert TiXmlAttribute::ValueStr from a std::string,
338                and puts it in the passed pointer.
339
340                @param value [OUT] A pointer to fill with the value
341                */
342                template < class T >
343                        void GetValue( T* value ) const
344                {
345                        ValidatePointer();
346                        FromString( m_tiXmlPointer->ValueStr(), value );
347                }
348
349                /**
350                Get the value of this attribute.
351                Simple wrapper for TiXmlAttribute::ValueStr.
352
353                @see GetValue
354                */
355                std::string Value() const;
356
357                /**
358                Set the value of this node.
359                Uses Base::ToString to convert value to a std::string, then calls TiXmlAttribute::SetValue.
360
361                @param value The value to set
362                */
363                template < class T >
364                        void SetValue( const T& value )
365                {
366                        ValidatePointer();
367                        m_tiXmlPointer->SetValue( ToString( value ) );
368                }
369
370                /**
371                Get the value of this attribute
372                Uses Base::FromString to convert TiXmlAttribute::Name from a std::string,
373                and puts it in the passed pointer.
374
375                @param name [OUT] A pointer to fill with the name
376                */
377                template < class T >
378                        void GetName( T* name ) const
379                {
380                        ValidatePointer();
381                        FromString( m_tiXmlPointer->Name(), name );
382                }
383
384                /**
385                Get the value of this attribute.
386                Simple wrapper for TiXmlAttribute::Name.
387
388                @see GetName
389                */
390                std::string Name() const;
391
392                /**
393                Set the value of this attribute.
394                Uses Base::ToString to convert @a name to a std::string, then calls TiXmlAttribute::SetName.
395
396                @param name The name to set
397                */
398                template < class T >
399                        void SetName( const T& name )
400                {
401                        ValidatePointer();
402                        m_tiXmlPointer->SetName( ToString( name ) );
403                }
404
405                /**
406                @internal
407                Updates the reference count for the old and new pointers.
408                */
409                void operator=( const Attribute& copy );
410
411                /**
412                @internal
413                Updates the reference count for the old and new pointers.
414                */
415                Attribute( const Attribute& copy );
416
417                /*
418                Decrements reference count.
419                */
420                ~Attribute();
421
422                /**
423                Get the next sibling attribute in the DOM.
424                */
425                Attribute* Next( bool throwIfNoAttribute = true ) const;
426
427                /**
428                Get the previous sibling attribute in the DOM.
429                */
430                Attribute* Previous( bool throwIfNoAttribute = true ) const;
431
432                /**
433                @internal
434                Just for Iterator<>
435
436                @param next [OUT] The pointer to the next valid attribute
437                @return true if there is a next attribute, false if not
438                */
439                void IterateNext( const std::string&, Attribute** next ) const;
440
441                /**
442                @internal
443                Just for Iterator<>
444
445                @param previous [OUT] The pointer to the previous valid attribute
446                @return true if there is a previous attribute, false if not
447                */
448                void IteratePrevious( const std::string&, Attribute** previous ) const;
449
450                /**
451                All TinyXml classes can print themselves to a filestream.
452                */
453                virtual void Print( FILE* file, int depth ) const;
454
455        private:
456
457                /**
458                @internal
459                Sets the internal pointer.
460                Saves a copy of the pointer to the RC object.
461
462                @param newPointer TiXmlAttribute* to set.
463                */
464                void SetTiXmlPointer( TiXmlAttribute* newPointer );
465        };
466
467        /**
468        Wrapper around TiXmlNode
469        */
470        class Node : public Base
471        {
472        public:
473
474                /**
475                Get the value of this node
476                Uses Base::FromString to convert TiXmlNode::ValueStr from a std::string,
477                and puts it in the passed pointer.
478
479                @param value [OUT] A pointer to fill with the value
480                */
481                template < class T >
482                        void GetValue( T* value) const
483                {
484                        FromString( GetTiXmlPointer()->ValueStr(), value );
485                }
486
487                /**
488                Get the value of this node.
489                Simple wrapper for TiXmlNode::ValueStr.
490
491                @see GetValue
492                */
493                std::string Value() const;
494
495                /**
496                Set the value of this node.
497                Uses Base::ToString to convert value to a std::string, then calls TiXmlNode::SetValue.
498
499                @param value The value to set
500                */
501                template < class T >
502                        void SetValue( const T& value )
503                {
504                        GetTiXmlPointer()->SetValue( ToString( value ) );
505                }
506
507                /**
508                Clear all Nodes below this.
509                Simple wrapper for TiXmlNode::Clear.
510                */
511                void Clear();
512
513                /**
514                The Parent of this Node.
515                Simple wrapper for TiXmlNode::Parent.
516
517                @param throwIfNoParent [DEF] If true, throws when Parent = NULL.
518                @return The parent of this node, NULL if there is no Parent.
519                @throws Exception When throwIfNoParent is true, and TiXmlNode::Parent returns Null.
520                */
521                Node* Parent( bool throwIfNoParent = true ) const;
522
523                /**
524                The first child of this node.
525
526                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no children.
527                @return Pointer to child, Null if no children and 'throwIfNoChildren' is false.
528                @throws Exception When throwIfNoChildren is true, and TiXmlNode::FirstChild returns Null.
529
530                @see TiXmlNode::FirstChild
531                */
532                Node* FirstChild( bool throwIfNoChildren = true ) const;
533
534                /**
535                @internal
536                The first child of this node with the matching @a value.
537
538                @overload
539                @param value                            Value to match.
540                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
541
542                @see FirstChild( bool throwIfNoChildren = true )
543                */
544                Node* FirstChild( const char* value, bool throwIfNoChildren = true ) const;
545
546                /**
547                The first child of this node with the matching @a value.
548
549                @overload
550                @param value                            Value to match.
551                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
552
553                @see FirstChild( const char* value, bool throwIfNoChildren = true )
554                */
555                Node* FirstChild( const std::string& value, bool throwIfNoChildren = true ) const;
556
557                /**
558                The last child of this node.
559
560                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no children.
561                @return Pointer to child, Null if no children and 'throwIfNoChildren' is false.
562                @throws Exception When throwIfNoChildren is true, and TiXmlNode::LastChild returns Null.
563
564                @see TiXmlNode::LastChild
565                */
566                Node* LastChild( bool throwIfNoChildren = true ) const;
567
568                /**
569                @internal
570                The last child of this node with the matching @a value.
571
572                @overload
573                @param value                            Value to match.
574                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
575
576                @see LastChild( bool throwIfNoChildren = true )
577                */
578                Node* LastChild( const char* value, bool throwIfNoChildren = true ) const;
579
580                /**
581                The last child of this node with the matching @a value.
582
583                @overload
584                @param value                            Value to match.
585                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
586
587                @see LastChild( const char* value, bool throwIfNoChildren = true )
588                */
589                Node* LastChild( const std::string& value, bool throwIfNoChildren = true ) const;
590
591                /**
592                An alternate way to walk the children of a node.
593                Simple wrapper for TiXmlNode::IterateChildren.
594
595                @param previous The previous Node* that was returned from IterateChildren.
596                @return NULL When there are no more children.
597                */
598                Node* IterateChildren( Node* previous ) const;
599
600                /**
601                This flavor of IterateChildren searches for children with a particular @a value.
602                Simple wrapper for TiXmlNode::IterateChildren.
603
604                @param value    The value you want to search for.
605                @param previous The previous Node* that was returned from IterateChildren.
606                @return NULL When there are no more children.
607                */
608                Node* IterateChildren( const std::string& value, Node* previous ) const;
609
610                /**
611                Adds a child past the LastChild.
612                Throws if you try to insert a document.
613
614                @note This takes a copy of @a addThis so it is not as efficiant as LinkEndChild.
615                @param addThis Node to insert.
616                @throws Exception When TiXmlNode::InsertEndChild returns Null
617
618                @see LinkEndChild
619                @see TiXmlNode::InsertEndChild
620                */
621                Node* InsertEndChild( Node& addThis );
622
623                /**
624                Adds a child past the LastChild.
625                Throws if you try to link a document.
626
627                @param childNode Node to link.
628                @throws Exception When TiXmlNode::LinkEndChild returns Null.
629
630                @see InsertEndChild
631                @see TiXmlNode::LinkEndChild
632                */
633                Node* LinkEndChild( Node* childNode );
634
635                /**
636                Adds a child before the specified child.
637                Throws if you try to insert a document.
638
639                @param beforeThis       Node that will have @a addThis linked before.
640                @param addThis          Node to insert before.
641                @throws Exception When TiXmlNode::InsertBeforeChild returns Null.
642
643                @see InsertAfterChild
644                @see TiXmlNode::InsertBeforeChild
645                */
646                Node* InsertBeforeChild( Node* beforeThis, Node& addThis );
647
648                /**
649                Adds a child after the specified child.
650                Throws if you try to insert a document.
651
652                @param afterThis        Node that will have @a addThis linked after.
653                @param addThis          Node to insert after.
654                @throws Exception When TiXmlNode::InsertAfterChild returns Null.
655
656                @see InsertBeforeChild
657                @see TiXmlNode::InsertAfterChild
658                */
659                Node* InsertAfterChild( Node* afterThis, Node& addThis );
660
661                /**
662                Replace a child of this node.
663                Throws if you try to replace with a document.
664
665                @param replaceThis      Node to replace.
666                @param withThis         Node that is replacing @a replaceThis.
667                @throws Exception When TiXmlNode::ReplaceChild returns Null.
668
669                @see TiXmlNode::ReplaceChild
670                */
671                Node* ReplaceChild( Node* replaceThis, Node& withThis );
672
673                /**
674                Delete a child of this node.
675
676                @param removeThis Node to delete.
677                @throws Exception When removeThis is not a child of this Node.
678
679                @see TiXmlNode::RemoveChild
680                */
681                void RemoveChild( Node* removeThis );
682
683                /**
684                Navigate to a sibling node.
685                Wrapper around TiXmlNode::PreviousSibling.
686
687                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
688                @return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
689                @throws Exception When TiXmlNode::PreviousSibling returns Null and 'throwIfNoSiblings' is true.
690                */
691                Node* PreviousSibling( bool throwIfNoSiblings = true ) const;
692
693                /**
694                Navigate to a sibling node with the given @a value.
695
696                @overload
697                @param value The value of the node to look for.
698                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
699
700                @see PreviousSibling( bool throwIfNoSiblings )
701                */
702                Node* PreviousSibling( const std::string& value, bool throwIfNoSiblings = true ) const;
703
704                /**
705                @internal
706                Navigate to a sibling node with the given @a value.
707
708                @overload
709                @param value The value of the node to look for.
710                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
711
712                @see PreviousSibling( const std::string& value, bool throwIfNoSiblings )
713                */
714                Node* PreviousSibling( const char* value, bool throwIfNoSiblings = true ) const;
715
716                /**
717                Navigate to a sibling node.
718                Wrapper around TiXmlNode::NextSibling.
719
720                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
721                @return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
722                @throws Exception When TiXmlNode::NextSibling returns Null and 'throwIfNoSiblings' is true.
723                */
724                Node* NextSibling( bool throwIfNoSiblings = true ) const;
725
726                /**
727                Navigate to a sibling node with the given @a value.
728
729                @overload
730                @param value The value of the node to look for.
731                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
732
733                @see NextSibling( bool throwIfNoSiblings )
734                */
735                Node* NextSibling( const std::string& value, bool throwIfNoSiblings = true ) const;
736
737                /**
738                @internal
739                Navigate to a sibling node with the given @a value.
740
741                @overload
742                @param value The value of the node to look for.
743                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
744
745                @see NextSibling( const std::string& value, bool throwIfNoSiblings )
746                */
747                Node* NextSibling( const char* value, bool throwIfNoSiblings = true ) const;
748
749                /**
750                @internal
751                Just for Iterator<>
752
753                @param value The value of nodes to iterate through
754                @param next [OUT] The pointer to the first valid node
755                */
756                template < class T >
757                        void IterateFirst( const std::string& value, T** first ) const
758                {
759                        *first = 0;
760                        for( Node* child = FirstChild( value, false ); child; child = child->NextSibling( value, false ) )
761                        {
762                                *first = dynamic_cast< T* >( child );
763                                if ( 0 != *first )
764                                {
765                                        return;
766                                }
767                        }
768                }
769
770                virtual void IterateFirst( const std::string&, Attribute** ) const
771                {
772                        TICPPTHROW( "Attributes can only be iterated with Elements." )
773                }
774
775                /**
776                @internal
777                Just for Iterator<>
778
779                @param value The value of nodes to iterate through
780                @param next [OUT] The pointer to the next valid node
781                */
782                template < class T >
783                        void IterateNext( const std::string& value, T** next ) const
784                {
785                        Node* sibling = NextSibling( value, false );
786                        *next = dynamic_cast< T* >( sibling );
787
788                        while ( ( 0 != sibling ) && ( 0 == *next ) )
789                        {
790                                sibling = sibling->NextSibling( value, false );
791                                *next = dynamic_cast< T* >( sibling );
792                        }
793                }
794
795                /**
796                @internal
797                Just for Iterator<>
798
799                @param value The value of nodes to iterate through
800                @param previous [OUT] The pointer to the previous valid node
801                */
802                template < class T >
803                        void IteratePrevious( const std::string& value, T** previous  ) const
804                {
805                        Node* sibling = PreviousSibling( value, false );
806                        *previous = dynamic_cast< T* >( sibling );
807
808                        while ( ( 0 != sibling ) && ( 0 == *previous ) )
809                        {
810                                sibling = sibling->PreviousSibling( value, false );
811                                *previous = dynamic_cast< T* >( sibling );
812                        }
813                }
814
815                /**
816                Navigate to a sibling element.
817                Wrapper around TiXmlNode::NextSibling.
818
819                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling element.
820                @return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
821                @throws Exception When TiXmlNode::NextSibling returns Null and 'throwIfNoSiblings' is true.
822                */
823                Element* NextSiblingElement( bool throwIfNoSiblings = true ) const;
824
825                /**
826                Navigate to a sibling element with the given @a value.
827
828                @overload
829                @param value The value of the element to look for.
830                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling elements.
831                @see NextSiblingElement( bool throwIfNoSiblings )
832                */
833                Element* NextSiblingElement( const std::string& value, bool throwIfNoSiblings = true ) const;
834
835                /**
836                @internal
837                Navigate to a sibling element with the given @a value.
838
839                @overload
840                @param value The value of the element to look for.
841                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling elements.
842
843                @see NextSiblingElement( const std::string& value, bool throwIfNoSiblings )
844                */
845                Element* NextSiblingElement( const char* value, bool throwIfNoSiblings = true ) const;
846
847                /**
848                The first child element of this node.
849
850                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
851                @return Pointer to child, Null if no element children and 'throwIfNoChildren' is false.
852                @throws Exception When throwIfNoChildren is true, and TiXmlNode::FirstChildElement returns Null.
853
854                @see TiXmlNode::FirstChildElement
855                */
856                Element* FirstChildElement( bool throwIfNoChildren = true ) const;
857
858                /**
859                @internal
860                The first child element of this node with the matching @a value.
861
862                @overload
863                @param value Value to match.
864                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
865
866                @see FirstChildElement( bool throwIfNoChildren = true )
867                */
868                Element* FirstChildElement( const char* value, bool throwIfNoChildren = true ) const;
869
870                /**
871                The first child element of this node with the matching @a value.
872
873                @overload
874                @param value Value to match.
875                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
876
877                @see FirstChildElement( const char* value, bool throwIfNoChildren = true )
878                */
879                Element* FirstChildElement( const std::string& value, bool throwIfNoChildren = true ) const;
880
881                /**
882                Query the type (as TiXmlNode::NodeType ) of this node.
883                */
884                int Type() const;
885
886                /**
887                Return a pointer to the Document this node lives in.
888
889                @param throwIfNoDocument [DEF] If true, will throw an exception if this node is not linked under a Document.
890                @return A pointer to the Document this node lives in, NULL if not linked under a Document, and 'throwIfNoDocument' is false.
891                @throws Exception When this node is not linked under a Document and 'throwIfNoDocument' is true.
892                */
893                Document* GetDocument( bool throwIfNoDocument = true ) const;
894
895                /**
896                Check if this node has no children.
897
898                @return true if this node has no children.
899                */
900                bool NoChildren() const;
901
902                #ifndef TICPP_NO_RTTI
903                /**
904                Pointer conversion ( NOT OBJECT CONVERSION ) - replaces TiXmlNode::ToElement, TiXmlNode::ToDocument, TiXmlNode::ToComment, etc.
905
906                @throws Exception When the target is not an object of class T
907                @warning Some ancient compilers do not support explicit specification of member template arguments, which this depends on ( e.g. VC6 ).
908                */
909                template < class T >
910                        T* To() const
911                {
912                        T* pointer = dynamic_cast< T* >( this );
913                        if ( 0 == pointer )
914                        {
915                                std::string thisType = typeid( this ).name();
916                                std::string targetType = typeid( T ).name();
917                                std::string thatType = typeid( *this ).name();
918                                TICPPTHROW( "The " << thisType.substr( 6 ) << " could not be casted to a " << targetType.substr( 6 )
919                                        << " *, because the target object is not a " << targetType.substr( 6 ) << ". (It is a " << thatType.substr( 6 ) << ")" );
920                        }
921                        return pointer;
922                }
923                #endif
924
925                /**
926                Pointer conversion - replaces TiXmlNode::ToDocument.
927
928                @throws Exception When this node is not a Document.
929                */
930                Document* ToDocument() const;
931
932                /**
933                Pointer conversion - replaces TiXmlNode::ToElement.
934
935                @throws Exception When this node is not a Element.
936                */
937                Element* ToElement() const;
938
939                /**
940                Pointer conversion - replaces TiXmlNode::ToComment.
941
942                @throws Exception When this node is not a Comment.
943                */
944                Comment* ToComment() const;
945
946                /**
947                Pointer conversion - replaces TiXmlNode::ToText.
948
949                @throws Exception When this node is not a Text.
950                */
951                Text* ToText() const;
952
953                /**
954                Pointer conversion - replaces TiXmlNode::ToDeclaration.
955
956                @throws Exception When this node is not a Declaration.
957                */
958                Declaration* ToDeclaration() const;
959
960                /**
961                Pointer conversion - replaces TiXmlNode::ToStylesheetReference.
962
963                @throws Exception When this node is not a StylesheetReference.
964                */
965                StylesheetReference* ToStylesheetReference() const;
966
967                /**
968                Create an exact duplicate of this node and return it.
969
970                @note Using auto_ptr to manage the memory declared on the heap by TiXmlNode::Clone.
971                @code
972                // Now using clone
973                ticpp::Document doc( "C:\\Test.xml" );
974                ticpp::Node* sectionToClone;
975                sectionToClone = doc.FirstChild( "settings" );
976                std::auto_ptr< ticpp::Node > clonedNode = sectionToClone->Clone();
977                // Now you can use the clone.
978                ticpp::Node* node2 = clonedNode->FirstChildElement()->FirstChild();
979                ...
980                // After the variable clonedNode goes out of scope it will automatically be cleaned up.
981                @endcode
982                @return Pointer the duplicate node.
983                */
984                std::auto_ptr< Node > Clone() const;
985
986                /**
987                Accept a hierchical visit the nodes in the TinyXML DOM.
988                @return The boolean returned by the visitor.
989                */
990                bool Accept( TiXmlVisitor* visitor ) const;
991
992                /**
993                Stream input operator.
994                */
995                friend std::istream& operator >>( std::istream& in, Node& base )
996                {
997                        in >> *base.GetTiXmlPointer();
998                        return in;
999                }
1000
1001                /**
1002                Stream output operator.
1003                */
1004                friend std::ostream& operator <<( std::ostream& out, const Node& base )
1005                {
1006                        out << *base.GetTiXmlPointer();
1007                        return out;
1008                }
1009
1010        protected:
1011                /**
1012                @internal
1013                Allows NodeImp to use Node*'s.
1014                */
1015                virtual TiXmlNode* GetTiXmlPointer() const = 0;
1016
1017                TiXmlBase* GetBasePointer() const
1018                {
1019                        return GetTiXmlPointer();
1020                }
1021
1022                /**
1023                @internal
1024                Constructs the correct child of Node, based on the Type of the TiXmlNode*.
1025                */
1026                Node* NodeFactory( TiXmlNode* tiXmlNode, bool throwIfNull = true, bool rememberSpawnedWrapper = true ) const;
1027
1028        };
1029
1030        /** Iterator for conveniently stepping through Nodes and Attributes.
1031        TinyXML++ introduces iterators:
1032        @code
1033        ticpp::Iterator< ticpp::Node > child;
1034        for ( child = child.begin( parent ); child != child.end(); child++ )
1035        @endcode
1036
1037        Iterators have the added advantage of filtering by type:
1038        @code
1039        // Only iterates through Comment nodes
1040        ticpp::Iterator< ticpp::Comment > child;
1041        for ( child = child.begin( parent ); child != child.end(); child++ )
1042        @endcode
1043
1044        @code
1045        // Only iterates through Element nodes with value "ElementValue"
1046        ticpp::Iterator< ticpp::Element > child( "ElementValue" );
1047        for ( child = child.begin( parent ); child != child.end(); child++ )
1048        @endcode
1049
1050        Finally, Iterators also work with Attributes
1051        @code
1052        ticpp::Iterator< ticpp::Attribute > attribute;
1053        for ( attribute = attribute.begin( element ); attribute != attribute.end(); attribute++ )
1054        @endcode
1055        */
1056        template < class T = Node >
1057                class Iterator
1058        {
1059        private:
1060                T* m_p;                                 /**< Internal Pointer */
1061                std::string m_value;    /**< Value for NextSibling  calls */
1062
1063        public:
1064
1065                /**
1066                For for loop comparisons.
1067                @param parent The parent of the nodes to iterate.
1068                @return The first child of type T.
1069                @code
1070                ticpp::Iterator< ticpp::Node > child;
1071                for ( child = child.begin( parent ); child != child.end(); child++ )
1072                @endcode
1073                */
1074                T* begin( const Node* parent ) const
1075                {
1076                        T* pointer;
1077                        parent->IterateFirst( m_value, &pointer );
1078                        return pointer;
1079                }
1080
1081                /**
1082                For for loop comparisons.
1083                @return NULL
1084                @code
1085                ticpp::Iterator< ticpp::Node > child;
1086                for ( child = child.begin( parent ); child != child.end(); child++ )
1087                @endcode
1088                */
1089                T* end() const
1090                {
1091                        return 0;
1092                }
1093
1094                /** Constructor.
1095                @param value If not empty, this iterator will only visit nodes with matching value.
1096                @code
1097                // Only iterates through Element nodes with value "ElementValue"
1098                ticpp::Iterator< ticpp::Element > child( "ElementValue" );
1099                for ( child = child.begin( parent ); child != child.end(); child++ )
1100                @endcode
1101                */
1102                Iterator( const std::string& value = "" )
1103                        : m_p( 0 ), m_value( value )
1104                {
1105                }
1106
1107                /// Constructor
1108                Iterator( T* node, const std::string& value = "" )
1109                        : m_p( node ), m_value( value )
1110                {
1111                }
1112
1113                /// Constructor
1114                Iterator( const Iterator& it )
1115                        : m_p( it.m_p ), m_value( it.m_value )
1116                {
1117                }
1118
1119                /**
1120                Gets internal pointer.
1121                @return The internal pointer.
1122                */
1123                T* Get() const
1124                {
1125                        return m_p;
1126                }
1127
1128                /** Sets internal pointer */
1129                Iterator& operator=( const Iterator& it )
1130                {
1131                        m_p = it.m_p;
1132                        m_value = it.m_value;
1133                        return *this;
1134                }
1135
1136                /** Sets internal pointer */
1137                Iterator& operator=( T* p )
1138                {
1139                        m_p = p;
1140                        return *this;
1141                }
1142
1143                /** Sets internal pointer to the Next Sibling, or Iterator::END, if there are no more siblings */
1144                Iterator& operator++()
1145                {
1146                        m_p->IterateNext( m_value, &m_p );
1147                        return *this;
1148                }
1149
1150                /** Sets internal pointer to the Next Sibling, or Iterator::END, if there are no more siblings */
1151                Iterator operator++(int)
1152                {
1153                        Iterator tmp(*this);
1154                        ++(*this);
1155                        return tmp;
1156                }
1157
1158                /** Sets internal pointer to the Previous Sibling, or Iterator::END, if there are no prior siblings */
1159                Iterator& operator--()
1160                {
1161                        m_p->IteratePrevious( m_value, &m_p );
1162                        return *this;
1163                }
1164
1165                /** Sets internal pointer to the Previous Sibling, or Iterator::END, if there are no prior siblings */
1166                Iterator operator--(int)
1167                {                       
1168                        Iterator tmp(*this);
1169                        --(*this);
1170                        return tmp;
1171                }
1172
1173                /** Compares internal pointer */
1174                bool operator!=( const T* p ) const
1175                {
1176                        if ( m_p == p )
1177                        {
1178                                return false;
1179                        }
1180                        if ( 0 == m_p || 0 == p )
1181                        {
1182                                return true;
1183                        }
1184                        return *m_p != *p;
1185                }
1186
1187                /** Compares internal pointer */
1188                bool operator!=( const Iterator& it ) const
1189                {
1190                        return operator!=( it.m_p );
1191                }
1192
1193                /** Compares internal pointer* */
1194                bool operator==( T* p ) const
1195                {
1196                        if ( m_p == p )
1197                        {
1198                                return true;
1199                        }
1200                        if ( 0 == m_p || 0 == p )
1201                        {
1202                                return false;
1203                        }
1204                        return *m_p == *p;
1205                }
1206
1207                /** Compares internal pointer */
1208                bool operator==( const Iterator& it ) const
1209                {
1210                        return operator==( it.m_p );
1211                }
1212
1213                /** So Iterator behaves like a STL iterator */
1214                T* operator->() const
1215                {
1216                        return m_p;
1217                }
1218
1219                /** So Iterator behaves like a STL iterator */
1220                T& operator*() const
1221                {
1222                        return *m_p;
1223                }
1224        };
1225
1226        /** Implementation of Node wrapper */
1227        template < class T >
1228                class NodeImp : public Node
1229        {
1230        protected:
1231
1232                T* m_tiXmlPointer;              /**< Internal pointer to the TiXml Class which is being wrapped */
1233
1234                /**
1235                @internal
1236                Gets the internal TinyXML pointer.
1237
1238                @returns The internal TiXmlNode*.
1239                */
1240                TiXmlNode* GetTiXmlPointer() const
1241                {
1242                        ValidatePointer();
1243                        return m_tiXmlPointer;
1244                }
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.