quadEM 7-0
|
00001 /* Note by Mark Rivers 00002 * I added shareLib.h and epicsShareFunc to class definitions to allow use in win32 DLL on EPICS */ 00003 00004 /* 00005 www.sourceforge.net/projects/tinyxml 00006 Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) 00007 00008 This software is provided 'as-is', without any express or implied 00009 warranty. In no event will the authors be held liable for any 00010 damages arising from the use of this software. 00011 00012 Permission is granted to anyone to use this software for any 00013 purpose, including commercial applications, and to alter it and 00014 redistribute it freely, subject to the following restrictions: 00015 00016 1. The origin of this software must not be misrepresented; you must 00017 not claim that you wrote the original software. If you use this 00018 software in a product, an acknowledgment in the product documentation 00019 would be appreciated but is not required. 00020 00021 2. Altered source versions must be plainly marked as such, and 00022 must not be misrepresented as being the original software. 00023 00024 3. This notice may not be removed or altered from any source 00025 distribution. 00026 */ 00027 00028 00029 #ifndef TINYXML_INCLUDED 00030 #define TINYXML_INCLUDED 00031 00032 #ifdef _MSC_VER 00033 #pragma warning( push ) 00034 #pragma warning( disable : 4530 ) 00035 #pragma warning( disable : 4786 ) 00036 #endif 00037 00038 #include <ctype.h> 00039 #include <stdio.h> 00040 #include <stdlib.h> 00041 #include <string.h> 00042 #include <assert.h> 00043 00044 #include <shareLib.h> 00045 00046 // Help out windows: 00047 #if defined( _DEBUG ) && !defined( DEBUG ) 00048 #define DEBUG 00049 #endif 00050 00051 #ifdef TIXML_USE_STL 00052 #include <string> 00053 #include <iostream> 00054 #include <sstream> 00055 #define TIXML_STRING std::string 00056 #else 00057 #include "tinystr.h" 00058 #define TIXML_STRING TiXmlString 00059 #endif 00060 00061 // Deprecated library function hell. Compilers want to use the 00062 // new safe versions. This probably doesn't fully address the problem, 00063 // but it gets closer. There are too many compilers for me to fully 00064 // test. If you get compilation troubles, undefine TIXML_SAFE 00065 #define TIXML_SAFE 00066 00067 #ifdef TIXML_SAFE 00068 #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) 00069 // Microsoft visual studio, version 2005 and higher. 00070 #define TIXML_SNPRINTF _snprintf_s 00071 #define TIXML_SNSCANF _snscanf_s 00072 #define TIXML_SSCANF sscanf_s 00073 #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) 00074 // Microsoft visual studio, version 6 and higher. 00075 //#pragma message( "Using _sn* functions." ) 00076 #define TIXML_SNPRINTF _snprintf 00077 #define TIXML_SNSCANF _snscanf 00078 #define TIXML_SSCANF sscanf 00079 #elif defined(__GNUC__) && (__GNUC__ >= 3 ) 00080 // GCC version 3 and higher.s 00081 //#warning( "Using sn* functions." ) 00082 #define TIXML_SNPRINTF snprintf 00083 #define TIXML_SNSCANF snscanf 00084 #define TIXML_SSCANF sscanf 00085 #else 00086 #define TIXML_SSCANF sscanf 00087 #endif 00088 #endif 00089 00090 class epicsShareFunc TiXmlDocument; 00091 class epicsShareFunc TiXmlElement; 00092 class epicsShareFunc TiXmlComment; 00093 class epicsShareFunc TiXmlUnknown; 00094 class epicsShareFunc TiXmlAttribute; 00095 class epicsShareFunc TiXmlText; 00096 class epicsShareFunc TiXmlDeclaration; 00097 class epicsShareFunc TiXmlParsingData; 00098 00099 const int TIXML_MAJOR_VERSION = 2; 00100 const int TIXML_MINOR_VERSION = 5; 00101 const int TIXML_PATCH_VERSION = 3; 00102 00103 /* Internal structure for tracking location of items 00104 in the XML file. 00105 */ 00106 struct epicsShareFunc TiXmlCursor 00107 { 00108 TiXmlCursor() { Clear(); } 00109 void Clear() { row = col = -1; } 00110 00111 int row; // 0 based. 00112 int col; // 0 based. 00113 }; 00114 00115 00134 class epicsShareFunc TiXmlVisitor 00135 { 00136 public: 00137 virtual ~TiXmlVisitor() {} 00138 00140 virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } 00142 virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } 00143 00145 virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } 00147 virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } 00148 00150 virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } 00152 virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } 00154 virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } 00156 virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } 00157 }; 00158 00159 // Only used by Attribute::Query functions 00160 enum 00161 { 00162 TIXML_SUCCESS, 00163 TIXML_NO_ATTRIBUTE, 00164 TIXML_WRONG_TYPE 00165 }; 00166 00167 00168 // Used by the parsing routines. 00169 enum TiXmlEncoding 00170 { 00171 TIXML_ENCODING_UNKNOWN, 00172 TIXML_ENCODING_UTF8, 00173 TIXML_ENCODING_LEGACY 00174 }; 00175 00176 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; 00177 00200 class epicsShareFunc TiXmlBase 00201 { 00202 friend class TiXmlNode; 00203 friend class TiXmlElement; 00204 friend class TiXmlDocument; 00205 00206 public: 00207 TiXmlBase() : userData(0) {} 00208 virtual ~TiXmlBase() {} 00209 00219 virtual void Print( FILE* cfile, int depth ) const = 0; 00220 00227 static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } 00228 00230 static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } 00231 00250 int Row() const { return location.row + 1; } 00251 int Column() const { return location.col + 1; } 00252 00253 void SetUserData( void* user ) { userData = user; } 00254 void* GetUserData() { return userData; } 00255 const void* GetUserData() const { return userData; } 00256 00257 // Table that returs, for a given lead byte, the total number of bytes 00258 // in the UTF-8 sequence. 00259 static const int utf8ByteTable[256]; 00260 00261 virtual const char* Parse( const char* p, 00262 TiXmlParsingData* data, 00263 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; 00264 00268 static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); 00269 00270 enum 00271 { 00272 TIXML_NO_ERROR = 0, 00273 TIXML_ERROR, 00274 TIXML_ERROR_OPENING_FILE, 00275 TIXML_ERROR_OUT_OF_MEMORY, 00276 TIXML_ERROR_PARSING_ELEMENT, 00277 TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, 00278 TIXML_ERROR_READING_ELEMENT_VALUE, 00279 TIXML_ERROR_READING_ATTRIBUTES, 00280 TIXML_ERROR_PARSING_EMPTY, 00281 TIXML_ERROR_READING_END_TAG, 00282 TIXML_ERROR_PARSING_UNKNOWN, 00283 TIXML_ERROR_PARSING_COMMENT, 00284 TIXML_ERROR_PARSING_DECLARATION, 00285 TIXML_ERROR_DOCUMENT_EMPTY, 00286 TIXML_ERROR_EMBEDDED_NULL, 00287 TIXML_ERROR_PARSING_CDATA, 00288 TIXML_ERROR_DOCUMENT_TOP_ONLY, 00289 00290 TIXML_ERROR_STRING_COUNT 00291 }; 00292 00293 protected: 00294 00295 static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); 00296 inline static bool IsWhiteSpace( char c ) 00297 { 00298 return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 00299 } 00300 inline static bool IsWhiteSpace( int c ) 00301 { 00302 if ( c < 256 ) 00303 return IsWhiteSpace( (char) c ); 00304 return false; // Again, only truly correct for English/Latin...but usually works. 00305 } 00306 00307 #ifdef TIXML_USE_STL 00308 static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); 00309 static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); 00310 #endif 00311 00312 /* Reads an XML name into the string provided. Returns 00313 a pointer just past the last character of the name, 00314 or 0 if the function has an error. 00315 */ 00316 static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); 00317 00318 /* Reads text. Returns a pointer past the given end tag. 00319 Wickedly complex options, but it keeps the (sensitive) code in one place. 00320 */ 00321 static const char* ReadText( const char* in, // where to start 00322 TIXML_STRING* text, // the string read 00323 bool ignoreWhiteSpace, // whether to keep the white space 00324 const char* endTag, // what ends this text 00325 bool ignoreCase, // whether to ignore case in the end tag 00326 TiXmlEncoding encoding ); // the current encoding 00327 00328 // If an entity has been found, transform it into a character. 00329 static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); 00330 00331 // Get a character, while interpreting entities. 00332 // The length can be from 0 to 4 bytes. 00333 inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) 00334 { 00335 assert( p ); 00336 if ( encoding == TIXML_ENCODING_UTF8 ) 00337 { 00338 *length = utf8ByteTable[ *((const unsigned char*)p) ]; 00339 assert( *length >= 0 && *length < 5 ); 00340 } 00341 else 00342 { 00343 *length = 1; 00344 } 00345 00346 if ( *length == 1 ) 00347 { 00348 if ( *p == '&' ) 00349 return GetEntity( p, _value, length, encoding ); 00350 *_value = *p; 00351 return p+1; 00352 } 00353 else if ( *length ) 00354 { 00355 //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), 00356 // and the null terminator isn't needed 00357 for( int i=0; p[i] && i<*length; ++i ) { 00358 _value[i] = p[i]; 00359 } 00360 return p + (*length); 00361 } 00362 else 00363 { 00364 // Not valid text. 00365 return 0; 00366 } 00367 } 00368 00369 // Return true if the next characters in the stream are any of the endTag sequences. 00370 // Ignore case only works for english, and should only be relied on when comparing 00371 // to English words: StringEqual( p, "version", true ) is fine. 00372 static bool StringEqual( const char* p, 00373 const char* endTag, 00374 bool ignoreCase, 00375 TiXmlEncoding encoding ); 00376 00377 static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; 00378 00379 TiXmlCursor location; 00380 00382 void* userData; 00383 00384 // None of these methods are reliable for any language except English. 00385 // Good for approximation, not great for accuracy. 00386 static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); 00387 static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); 00388 inline static int ToLower( int v, TiXmlEncoding encoding ) 00389 { 00390 if ( encoding == TIXML_ENCODING_UTF8 ) 00391 { 00392 if ( v < 128 ) return tolower( v ); 00393 return v; 00394 } 00395 else 00396 { 00397 return tolower( v ); 00398 } 00399 } 00400 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); 00401 00402 private: 00403 TiXmlBase( const TiXmlBase& ); // not implemented. 00404 void operator=( const TiXmlBase& base ); // not allowed. 00405 00406 struct Entity 00407 { 00408 const char* str; 00409 unsigned int strLength; 00410 char chr; 00411 }; 00412 enum 00413 { 00414 NUM_ENTITY = 5, 00415 MAX_ENTITY_LENGTH = 6 00416 00417 }; 00418 static Entity entity[ NUM_ENTITY ]; 00419 static bool condenseWhiteSpace; 00420 }; 00421 00422 00429 class epicsShareFunc TiXmlNode : public TiXmlBase 00430 { 00431 friend class TiXmlDocument; 00432 friend class TiXmlElement; 00433 00434 public: 00435 #ifdef TIXML_USE_STL 00436 00440 friend std::istream& operator >> (std::istream& in, TiXmlNode& base); 00441 00458 friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); 00459 00461 friend std::string& operator<< (std::string& out, const TiXmlNode& base ); 00462 00463 #endif 00464 00468 enum NodeType 00469 { 00470 DOCUMENT, 00471 ELEMENT, 00472 COMMENT, 00473 UNKNOWN, 00474 TEXT, 00475 DECLARATION, 00476 TYPECOUNT 00477 }; 00478 00479 virtual ~TiXmlNode(); 00480 00493 const char *Value() const { return value.c_str (); } 00494 00495 #ifdef TIXML_USE_STL 00496 00500 const std::string& ValueStr() const { return value; } 00501 #endif 00502 00503 const TIXML_STRING& ValueTStr() const { return value; } 00504 00514 void SetValue(const char * _value) { value = _value;} 00515 00516 #ifdef TIXML_USE_STL 00517 00518 void SetValue( const std::string& _value ) { value = _value; } 00519 #endif 00520 00522 void Clear(); 00523 00525 TiXmlNode* Parent() { return parent; } 00526 const TiXmlNode* Parent() const { return parent; } 00527 00528 const TiXmlNode* FirstChild() const { return firstChild; } 00529 TiXmlNode* FirstChild() { return firstChild; } 00530 const TiXmlNode* FirstChild( const char * value ) const; 00531 00532 TiXmlNode* FirstChild( const char * _value ) { 00533 // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) 00534 // call the method, cast the return back to non-const. 00535 return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); 00536 } 00537 const TiXmlNode* LastChild() const { return lastChild; } 00538 TiXmlNode* LastChild() { return lastChild; } 00539 00540 const TiXmlNode* LastChild( const char * value ) const; 00541 TiXmlNode* LastChild( const char * _value ) { 00542 return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); 00543 } 00544 00545 #ifdef TIXML_USE_STL 00546 const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } 00547 TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } 00548 const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } 00549 TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } 00550 #endif 00551 00568 const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; 00569 TiXmlNode* IterateChildren( const TiXmlNode* previous ) { 00570 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); 00571 } 00572 00574 const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; 00575 TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { 00576 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); 00577 } 00578 00579 #ifdef TIXML_USE_STL 00580 const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } 00581 TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } 00582 #endif 00583 00587 TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); 00588 00589 00599 TiXmlNode* LinkEndChild( TiXmlNode* addThis ); 00600 00604 TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); 00605 00609 TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); 00610 00614 TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); 00615 00617 bool RemoveChild( TiXmlNode* removeThis ); 00618 00620 const TiXmlNode* PreviousSibling() const { return prev; } 00621 TiXmlNode* PreviousSibling() { return prev; } 00622 00624 const TiXmlNode* PreviousSibling( const char * ) const; 00625 TiXmlNode* PreviousSibling( const char *_prev ) { 00626 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); 00627 } 00628 00629 #ifdef TIXML_USE_STL 00630 const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } 00631 TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } 00632 const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } 00633 TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } 00634 #endif 00635 00637 const TiXmlNode* NextSibling() const { return next; } 00638 TiXmlNode* NextSibling() { return next; } 00639 00641 const TiXmlNode* NextSibling( const char * ) const; 00642 TiXmlNode* NextSibling( const char* _next ) { 00643 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); 00644 } 00645 00650 const TiXmlElement* NextSiblingElement() const; 00651 TiXmlElement* NextSiblingElement() { 00652 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); 00653 } 00654 00659 const TiXmlElement* NextSiblingElement( const char * ) const; 00660 TiXmlElement* NextSiblingElement( const char *_next ) { 00661 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); 00662 } 00663 00664 #ifdef TIXML_USE_STL 00665 const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } 00666 TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } 00667 #endif 00668 00670 const TiXmlElement* FirstChildElement() const; 00671 TiXmlElement* FirstChildElement() { 00672 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); 00673 } 00674 00676 const TiXmlElement* FirstChildElement( const char * _value ) const; 00677 TiXmlElement* FirstChildElement( const char * _value ) { 00678 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); 00679 } 00680 00681 #ifdef TIXML_USE_STL 00682 const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } 00683 TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } 00684 #endif 00685 00690 int Type() const { return type; } 00691 00695 const TiXmlDocument* GetDocument() const; 00696 TiXmlDocument* GetDocument() { 00697 return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); 00698 } 00699 00701 bool NoChildren() const { return !firstChild; } 00702 00703 virtual const TiXmlDocument* ToDocument() const { return 0; } 00704 virtual const TiXmlElement* ToElement() const { return 0; } 00705 virtual const TiXmlComment* ToComment() const { return 0; } 00706 virtual const TiXmlUnknown* ToUnknown() const { return 0; } 00707 virtual const TiXmlText* ToText() const { return 0; } 00708 virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } 00709 00710 virtual TiXmlDocument* ToDocument() { return 0; } 00711 virtual TiXmlElement* ToElement() { return 0; } 00712 virtual TiXmlComment* ToComment() { return 0; } 00713 virtual TiXmlUnknown* ToUnknown() { return 0; } 00714 virtual TiXmlText* ToText() { return 0; } 00715 virtual TiXmlDeclaration* ToDeclaration() { return 0; } 00716 00720 virtual TiXmlNode* Clone() const = 0; 00721 00744 virtual bool Accept( TiXmlVisitor* visitor ) const = 0; 00745 00746 protected: 00747 TiXmlNode( NodeType _type ); 00748 00749 // Copy to the allocated object. Shared functionality between Clone, Copy constructor, 00750 // and the assignment operator. 00751 void CopyTo( TiXmlNode* target ) const; 00752 00753 #ifdef TIXML_USE_STL 00754 // The real work of the input operator. 00755 virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; 00756 #endif 00757 00758 // Figure out what is at *p, and parse it. Returns null if it is not an xml node. 00759 TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); 00760 00761 TiXmlNode* parent; 00762 NodeType type; 00763 00764 TiXmlNode* firstChild; 00765 TiXmlNode* lastChild; 00766 00767 TIXML_STRING value; 00768 00769 TiXmlNode* prev; 00770 TiXmlNode* next; 00771 00772 private: 00773 TiXmlNode( const TiXmlNode& ); // not implemented. 00774 void operator=( const TiXmlNode& base ); // not allowed. 00775 }; 00776 00777 00785 class epicsShareFunc TiXmlAttribute : public TiXmlBase 00786 { 00787 friend class TiXmlAttributeSet; 00788 00789 public: 00791 TiXmlAttribute() : TiXmlBase() 00792 { 00793 document = 0; 00794 prev = next = 0; 00795 } 00796 00797 #ifdef TIXML_USE_STL 00798 00799 TiXmlAttribute( const std::string& _name, const std::string& _value ) 00800 { 00801 name = _name; 00802 value = _value; 00803 document = 0; 00804 prev = next = 0; 00805 } 00806 #endif 00807 00809 TiXmlAttribute( const char * _name, const char * _value ) 00810 { 00811 name = _name; 00812 value = _value; 00813 document = 0; 00814 prev = next = 0; 00815 } 00816 00817 const char* Name() const { return name.c_str(); } 00818 const char* Value() const { return value.c_str(); } 00819 #ifdef TIXML_USE_STL 00820 const std::string& ValueStr() const { return value; } 00821 #endif 00822 int IntValue() const; 00823 double DoubleValue() const; 00824 00825 // Get the tinyxml string representation 00826 const TIXML_STRING& NameTStr() const { return name; } 00827 00837 int QueryIntValue( int* _value ) const; 00839 int QueryDoubleValue( double* _value ) const; 00840 00841 void SetName( const char* _name ) { name = _name; } 00842 void SetValue( const char* _value ) { value = _value; } 00843 00844 void SetIntValue( int _value ); 00845 void SetDoubleValue( double _value ); 00846 00847 #ifdef TIXML_USE_STL 00848 00849 void SetName( const std::string& _name ) { name = _name; } 00851 void SetValue( const std::string& _value ) { value = _value; } 00852 #endif 00853 00855 const TiXmlAttribute* Next() const; 00856 TiXmlAttribute* Next() { 00857 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 00858 } 00859 00861 const TiXmlAttribute* Previous() const; 00862 TiXmlAttribute* Previous() { 00863 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 00864 } 00865 00866 bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } 00867 bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } 00868 bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } 00869 00870 /* Attribute parsing starts: first letter of the name 00871 returns: the next char after the value end quote 00872 */ 00873 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 00874 00875 // Prints this Attribute to a FILE stream. 00876 virtual void Print( FILE* cfile, int depth ) const { 00877 Print( cfile, depth, 0 ); 00878 } 00879 void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; 00880 00881 // [internal use] 00882 // Set the document pointer so the attribute can report errors. 00883 void SetDocument( TiXmlDocument* doc ) { document = doc; } 00884 00885 private: 00886 TiXmlAttribute( const TiXmlAttribute& ); // not implemented. 00887 void operator=( const TiXmlAttribute& base ); // not allowed. 00888 00889 TiXmlDocument* document; // A pointer back to a document, for error reporting. 00890 TIXML_STRING name; 00891 TIXML_STRING value; 00892 TiXmlAttribute* prev; 00893 TiXmlAttribute* next; 00894 }; 00895 00896 00897 /* A class used to manage a group of attributes. 00898 It is only used internally, both by the ELEMENT and the DECLARATION. 00899 00900 The set can be changed transparent to the Element and Declaration 00901 classes that use it, but NOT transparent to the Attribute 00902 which has to implement a next() and previous() method. Which makes 00903 it a bit problematic and prevents the use of STL. 00904 00905 This version is implemented with circular lists because: 00906 - I like circular lists 00907 - it demonstrates some independence from the (typical) doubly linked list. 00908 */ 00909 class epicsShareFunc TiXmlAttributeSet 00910 { 00911 public: 00912 TiXmlAttributeSet(); 00913 ~TiXmlAttributeSet(); 00914 00915 void Add( TiXmlAttribute* attribute ); 00916 void Remove( TiXmlAttribute* attribute ); 00917 00918 const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } 00919 TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } 00920 const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } 00921 TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } 00922 00923 const TiXmlAttribute* Find( const char* _name ) const; 00924 TiXmlAttribute* Find( const char* _name ) { 00925 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); 00926 } 00927 #ifdef TIXML_USE_STL 00928 const TiXmlAttribute* Find( const std::string& _name ) const; 00929 TiXmlAttribute* Find( const std::string& _name ) { 00930 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); 00931 } 00932 00933 #endif 00934 00935 private: 00936 //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), 00937 //*ME: this class must be also use a hidden/disabled copy-constructor !!! 00938 TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed 00939 void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) 00940 00941 TiXmlAttribute sentinel; 00942 }; 00943 00944 00949 class epicsShareFunc TiXmlElement : public TiXmlNode 00950 { 00951 public: 00953 TiXmlElement (const char * in_value); 00954 00955 #ifdef TIXML_USE_STL 00956 00957 TiXmlElement( const std::string& _value ); 00958 #endif 00959 00960 TiXmlElement( const TiXmlElement& ); 00961 00962 void operator=( const TiXmlElement& base ); 00963 00964 virtual ~TiXmlElement(); 00965 00969 const char* Attribute( const char* name ) const; 00970 00977 const char* Attribute( const char* name, int* i ) const; 00978 00985 const char* Attribute( const char* name, double* d ) const; 00986 00994 int QueryIntAttribute( const char* name, int* _value ) const; 00996 int QueryDoubleAttribute( const char* name, double* _value ) const; 00998 int QueryFloatAttribute( const char* name, float* _value ) const { 00999 double d; 01000 int result = QueryDoubleAttribute( name, &d ); 01001 if ( result == TIXML_SUCCESS ) { 01002 *_value = (float)d; 01003 } 01004 return result; 01005 } 01006 01007 #ifdef TIXML_USE_STL 01008 01016 template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const 01017 { 01018 const TiXmlAttribute* node = attributeSet.Find( name ); 01019 if ( !node ) 01020 return TIXML_NO_ATTRIBUTE; 01021 01022 std::stringstream sstream( node->ValueStr() ); 01023 sstream >> *outValue; 01024 if ( !sstream.fail() ) 01025 return TIXML_SUCCESS; 01026 return TIXML_WRONG_TYPE; 01027 } 01028 /* 01029 This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string" 01030 but template specialization is hard to get working cross-compiler. Leaving the bug for now. 01031 01032 // The above will fail for std::string because the space character is used as a seperator. 01033 // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string 01034 template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const 01035 { 01036 const TiXmlAttribute* node = attributeSet.Find( name ); 01037 if ( !node ) 01038 return TIXML_NO_ATTRIBUTE; 01039 *outValue = node->ValueStr(); 01040 return TIXML_SUCCESS; 01041 } 01042 */ 01043 #endif 01044 01048 void SetAttribute( const char* name, const char * _value ); 01049 01050 #ifdef TIXML_USE_STL 01051 const std::string* Attribute( const std::string& name ) const; 01052 const std::string* Attribute( const std::string& name, int* i ) const; 01053 const std::string* Attribute( const std::string& name, double* d ) const; 01054 int QueryIntAttribute( const std::string& name, int* _value ) const; 01055 int QueryDoubleAttribute( const std::string& name, double* _value ) const; 01056 01058 void SetAttribute( const std::string& name, const std::string& _value ); 01060 void SetAttribute( const std::string& name, int _value ); 01061 #endif 01062 01066 void SetAttribute( const char * name, int value ); 01067 01071 void SetDoubleAttribute( const char * name, double value ); 01072 01075 void RemoveAttribute( const char * name ); 01076 #ifdef TIXML_USE_STL 01077 void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } 01078 #endif 01079 01080 const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } 01081 TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } 01082 const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } 01083 TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } 01084 01117 const char* GetText() const; 01118 01120 virtual TiXmlNode* Clone() const; 01121 // Print the Element to a FILE stream. 01122 virtual void Print( FILE* cfile, int depth ) const; 01123 01124 /* Attribtue parsing starts: next char past '<' 01125 returns: next char past '>' 01126 */ 01127 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 01128 01129 virtual const TiXmlElement* ToElement() const { return this; } 01130 virtual TiXmlElement* ToElement() { return this; } 01131 01134 virtual bool Accept( TiXmlVisitor* visitor ) const; 01135 01136 protected: 01137 01138 void CopyTo( TiXmlElement* target ) const; 01139 void ClearThis(); // like clear, but initializes 'this' object as well 01140 01141 // Used to be public [internal use] 01142 #ifdef TIXML_USE_STL 01143 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 01144 #endif 01145 /* [internal use] 01146 Reads the "value" of the element -- another element, or text. 01147 This should terminate with the current end tag. 01148 */ 01149 const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); 01150 01151 private: 01152 01153 TiXmlAttributeSet attributeSet; 01154 }; 01155 01156 01159 class epicsShareFunc TiXmlComment : public TiXmlNode 01160 { 01161 public: 01163 TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} 01165 TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { 01166 SetValue( _value ); 01167 } 01168 TiXmlComment( const TiXmlComment& ); 01169 void operator=( const TiXmlComment& base ); 01170 01171 virtual ~TiXmlComment() {} 01172 01174 virtual TiXmlNode* Clone() const; 01175 // Write this Comment to a FILE stream. 01176 virtual void Print( FILE* cfile, int depth ) const; 01177 01178 /* Attribtue parsing starts: at the ! of the !-- 01179 returns: next char past '>' 01180 */ 01181 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 01182 01183 virtual const TiXmlComment* ToComment() const { return this; } 01184 virtual TiXmlComment* ToComment() { return this; } 01185 01188 virtual bool Accept( TiXmlVisitor* visitor ) const; 01189 01190 protected: 01191 void CopyTo( TiXmlComment* target ) const; 01192 01193 // used to be public 01194 #ifdef TIXML_USE_STL 01195 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 01196 #endif 01197 // virtual void StreamOut( TIXML_OSTREAM * out ) const; 01198 01199 private: 01200 01201 }; 01202 01203 01209 class epicsShareFunc TiXmlText : public TiXmlNode 01210 { 01211 friend class TiXmlElement; 01212 public: 01217 TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) 01218 { 01219 SetValue( initValue ); 01220 cdata = false; 01221 } 01222 virtual ~TiXmlText() {} 01223 01224 #ifdef TIXML_USE_STL 01225 01226 TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) 01227 { 01228 SetValue( initValue ); 01229 cdata = false; 01230 } 01231 #endif 01232 01233 TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } 01234 void operator=( const TiXmlText& base ) { base.CopyTo( this ); } 01235 01236 // Write this text object to a FILE stream. 01237 virtual void Print( FILE* cfile, int depth ) const; 01238 01240 bool CDATA() const { return cdata; } 01242 void SetCDATA( bool _cdata ) { cdata = _cdata; } 01243 01244 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 01245 01246 virtual const TiXmlText* ToText() const { return this; } 01247 virtual TiXmlText* ToText() { return this; } 01248 01251 virtual bool Accept( TiXmlVisitor* content ) const; 01252 01253 protected : 01255 virtual TiXmlNode* Clone() const; 01256 void CopyTo( TiXmlText* target ) const; 01257 01258 bool Blank() const; // returns true if all white space and new lines 01259 // [internal use] 01260 #ifdef TIXML_USE_STL 01261 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 01262 #endif 01263 01264 private: 01265 bool cdata; // true if this should be input and output as a CDATA style text element 01266 }; 01267 01268 01282 class epicsShareFunc TiXmlDeclaration : public TiXmlNode 01283 { 01284 public: 01286 TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} 01287 01288 #ifdef TIXML_USE_STL 01289 01290 TiXmlDeclaration( const std::string& _version, 01291 const std::string& _encoding, 01292 const std::string& _standalone ); 01293 #endif 01294 01296 TiXmlDeclaration( const char* _version, 01297 const char* _encoding, 01298 const char* _standalone ); 01299 01300 TiXmlDeclaration( const TiXmlDeclaration& copy ); 01301 void operator=( const TiXmlDeclaration& copy ); 01302 01303 virtual ~TiXmlDeclaration() {} 01304 01306 const char *Version() const { return version.c_str (); } 01308 const char *Encoding() const { return encoding.c_str (); } 01310 const char *Standalone() const { return standalone.c_str (); } 01311 01313 virtual TiXmlNode* Clone() const; 01314 // Print this declaration to a FILE stream. 01315 virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; 01316 virtual void Print( FILE* cfile, int depth ) const { 01317 Print( cfile, depth, 0 ); 01318 } 01319 01320 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 01321 01322 virtual const TiXmlDeclaration* ToDeclaration() const { return this; } 01323 virtual TiXmlDeclaration* ToDeclaration() { return this; } 01324 01327 virtual bool Accept( TiXmlVisitor* visitor ) const; 01328 01329 protected: 01330 void CopyTo( TiXmlDeclaration* target ) const; 01331 // used to be public 01332 #ifdef TIXML_USE_STL 01333 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 01334 #endif 01335 01336 private: 01337 01338 TIXML_STRING version; 01339 TIXML_STRING encoding; 01340 TIXML_STRING standalone; 01341 }; 01342 01343 01351 class epicsShareFunc TiXmlUnknown : public TiXmlNode 01352 { 01353 public: 01354 TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} 01355 virtual ~TiXmlUnknown() {} 01356 01357 TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } 01358 void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } 01359 01361 virtual TiXmlNode* Clone() const; 01362 // Print this Unknown to a FILE stream. 01363 virtual void Print( FILE* cfile, int depth ) const; 01364 01365 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 01366 01367 virtual const TiXmlUnknown* ToUnknown() const { return this; } 01368 virtual TiXmlUnknown* ToUnknown() { return this; } 01369 01372 virtual bool Accept( TiXmlVisitor* content ) const; 01373 01374 protected: 01375 void CopyTo( TiXmlUnknown* target ) const; 01376 01377 #ifdef TIXML_USE_STL 01378 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 01379 #endif 01380 01381 private: 01382 01383 }; 01384 01385 01390 class epicsShareFunc TiXmlDocument : public TiXmlNode 01391 { 01392 public: 01394 TiXmlDocument(); 01396 TiXmlDocument( const char * documentName ); 01397 01398 #ifdef TIXML_USE_STL 01399 01400 TiXmlDocument( const std::string& documentName ); 01401 #endif 01402 01403 TiXmlDocument( const TiXmlDocument& copy ); 01404 void operator=( const TiXmlDocument& copy ); 01405 01406 virtual ~TiXmlDocument() {} 01407 01412 bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); 01414 bool SaveFile() const; 01416 bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); 01418 bool SaveFile( const char * filename ) const; 01424 bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); 01426 bool SaveFile( FILE* ) const; 01427 01428 #ifdef TIXML_USE_STL 01429 bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) 01430 { 01431 // StringToBuffer f( filename ); 01432 // return ( f.buffer && LoadFile( f.buffer, encoding )); 01433 return LoadFile( filename.c_str(), encoding ); 01434 } 01435 bool SaveFile( const std::string& filename ) const 01436 { 01437 // StringToBuffer f( filename ); 01438 // return ( f.buffer && SaveFile( f.buffer )); 01439 return SaveFile( filename.c_str() ); 01440 } 01441 #endif 01442 01447 virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); 01448 01453 const TiXmlElement* RootElement() const { return FirstChildElement(); } 01454 TiXmlElement* RootElement() { return FirstChildElement(); } 01455 01461 bool Error() const { return error; } 01462 01464 const char * ErrorDesc() const { return errorDesc.c_str (); } 01465 01469 int ErrorId() const { return errorId; } 01470 01478 int ErrorRow() const { return errorLocation.row+1; } 01479 int ErrorCol() const { return errorLocation.col+1; } 01480 01505 void SetTabSize( int _tabsize ) { tabsize = _tabsize; } 01506 01507 int TabSize() const { return tabsize; } 01508 01512 void ClearError() { error = false; 01513 errorId = 0; 01514 errorDesc = ""; 01515 errorLocation.row = errorLocation.col = 0; 01516 //errorLocation.last = 0; 01517 } 01518 01520 void Print() const { Print( stdout, 0 ); } 01521 01522 /* Write the document to a string using formatted printing ("pretty print"). This 01523 will allocate a character array (new char[]) and return it as a pointer. The 01524 calling code pust call delete[] on the return char* to avoid a memory leak. 01525 */ 01526 //char* PrintToMemory() const; 01527 01529 virtual void Print( FILE* cfile, int depth = 0 ) const; 01530 // [internal use] 01531 void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); 01532 01533 virtual const TiXmlDocument* ToDocument() const { return this; } 01534 virtual TiXmlDocument* ToDocument() { return this; } 01535 01538 virtual bool Accept( TiXmlVisitor* content ) const; 01539 01540 protected : 01541 // [internal use] 01542 virtual TiXmlNode* Clone() const; 01543 #ifdef TIXML_USE_STL 01544 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 01545 #endif 01546 01547 private: 01548 void CopyTo( TiXmlDocument* target ) const; 01549 01550 bool error; 01551 int errorId; 01552 TIXML_STRING errorDesc; 01553 int tabsize; 01554 TiXmlCursor errorLocation; 01555 bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. 01556 }; 01557 01558 01639 class epicsShareFunc TiXmlHandle 01640 { 01641 public: 01643 TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } 01645 TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } 01646 TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } 01647 01649 TiXmlHandle FirstChild() const; 01651 TiXmlHandle FirstChild( const char * value ) const; 01653 TiXmlHandle FirstChildElement() const; 01655 TiXmlHandle FirstChildElement( const char * value ) const; 01656 01660 TiXmlHandle Child( const char* value, int index ) const; 01664 TiXmlHandle Child( int index ) const; 01669 TiXmlHandle ChildElement( const char* value, int index ) const; 01674 TiXmlHandle ChildElement( int index ) const; 01675 01676 #ifdef TIXML_USE_STL 01677 TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } 01678 TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } 01679 01680 TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } 01681 TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } 01682 #endif 01683 01686 TiXmlNode* ToNode() const { return node; } 01689 TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } 01692 TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } 01695 TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } 01696 01700 TiXmlNode* Node() const { return ToNode(); } 01704 TiXmlElement* Element() const { return ToElement(); } 01708 TiXmlText* Text() const { return ToText(); } 01712 TiXmlUnknown* Unknown() const { return ToUnknown(); } 01713 01714 private: 01715 TiXmlNode* node; 01716 }; 01717 01718 01738 class epicsShareFunc TiXmlPrinter : public TiXmlVisitor 01739 { 01740 public: 01741 TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), 01742 buffer(), indent( " " ), lineBreak( "\n" ) {} 01743 01744 virtual bool VisitEnter( const TiXmlDocument& doc ); 01745 virtual bool VisitExit( const TiXmlDocument& doc ); 01746 01747 virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); 01748 virtual bool VisitExit( const TiXmlElement& element ); 01749 01750 virtual bool Visit( const TiXmlDeclaration& declaration ); 01751 virtual bool Visit( const TiXmlText& text ); 01752 virtual bool Visit( const TiXmlComment& comment ); 01753 virtual bool Visit( const TiXmlUnknown& unknown ); 01754 01758 void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } 01760 const char* Indent() { return indent.c_str(); } 01765 void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } 01767 const char* LineBreak() { return lineBreak.c_str(); } 01768 01772 void SetStreamPrinting() { indent = ""; 01773 lineBreak = ""; 01774 } 01776 const char* CStr() { return buffer.c_str(); } 01778 size_t Size() { return buffer.size(); } 01779 01780 #ifdef TIXML_USE_STL 01781 01782 const std::string& Str() { return buffer; } 01783 #endif 01784 01785 private: 01786 void DoIndent() { 01787 for( int i=0; i<depth; ++i ) 01788 buffer += indent; 01789 } 01790 void DoLineBreak() { 01791 buffer += lineBreak; 01792 } 01793 01794 int depth; 01795 bool simpleTextPrint; 01796 TIXML_STRING buffer; 01797 TIXML_STRING indent; 01798 TIXML_STRING lineBreak; 01799 }; 01800 01801 01802 #ifdef _MSC_VER 01803 #pragma warning( pop ) 01804 #endif 01805 01806 #endif 01807