Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1824 was 1639, checked in by rgrieder, 16 years ago

merged nico's fixes for gcc 4.3 back to trunk.
I'm not going to delete branch yet.

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