Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Updated tinycpp to it's trunk revision 98.
Note that our own changes are lost for now. Going to merge them in right after.
Added readme.txt with license and changes.txt.

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