00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00040 #ifdef TIXML_USE_TICPP
00041
00042 #ifndef TICPP_INCLUDED
00043 #define TICPP_INCLUDED
00044
00045 #include "tinyxml.h"
00046 #include <sstream>
00047 #include <vector>
00048 #include <memory>
00049
00060 namespace ticpp
00061 {
00065 class Exception
00066 {
00067 public:
00068 Exception( const std::string& details );
00069
00070 std::string m_details;
00071 };
00072
00077 #define THROW( message ) \
00078 std::stringstream hopefullyThisNameWontConflictWithOtherVariables; \
00079 std::string file( __FILE__ ); \
00080 file = file.substr( file.find_last_of( "\\/" ) + 1 ); \
00081 hopefullyThisNameWontConflictWithOtherVariables << message << " <" << file << "@" << __LINE__ << ">"; \
00082 throw Exception( hopefullyThisNameWontConflictWithOtherVariables.str() );
00083
00085 class Base
00086 {
00087 public:
00088
00094 template < class T >
00095 std::string ToString( const T& value )
00096 {
00097 std::stringstream convert;
00098 convert << value;
00099 if ( convert.fail() )
00100 {
00101 THROW( "Could not convert value to text" );
00102 }
00103 return convert.str();
00104 }
00105
00106 std::string ToString( const std::string& value )
00107 {
00108 return value;
00109 }
00110
00117 template < class T >
00118 void FromString( const std::string& temp, T* out )
00119 {
00120 std::istringstream val( temp );
00121 val >> *out;
00122
00123 if ( val.fail() )
00124 {
00125 THROW( "Could not convert \"" << temp << "\" to target type" );
00126 }
00127 }
00128
00132 void FromString( const std::string& temp, std::string* out )
00133 {
00134 *out = temp;
00135 }
00136
00141 int Row()
00142 {
00143 return GetBasePointer()->Row();
00144 }
00145
00150 int Column()
00151 {
00152 return GetBasePointer()->Column();
00153 }
00154
00158 virtual ~Base()
00159 {
00160 DeleteSpawnedWrappers();
00161 }
00162
00163 protected:
00164 TiCppRCImp* m_impRC;
00166 std::vector< Base* > m_spawnedWrappers;
00174 void SetImpRC( TiXmlBase* node )
00175 {
00176 m_impRC = node->m_tiRC;
00177 }
00178
00179 void ValidatePointer()
00180 {
00181 if ( m_impRC->IsNull() )
00182 {
00183 THROW( "Internal TiXml Pointer is NULL" );
00184 }
00185 }
00186
00191 void DeleteSpawnedWrappers()
00192 {
00193 std::vector< Base* >::reverse_iterator wrapper;
00194 for ( wrapper = m_spawnedWrappers.rbegin(); wrapper != m_spawnedWrappers.rend(); ++wrapper )
00195 {
00196 delete *wrapper;
00197 }
00198 m_spawnedWrappers.clear();
00199 }
00200
00205 virtual TiXmlBase* GetBasePointer() = 0;
00206 };
00207
00211 class Attribute : public Base
00212 {
00213 private:
00214 TiXmlAttribute* m_tiXmlPointer;
00215 TiXmlBase* GetBasePointer()
00216 {
00217 ValidatePointer();
00218 return m_tiXmlPointer;
00219 }
00220
00221 public:
00225 Attribute();
00226
00233 Attribute( const std::string& name, const std::string& value );
00234
00241 Attribute( TiXmlAttribute* attribute );
00242
00250 template < class T >
00251 void GetValue( T* value )
00252 {
00253 ValidatePointer();
00254 FromString( m_tiXmlPointer->ValueStr(), value );
00255 }
00256
00263 std::string Value();
00264
00271 template < class T >
00272 void SetValue( const T& value )
00273 {
00274 ValidatePointer();
00275 m_tiXmlPointer->SetValue( ToString( value ) );
00276 }
00277
00285 template < class T >
00286 void GetName( T* name )
00287 {
00288 ValidatePointer();
00289 FromString( m_tiXmlPointer->Name(), name );
00290 }
00291
00298 std::string Name();
00299
00306 template < class T >
00307 void SetName( const T& name )
00308 {
00309 ValidatePointer();
00310 m_tiXmlPointer->SetName( ToString( name ) );
00311 }
00312
00317 void operator=( const Attribute& copy );
00318
00323 Attribute( const Attribute& copy );
00324
00325
00326
00327
00328 ~Attribute();
00329
00333 Attribute* Next( bool throwIfNoAttribute = true );
00334
00338 Attribute* Previous( bool throwIfNoAttribute = true );
00339
00347 void IterateNext( const std::string&, Attribute** next );
00348
00356 void IteratePrevious( const std::string&, Attribute** previous );
00357
00361 virtual void Print( FILE* file, int depth );
00362
00363 private:
00364
00372 void SetTiXmlPointer( TiXmlAttribute* newPointer );
00373 };
00374
00375
00376 class Element;
00377 class Document;
00378 class Text;
00379 class Comment;
00380 class Declaration;
00381
00385 class Node : public Base
00386 {
00387 public:
00388
00396 template < class T >
00397 void GetValue( T* value)
00398 {
00399 FromString( GetTiXmlPointer()->ValueStr(), value );
00400 }
00401
00408 std::string Value();
00409
00416 template < class T >
00417 void SetValue( const T& value )
00418 {
00419 GetTiXmlPointer()->SetValue( ToString( value ) );
00420 }
00421
00426 void Clear();
00427
00436 Node* Parent( bool throwIfNoParent = true );
00437
00447 Node* FirstChild( bool throwIfNoChildren = true );
00448
00459 Node* FirstChild( const char* value, bool throwIfNoChildren = true );
00460
00470 Node* FirstChild( const std::string& value, bool throwIfNoChildren = true );
00471
00481 Node* LastChild( bool throwIfNoChildren = true );
00482
00493 Node* LastChild( const char* value, bool throwIfNoChildren = true );
00494
00504 Node* LastChild( const std::string& value, bool throwIfNoChildren = true );
00505
00512 Node* IterateChildren( Node* previous );
00513
00521 Node* IterateChildren( const std::string& value, Node* previous );
00522
00534 Node* InsertEndChild( Node& addThis );
00535
00546 Node* LinkEndChild( Node* childNode );
00547
00559 Node* InsertBeforeChild( Node* beforeThis, Node& addThis );
00560
00572 Node* InsertAfterChild( Node* afterThis, Node& addThis );
00573
00584 Node* ReplaceChild( Node* replaceThis, Node& withThis );
00585
00594 void RemoveChild( Node* removeThis );
00595
00604 Node* PreviousSibling( bool throwIfNoSiblings = true );
00605
00615 Node* PreviousSibling( const std::string& value, bool throwIfNoSiblings = true );
00616
00627 Node* PreviousSibling( const char* value, bool throwIfNoSiblings = true );
00628
00637 Node* NextSibling( bool throwIfNoSiblings = true );
00638
00648 Node* NextSibling( const std::string& value, bool throwIfNoSiblings = true );
00649
00660 Node* NextSibling( const char* value, bool throwIfNoSiblings = true );
00661
00669 template < class T >
00670 void IterateNext( const std::string& value, T** next )
00671 {
00672 Node* sibling = NextSibling( value, false );
00673 *next = dynamic_cast< T* >( sibling );
00674
00675 while ( ( NULL != sibling ) && ( NULL == *next ) )
00676 {
00677 sibling = sibling->NextSibling( value, false );
00678 *next = dynamic_cast< T* >( sibling );
00679 }
00680 }
00681
00689 template < class T >
00690 void IteratePrevious( const std::string& value, T** previous )
00691 {
00692 Node* sibling = PreviousSibling( value, false );
00693 *previous = dynamic_cast< T* >( sibling );
00694
00695 while ( ( NULL != sibling ) && ( NULL == *previous ) )
00696 {
00697 sibling = sibling->PreviousSibling( value, false );
00698 *previous = dynamic_cast< T* >( sibling );
00699 }
00700 }
00701
00710 Element* NextSiblingElement( bool throwIfNoSiblings = true );
00711
00720 Element* NextSiblingElement( const std::string& value, bool throwIfNoSiblings = true );
00721
00732 Element* NextSiblingElement( const char* value, bool throwIfNoSiblings = true );
00733
00743 Element* FirstChildElement( bool throwIfNoChildren = true );
00744
00755 Element* FirstChildElement( const char* value, bool throwIfNoChildren = true );
00756
00766 Element* FirstChildElement( const std::string& value, bool throwIfNoChildren = true );
00767
00771 int Type();
00772
00780 Document* GetDocument( bool throwIfNoDocument = true );
00781
00787 bool NoChildren();
00788
00795 template < class T >
00796 T* To()
00797 {
00798 T* pointer = dynamic_cast< T* >( this );
00799 if ( NULL == pointer )
00800 {
00801 std::string thisType = typeid( this ).name();
00802 std::string targetType = typeid( T ).name();
00803 std::string thatType = typeid( *this ).name();
00804 THROW( "The " << thisType.substr( 6 ) << " could not be casted to a " << targetType.substr( 6 )
00805 << " *, because the target object is not a " << targetType.substr( 6 ) << ". (It is a " << thatType.substr( 6 ) << ")" );
00806 }
00807 return pointer;
00808 }
00809
00815 Document* ToDocument();
00816
00822 Element* ToElement();
00823
00829 Comment* ToComment();
00830
00836 Text* ToText();
00837
00843 Declaration* ToDeclaration();
00844
00862 std::auto_ptr< Node > Clone();
00863
00864
00865 protected:
00870 virtual TiXmlNode* GetTiXmlPointer() = 0;
00871
00872 TiXmlBase* GetBasePointer()
00873 {
00874 return GetTiXmlPointer();
00875 }
00876
00881 Node* NodeFactory( TiXmlNode* tiXmlNode, bool throwIfNull = true, bool rememberSpawnedWrapper = true );
00882
00883 };
00884
00886 template < class T = Node >
00887 class Iterator
00888 {
00889 private:
00890 T* m_p;
00891 std::string m_value;
00893 public:
00894
00898 T* end()
00899 {
00900 return NULL;
00901 }
00902
00904 Iterator( const std::string& value = "" )
00905 : m_p( NULL ), m_value( value )
00906 {
00907 }
00908
00910 Iterator( T* node, const std::string& value = "" )
00911 : m_p( node ), m_value( value )
00912 {
00913 }
00914
00916 Iterator( const Iterator& it, const std::string& value = "" )
00917 : m_p( it.m_p ), m_value( value )
00918 {
00919 }
00920
00925 T* Get()
00926 {
00927 return m_p;
00928 }
00929
00931 Iterator& operator=( const Iterator& it )
00932 {
00933 m_p = it.m_p;
00934 return *this;
00935 }
00936
00938 Iterator& operator=( T* p )
00939 {
00940 m_p = p;
00941 return *this;
00942 }
00943
00945 Iterator& operator++()
00946 {
00947 m_p->IterateNext( m_value, &m_p );
00948 return *this;
00949 }
00950
00952 Iterator& operator++(int)
00953 {
00954 return this->operator ++();
00955 }
00956
00958 Iterator& operator--()
00959 {
00960 m_p->IteratePrevious( m_value, &m_p );
00961 return *this;
00962 }
00963
00965 Iterator& operator--(int)
00966 {
00967 return this->operator --();
00968 }
00969
00971 bool operator!=( T* p )
00972 {
00973 return m_p != p;
00974 }
00975
00977 bool operator!=( const Iterator& it )
00978 {
00979 return m_p != it.m_p;
00980 }
00981
00983 bool operator==( T* p )
00984 {
00985 return m_p == p;
00986 }
00987
00989 bool operator==( const Iterator& it )
00990 {
00991 return m_p == it.m_p;
00992 }
00993
00995 T* operator->()
00996 {
00997 return m_p;
00998 }
00999
01001 T& operator*()
01002 {
01003 return *m_p;
01004 }
01005 };
01006
01008 template < class T >
01009 class NodeImp : public Node
01010 {
01011 protected:
01012
01013 T* m_tiXmlPointer;
01021 TiXmlNode* GetTiXmlPointer()
01022 {
01023 ValidatePointer();
01024 return m_tiXmlPointer;
01025 }
01026
01034 void SetTiXmlPointer( T* newPointer )
01035 {
01036 m_tiXmlPointer = newPointer;
01037 SetImpRC( newPointer );
01038 }
01039
01044 NodeImp( T* tiXmlPointer )
01045 {
01046
01047 if ( NULL == tiXmlPointer )
01048 {
01049 THROW( "Can not create a " << typeid( T ).name() );
01050 }
01051 SetTiXmlPointer( tiXmlPointer );
01052 m_impRC->IncRef();
01053 }
01054
01060 virtual void operator=( const NodeImp<T>& copy )
01061 {
01062 DeleteSpawnedWrappers();
01063
01064
01065 this->m_impRC->DecRef();
01066
01067
01068 SetTiXmlPointer( copy.m_tiXmlPointer );
01069
01070
01071 this->m_impRC->IncRef();
01072 }
01073
01079 NodeImp( const NodeImp<T>& copy ) : Node()
01080 {
01081 DeleteSpawnedWrappers();
01082
01083
01084 this->m_impRC->DecRef();
01085
01086
01087 SetTiXmlPointer( copy.m_tiXmlPointer );
01088
01089
01090 this->m_impRC->IncRef();
01091 }
01092
01093 public:
01094
01095
01096
01097
01098
01099 virtual ~NodeImp()
01100 {
01101
01102 DeleteSpawnedWrappers();
01103 m_impRC->DecRef();
01104 }
01105 };
01106
01108 class Comment : public NodeImp< TiXmlComment >
01109 {
01110 public:
01111
01115 Comment();
01116
01120 Comment( TiXmlComment* comment );
01121
01125 Comment( const std::string& comment );
01126 };
01127
01129 class Text : public NodeImp< TiXmlText >
01130 {
01131 public:
01132
01136 Text();
01137
01142 Text( TiXmlText* text );
01143
01148 Text( const std::string& value );
01149
01159 template < class T >
01160 Text( const T& value )
01161 : NodeImp< TiXmlText >( new TiXmlText( ToString( value ) ) )
01162 {
01163 m_impRC->InitRef();
01164 }
01165 };
01166
01168 class Document : public NodeImp< TiXmlDocument >
01169 {
01170 public:
01175 Document();
01176
01180 Document( TiXmlDocument* document );
01181
01185 Document( const char* documentName );
01186
01193 Document( const std::string& documentName );
01194
01199 std::string GetAsString();
01200
01208 void LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01209
01215 void SaveFile() const;
01216
01225 void LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01226
01233 void SaveFile( const std::string& filename ) const;
01234
01235 };
01236
01238 class Element : public NodeImp< TiXmlElement >
01239 {
01240 public:
01244 Element();
01245
01249 Element( const std::string& value );
01250
01254 Element( TiXmlElement* element );
01255
01262 Attribute* FirstAttribute( bool throwIfNoAttributes = true );
01263
01270 Attribute* LastAttribute( bool throwIfNoAttributes = true );
01271
01279 template < class T >
01280 void SetAttribute ( const std::string& name, const T& value )
01281 {
01282 ValidatePointer();
01283 m_tiXmlPointer->SetAttribute( name, ToString( value ) );
01284 }
01285
01298 std::string GetText( bool throwIfNotFound = true )
01299 {
01300
01301 std::string temp;
01302 if ( !GetTextImp( &temp ) )
01303 {
01304 if ( throwIfNotFound )
01305 {
01306 THROW( "Text does not exists in the current element" );
01307 }
01308 }
01309
01310 return temp;
01311 }
01312
01324 std::string GetTextOrDefault( const std::string& defaultValue )
01325 {
01326
01327 std::string temp;
01328 if ( !GetTextImp( &temp ) )
01329 {
01330 return defaultValue;
01331 }
01332
01333 return temp;
01334 }
01335
01350 template < class T, class DefaultT >
01351 void GetTextOrDefault( T* value, const DefaultT& defaultValue )
01352 {
01353
01354 std::string temp;
01355 if ( !GetTextImp( &temp ) )
01356 {
01357
01358 *value = defaultValue;
01359 return;
01360 }
01361
01362
01363 FromString( temp, value );
01364 }
01365
01381 template< class T >
01382 void GetText( T* value, bool throwIfNotFound = true )
01383 {
01384
01385 std::string temp;
01386 if ( !GetTextImp( &temp ) )
01387 {
01388 if ( throwIfNotFound )
01389 {
01390 THROW( "Text does not exists in the current element" );
01391 }
01392 else
01393 {
01394 return;
01395 }
01396 }
01397
01398
01399 FromString( temp, value );
01400 }
01401
01409 template < class T >
01410 void SetText( const T& value )
01411 {
01412 ValidatePointer();
01413 std::string temp = ToString( value );
01414
01415 if ( m_tiXmlPointer->NoChildren() )
01416 {
01417 m_tiXmlPointer->LinkEndChild( new TiXmlText( temp ) );
01418 }
01419 else
01420 {
01421 if ( NULL == m_tiXmlPointer->GetText() )
01422 {
01423 m_tiXmlPointer->InsertBeforeChild( m_tiXmlPointer->FirstChild(), TiXmlText( temp ) );
01424 }
01425 else
01426 {
01427
01428 m_tiXmlPointer->FirstChild()->SetValue( temp );
01429 }
01430 }
01431 }
01432
01444 template < class T, class DefaulT >
01445 void GetAttributeOrDefault( const std::string& name, T* value, const DefaulT& defaultValue )
01446 {
01447
01448 std::string temp;
01449 if ( !GetAttributeImp( name, &temp ) )
01450 {
01451
01452 *value = defaultValue;
01453 return;
01454 }
01455
01456
01457 FromString( temp, value );
01458 }
01459
01471 template< class T >
01472 void GetAttribute( const std::string& name, T* value, bool throwIfNotFound = true )
01473 {
01474
01475 std::string temp;
01476 if ( !GetAttributeImp( name, &temp ) )
01477 {
01478 if ( throwIfNotFound )
01479 {
01480 THROW( "Attribute does not exist" );
01481 }
01482 else
01483 {
01484 return;
01485 }
01486 }
01487
01488
01489 FromString( temp, value );
01490 }
01491
01492 private:
01493
01498 bool GetAttributeImp( const std::string& name, std::string* value );
01499
01504 bool GetTextImp( std::string* value );
01505 };
01506
01508 class Declaration : public NodeImp< TiXmlDeclaration >
01509 {
01510 public:
01514 Declaration( void );
01515
01519 Declaration( TiXmlDeclaration* declaration );
01520
01524 Declaration( const std::string& version, const std::string& encoding, const std::string& standalone );
01525
01529 std::string Version( void );
01530
01534 std::string Encoding( void );
01535
01539 std::string Standalone( void );
01540 };
01541 }
01542
01543 #endif // TICPP_INCLUDED
01544
01545 #endif // TIXML_USE_TICPP