Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2461 was 2087, checked in by landauf, 16 years ago

merged objecthierarchy branch back to trunk

  • 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    public:
1187                /**
1188                @internal
1189                Gets the internal TinyXML pointer.
1190
1191                @returns The internal TiXmlNode*.
1192                */
1193                TiXmlNode* GetTiXmlPointer() const
1194                {
1195                        ValidatePointer();
1196                        return m_tiXmlPointer;
1197                }
1198    protected:
1199
1200                /**
1201                @internal
1202                Sets the internal pointer.
1203                Saves a copy of the pointer to the RC object.
1204
1205                @param newPointer TiXmlNode* to set.
1206                */
1207                void SetTiXmlPointer( T* newPointer )
1208                {
1209                        m_tiXmlPointer = newPointer;
1210                        SetImpRC( newPointer );
1211                }
1212
1213                /**
1214                @internal
1215                Constructor used by child classes.
1216                */
1217                NodeImp( T* tiXmlPointer )
1218                {
1219                        // Check for NULL pointers
1220                        if ( 0 == tiXmlPointer )
1221                        {
1222                                TICPPTHROW( "Can not create a " << typeid( T ).name() );
1223                        }
1224                        SetTiXmlPointer( tiXmlPointer );
1225                        m_impRC->IncRef();
1226                }
1227
1228                /**
1229                @internal
1230                Updates the reference count for the old and new pointers.
1231                In addition, the spawnedWrappers must be cleared out before a new TiXml object is loaded in.
1232                */
1233                virtual void operator=( const NodeImp<T>& copy )
1234                {
1235                        DeleteSpawnedWrappers();
1236
1237                        // Dropping the reference to the old object
1238                        this->m_impRC->DecRef();
1239
1240                        // Pointing to the new Object
1241                        SetTiXmlPointer( copy.m_tiXmlPointer );
1242
1243                        // The internal tixml pointer changed in the above line
1244                        this->m_impRC->IncRef();
1245                }
1246
1247                /**
1248                @internal
1249                Updates the reference count for the old and new pointers.
1250                In addition, the spawnedWrappers must be cleared out before a new TiXml object is loaded in
1251                */
1252                NodeImp( const NodeImp<T>& copy ) : Node( copy )
1253                {
1254                        // Pointing to the new Object
1255                        SetTiXmlPointer( copy.m_tiXmlPointer );
1256
1257                        // The internal tixml pointer changed in the above line
1258                        this->m_impRC->IncRef();
1259                }
1260
1261        public:
1262
1263                /*
1264                Deletes the spawned wrapper objects.
1265                Decrements reference count.
1266                */
1267                virtual ~NodeImp()
1268                {
1269                        // The spawnedWrappers need to be deleted before m_tiXmlPointer
1270                        DeleteSpawnedWrappers();
1271                        m_impRC->DecRef();
1272                }
1273        };
1274
1275        /** Wrapper around TiXmlComment */
1276        class Comment : public NodeImp< TiXmlComment >
1277        {
1278        public:
1279
1280                /**
1281                Constructor.
1282                */
1283                Comment();
1284
1285                /**
1286                Constructor.
1287                */
1288                Comment( TiXmlComment* comment );
1289
1290                /**
1291                Constructor.
1292                */
1293                Comment( const std::string& comment );
1294        };
1295
1296        /** Wrapper around TiXmlText */
1297        class Text : public NodeImp< TiXmlText >
1298        {
1299        public:
1300
1301                /**
1302                Constructor.
1303                */
1304                Text();
1305
1306                /**
1307                Constructor.
1308                @overload
1309                */
1310                Text( TiXmlText* text );
1311
1312                /**
1313                Constructor.
1314                @overload
1315                */
1316                Text( const std::string& value );
1317
1318                /**
1319                Streams value into a string and creates a Text with it.
1320                Uses ToString to covert the parameter to a string.
1321
1322                @param value The value of the Text node.
1323                @throws Exception
1324
1325                @see TiXmlText
1326        */
1327                template < class T >
1328                        Text( const T& value )
1329                                : NodeImp< TiXmlText >( new TiXmlText( ToString( value ) ) )
1330                {
1331                        m_impRC->InitRef();
1332                }
1333        };
1334
1335        /** Wrapper around TiXmlDocument */
1336        class Document : public NodeImp< TiXmlDocument >
1337        {
1338        public:
1339                /**
1340                Default Constructor.
1341                Create an empty document, that has no name.
1342                */
1343                Document();
1344
1345                /**
1346                Constructor.
1347                */
1348                Document( TiXmlDocument* document );
1349
1350                /**
1351                Constructor.
1352                */
1353                Document( const char* documentName );
1354
1355                /**
1356                Constructor.
1357                Create a document with a name. The name of the document is also the filename of the xml.
1358
1359                @param documentName Name to set in the Document.
1360                */
1361                Document( const std::string& documentName );
1362
1363                /**
1364                Load a file using the current document value. Throws if load is unsuccessful.
1365
1366                @param encoding Sets the documents encoding.
1367                @see TiXmlEncoding
1368                @throws Exception
1369                */
1370                void LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1371
1372                /**
1373                Save a file using the current document value. Throws if it can't save the file.
1374
1375                @throws Exception
1376                */
1377                void SaveFile() const;
1378
1379                /**
1380                Load a file using the given filename. Throws if load is unsuccessful.
1381
1382                @param filename File to load.
1383                @param encoding Sets the documents encoding.
1384                @see TiXmlEncoding
1385                @throws Exception
1386                */
1387                void LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1388
1389                /**
1390                @copydoc Document::LoadFile( const std::string&, TiXmlEncoding )
1391                */
1392                void LoadFile( const char* filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1393
1394                /**
1395                Save a file using the given filename. Throws if it can't save the file.
1396
1397                @param filename File to save.
1398                @throws Exception
1399                */
1400                void SaveFile( const std::string& filename ) const;
1401
1402                /**
1403                Parse the given xml data.
1404
1405                @param xml Xml to parse.
1406                @param throwIfParseError [DEF] If true, throws when there is a parse error.
1407                @param encoding Sets the documents encoding.
1408                @throws Exception
1409                */
1410                void Parse( const std::string& xml, bool throwIfParseError = true, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1411        };
1412
1413        /** Wrapper around TiXmlElement */
1414        class Element : public NodeImp< TiXmlElement >
1415        {
1416        public:
1417                /**
1418                Default Constructor.
1419                */
1420                Element();
1421
1422                /**
1423                Default Constructor. Initializes all the variables.
1424                @param value The value of the element.
1425                */
1426                Element( const std::string& value );
1427
1428                /**
1429                Default Constructor. Initializes all the variables.
1430                @param value The value of the element.
1431                */
1432                Element( const char* value );
1433
1434                /**
1435                Constructor.
1436                */
1437                Element( TiXmlElement* element );
1438
1439                /**
1440                Constructor that allows you to set the element text
1441                @param value The value of the element.
1442                @param text The text to set.
1443                */
1444                template < class T >
1445                        Element( const std::string& value, const T& text )
1446                        : NodeImp< TiXmlElement >( new TiXmlElement( value ) )
1447                {
1448                        m_impRC->InitRef();
1449                        SetText( text );
1450                }
1451
1452                /**
1453                Access the first attribute in this element.
1454
1455                @param throwIfNoAttributes [DEF] If true, throws when there are no attributes
1456                @return The first attribute, NULL if there are none and @a throwIfNoAttributes is true
1457                */
1458                Attribute* FirstAttribute( bool throwIfNoAttributes = true ) const;
1459
1460                /**
1461                Access the last attribute in this element.
1462
1463                @param throwIfNoAttributes [DEF] If true, throws when there are no attributes
1464                @return The last attribute, NULL if there are none and @a throwIfNoAttributes is true
1465                */
1466                Attribute* LastAttribute( bool throwIfNoAttributes = true ) const;
1467
1468                /**
1469                @internal
1470                Just for Iterator<>
1471
1472                @param value The value of nodes to iterate through
1473                @param next [OUT] The pointer to the first valid node
1474                */
1475                void IterateFirst( const std::string&, Attribute** first ) const
1476                {
1477                        *first = 0;
1478                        for( Attribute* child = FirstAttribute( false ); child; child = child->Next( false ) )
1479                        {
1480                                *first = dynamic_cast< Attribute* >( child );
1481                                if ( 0 != *first )
1482                                {
1483                                        return;
1484                                }
1485                        }
1486                }
1487
1488                /**
1489                Sets an attribute of name to a given value.
1490                The attribute will be created if it does not exist, or changed if it does.
1491                Uses ToString to convert the @a value to a string, so there is no need to use any other SetAttribute methods.
1492
1493                @see GetAttribute
1494                */
1495                template < class T >
1496                        void SetAttribute ( const std::string& name, const T& value )
1497                {
1498                        ValidatePointer();
1499                        m_tiXmlPointer->SetAttribute( name, ToString( value ) );
1500                }
1501
1502                /**
1503                Gets the text of an Element.
1504
1505                @param throwIfNotFound  [DEF]   If true, will throw an exception if there is no text in this element
1506                @note This only works if the Text is the FirstChild node
1507                @throws Exception When there is no text and throwIfNotFound is true
1508
1509                @see GetText( T* value, bool throwIfNotFound = false )
1510                @see GetTextOrDefault
1511                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1512                @see TiXmlElement::GetText
1513                */
1514                std::string GetText( bool throwIfNotFound = true ) const
1515                {
1516                        // Get the element's text value as a std::string
1517                        std::string temp;
1518                        if ( !GetTextImp( &temp ) )
1519                        {
1520                                if ( throwIfNotFound )
1521                                {
1522                                        TICPPTHROW( "Text does not exists in the current element" );
1523                                }
1524                        }
1525
1526                        return temp;
1527                }
1528
1529                /**
1530                Gets the text of an Element, if it doesn't exist it will return the defaultValue.
1531
1532                @param defaultValue                     What to put in 'value' if there is no text in this element
1533                @note This only works if the Text is the FirstChild node
1534
1535                @see GetText
1536                @see GetText( T* value, bool throwIfNotFound = false )
1537                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1538                @see TiXmlElement::GetText
1539                */
1540                std::string GetTextOrDefault( const std::string& defaultValue ) const
1541                {
1542                        // Get the element's text value as a std::string
1543                        std::string temp;
1544                        if ( !GetTextImp( &temp ) )
1545                        {
1546                                return defaultValue;
1547                        }
1548
1549                        return temp;
1550                }
1551
1552                /**
1553                Gets the text value of an Element, if it doesn't exist it will return the defaultValue.
1554                Uses FromString to convert the string to the type of choice
1555
1556                @param value            [OUT]   The container for the returned value
1557                @param defaultValue                     What to put in 'value' if there is no text in this element
1558                @note This is different than GetText() in that it will covert the text to what ever type you want.
1559                @note This only works if the Text is the FirstChild node
1560
1561                @see GetText
1562                @see GetText( T* value, bool throwIfNotFound = false )
1563                @see GetTextOrDefault( const std::string& defaultValue )
1564                @see TiXmlElement::GetText
1565                */
1566                template < class T, class DefaultT >
1567                        void GetTextOrDefault( T* value, const DefaultT& defaultValue ) const
1568                {
1569                        // Get the element's text value as a std::string
1570                        std::string temp;
1571                        if ( !GetTextImp( &temp ) )
1572                        {
1573                                // The text value does not exist - set value to the default
1574                                *value = defaultValue;
1575                                return;
1576                        }
1577
1578                        // Stream the value from the string to T
1579                        FromString( temp, value );
1580                }
1581
1582                /**
1583                Gets the text of an Element.
1584                Uses FromString to convert the string to the type of choice.
1585
1586                @param value                    [OUT]   The container for the returned value
1587                @param throwIfNotFound  [DEF]   If true, will throw an exception if there is no text in this element
1588                @note This is different than GetText() in that it will covert the text to what ever type you want
1589                @note This only works if the Text is the FirstChild node
1590                @throws Exception When there is no text and throwIfNotFound is true
1591
1592                @see GetText
1593                @see GetTextOrDefault
1594                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1595                @see TiXmlElement::GetText
1596                */
1597                template< class T >
1598                        void GetText( T* value, bool throwIfNotFound = true ) const
1599                {
1600                        // Get the element's text value as a std::string
1601                        std::string temp;
1602                        if ( !GetTextImp( &temp ) )
1603                        {
1604                                if ( throwIfNotFound )
1605                                {
1606                                        TICPPTHROW( "Text does not exists in the current element" );
1607                                }
1608                                else
1609                                {
1610                                        return;
1611                                }
1612                        }
1613
1614                        // Stream the value from the string to T
1615                        FromString( temp, value );
1616                }
1617
1618                /**
1619                Convenience function to set the text of an element.
1620                Creates a Text node and inserts it as the first child.
1621                Uses ToString to convert the parameter to a string.
1622
1623                @param value The text to set.
1624                */
1625                template < class T >
1626                        void SetText( const T& value )
1627                {
1628                        ValidatePointer();
1629                        std::string temp = ToString( value );
1630
1631                        if ( m_tiXmlPointer->NoChildren() )
1632                        {
1633                                m_tiXmlPointer->LinkEndChild( new TiXmlText( temp ) );
1634                        }
1635                        else
1636                        {
1637                                if ( 0 == m_tiXmlPointer->GetText() )
1638                                {
1639                                        m_tiXmlPointer->InsertBeforeChild( m_tiXmlPointer->FirstChild(), TiXmlText( temp ) );
1640                                }
1641                                else
1642                                {
1643                                        // There already is text, so change it
1644                                        m_tiXmlPointer->FirstChild()->SetValue( temp );
1645                                }
1646                        }
1647                }
1648
1649                /**
1650                Gets an attribute of @a name from an element, if it doesn't exist it will return the defaultValue.
1651                Uses FromString to convert the string to the type of choice.
1652
1653                @param name                     The name of the attribute you are querying.
1654                @param value            [OUT] The container for the returned value.
1655                @param defaultValue     What to put in @a value if there is no attribute in this element.
1656                @throws Exception
1657
1658                @see GetAttribute
1659                */
1660                template < class T, class DefaulT >
1661                        void GetAttributeOrDefault( const std::string& name, T* value, const DefaulT& defaultValue ) const
1662                {
1663                        // Get the attribute's value as a std::string
1664                        std::string temp;
1665                        if ( !GetAttributeImp( name, &temp ) )
1666                        {
1667                                // The attribute does not exist - set value to the default
1668                                *value = defaultValue;
1669                                return;
1670                        }
1671
1672                        // Stream the value from the string to T
1673                        FromString( temp, value );
1674                }
1675
1676                /**
1677                Gets an attribute of @a name from an element, if it doesn't exist it will return the defaultValue.
1678
1679                @param name                     The name of the attribute you are querying.
1680                @param defaultValue     What to put in @a value if there is no attribute in this element.
1681
1682                @see GetAttribute
1683                */
1684                std::string GetAttributeOrDefault( const std::string& name, const std::string& defaultValue ) const;
1685
1686                /**
1687                Gets an attribute of @a name from an element.
1688                Uses FromString to convert the string to the type of choice.
1689
1690                @param name                             The name of the attribute you are querying.
1691                @param value                    [OUT]   The container for the returned value
1692                @param throwIfNotFound  [DEF]   If true, will throw an exception if the attribute doesn't exist
1693                @throws Exception When the attribute doesn't exist and throwIfNotFound is true
1694
1695                @see GetAttributeOrDefault
1696                */
1697                template< class T >
1698                        void GetAttribute( const std::string& name, T* value, bool throwIfNotFound = true ) const
1699                {
1700                        // Get the attribute's value as a std::string
1701                        std::string temp;
1702                        if ( !GetAttributeImp( name, &temp ) )
1703                        {
1704                                if ( throwIfNotFound )
1705                                {
1706                                        TICPPTHROW( "Attribute does not exist" );
1707                                }
1708                                else
1709                                {
1710                                        return;
1711                                }
1712                        }
1713
1714                        // Stream the value from the string to T
1715                        FromString( temp, value );
1716                }
1717
1718                /**
1719                Gets an attribute of @a name from an element.
1720                Returns an empty string if the attribute does not exist.
1721
1722                @param name     The name of the attribute you are querying.
1723                @return The value of the attribute, or an empty string if it does not exist.
1724
1725                @see GetAttributeOrDefault
1726                */
1727                std::string GetAttribute( const std::string& name ) const;
1728
1729        private:
1730
1731                /**
1732                @internal
1733                Implimentation of the GetAttribute and GetAttributeOrDefault template methods.
1734                */
1735                bool GetAttributeImp( const std::string& name, std::string* value ) const;
1736
1737                /**
1738                @internal
1739                Implimentation of the GetText, GetTextOrDefault, GetTextValue, and GetTextValueOrDefault template methods.
1740                */
1741                bool GetTextImp( std::string* value ) const;
1742        };
1743
1744        /** Wrapper around TiXmlDeclaration */
1745        class Declaration : public NodeImp< TiXmlDeclaration >
1746        {
1747        public:
1748                /**
1749                Default Constructor. Construct an empty declaration.
1750                */
1751                Declaration();
1752
1753                /**
1754                Constructor.
1755                */
1756                Declaration( TiXmlDeclaration* declaration );
1757
1758                /**
1759                Constructor.
1760                */
1761                Declaration( const std::string& version, const std::string& encoding, const std::string& standalone );
1762
1763                /**
1764                Version. Will return an empty string if none was found.
1765                */
1766                std::string Version() const;
1767
1768                /**
1769                Encoding. Will return an empty string if none was found.
1770                */
1771                std::string Encoding() const;
1772
1773                /**
1774                StandAlone. Is this a standalone document?
1775                */
1776                std::string Standalone() const;
1777        };
1778
1779        /** Wrapper around TiXmlStylesheetReference */
1780        class StylesheetReference : public NodeImp< TiXmlStylesheetReference >
1781        {
1782        public:
1783                /**
1784                Default Constructor. Construct an empty declaration.
1785                */
1786                StylesheetReference();
1787
1788                /**
1789                Constructor.
1790                */
1791                StylesheetReference( TiXmlStylesheetReference* stylesheetReference );
1792
1793                /**
1794                Constructor.
1795                */
1796                StylesheetReference( const std::string& type, const std::string& href );
1797
1798                /**
1799                Type. Will return an empty string if none was found.
1800                */
1801                std::string Type() const;
1802
1803                /**
1804                Href. Will return an empty string if none was found.
1805                */
1806                std::string Href() const;
1807        };
1808}
1809
1810#endif  // TICPP_INCLUDED
1811
1812#endif // TIXML_USE_TICPP
Note: See TracBrowser for help on using the repository browser.