![]() |
OpenAlbum 1.0.b
|
00001 /* 00002 http://code.google.com/p/ticpp/ 00003 Copyright (c) 2006 Ryan Pusztai, Ryan Mulder 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy of 00006 this software and associated documentation files (the "Software"), to deal in 00007 the Software without restriction, including without limitation the rights to 00008 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 00009 the Software, and to permit persons to whom the Software is furnished to do so, 00010 subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in all 00013 copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 00017 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 00018 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 00019 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00020 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00021 */ 00022 00041 #ifdef TIXML_USE_TICPP 00042 00043 #ifndef TICPP_INCLUDED 00044 #define TICPP_INCLUDED 00045 00046 #include "tinyxml.h" 00047 #include <sstream> 00048 #include <vector> 00049 #include <memory> 00050 #include <exception> 00051 #include <typeinfo> 00052 00063 namespace ticpp 00064 { 00068 class Exception : public std::exception 00069 { 00070 public: 00074 Exception( const std::string& details ); 00075 ~Exception() throw(); 00076 00078 const char* what() const throw(); 00079 00080 std::string m_details; 00081 }; 00082 00087 #define TICPPTHROW( message ) \ 00088 { \ 00089 std::ostringstream full_message; \ 00090 std::string file( __FILE__ ); \ 00091 file = file.substr( file.find_last_of( "\\/" ) + 1 ); \ 00092 full_message << message << " <" << file << "@" << __LINE__ << ">"; \ 00093 full_message << BuildDetailedErrorString(); \ 00094 throw Exception( full_message.str() ); \ 00095 } 00096 00097 // Forward Declarations for Visitor, and others. 00098 class Document; 00099 class Element; 00100 class Declaration; 00101 class StylesheetReference; 00102 class Text; 00103 class Comment; 00104 class Attribute; 00105 00107 class Visitor : public TiXmlVisitor 00108 { 00109 public: 00110 // Overload the TiXmlVisitor functions, wrap objects, call ticpp::Visitor functions 00112 virtual bool VisitEnter( const TiXmlDocument& doc ); 00114 virtual bool VisitExit( const TiXmlDocument& doc ); 00116 virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); 00118 virtual bool VisitExit( const TiXmlElement& element ); 00120 virtual bool Visit( const TiXmlDeclaration& declaration ); 00122 virtual bool Visit( const TiXmlStylesheetReference& stylesheet ); 00124 virtual bool Visit( const TiXmlText& text ); 00126 virtual bool Visit( const TiXmlComment& comment ); 00127 00128 public: 00130 virtual bool VisitEnter( const Document& /*doc*/ ) { return true; } 00132 virtual bool VisitExit( const Document& /*doc*/ ) { return true; } 00133 00135 virtual bool VisitEnter( const Element& /*element*/, const Attribute* /*firstAttribute*/ ) { return true; } 00137 virtual bool VisitExit( const Element& /*element*/ ) { return true; } 00138 00140 virtual bool Visit( const Declaration& /*declaration*/ ) { return true; } 00142 virtual bool Visit( const StylesheetReference& /*stylesheet*/ ) { return true; } 00144 virtual bool Visit( const Text& /*text*/ ) { return true; } 00146 virtual bool Visit( const Comment& /*comment*/ ) { return true; } 00147 }; 00148 00150 class Base 00151 { 00152 public: 00153 00159 template < class T > 00160 std::string ToString( const T& value ) const 00161 { 00162 std::stringstream convert; 00163 convert << value; 00164 if ( convert.fail() ) 00165 { 00166 TICPPTHROW( "Could not convert value to text" ); 00167 } 00168 return convert.str(); 00169 } 00170 00171 std::string ToString( const std::string& value ) const 00172 { 00173 return value; 00174 } 00175 00182 template < class T > 00183 void FromString( const std::string& temp, T* out ) const 00184 { 00185 std::istringstream val( temp ); 00186 val >> *out; 00187 00188 if ( val.fail() ) 00189 { 00190 TICPPTHROW( "Could not convert \"" << temp << "\" to target type" ); 00191 } 00192 } 00193 00197 void FromString( const std::string& temp, std::string* out ) const 00198 { 00199 *out = temp; 00200 } 00201 00206 int Row() const 00207 { 00208 return GetBasePointer()->Row(); 00209 } 00210 00215 int Column() const 00216 { 00217 return GetBasePointer()->Column(); 00218 } 00219 00223 bool operator == ( const Base& rhs ) const 00224 { 00225 return ( GetBasePointer() == rhs.GetBasePointer() ); 00226 } 00227 00231 bool operator != ( const Base& rhs ) const 00232 { 00233 return ( GetBasePointer() != rhs.GetBasePointer() ); 00234 } 00235 00239 std::string BuildDetailedErrorString() const 00240 { 00241 std::ostringstream full_message; 00242 #ifndef TICPP_NO_RTTI 00243 TiXmlNode* node = dynamic_cast< TiXmlNode* >( GetBasePointer() ); 00244 if ( node != 0 ) 00245 { 00246 TiXmlDocument* doc = node->GetDocument(); 00247 if ( doc != 0 ) 00248 { 00249 if ( doc->Error() ) 00250 { 00251 full_message << "\nDescription: " << doc->ErrorDesc() 00252 << "\nFile: " << (strlen( doc->Value() ) > 0 ? doc->Value() : "<unnamed-file>") 00253 << "\nLine: " << doc->ErrorRow() 00254 << "\nColumn: " << doc->ErrorCol(); 00255 } 00256 } 00257 } 00258 #endif 00259 return full_message.str(); 00260 } 00261 00265 virtual ~Base() 00266 { 00267 } 00268 00269 protected: 00270 mutable TiCppRCImp* m_impRC; 00278 void SetImpRC( TiXmlBase* node ) 00279 { 00280 m_impRC = node->m_tiRC; 00281 } 00282 00283 void ValidatePointer() const 00284 { 00285 if ( m_impRC->IsNull() ) 00286 { 00287 TICPPTHROW( "Internal TiXml Pointer is NULL" ); 00288 } 00289 } 00290 00295 virtual TiXmlBase* GetBasePointer() const = 0; 00296 }; 00297 00301 class Attribute : public Base 00302 { 00303 private: 00304 TiXmlAttribute* m_tiXmlPointer; 00305 TiXmlBase* GetBasePointer() const 00306 { 00307 ValidatePointer(); 00308 return m_tiXmlPointer; 00309 } 00310 00311 public: 00315 Attribute(); 00316 00323 Attribute( const std::string& name, const std::string& value ); 00324 00331 Attribute( TiXmlAttribute* attribute ); 00332 00340 template < class T > 00341 void GetValue( T* value ) const 00342 { 00343 ValidatePointer(); 00344 FromString( m_tiXmlPointer->ValueStr(), value ); 00345 } 00346 00353 std::string Value() const; 00354 00361 template < class T > 00362 void SetValue( const T& value ) 00363 { 00364 ValidatePointer(); 00365 m_tiXmlPointer->SetValue( ToString( value ) ); 00366 } 00367 00375 template < class T > 00376 void GetName( T* name ) const 00377 { 00378 ValidatePointer(); 00379 FromString( m_tiXmlPointer->Name(), name ); 00380 } 00381 00388 std::string Name() const; 00389 00396 template < class T > 00397 void SetName( const T& name ) 00398 { 00399 ValidatePointer(); 00400 m_tiXmlPointer->SetName( ToString( name ) ); 00401 } 00402 00407 void operator=( const Attribute& copy ); 00408 00413 Attribute( const Attribute& copy ); 00414 00415 /* 00416 Decrements reference count. 00417 */ 00418 ~Attribute(); 00419 00423 Attribute* Next( bool throwIfNoAttribute = true ) const; 00424 00428 Attribute* Previous( bool throwIfNoAttribute = true ) const; 00429 00437 void IterateNext( const std::string&, Attribute** next ) const; 00438 00446 void IteratePrevious( const std::string&, Attribute** previous ) const; 00447 00451 virtual void Print( FILE* file, int depth ) const; 00452 00453 private: 00454 00462 void SetTiXmlPointer( TiXmlAttribute* newPointer ); 00463 }; 00464 00468 class Node : public Base 00469 { 00470 public: 00471 00479 template < class T > 00480 void GetValue( T* value) const 00481 { 00482 FromString( GetTiXmlPointer()->ValueStr(), value ); 00483 } 00484 00491 std::string Value() const; 00492 00499 template < class T > 00500 void SetValue( const T& value ) 00501 { 00502 GetTiXmlPointer()->SetValue( ToString( value ) ); 00503 } 00504 00509 void Clear(); 00510 00519 Node* Parent( bool throwIfNoParent = true ) const; 00520 00530 Node* FirstChild( bool throwIfNoChildren = true ) const; 00531 00542 Node* FirstChild( const char* value, bool throwIfNoChildren = true ) const; 00543 00553 Node* FirstChild( const std::string& value, bool throwIfNoChildren = true ) const; 00554 00564 Node* LastChild( bool throwIfNoChildren = true ) const; 00565 00576 Node* LastChild( const char* value, bool throwIfNoChildren = true ) const; 00577 00587 Node* LastChild( const std::string& value, bool throwIfNoChildren = true ) const; 00588 00596 Node* IterateChildren( Node* previous ) const; 00597 00606 Node* IterateChildren( const std::string& value, Node* previous ) const; 00607 00619 Node* InsertEndChild( Node& addThis ); 00620 00631 Node* LinkEndChild( Node* childNode ); 00632 00644 Node* InsertBeforeChild( Node* beforeThis, Node& addThis ); 00645 00657 Node* InsertAfterChild( Node* afterThis, Node& addThis ); 00658 00669 Node* ReplaceChild( Node* replaceThis, Node& withThis ); 00670 00679 void RemoveChild( Node* removeThis ); 00680 00689 Node* PreviousSibling( bool throwIfNoSiblings = true ) const; 00690 00700 Node* PreviousSibling( const std::string& value, bool throwIfNoSiblings = true ) const; 00701 00712 Node* PreviousSibling( const char* value, bool throwIfNoSiblings = true ) const; 00713 00722 Node* NextSibling( bool throwIfNoSiblings = true ) const; 00723 00733 Node* NextSibling( const std::string& value, bool throwIfNoSiblings = true ) const; 00734 00745 Node* NextSibling( const char* value, bool throwIfNoSiblings = true ) const; 00746 00754 template < class T > 00755 void IterateFirst( const std::string& value, T** first ) const 00756 { 00757 *first = 0; 00758 for( Node* child = FirstChild( value, false ); child; child = child->NextSibling( value, false ) ) 00759 { 00760 *first = dynamic_cast< T* >( child ); 00761 if ( 0 != *first ) 00762 { 00763 return; 00764 } 00765 } 00766 } 00767 00768 virtual void IterateFirst( const std::string&, Attribute** ) const 00769 { 00770 TICPPTHROW( "Attributes can only be iterated with Elements." ) 00771 } 00772 00780 template < class T > 00781 void IterateNext( const std::string& value, T** next ) const 00782 { 00783 Node* sibling = NextSibling( value, false ); 00784 *next = dynamic_cast< T* >( sibling ); 00785 00786 while ( ( 0 != sibling ) && ( 0 == *next ) ) 00787 { 00788 sibling = sibling->NextSibling( value, false ); 00789 *next = dynamic_cast< T* >( sibling ); 00790 } 00791 } 00792 00800 template < class T > 00801 void IteratePrevious( const std::string& value, T** previous ) const 00802 { 00803 Node* sibling = PreviousSibling( value, false ); 00804 *previous = dynamic_cast< T* >( sibling ); 00805 00806 while ( ( 0 != sibling ) && ( 0 == *previous ) ) 00807 { 00808 sibling = sibling->PreviousSibling( value, false ); 00809 *previous = dynamic_cast< T* >( sibling ); 00810 } 00811 } 00812 00821 Element* NextSiblingElement( bool throwIfNoSiblings = true ) const; 00822 00831 Element* NextSiblingElement( const std::string& value, bool throwIfNoSiblings = true ) const; 00832 00843 Element* NextSiblingElement( const char* value, bool throwIfNoSiblings = true ) const; 00844 00854 Element* FirstChildElement( bool throwIfNoChildren = true ) const; 00855 00866 Element* FirstChildElement( const char* value, bool throwIfNoChildren = true ) const; 00867 00877 Element* FirstChildElement( const std::string& value, bool throwIfNoChildren = true ) const; 00878 00882 int Type() const; 00883 00891 Document* GetDocument( bool throwIfNoDocument = true ) const; 00892 00898 bool NoChildren() const; 00899 00900 #ifndef TICPP_NO_RTTI 00901 00907 template < class T > 00908 T* To() const 00909 { 00910 T* pointer = dynamic_cast< T* >( this ); 00911 if ( 0 == pointer ) 00912 { 00913 std::string thisType = typeid( this ).name(); 00914 std::string targetType = typeid( T ).name(); 00915 std::string thatType = typeid( *this ).name(); 00916 TICPPTHROW( "The " << thisType.substr( 6 ) << " could not be casted to a " << targetType.substr( 6 ) 00917 << " *, because the target object is not a " << targetType.substr( 6 ) << ". (It is a " << thatType.substr( 6 ) << ")" ); 00918 } 00919 return pointer; 00920 } 00921 #endif 00922 00928 Document* ToDocument() const; 00929 00935 Element* ToElement() const; 00936 00942 Comment* ToComment() const; 00943 00949 Text* ToText() const; 00950 00956 Declaration* ToDeclaration() const; 00957 00963 StylesheetReference* ToStylesheetReference() const; 00964 00982 std::auto_ptr< Node > Clone() const; 00983 00988 bool Accept( TiXmlVisitor* visitor ) const; 00989 00993 friend std::istream& operator >>( std::istream& in, Node& base ) 00994 { 00995 in >> *base.GetTiXmlPointer(); 00996 return in; 00997 } 00998 01002 friend std::ostream& operator <<( std::ostream& out, const Node& base ) 01003 { 01004 out << *base.GetTiXmlPointer(); 01005 return out; 01006 } 01007 01008 protected: 01013 virtual TiXmlNode* GetTiXmlPointer() const = 0; 01014 01015 TiXmlBase* GetBasePointer() const 01016 { 01017 return GetTiXmlPointer(); 01018 } 01019 01024 Node* NodeFactory( TiXmlNode* tiXmlNode, bool throwIfNull = true, bool rememberSpawnedWrapper = true ) const; 01025 01026 }; 01027 01054 template < class T = Node > 01055 class Iterator 01056 { 01057 private: 01058 T* m_p; 01059 std::string m_value; 01061 public: 01062 01072 T* begin( const Node* parent ) const 01073 { 01074 T* pointer; 01075 parent->IterateFirst( m_value, &pointer ); 01076 return pointer; 01077 } 01078 01087 T* end() const 01088 { 01089 return 0; 01090 } 01091 01100 Iterator( const std::string& value = "" ) 01101 : m_p( 0 ), m_value( value ) 01102 { 01103 } 01104 01106 Iterator( T* node, const std::string& value = "" ) 01107 : m_p( node ), m_value( value ) 01108 { 01109 } 01110 01112 Iterator( const Iterator& it ) 01113 : m_p( it.m_p ), m_value( it.m_value ) 01114 { 01115 } 01116 01121 T* Get() const 01122 { 01123 return m_p; 01124 } 01125 01127 Iterator& operator=( const Iterator& it ) 01128 { 01129 m_p = it.m_p; 01130 m_value = it.m_value; 01131 return *this; 01132 } 01133 01135 Iterator& operator=( T* p ) 01136 { 01137 m_p = p; 01138 return *this; 01139 } 01140 01142 Iterator& operator++() 01143 { 01144 m_p->IterateNext( m_value, &m_p ); 01145 return *this; 01146 } 01147 01149 Iterator operator++(int) 01150 { 01151 Iterator tmp(*this); 01152 ++(*this); 01153 return tmp; 01154 } 01155 01157 Iterator& operator--() 01158 { 01159 m_p->IteratePrevious( m_value, &m_p ); 01160 return *this; 01161 } 01162 01164 Iterator operator--(int) 01165 { 01166 Iterator tmp(*this); 01167 --(*this); 01168 return tmp; 01169 } 01170 01172 bool operator!=( const T* p ) const 01173 { 01174 if ( m_p == p ) 01175 { 01176 return false; 01177 } 01178 if ( 0 == m_p || 0 == p ) 01179 { 01180 return true; 01181 } 01182 return *m_p != *p; 01183 } 01184 01186 bool operator!=( const Iterator& it ) const 01187 { 01188 return operator!=( it.m_p ); 01189 } 01190 01192 bool operator==( T* p ) const 01193 { 01194 if ( m_p == p ) 01195 { 01196 return true; 01197 } 01198 if ( 0 == m_p || 0 == p ) 01199 { 01200 return false; 01201 } 01202 return *m_p == *p; 01203 } 01204 01206 bool operator==( const Iterator& it ) const 01207 { 01208 return operator==( it.m_p ); 01209 } 01210 01212 T* operator->() const 01213 { 01214 return m_p; 01215 } 01216 01218 T& operator*() const 01219 { 01220 return *m_p; 01221 } 01222 }; 01223 01225 template < class T > 01226 class NodeImp : public Node 01227 { 01228 protected: 01229 01230 T* m_tiXmlPointer; 01238 TiXmlNode* GetTiXmlPointer() const 01239 { 01240 ValidatePointer(); 01241 return m_tiXmlPointer; 01242 } 01243 01251 void SetTiXmlPointer( T* newPointer ) 01252 { 01253 m_tiXmlPointer = newPointer; 01254 SetImpRC( newPointer ); 01255 } 01256 01261 NodeImp( T* tiXmlPointer ) 01262 { 01263 // Check for NULL pointers 01264 if ( 0 == tiXmlPointer ) 01265 { 01266 #ifdef TICPP_NO_RTTI 01267 TICPPTHROW( "Can not create TinyXML objext" ); 01268 #else 01269 TICPPTHROW( "Can not create a " << typeid( T ).name() ); 01270 #endif 01271 } 01272 SetTiXmlPointer( tiXmlPointer ); 01273 m_impRC->IncRef(); 01274 } 01275 01281 virtual void operator=( const NodeImp<T>& copy ) 01282 { 01283 // Dropping the reference to the old object 01284 this->m_impRC->DecRef(); 01285 01286 // Pointing to the new Object 01287 SetTiXmlPointer( copy.m_tiXmlPointer ); 01288 01289 // The internal tixml pointer changed in the above line 01290 this->m_impRC->IncRef(); 01291 } 01292 01298 NodeImp( const NodeImp<T>& copy ) : Node( copy ) 01299 { 01300 // Pointing to the new Object 01301 SetTiXmlPointer( copy.m_tiXmlPointer ); 01302 01303 // The internal tixml pointer changed in the above line 01304 this->m_impRC->IncRef(); 01305 } 01306 01307 public: 01308 01309 /* 01310 Deletes the spawned wrapper objects. 01311 Decrements reference count. 01312 */ 01313 virtual ~NodeImp() 01314 { 01315 m_impRC->DecRef(); 01316 } 01317 }; 01318 01320 class Comment : public NodeImp< TiXmlComment > 01321 { 01322 public: 01323 01327 Comment(); 01328 01332 Comment( TiXmlComment* comment ); 01333 01337 Comment( const std::string& comment ); 01338 }; 01339 01341 class Text : public NodeImp< TiXmlText > 01342 { 01343 public: 01344 01348 Text(); 01349 01354 Text( TiXmlText* text ); 01355 01360 Text( const std::string& value ); 01361 01371 template < class T > 01372 Text( const T& value ) 01373 : NodeImp< TiXmlText >( new TiXmlText( ToString( value ) ) ) 01374 { 01375 m_impRC->InitRef(); 01376 } 01377 }; 01378 01380 class Document : public NodeImp< TiXmlDocument > 01381 { 01382 public: 01387 Document(); 01388 01392 Document( TiXmlDocument* document ); 01393 01397 Document( const char* documentName ); 01398 01405 Document( const std::string& documentName ); 01406 01414 void LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); 01415 01421 void SaveFile() const; 01422 01431 void LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); 01432 01436 void LoadFile( const char* filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); 01437 01444 void SaveFile( const std::string& filename ) const; 01445 01454 void Parse( const std::string& xml, bool throwIfParseError = true, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); 01455 }; 01456 01458 class Element : public NodeImp< TiXmlElement > 01459 { 01460 public: 01464 Element(); 01465 01470 Element( const std::string& value ); 01471 01476 Element( const char* value ); 01477 01481 Element( TiXmlElement* element ); 01482 01488 template < class T > 01489 Element( const std::string& value, const T& text ) 01490 : NodeImp< TiXmlElement >( new TiXmlElement( value ) ) 01491 { 01492 m_impRC->InitRef(); 01493 SetText( text ); 01494 } 01495 01502 Attribute* FirstAttribute( bool throwIfNoAttributes = true ) const; 01503 01510 Attribute* LastAttribute( bool throwIfNoAttributes = true ) const; 01511 01519 void IterateFirst( const std::string&, Attribute** first ) const 01520 { 01521 *first = 0; 01522 for( Attribute* child = FirstAttribute( false ); child; child = child->Next( false ) ) 01523 { 01524 *first = dynamic_cast< Attribute* >( child ); 01525 if ( 0 != *first ) 01526 { 01527 return; 01528 } 01529 } 01530 } 01531 01539 template < class T > 01540 void SetAttribute ( const std::string& name, const T& value ) 01541 { 01542 ValidatePointer(); 01543 m_tiXmlPointer->SetAttribute( name, ToString( value ) ); 01544 } 01545 01558 std::string GetText( bool throwIfNotFound = true ) const 01559 { 01560 // Get the element's text value as a std::string 01561 std::string temp; 01562 if ( !GetTextImp( &temp ) ) 01563 { 01564 if ( throwIfNotFound ) 01565 { 01566 TICPPTHROW( "Text does not exists in the current element" ); 01567 } 01568 } 01569 01570 return temp; 01571 } 01572 01584 std::string GetTextOrDefault( const std::string& defaultValue ) const 01585 { 01586 // Get the element's text value as a std::string 01587 std::string temp; 01588 if ( !GetTextImp( &temp ) ) 01589 { 01590 return defaultValue; 01591 } 01592 01593 return temp; 01594 } 01595 01610 template < class T, class DefaultT > 01611 void GetTextOrDefault( T* value, const DefaultT& defaultValue ) const 01612 { 01613 // Get the element's text value as a std::string 01614 std::string temp; 01615 if ( !GetTextImp( &temp ) ) 01616 { 01617 // The text value does not exist - set value to the default 01618 *value = defaultValue; 01619 return; 01620 } 01621 01622 // Stream the value from the string to T 01623 FromString( temp, value ); 01624 } 01625 01641 template< class T > 01642 void GetText( T* value, bool throwIfNotFound = true ) const 01643 { 01644 // Get the element's text value as a std::string 01645 std::string temp; 01646 if ( !GetTextImp( &temp ) ) 01647 { 01648 if ( throwIfNotFound ) 01649 { 01650 TICPPTHROW( "Text does not exists in the current element" ); 01651 } 01652 else 01653 { 01654 return; 01655 } 01656 } 01657 01658 // Stream the value from the string to T 01659 FromString( temp, value ); 01660 } 01661 01669 template < class T > 01670 void SetText( const T& value ) 01671 { 01672 ValidatePointer(); 01673 std::string temp = ToString( value ); 01674 01675 if ( m_tiXmlPointer->NoChildren() ) 01676 { 01677 m_tiXmlPointer->LinkEndChild( new TiXmlText( temp ) ); 01678 } 01679 else 01680 { 01681 if ( 0 == m_tiXmlPointer->GetText() ) 01682 { 01683 m_tiXmlPointer->InsertBeforeChild( m_tiXmlPointer->FirstChild(), TiXmlText( temp ) ); 01684 } 01685 else 01686 { 01687 // There already is text, so change it 01688 m_tiXmlPointer->FirstChild()->SetValue( temp ); 01689 } 01690 } 01691 } 01692 01704 template < class T, class DefaulT > 01705 void GetAttributeOrDefault( const std::string& name, T* value, const DefaulT& defaultValue ) const 01706 { 01707 // Get the attribute's value as a std::string 01708 std::string temp; 01709 if ( !GetAttributeImp( name, &temp ) ) 01710 { 01711 // The attribute does not exist - set value to the default 01712 *value = defaultValue; 01713 return; 01714 } 01715 01716 // Stream the value from the string to T 01717 FromString( temp, value ); 01718 } 01719 01728 std::string GetAttributeOrDefault( const std::string& name, const std::string& defaultValue ) const; 01729 01739 template < class T > 01740 T GetAttribute( const std::string& name, bool throwIfNotFound = true ) const 01741 { 01742 // Get the attribute's value as a std::string 01743 std::string temp; 01744 T value; 01745 if ( !GetAttributeImp( name, &temp ) ) 01746 { 01747 if ( throwIfNotFound ) 01748 { 01749 TICPPTHROW( "Attribute does not exist" ); 01750 } 01751 } 01752 else 01753 { 01754 // Stream the value from the string to T 01755 FromString( temp, &value ); 01756 } 01757 01758 return value; 01759 } 01760 01772 template< class T > 01773 void GetAttribute( const std::string& name, T* value, bool throwIfNotFound = true ) const 01774 { 01775 // Get the attribute's value as a std::string 01776 std::string temp; 01777 if ( !GetAttributeImp( name, &temp ) ) 01778 { 01779 if ( throwIfNotFound ) 01780 { 01781 TICPPTHROW( "Attribute does not exist" ); 01782 } 01783 else 01784 { 01785 return; 01786 } 01787 } 01788 01789 // Stream the value from the string to T 01790 FromString( temp, value ); 01791 } 01792 01802 std::string GetAttribute( const std::string& name ) const; 01803 01810 bool HasAttribute( const std::string& name ) const; 01811 01817 void RemoveAttribute( const std::string& name ); 01818 01819 private: 01820 01825 bool GetAttributeImp( const std::string& name, std::string* value ) const; 01826 01831 bool GetTextImp( std::string* value ) const; 01832 }; 01833 01835 class Declaration : public NodeImp< TiXmlDeclaration > 01836 { 01837 public: 01841 Declaration(); 01842 01846 Declaration( TiXmlDeclaration* declaration ); 01847 01851 Declaration( const std::string& version, const std::string& encoding, const std::string& standalone ); 01852 01856 std::string Version() const; 01857 01861 std::string Encoding() const; 01862 01866 std::string Standalone() const; 01867 }; 01868 01870 class StylesheetReference : public NodeImp< TiXmlStylesheetReference > 01871 { 01872 public: 01876 StylesheetReference(); 01877 01881 StylesheetReference( TiXmlStylesheetReference* stylesheetReference ); 01882 01886 StylesheetReference( const std::string& type, const std::string& href ); 01887 01891 std::string Type() const; 01892 01896 std::string Href() const; 01897 }; 01898 } 01899 01900 #endif // TICPP_INCLUDED 01901 01902 #endif // TIXML_USE_TICPP