| [3940] | 1 | /* | 
|---|
 | 2 | www.sourceforge.net/projects/tinyxml | 
|---|
 | 3 | Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) | 
|---|
 | 4 |  | 
|---|
 | 5 | This software is provided 'as-is', without any express or implied | 
|---|
 | 6 | warranty. In no event will the authors be held liable for any | 
|---|
 | 7 | damages arising from the use of this software. | 
|---|
 | 8 |  | 
|---|
 | 9 | Permission is granted to anyone to use this software for any | 
|---|
 | 10 | purpose, including commercial applications, and to alter it and | 
|---|
 | 11 | redistribute it freely, subject to the following restrictions: | 
|---|
 | 12 |  | 
|---|
 | 13 | 1. The origin of this software must not be misrepresented; you must | 
|---|
 | 14 | not claim that you wrote the original software. If you use this | 
|---|
 | 15 | software in a product, an acknowledgment in the product documentation | 
|---|
 | 16 | would be appreciated but is not required. | 
|---|
 | 17 |  | 
|---|
 | 18 | 2. Altered source versions must be plainly marked as such, and | 
|---|
 | 19 | must not be misrepresented as being the original software. | 
|---|
 | 20 |  | 
|---|
 | 21 | 3. This notice may not be removed or altered from any source | 
|---|
 | 22 | distribution. | 
|---|
 | 23 | */ | 
|---|
 | 24 |  | 
|---|
 | 25 |  | 
|---|
 | 26 | #ifndef TINYXML_INCLUDED | 
|---|
 | 27 | #define TINYXML_INCLUDED | 
|---|
 | 28 |  | 
|---|
 | 29 | #ifdef _MSC_VER | 
|---|
 | 30 | #pragma warning( disable : 4530 ) | 
|---|
 | 31 | #pragma warning( disable : 4786 ) | 
|---|
 | 32 | #endif | 
|---|
 | 33 |  | 
|---|
 | 34 | #include <ctype.h> | 
|---|
 | 35 | #include <stdio.h> | 
|---|
 | 36 | #include <stdlib.h> | 
|---|
 | 37 | #include <string.h> | 
|---|
 | 38 | #include <assert.h> | 
|---|
 | 39 |  | 
|---|
 | 40 | // Help out windows: | 
|---|
 | 41 | #if defined( _DEBUG ) && !defined( DEBUG ) | 
|---|
 | 42 | #define DEBUG | 
|---|
 | 43 | #endif | 
|---|
 | 44 |  | 
|---|
 | 45 | #if defined( DEBUG ) && defined( _MSC_VER ) | 
|---|
 | 46 | #include <windows.h> | 
|---|
 | 47 | #define TIXML_LOG OutputDebugString | 
|---|
 | 48 | #else | 
|---|
 | 49 | #define TIXML_LOG printf | 
|---|
 | 50 | #endif | 
|---|
 | 51 |  | 
|---|
 | 52 | #ifdef TIXML_USE_STL | 
|---|
 | 53 |         #include <string> | 
|---|
 | 54 |         #include <iostream> | 
|---|
 | 55 |         #define TIXML_STRING    std::string | 
|---|
 | 56 |         #define TIXML_ISTREAM   std::istream | 
|---|
 | 57 |         #define TIXML_OSTREAM   std::ostream | 
|---|
 | 58 | #else | 
|---|
 | 59 |         #include "tinystr.h" | 
|---|
 | 60 |         #define TIXML_STRING    TiXmlString | 
|---|
 | 61 |         #define TIXML_OSTREAM   TiXmlOutStream | 
|---|
 | 62 | #endif | 
|---|
 | 63 |  | 
|---|
 | 64 | class TiXmlDocument; | 
|---|
 | 65 | class TiXmlElement; | 
|---|
 | 66 | class TiXmlComment; | 
|---|
 | 67 | class TiXmlUnknown; | 
|---|
 | 68 | class TiXmlAttribute; | 
|---|
 | 69 | class TiXmlText; | 
|---|
 | 70 | class TiXmlDeclaration; | 
|---|
 | 71 | class TiXmlParsingData; | 
|---|
 | 72 |  | 
|---|
 | 73 | const int TIXML_MAJOR_VERSION = 2; | 
|---|
 | 74 | const int TIXML_MINOR_VERSION = 3; | 
|---|
 | 75 | const int TIXML_PATCH_VERSION = 3; | 
|---|
 | 76 |  | 
|---|
 | 77 | /*      Internal structure for tracking location of items  | 
|---|
 | 78 |         in the XML file. | 
|---|
 | 79 | */ | 
|---|
 | 80 | struct TiXmlCursor | 
|---|
 | 81 | { | 
|---|
 | 82 |         TiXmlCursor()           { Clear(); } | 
|---|
 | 83 |         void Clear()            { row = col = -1; } | 
|---|
 | 84 |  | 
|---|
 | 85 |         int row;        // 0 based. | 
|---|
 | 86 |         int col;        // 0 based. | 
|---|
 | 87 | }; | 
|---|
 | 88 |  | 
|---|
 | 89 |  | 
|---|
 | 90 | // Only used by Attribute::Query functions | 
|---|
 | 91 | enum  | 
|---|
 | 92 | {  | 
|---|
 | 93 |         TIXML_SUCCESS, | 
|---|
 | 94 |         TIXML_NO_ATTRIBUTE, | 
|---|
 | 95 |         TIXML_WRONG_TYPE | 
|---|
 | 96 | }; | 
|---|
 | 97 |  | 
|---|
 | 98 |  | 
|---|
 | 99 | // Used by the parsing routines. | 
|---|
 | 100 | enum TiXmlEncoding | 
|---|
 | 101 | { | 
|---|
 | 102 |         TIXML_ENCODING_UNKNOWN, | 
|---|
 | 103 |         TIXML_ENCODING_UTF8, | 
|---|
 | 104 |         TIXML_ENCODING_LEGACY | 
|---|
 | 105 | }; | 
|---|
 | 106 |  | 
|---|
 | 107 | const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; | 
|---|
 | 108 |  | 
|---|
 | 109 | /** TiXmlBase is a base class for every class in TinyXml. | 
|---|
 | 110 |         It does little except to establish that TinyXml classes | 
|---|
 | 111 |         can be printed and provide some utility functions. | 
|---|
 | 112 |  | 
|---|
 | 113 |         In XML, the document and elements can contain | 
|---|
 | 114 |         other elements and other types of nodes. | 
|---|
 | 115 |  | 
|---|
 | 116 |         @verbatim | 
|---|
 | 117 |         A Document can contain: Element (container or leaf) | 
|---|
 | 118 |                                                         Comment (leaf) | 
|---|
 | 119 |                                                         Unknown (leaf) | 
|---|
 | 120 |                                                         Declaration( leaf ) | 
|---|
 | 121 |  | 
|---|
 | 122 |         An Element can contain: Element (container or leaf) | 
|---|
 | 123 |                                                         Text    (leaf) | 
|---|
 | 124 |                                                         Attributes (not on tree) | 
|---|
 | 125 |                                                         Comment (leaf) | 
|---|
 | 126 |                                                         Unknown (leaf) | 
|---|
 | 127 |  | 
|---|
 | 128 |         A Decleration contains: Attributes (not on tree) | 
|---|
 | 129 |         @endverbatim | 
|---|
 | 130 | */ | 
|---|
 | 131 | class TiXmlBase | 
|---|
 | 132 | { | 
|---|
 | 133 |         friend class TiXmlNode; | 
|---|
 | 134 |         friend class TiXmlElement; | 
|---|
 | 135 |         friend class TiXmlDocument; | 
|---|
 | 136 |  | 
|---|
 | 137 | public: | 
|---|
 | 138 |         TiXmlBase()     :       userData(0) {} | 
|---|
 | 139 |         virtual ~TiXmlBase()                                    {} | 
|---|
 | 140 |  | 
|---|
 | 141 |         /**     All TinyXml classes can print themselves to a filestream. | 
|---|
 | 142 |                 This is a formatted print, and will insert tabs and newlines. | 
|---|
 | 143 |                  | 
|---|
 | 144 |                 (For an unformatted stream, use the << operator.) | 
|---|
 | 145 |         */ | 
|---|
 | 146 |         virtual void Print( FILE* cfile, int depth ) const = 0; | 
|---|
 | 147 |  | 
|---|
 | 148 |         /**     The world does not agree on whether white space should be kept or | 
|---|
 | 149 |                 not. In order to make everyone happy, these global, static functions | 
|---|
 | 150 |                 are provided to set whether or not TinyXml will condense all white space | 
|---|
 | 151 |                 into a single space or not. The default is to condense. Note changing this | 
|---|
 | 152 |                 values is not thread safe. | 
|---|
 | 153 |         */ | 
|---|
 | 154 |         static void SetCondenseWhiteSpace( bool condense )              { condenseWhiteSpace = condense; } | 
|---|
 | 155 |  | 
|---|
 | 156 |         /// Return the current white space setting. | 
|---|
 | 157 |         static bool IsWhiteSpaceCondensed()                                             { return condenseWhiteSpace; } | 
|---|
 | 158 |  | 
|---|
 | 159 |         /** Return the position, in the original source file, of this node or attribute. | 
|---|
 | 160 |                 The row and column are 1-based. (That is the first row and first column is | 
|---|
 | 161 |                 1,1). If the returns values are 0 or less, then the parser does not have | 
|---|
 | 162 |                 a row and column value. | 
|---|
 | 163 |  | 
|---|
 | 164 |                 Generally, the row and column value will be set when the TiXmlDocument::Load(), | 
|---|
 | 165 |                 TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set | 
|---|
 | 166 |                 when the DOM was created from operator>>. | 
|---|
 | 167 |  | 
|---|
 | 168 |                 The values reflect the initial load. Once the DOM is modified programmatically | 
|---|
 | 169 |                 (by adding or changing nodes and attributes) the new values will NOT update to | 
|---|
 | 170 |                 reflect changes in the document. | 
|---|
 | 171 |  | 
|---|
 | 172 |                 There is a minor performance cost to computing the row and column. Computation | 
|---|
 | 173 |                 can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. | 
|---|
 | 174 |  | 
|---|
 | 175 |                 @sa TiXmlDocument::SetTabSize() | 
|---|
 | 176 |         */ | 
|---|
 | 177 |         int Row() const                 { return location.row + 1; } | 
|---|
 | 178 |         int Column() const              { return location.col + 1; }    ///< See Row() | 
|---|
 | 179 |  | 
|---|
 | 180 |         void  SetUserData( void* user )                 { userData = user; } | 
|---|
 | 181 |         void* GetUserData()                                             { return userData; } | 
|---|
 | 182 |  | 
|---|
 | 183 |         // Table that returs, for a given lead byte, the total number of bytes | 
|---|
 | 184 |         // in the UTF-8 sequence. | 
|---|
 | 185 |         static const int utf8ByteTable[256]; | 
|---|
 | 186 |  | 
|---|
 | 187 |         virtual const char* Parse(      const char* p,  | 
|---|
 | 188 |                                                                 TiXmlParsingData* data,  | 
|---|
 | 189 |                                                                 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; | 
|---|
 | 190 |  | 
|---|
 | 191 |         enum | 
|---|
 | 192 |         { | 
|---|
 | 193 |                 TIXML_NO_ERROR = 0, | 
|---|
 | 194 |                 TIXML_ERROR, | 
|---|
 | 195 |                 TIXML_ERROR_OPENING_FILE, | 
|---|
 | 196 |                 TIXML_ERROR_OUT_OF_MEMORY, | 
|---|
 | 197 |                 TIXML_ERROR_PARSING_ELEMENT, | 
|---|
 | 198 |                 TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, | 
|---|
 | 199 |                 TIXML_ERROR_READING_ELEMENT_VALUE, | 
|---|
 | 200 |                 TIXML_ERROR_READING_ATTRIBUTES, | 
|---|
 | 201 |                 TIXML_ERROR_PARSING_EMPTY, | 
|---|
 | 202 |                 TIXML_ERROR_READING_END_TAG, | 
|---|
 | 203 |                 TIXML_ERROR_PARSING_UNKNOWN, | 
|---|
 | 204 |                 TIXML_ERROR_PARSING_COMMENT, | 
|---|
 | 205 |                 TIXML_ERROR_PARSING_DECLARATION, | 
|---|
 | 206 |                 TIXML_ERROR_DOCUMENT_EMPTY, | 
|---|
 | 207 |                 TIXML_ERROR_EMBEDDED_NULL, | 
|---|
 | 208 |  | 
|---|
 | 209 |                 TIXML_ERROR_STRING_COUNT | 
|---|
 | 210 |         }; | 
|---|
 | 211 |  | 
|---|
 | 212 | protected: | 
|---|
 | 213 |  | 
|---|
 | 214 |         // See STL_STRING_BUG | 
|---|
 | 215 |         // Utility class to overcome a bug. | 
|---|
 | 216 |         class StringToBuffer | 
|---|
 | 217 |         { | 
|---|
 | 218 |           public: | 
|---|
 | 219 |                 StringToBuffer( const TIXML_STRING& str ); | 
|---|
 | 220 |                 ~StringToBuffer(); | 
|---|
 | 221 |                 char* buffer; | 
|---|
 | 222 |         }; | 
|---|
 | 223 |  | 
|---|
 | 224 |         static const char*      SkipWhiteSpace( const char*, TiXmlEncoding encoding ); | 
|---|
 | 225 |         inline static bool      IsWhiteSpace( char c )           | 
|---|
 | 226 |         {  | 
|---|
 | 227 |                 return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );  | 
|---|
 | 228 |         } | 
|---|
 | 229 |  | 
|---|
 | 230 |         virtual void StreamOut (TIXML_OSTREAM *) const = 0; | 
|---|
 | 231 |  | 
|---|
 | 232 |         #ifdef TIXML_USE_STL | 
|---|
 | 233 |             static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ); | 
|---|
 | 234 |             static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ); | 
|---|
 | 235 |         #endif | 
|---|
 | 236 |  | 
|---|
 | 237 |         /*      Reads an XML name into the string provided. Returns | 
|---|
 | 238 |                 a pointer just past the last character of the name, | 
|---|
 | 239 |                 or 0 if the function has an error. | 
|---|
 | 240 |         */ | 
|---|
 | 241 |         static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); | 
|---|
 | 242 |  | 
|---|
 | 243 |         /*      Reads text. Returns a pointer past the given end tag. | 
|---|
 | 244 |                 Wickedly complex options, but it keeps the (sensitive) code in one place. | 
|---|
 | 245 |         */ | 
|---|
 | 246 |         static const char* ReadText(    const char* in,                         // where to start | 
|---|
 | 247 |                                                                         TIXML_STRING* text,                     // the string read | 
|---|
 | 248 |                                                                         bool ignoreWhiteSpace,          // whether to keep the white space | 
|---|
 | 249 |                                                                         const char* endTag,                     // what ends this text | 
|---|
 | 250 |                                                                         bool ignoreCase,                        // whether to ignore case in the end tag | 
|---|
 | 251 |                                                                         TiXmlEncoding encoding );       // the current encoding | 
|---|
 | 252 |  | 
|---|
 | 253 |         // If an entity has been found, transform it into a character. | 
|---|
 | 254 |         static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); | 
|---|
 | 255 |  | 
|---|
 | 256 |         // Get a character, while interpreting entities. | 
|---|
 | 257 |         // The length can be from 0 to 4 bytes. | 
|---|
 | 258 |         inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) | 
|---|
 | 259 |         { | 
|---|
 | 260 |                 assert( p ); | 
|---|
 | 261 |                 if ( encoding == TIXML_ENCODING_UTF8 ) | 
|---|
 | 262 |                 { | 
|---|
 | 263 |                         *length = utf8ByteTable[ *((unsigned char*)p) ]; | 
|---|
 | 264 |                         assert( *length >= 0 && *length < 5 ); | 
|---|
 | 265 |                 } | 
|---|
 | 266 |                 else | 
|---|
 | 267 |                 { | 
|---|
 | 268 |                         *length = 1; | 
|---|
 | 269 |                 } | 
|---|
 | 270 |  | 
|---|
 | 271 |                 if ( *length == 1 ) | 
|---|
 | 272 |                 { | 
|---|
 | 273 |                         if ( *p == '&' ) | 
|---|
 | 274 |                                 return GetEntity( p, _value, length, encoding ); | 
|---|
 | 275 |                         *_value = *p; | 
|---|
 | 276 |                         return p+1; | 
|---|
 | 277 |                 } | 
|---|
 | 278 |                 else if ( *length ) | 
|---|
 | 279 |                 { | 
|---|
 | 280 |                         strncpy( _value, p, *length ); | 
|---|
 | 281 |                         return p + (*length); | 
|---|
 | 282 |                 } | 
|---|
 | 283 |                 else | 
|---|
 | 284 |                 { | 
|---|
 | 285 |                         // Not valid text. | 
|---|
 | 286 |                         return 0; | 
|---|
 | 287 |                 } | 
|---|
 | 288 |         } | 
|---|
 | 289 |  | 
|---|
 | 290 |         // Puts a string to a stream, expanding entities as it goes. | 
|---|
 | 291 |         // Note this should not contian the '<', '>', etc, or they will be transformed into entities! | 
|---|
 | 292 |         static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out ); | 
|---|
 | 293 |  | 
|---|
 | 294 |         static void PutString( const TIXML_STRING& str, TIXML_STRING* out ); | 
|---|
 | 295 |  | 
|---|
 | 296 |         // Return true if the next characters in the stream are any of the endTag sequences. | 
|---|
 | 297 |         // Ignore case only works for english, and should only be relied on when comparing | 
|---|
 | 298 |         // to Engilish words: StringEqual( p, "version", true ) is fine. | 
|---|
 | 299 |         static bool StringEqual(        const char* p, | 
|---|
 | 300 |                                                                 const char* endTag, | 
|---|
 | 301 |                                                                 bool ignoreCase, | 
|---|
 | 302 |                                                                 TiXmlEncoding encoding ); | 
|---|
 | 303 |  | 
|---|
 | 304 |         static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; | 
|---|
 | 305 |  | 
|---|
 | 306 |         TiXmlCursor location; | 
|---|
 | 307 |  | 
|---|
 | 308 |     /// Field containing a generic user pointer | 
|---|
 | 309 |         void*                   userData; | 
|---|
 | 310 |          | 
|---|
 | 311 |         // None of these methods are reliable for any language except English. | 
|---|
 | 312 |         // Good for approximation, not great for accuracy. | 
|---|
 | 313 |         static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); | 
|---|
 | 314 |         static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); | 
|---|
 | 315 |         inline static int ToLower( int v, TiXmlEncoding encoding ) | 
|---|
 | 316 |         { | 
|---|
 | 317 |                 if ( encoding == TIXML_ENCODING_UTF8 ) | 
|---|
 | 318 |                 { | 
|---|
 | 319 |                         if ( v < 128 ) return tolower( v ); | 
|---|
 | 320 |                         return v; | 
|---|
 | 321 |                 } | 
|---|
 | 322 |                 else | 
|---|
 | 323 |                 { | 
|---|
 | 324 |                         return tolower( v ); | 
|---|
 | 325 |                 } | 
|---|
 | 326 |         } | 
|---|
 | 327 |         static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); | 
|---|
 | 328 |  | 
|---|
 | 329 | private: | 
|---|
 | 330 |         TiXmlBase( const TiXmlBase& );                          // not implemented. | 
|---|
 | 331 |         void operator=( const TiXmlBase& base );        // not allowed. | 
|---|
 | 332 |  | 
|---|
 | 333 |         struct Entity | 
|---|
 | 334 |         { | 
|---|
 | 335 |                 const char*     str; | 
|---|
 | 336 |                 unsigned int    strLength; | 
|---|
 | 337 |                 char                chr; | 
|---|
 | 338 |         }; | 
|---|
 | 339 |         enum | 
|---|
 | 340 |         { | 
|---|
 | 341 |                 NUM_ENTITY = 5, | 
|---|
 | 342 |                 MAX_ENTITY_LENGTH = 6 | 
|---|
 | 343 |  | 
|---|
 | 344 |         }; | 
|---|
 | 345 |         static Entity entity[ NUM_ENTITY ]; | 
|---|
 | 346 |         static bool condenseWhiteSpace; | 
|---|
 | 347 | }; | 
|---|
 | 348 |  | 
|---|
 | 349 |  | 
|---|
 | 350 | /** The parent class for everything in the Document Object Model. | 
|---|
 | 351 |         (Except for attributes). | 
|---|
 | 352 |         Nodes have siblings, a parent, and children. A node can be | 
|---|
 | 353 |         in a document, or stand on its own. The type of a TiXmlNode | 
|---|
 | 354 |         can be queried, and it can be cast to its more defined type. | 
|---|
 | 355 | */ | 
|---|
 | 356 | class TiXmlNode : public TiXmlBase | 
|---|
 | 357 | { | 
|---|
 | 358 |         friend class TiXmlDocument; | 
|---|
 | 359 |         friend class TiXmlElement; | 
|---|
 | 360 |  | 
|---|
 | 361 | public: | 
|---|
 | 362 |         #ifdef TIXML_USE_STL     | 
|---|
 | 363 |  | 
|---|
 | 364 |             /** An input stream operator, for every class. Tolerant of newlines and | 
|---|
 | 365 |                     formatting, but doesn't expect them. | 
|---|
 | 366 |             */ | 
|---|
 | 367 |             friend std::istream& operator >> (std::istream& in, TiXmlNode& base); | 
|---|
 | 368 |  | 
|---|
 | 369 |             /** An output stream operator, for every class. Note that this outputs | 
|---|
 | 370 |                     without any newlines or formatting, as opposed to Print(), which | 
|---|
 | 371 |                     includes tabs and new lines. | 
|---|
 | 372 |  | 
|---|
 | 373 |                     The operator<< and operator>> are not completely symmetric. Writing | 
|---|
 | 374 |                     a node to a stream is very well defined. You'll get a nice stream | 
|---|
 | 375 |                     of output, without any extra whitespace or newlines. | 
|---|
 | 376 |                      | 
|---|
 | 377 |                     But reading is not as well defined. (As it always is.) If you create | 
|---|
 | 378 |                     a TiXmlElement (for example) and read that from an input stream, | 
|---|
 | 379 |                     the text needs to define an element or junk will result. This is | 
|---|
 | 380 |                     true of all input streams, but it's worth keeping in mind. | 
|---|
 | 381 |  | 
|---|
 | 382 |                     A TiXmlDocument will read nodes until it reads a root element, and | 
|---|
 | 383 |                         all the children of that root element. | 
|---|
 | 384 |             */   | 
|---|
 | 385 |             friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); | 
|---|
 | 386 |  | 
|---|
 | 387 |                 /// Appends the XML node or attribute to a std::string. | 
|---|
 | 388 |                 friend std::string& operator<< (std::string& out, const TiXmlNode& base ); | 
|---|
 | 389 |  | 
|---|
 | 390 |         #else | 
|---|
 | 391 |             // Used internally, not part of the public API. | 
|---|
 | 392 |             friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base); | 
|---|
 | 393 |         #endif | 
|---|
 | 394 |  | 
|---|
 | 395 |         /** The types of XML nodes supported by TinyXml. (All the | 
|---|
 | 396 |                         unsupported types are picked up by UNKNOWN.) | 
|---|
 | 397 |         */ | 
|---|
 | 398 |         enum NodeType | 
|---|
 | 399 |         { | 
|---|
 | 400 |                 DOCUMENT, | 
|---|
 | 401 |                 ELEMENT, | 
|---|
 | 402 |                 COMMENT, | 
|---|
 | 403 |                 UNKNOWN, | 
|---|
 | 404 |                 TEXT, | 
|---|
 | 405 |                 DECLARATION, | 
|---|
 | 406 |                 TYPECOUNT | 
|---|
 | 407 |         }; | 
|---|
 | 408 |  | 
|---|
 | 409 |         virtual ~TiXmlNode(); | 
|---|
 | 410 |  | 
|---|
 | 411 |         /** The meaning of 'value' changes for the specific type of | 
|---|
 | 412 |                 TiXmlNode. | 
|---|
 | 413 |                 @verbatim | 
|---|
 | 414 |                 Document:       filename of the xml file | 
|---|
 | 415 |                 Element:        name of the element | 
|---|
 | 416 |                 Comment:        the comment text | 
|---|
 | 417 |                 Unknown:        the tag contents | 
|---|
 | 418 |                 Text:           the text string | 
|---|
 | 419 |                 @endverbatim | 
|---|
 | 420 |  | 
|---|
 | 421 |                 The subclasses will wrap this function. | 
|---|
 | 422 |         */ | 
|---|
 | 423 |         const char * Value() const { return value.c_str (); } | 
|---|
 | 424 |  | 
|---|
 | 425 |         /** Changes the value of the node. Defined as: | 
|---|
 | 426 |                 @verbatim | 
|---|
 | 427 |                 Document:       filename of the xml file | 
|---|
 | 428 |                 Element:        name of the element | 
|---|
 | 429 |                 Comment:        the comment text | 
|---|
 | 430 |                 Unknown:        the tag contents | 
|---|
 | 431 |                 Text:           the text string | 
|---|
 | 432 |                 @endverbatim | 
|---|
 | 433 |         */ | 
|---|
 | 434 |         void SetValue(const char * _value) { value = _value;} | 
|---|
 | 435 |  | 
|---|
 | 436 |     #ifdef TIXML_USE_STL | 
|---|
 | 437 |         /// STL std::string form. | 
|---|
 | 438 |         void SetValue( const std::string& _value )     | 
|---|
 | 439 |         {          | 
|---|
 | 440 |                 StringToBuffer buf( _value ); | 
|---|
 | 441 |                 SetValue( buf.buffer ? buf.buffer : "" );        | 
|---|
 | 442 |         }        | 
|---|
 | 443 |         #endif | 
|---|
 | 444 |  | 
|---|
 | 445 |         /// Delete all the children of this node. Does not affect 'this'. | 
|---|
 | 446 |         void Clear(); | 
|---|
 | 447 |  | 
|---|
 | 448 |         /// One step up the DOM. | 
|---|
 | 449 |         TiXmlNode* Parent()                                                     { return parent; } | 
|---|
 | 450 |         const TiXmlNode* Parent() const                         { return parent; } | 
|---|
 | 451 |  | 
|---|
 | 452 |         const TiXmlNode* FirstChild()   const   { return firstChild; }          ///< The first child of this node. Will be null if there are no children. | 
|---|
 | 453 |         TiXmlNode* FirstChild()                                 { return firstChild; } | 
|---|
 | 454 |         const TiXmlNode* FirstChild( const char * value ) const;                        ///< The first child of this node with the matching 'value'. Will be null if none found. | 
|---|
 | 455 |         TiXmlNode* FirstChild( const char * value );                                            ///< The first child of this node with the matching 'value'. Will be null if none found. | 
|---|
 | 456 |  | 
|---|
 | 457 |         const TiXmlNode* LastChild() const      { return lastChild; }           /// The last child of this node. Will be null if there are no children. | 
|---|
 | 458 |         TiXmlNode* LastChild()  { return lastChild; } | 
|---|
 | 459 |         const TiXmlNode* LastChild( const char * value ) const;                 /// The last child of this node matching 'value'. Will be null if there are no children. | 
|---|
 | 460 |         TiXmlNode* LastChild( const char * value );      | 
|---|
 | 461 |  | 
|---|
 | 462 |     #ifdef TIXML_USE_STL | 
|---|
 | 463 |         const TiXmlNode* FirstChild( const std::string& _value ) const  {       return FirstChild (_value.c_str ());    }       ///< STL std::string form. | 
|---|
 | 464 |         TiXmlNode* FirstChild( const std::string& _value )                              {       return FirstChild (_value.c_str ());    }       ///< STL std::string form. | 
|---|
 | 465 |         const TiXmlNode* LastChild( const std::string& _value ) const   {       return LastChild (_value.c_str ());     }       ///< STL std::string form. | 
|---|
 | 466 |         TiXmlNode* LastChild( const std::string& _value )                               {       return LastChild (_value.c_str ());     }       ///< STL std::string form. | 
|---|
 | 467 |         #endif | 
|---|
 | 468 |  | 
|---|
 | 469 |         /** An alternate way to walk the children of a node. | 
|---|
 | 470 |                 One way to iterate over nodes is: | 
|---|
 | 471 |                 @verbatim | 
|---|
 | 472 |                         for( child = parent->FirstChild(); child; child = child->NextSibling() ) | 
|---|
 | 473 |                 @endverbatim | 
|---|
 | 474 |  | 
|---|
 | 475 |                 IterateChildren does the same thing with the syntax: | 
|---|
 | 476 |                 @verbatim | 
|---|
 | 477 |                         child = 0; | 
|---|
 | 478 |                         while( child = parent->IterateChildren( child ) ) | 
|---|
 | 479 |                 @endverbatim | 
|---|
 | 480 |  | 
|---|
 | 481 |                 IterateChildren takes the previous child as input and finds | 
|---|
 | 482 |                 the next one. If the previous child is null, it returns the | 
|---|
 | 483 |                 first. IterateChildren will return null when done. | 
|---|
 | 484 |         */ | 
|---|
 | 485 |         const TiXmlNode* IterateChildren( TiXmlNode* previous ) const; | 
|---|
 | 486 |         TiXmlNode* IterateChildren( TiXmlNode* previous ); | 
|---|
 | 487 |  | 
|---|
 | 488 |         /// This flavor of IterateChildren searches for children with a particular 'value' | 
|---|
 | 489 |         const TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const; | 
|---|
 | 490 |         TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ); | 
|---|
 | 491 |  | 
|---|
 | 492 |     #ifdef TIXML_USE_STL | 
|---|
 | 493 |         const TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) const        {       return IterateChildren (_value.c_str (), previous);     }       ///< STL std::string form. | 
|---|
 | 494 |         TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) {  return IterateChildren (_value.c_str (), previous);     }       ///< STL std::string form. | 
|---|
 | 495 |         #endif | 
|---|
 | 496 |  | 
|---|
 | 497 |         /** Add a new node related to this. Adds a child past the LastChild. | 
|---|
 | 498 |                 Returns a pointer to the new object or NULL if an error occured. | 
|---|
 | 499 |         */ | 
|---|
 | 500 |         TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); | 
|---|
 | 501 |  | 
|---|
 | 502 |  | 
|---|
 | 503 |         /** Add a new node related to this. Adds a child past the LastChild. | 
|---|
 | 504 |  | 
|---|
 | 505 |                 NOTE: the node to be added is passed by pointer, and will be | 
|---|
 | 506 |                 henceforth owned (and deleted) by tinyXml. This method is efficient | 
|---|
 | 507 |                 and avoids an extra copy, but should be used with care as it | 
|---|
 | 508 |                 uses a different memory model than the other insert functions. | 
|---|
 | 509 |  | 
|---|
 | 510 |                 @sa InsertEndChild | 
|---|
 | 511 |         */ | 
|---|
 | 512 |         TiXmlNode* LinkEndChild( TiXmlNode* addThis ); | 
|---|
 | 513 |  | 
|---|
 | 514 |         /** Add a new node related to this. Adds a child before the specified child. | 
|---|
 | 515 |                 Returns a pointer to the new object or NULL if an error occured. | 
|---|
 | 516 |         */ | 
|---|
 | 517 |         TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); | 
|---|
 | 518 |  | 
|---|
 | 519 |         /** Add a new node related to this. Adds a child after the specified child. | 
|---|
 | 520 |                 Returns a pointer to the new object or NULL if an error occured. | 
|---|
 | 521 |         */ | 
|---|
 | 522 |         TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis ); | 
|---|
 | 523 |  | 
|---|
 | 524 |         /** Replace a child of this node. | 
|---|
 | 525 |                 Returns a pointer to the new object or NULL if an error occured. | 
|---|
 | 526 |         */ | 
|---|
 | 527 |         TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); | 
|---|
 | 528 |  | 
|---|
 | 529 |         /// Delete a child of this node. | 
|---|
 | 530 |         bool RemoveChild( TiXmlNode* removeThis ); | 
|---|
 | 531 |  | 
|---|
 | 532 |         /// Navigate to a sibling node. | 
|---|
 | 533 |         const TiXmlNode* PreviousSibling() const                        { return prev; } | 
|---|
 | 534 |         TiXmlNode* PreviousSibling()                                            { return prev; } | 
|---|
 | 535 |  | 
|---|
 | 536 |         /// Navigate to a sibling node. | 
|---|
 | 537 |         const TiXmlNode* PreviousSibling( const char * ) const; | 
|---|
 | 538 |         TiXmlNode* PreviousSibling( const char * ); | 
|---|
 | 539 |  | 
|---|
 | 540 |     #ifdef TIXML_USE_STL | 
|---|
 | 541 |         const TiXmlNode* PreviousSibling( const std::string& _value ) const     {       return PreviousSibling (_value.c_str ());       }       ///< STL std::string form. | 
|---|
 | 542 |         TiXmlNode* PreviousSibling( const std::string& _value )                         {       return PreviousSibling (_value.c_str ());       }       ///< STL std::string form. | 
|---|
 | 543 |         const TiXmlNode* NextSibling( const std::string& _value) const          {       return NextSibling (_value.c_str ());   }       ///< STL std::string form. | 
|---|
 | 544 |         TiXmlNode* NextSibling( const std::string& _value)                                      {       return NextSibling (_value.c_str ());   }       ///< STL std::string form. | 
|---|
 | 545 |         #endif | 
|---|
 | 546 |  | 
|---|
 | 547 |         /// Navigate to a sibling node. | 
|---|
 | 548 |         const TiXmlNode* NextSibling() const                            { return next; } | 
|---|
 | 549 |         TiXmlNode* NextSibling()                                                        { return next; } | 
|---|
 | 550 |  | 
|---|
 | 551 |         /// Navigate to a sibling node with the given 'value'. | 
|---|
 | 552 |         const TiXmlNode* NextSibling( const char * ) const; | 
|---|
 | 553 |         TiXmlNode* NextSibling( const char * ); | 
|---|
 | 554 |  | 
|---|
 | 555 |         /** Convenience function to get through elements. | 
|---|
 | 556 |                 Calls NextSibling and ToElement. Will skip all non-Element | 
|---|
 | 557 |                 nodes. Returns 0 if there is not another element. | 
|---|
 | 558 |         */ | 
|---|
 | 559 |         const TiXmlElement* NextSiblingElement() const; | 
|---|
 | 560 |         TiXmlElement* NextSiblingElement(); | 
|---|
 | 561 |  | 
|---|
 | 562 |         /** Convenience function to get through elements. | 
|---|
 | 563 |                 Calls NextSibling and ToElement. Will skip all non-Element | 
|---|
 | 564 |                 nodes. Returns 0 if there is not another element. | 
|---|
 | 565 |         */ | 
|---|
 | 566 |         const TiXmlElement* NextSiblingElement( const char * ) const; | 
|---|
 | 567 |         TiXmlElement* NextSiblingElement( const char * ); | 
|---|
 | 568 |  | 
|---|
 | 569 |     #ifdef TIXML_USE_STL | 
|---|
 | 570 |         const TiXmlElement* NextSiblingElement( const std::string& _value) const        {       return NextSiblingElement (_value.c_str ());    }       ///< STL std::string form. | 
|---|
 | 571 |         TiXmlElement* NextSiblingElement( const std::string& _value)                            {       return NextSiblingElement (_value.c_str ());    }       ///< STL std::string form. | 
|---|
 | 572 |         #endif | 
|---|
 | 573 |  | 
|---|
 | 574 |         /// Convenience function to get through elements. | 
|---|
 | 575 |         const TiXmlElement* FirstChildElement() const; | 
|---|
 | 576 |         TiXmlElement* FirstChildElement(); | 
|---|
 | 577 |  | 
|---|
 | 578 |         /// Convenience function to get through elements. | 
|---|
 | 579 |         const TiXmlElement* FirstChildElement( const char * value ) const; | 
|---|
 | 580 |         TiXmlElement* FirstChildElement( const char * value ); | 
|---|
 | 581 |  | 
|---|
 | 582 |     #ifdef TIXML_USE_STL | 
|---|
 | 583 |         const TiXmlElement* FirstChildElement( const std::string& _value ) const        {       return FirstChildElement (_value.c_str ());     }       ///< STL std::string form. | 
|---|
 | 584 |         TiXmlElement* FirstChildElement( const std::string& _value )                            {       return FirstChildElement (_value.c_str ());     }       ///< STL std::string form. | 
|---|
 | 585 |         #endif | 
|---|
 | 586 |  | 
|---|
 | 587 |         /** Query the type (as an enumerated value, above) of this node. | 
|---|
 | 588 |                 The possible types are: DOCUMENT, ELEMENT, COMMENT, | 
|---|
 | 589 |                                                                 UNKNOWN, TEXT, and DECLARATION. | 
|---|
 | 590 |         */ | 
|---|
 | 591 |         virtual int Type() const        { return type; } | 
|---|
 | 592 |  | 
|---|
 | 593 |         /** Return a pointer to the Document this node lives in. | 
|---|
 | 594 |                 Returns null if not in a document. | 
|---|
 | 595 |         */ | 
|---|
 | 596 |         const TiXmlDocument* GetDocument() const; | 
|---|
 | 597 |         TiXmlDocument* GetDocument(); | 
|---|
 | 598 |  | 
|---|
 | 599 |         /// Returns true if this node has no children. | 
|---|
 | 600 |         bool NoChildren() const                                         { return !firstChild; } | 
|---|
 | 601 |  | 
|---|
 | 602 |         const TiXmlDocument* ToDocument()       const           { return ( this && type == DOCUMENT ) ? (const TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 603 |         const TiXmlElement*  ToElement() const                  { return ( this && type == ELEMENT  ) ? (const TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 604 |         const TiXmlComment*  ToComment() const                  { return ( this && type == COMMENT  ) ? (const TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 605 |         const TiXmlUnknown*  ToUnknown() const                  { return ( this && type == UNKNOWN  ) ? (const TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 606 |         const TiXmlText*           ToText()    const            { return ( this && type == TEXT     ) ? (const TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 607 |         const TiXmlDeclaration* ToDeclaration() const   { return ( this && type == DECLARATION ) ? (const TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 608 |  | 
|---|
 | 609 |         TiXmlDocument* ToDocument()                     { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 610 |         TiXmlElement*  ToElement()                      { return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 611 |         TiXmlComment*  ToComment()                      { return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 612 |         TiXmlUnknown*  ToUnknown()                      { return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 613 |         TiXmlText*         ToText()                     { return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 614 |         TiXmlDeclaration* ToDeclaration()       { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. | 
|---|
 | 615 |  | 
|---|
 | 616 |         /** Create an exact duplicate of this node and return it. The memory must be deleted | 
|---|
 | 617 |                 by the caller.  | 
|---|
 | 618 |         */ | 
|---|
 | 619 |         virtual TiXmlNode* Clone() const = 0; | 
|---|
 | 620 |  | 
|---|
 | 621 | protected: | 
|---|
 | 622 |         TiXmlNode( NodeType _type ); | 
|---|
 | 623 |  | 
|---|
 | 624 |         // Copy to the allocated object. Shared functionality between Clone, Copy constructor, | 
|---|
 | 625 |         // and the assignment operator. | 
|---|
 | 626 |         void CopyTo( TiXmlNode* target ) const; | 
|---|
 | 627 |  | 
|---|
 | 628 |         #ifdef TIXML_USE_STL | 
|---|
 | 629 |             // The real work of the input operator. | 
|---|
 | 630 |             virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0; | 
|---|
 | 631 |         #endif | 
|---|
 | 632 |  | 
|---|
 | 633 |         // Figure out what is at *p, and parse it. Returns null if it is not an xml node. | 
|---|
 | 634 |         TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); | 
|---|
 | 635 |  | 
|---|
 | 636 |         // Internal Value function returning a TIXML_STRING | 
|---|
 | 637 |         const TIXML_STRING& SValue() const      { return value ; } | 
|---|
 | 638 |  | 
|---|
 | 639 |         TiXmlNode*              parent; | 
|---|
 | 640 |         NodeType                type; | 
|---|
 | 641 |  | 
|---|
 | 642 |         TiXmlNode*              firstChild; | 
|---|
 | 643 |         TiXmlNode*              lastChild; | 
|---|
 | 644 |  | 
|---|
 | 645 |         TIXML_STRING    value; | 
|---|
 | 646 |  | 
|---|
 | 647 |         TiXmlNode*              prev; | 
|---|
 | 648 |         TiXmlNode*              next; | 
|---|
 | 649 |  | 
|---|
 | 650 | private: | 
|---|
 | 651 |         TiXmlNode( const TiXmlNode& );                          // not implemented. | 
|---|
 | 652 |         void operator=( const TiXmlNode& base );        // not allowed. | 
|---|
 | 653 | }; | 
|---|
 | 654 |  | 
|---|
 | 655 |  | 
|---|
 | 656 | /** An attribute is a name-value pair. Elements have an arbitrary | 
|---|
 | 657 |         number of attributes, each with a unique name. | 
|---|
 | 658 |  | 
|---|
 | 659 |         @note The attributes are not TiXmlNodes, since they are not | 
|---|
 | 660 |                   part of the tinyXML document object model. There are other | 
|---|
 | 661 |                   suggested ways to look at this problem. | 
|---|
 | 662 | */ | 
|---|
 | 663 | class TiXmlAttribute : public TiXmlBase | 
|---|
 | 664 | { | 
|---|
 | 665 |         friend class TiXmlAttributeSet; | 
|---|
 | 666 |  | 
|---|
 | 667 | public: | 
|---|
 | 668 |         /// Construct an empty attribute. | 
|---|
 | 669 |         TiXmlAttribute() : TiXmlBase() | 
|---|
 | 670 |         { | 
|---|
 | 671 |                 document = 0; | 
|---|
 | 672 |                 prev = next = 0; | 
|---|
 | 673 |         } | 
|---|
 | 674 |  | 
|---|
 | 675 |         #ifdef TIXML_USE_STL | 
|---|
 | 676 |         /// std::string constructor. | 
|---|
 | 677 |         TiXmlAttribute( const std::string& _name, const std::string& _value ) | 
|---|
 | 678 |         { | 
|---|
 | 679 |                 name = _name; | 
|---|
 | 680 |                 value = _value; | 
|---|
 | 681 |                 document = 0; | 
|---|
 | 682 |                 prev = next = 0; | 
|---|
 | 683 |         } | 
|---|
 | 684 |         #endif | 
|---|
 | 685 |  | 
|---|
 | 686 |         /// Construct an attribute with a name and value. | 
|---|
 | 687 |         TiXmlAttribute( const char * _name, const char * _value ) | 
|---|
 | 688 |         { | 
|---|
 | 689 |                 name = _name; | 
|---|
 | 690 |                 value = _value; | 
|---|
 | 691 |                 document = 0; | 
|---|
 | 692 |                 prev = next = 0; | 
|---|
 | 693 |         } | 
|---|
 | 694 |  | 
|---|
 | 695 |         const char*             Name()  const           { return name.c_str (); }               ///< Return the name of this attribute. | 
|---|
 | 696 |         const char*             Value() const           { return value.c_str (); }              ///< Return the value of this attribute. | 
|---|
 | 697 |         const int       IntValue() const;                                                                       ///< Return the value of this attribute, converted to an integer. | 
|---|
 | 698 |         const double    DoubleValue() const;                                                            ///< Return the value of this attribute, converted to a double. | 
|---|
 | 699 |  | 
|---|
 | 700 |         /** QueryIntValue examines the value string. It is an alternative to the | 
|---|
 | 701 |                 IntValue() method with richer error checking. | 
|---|
 | 702 |                 If the value is an integer, it is stored in 'value' and  | 
|---|
 | 703 |                 the call returns TIXML_SUCCESS. If it is not | 
|---|
 | 704 |                 an integer, it returns TIXML_WRONG_TYPE. | 
|---|
 | 705 |  | 
|---|
 | 706 |                 A specialized but useful call. Note that for success it returns 0, | 
|---|
 | 707 |                 which is the opposite of almost all other TinyXml calls. | 
|---|
 | 708 |         */ | 
|---|
 | 709 |         int QueryIntValue( int* value ) const; | 
|---|
 | 710 |         /// QueryDoubleValue examines the value string. See QueryIntValue(). | 
|---|
 | 711 |         int QueryDoubleValue( double* value ) const; | 
|---|
 | 712 |  | 
|---|
 | 713 |         void SetName( const char* _name )       { name = _name; }                               ///< Set the name of this attribute. | 
|---|
 | 714 |         void SetValue( const char* _value )     { value = _value; }                             ///< Set the value. | 
|---|
 | 715 |  | 
|---|
 | 716 |         void SetIntValue( int value );                                                                          ///< Set the value from an integer. | 
|---|
 | 717 |         void SetDoubleValue( double value );                                                            ///< Set the value from a double. | 
|---|
 | 718 |  | 
|---|
 | 719 |     #ifdef TIXML_USE_STL | 
|---|
 | 720 |         /// STL std::string form. | 
|---|
 | 721 |         void SetName( const std::string& _name )         | 
|---|
 | 722 |         {        | 
|---|
 | 723 |                 StringToBuffer buf( _name ); | 
|---|
 | 724 |                 SetName ( buf.buffer ? buf.buffer : "error" );   | 
|---|
 | 725 |         } | 
|---|
 | 726 |         /// STL std::string form.        | 
|---|
 | 727 |         void SetValue( const std::string& _value )       | 
|---|
 | 728 |         {        | 
|---|
 | 729 |                 StringToBuffer buf( _value ); | 
|---|
 | 730 |                 SetValue( buf.buffer ? buf.buffer : "error" );   | 
|---|
 | 731 |         } | 
|---|
 | 732 |         #endif | 
|---|
 | 733 |  | 
|---|
 | 734 |         /// Get the next sibling attribute in the DOM. Returns null at end. | 
|---|
 | 735 |         const TiXmlAttribute* Next() const; | 
|---|
 | 736 |         TiXmlAttribute* Next(); | 
|---|
 | 737 |         /// Get the previous sibling attribute in the DOM. Returns null at beginning. | 
|---|
 | 738 |         const TiXmlAttribute* Previous() const; | 
|---|
 | 739 |         TiXmlAttribute* Previous(); | 
|---|
 | 740 |  | 
|---|
 | 741 |         bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } | 
|---|
 | 742 |         bool operator<( const TiXmlAttribute& rhs )      const { return name < rhs.name; } | 
|---|
 | 743 |         bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; } | 
|---|
 | 744 |  | 
|---|
 | 745 |         /*      Attribute parsing starts: first letter of the name | 
|---|
 | 746 |                                                  returns: the next char after the value end quote | 
|---|
 | 747 |         */ | 
|---|
 | 748 |         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); | 
|---|
 | 749 |  | 
|---|
 | 750 |         // Prints this Attribute to a FILE stream. | 
|---|
 | 751 |         virtual void Print( FILE* cfile, int depth ) const; | 
|---|
 | 752 |  | 
|---|
 | 753 |         virtual void StreamOut( TIXML_OSTREAM * out ) const; | 
|---|
 | 754 |         // [internal use] | 
|---|
 | 755 |         // Set the document pointer so the attribute can report errors. | 
|---|
 | 756 |         void SetDocument( TiXmlDocument* doc )  { document = doc; } | 
|---|
 | 757 |  | 
|---|
 | 758 | private: | 
|---|
 | 759 |         TiXmlAttribute( const TiXmlAttribute& );                                // not implemented. | 
|---|
 | 760 |         void operator=( const TiXmlAttribute& base );   // not allowed. | 
|---|
 | 761 |  | 
|---|
 | 762 |         TiXmlDocument*  document;       // A pointer back to a document, for error reporting. | 
|---|
 | 763 |         TIXML_STRING name; | 
|---|
 | 764 |         TIXML_STRING value; | 
|---|
 | 765 |         TiXmlAttribute* prev; | 
|---|
 | 766 |         TiXmlAttribute* next; | 
|---|
 | 767 | }; | 
|---|
 | 768 |  | 
|---|
 | 769 |  | 
|---|
 | 770 | /*      A class used to manage a group of attributes. | 
|---|
 | 771 |         It is only used internally, both by the ELEMENT and the DECLARATION. | 
|---|
 | 772 |          | 
|---|
 | 773 |         The set can be changed transparent to the Element and Declaration | 
|---|
 | 774 |         classes that use it, but NOT transparent to the Attribute | 
|---|
 | 775 |         which has to implement a next() and previous() method. Which makes | 
|---|
 | 776 |         it a bit problematic and prevents the use of STL. | 
|---|
 | 777 |  | 
|---|
 | 778 |         This version is implemented with circular lists because: | 
|---|
 | 779 |                 - I like circular lists | 
|---|
 | 780 |                 - it demonstrates some independence from the (typical) doubly linked list. | 
|---|
 | 781 | */ | 
|---|
 | 782 | class TiXmlAttributeSet | 
|---|
 | 783 | { | 
|---|
 | 784 | public: | 
|---|
 | 785 |         TiXmlAttributeSet(); | 
|---|
 | 786 |         ~TiXmlAttributeSet(); | 
|---|
 | 787 |  | 
|---|
 | 788 |         void Add( TiXmlAttribute* attribute ); | 
|---|
 | 789 |         void Remove( TiXmlAttribute* attribute ); | 
|---|
 | 790 |  | 
|---|
 | 791 |         const TiXmlAttribute* First()   const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } | 
|---|
 | 792 |         TiXmlAttribute* First()                                 { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } | 
|---|
 | 793 |         const TiXmlAttribute* Last() const              { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } | 
|---|
 | 794 |         TiXmlAttribute* Last()                                  { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } | 
|---|
 | 795 |  | 
|---|
 | 796 |         const TiXmlAttribute*   Find( const char * name ) const; | 
|---|
 | 797 |         TiXmlAttribute* Find( const char * name ); | 
|---|
 | 798 |  | 
|---|
 | 799 | private: | 
|---|
 | 800 |         //*ME:  Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), | 
|---|
 | 801 |         //*ME:  this class must be also use a hidden/disabled copy-constructor !!! | 
|---|
 | 802 |         TiXmlAttributeSet( const TiXmlAttributeSet& );  // not allowed | 
|---|
 | 803 |         void operator=( const TiXmlAttributeSet& );     // not allowed (as TiXmlAttribute) | 
|---|
 | 804 |  | 
|---|
 | 805 |         TiXmlAttribute sentinel; | 
|---|
 | 806 | }; | 
|---|
 | 807 |  | 
|---|
 | 808 |  | 
|---|
 | 809 | /** The element is a container class. It has a value, the element name, | 
|---|
 | 810 |         and can contain other elements, text, comments, and unknowns. | 
|---|
 | 811 |         Elements also contain an arbitrary number of attributes. | 
|---|
 | 812 | */ | 
|---|
 | 813 | class TiXmlElement : public TiXmlNode | 
|---|
 | 814 | { | 
|---|
 | 815 | public: | 
|---|
 | 816 |         /// Construct an element. | 
|---|
 | 817 |         TiXmlElement (const char * in_value); | 
|---|
 | 818 |  | 
|---|
 | 819 |         #ifdef TIXML_USE_STL | 
|---|
 | 820 |         /// std::string constructor. | 
|---|
 | 821 |         TiXmlElement( const std::string& _value ); | 
|---|
 | 822 |         #endif | 
|---|
 | 823 |  | 
|---|
 | 824 |         TiXmlElement( const TiXmlElement& ); | 
|---|
 | 825 |  | 
|---|
 | 826 |         void operator=( const TiXmlElement& base ); | 
|---|
 | 827 |  | 
|---|
 | 828 |         virtual ~TiXmlElement(); | 
|---|
 | 829 |  | 
|---|
 | 830 |         /** Given an attribute name, Attribute() returns the value | 
|---|
 | 831 |                 for the attribute of that name, or null if none exists. | 
|---|
 | 832 |         */ | 
|---|
 | 833 |         const char* Attribute( const char* name ) const; | 
|---|
 | 834 |  | 
|---|
 | 835 |         /** Given an attribute name, Attribute() returns the value | 
|---|
 | 836 |                 for the attribute of that name, or null if none exists. | 
|---|
 | 837 |                 If the attribute exists and can be converted to an integer, | 
|---|
 | 838 |                 the integer value will be put in the return 'i', if 'i' | 
|---|
 | 839 |                 is non-null. | 
|---|
 | 840 |         */ | 
|---|
 | 841 |         const char* Attribute( const char* name, int* i ) const; | 
|---|
 | 842 |  | 
|---|
 | 843 |         /** Given an attribute name, Attribute() returns the value | 
|---|
 | 844 |                 for the attribute of that name, or null if none exists. | 
|---|
 | 845 |                 If the attribute exists and can be converted to an double, | 
|---|
 | 846 |                 the double value will be put in the return 'd', if 'd' | 
|---|
 | 847 |                 is non-null. | 
|---|
 | 848 |         */ | 
|---|
 | 849 |         const char* Attribute( const char* name, double* d ) const; | 
|---|
 | 850 |  | 
|---|
 | 851 |         /** QueryIntAttribute examines the attribute - it is an alternative to the | 
|---|
 | 852 |                 Attribute() method with richer error checking. | 
|---|
 | 853 |                 If the attribute is an integer, it is stored in 'value' and  | 
|---|
 | 854 |                 the call returns TIXML_SUCCESS. If it is not | 
|---|
 | 855 |                 an integer, it returns TIXML_WRONG_TYPE. If the attribute | 
|---|
 | 856 |                 does not exist, then TIXML_NO_ATTRIBUTE is returned. | 
|---|
 | 857 |         */       | 
|---|
 | 858 |         int QueryIntAttribute( const char* name, int* value ) const; | 
|---|
 | 859 |         /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). | 
|---|
 | 860 |         int QueryDoubleAttribute( const char* name, double* value ) const; | 
|---|
 | 861 |         /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). | 
|---|
 | 862 |         int QueryDoubleAttribute( const char* name, float* value ) const { | 
|---|
 | 863 |                 double d; | 
|---|
 | 864 |                 int result = QueryDoubleAttribute( name, &d ); | 
|---|
 | 865 |                 *value = (float)d; | 
|---|
 | 866 |                 return result; | 
|---|
 | 867 |         } | 
|---|
 | 868 |  | 
|---|
 | 869 |         /** Sets an attribute of name to a given value. The attribute | 
|---|
 | 870 |                 will be created if it does not exist, or changed if it does. | 
|---|
 | 871 |         */ | 
|---|
 | 872 |         void SetAttribute( const char* name, const char * value ); | 
|---|
 | 873 |  | 
|---|
 | 874 |     #ifdef TIXML_USE_STL | 
|---|
 | 875 |         const char* Attribute( const std::string& name ) const                          { return Attribute( name.c_str() ); } | 
|---|
 | 876 |         const char* Attribute( const std::string& name, int* i ) const          { return Attribute( name.c_str(), i ); } | 
|---|
 | 877 |         const char* Attribute( const std::string& name, double* d ) const       { return Attribute( name.c_str(), d ); } | 
|---|
 | 878 |         int QueryIntAttribute( const std::string& name, int* value ) const      { return QueryIntAttribute( name.c_str(), value ); } | 
|---|
 | 879 |         int QueryDoubleAttribute( const std::string& name, double* value ) const { return QueryDoubleAttribute( name.c_str(), value ); } | 
|---|
 | 880 |  | 
|---|
 | 881 |         /// STL std::string form. | 
|---|
 | 882 |         void SetAttribute( const std::string& name, const std::string& _value )  | 
|---|
 | 883 |         {        | 
|---|
 | 884 |                 StringToBuffer n( name ); | 
|---|
 | 885 |                 StringToBuffer v( _value ); | 
|---|
 | 886 |                 if ( n.buffer && v.buffer ) | 
|---|
 | 887 |                         SetAttribute (n.buffer, v.buffer );      | 
|---|
 | 888 |         }        | 
|---|
 | 889 |         ///< STL std::string form. | 
|---|
 | 890 |         void SetAttribute( const std::string& name, int _value )         | 
|---|
 | 891 |         {        | 
|---|
 | 892 |                 StringToBuffer n( name ); | 
|---|
 | 893 |                 if ( n.buffer ) | 
|---|
 | 894 |                         SetAttribute (n.buffer, _value);         | 
|---|
 | 895 |         }        | 
|---|
 | 896 |         #endif | 
|---|
 | 897 |  | 
|---|
 | 898 |         /** Sets an attribute of name to a given value. The attribute | 
|---|
 | 899 |                 will be created if it does not exist, or changed if it does. | 
|---|
 | 900 |         */ | 
|---|
 | 901 |         void SetAttribute( const char * name, int value ); | 
|---|
 | 902 |  | 
|---|
 | 903 |         /** Sets an attribute of name to a given value. The attribute | 
|---|
 | 904 |                 will be created if it does not exist, or changed if it does. | 
|---|
 | 905 |         */ | 
|---|
 | 906 |         void SetDoubleAttribute( const char * name, double value ); | 
|---|
 | 907 |  | 
|---|
 | 908 |         /** Deletes an attribute with the given name. | 
|---|
 | 909 |         */ | 
|---|
 | 910 |         void RemoveAttribute( const char * name ); | 
|---|
 | 911 |     #ifdef TIXML_USE_STL | 
|---|
 | 912 |         void RemoveAttribute( const std::string& name ) {       RemoveAttribute (name.c_str ());        }       ///< STL std::string form. | 
|---|
 | 913 |         #endif | 
|---|
 | 914 |  | 
|---|
 | 915 |         const TiXmlAttribute* FirstAttribute() const    { return attributeSet.First(); }                ///< Access the first attribute in this element. | 
|---|
 | 916 |         TiXmlAttribute* FirstAttribute()                                { return attributeSet.First(); } | 
|---|
 | 917 |         const TiXmlAttribute* LastAttribute()   const   { return attributeSet.Last(); }         ///< Access the last attribute in this element. | 
|---|
 | 918 |         TiXmlAttribute* LastAttribute()                                 { return attributeSet.Last(); } | 
|---|
 | 919 |  | 
|---|
 | 920 |         /// Creates a new Element and returns it - the returned element is a copy. | 
|---|
 | 921 |         virtual TiXmlNode* Clone() const; | 
|---|
 | 922 |         // Print the Element to a FILE stream. | 
|---|
 | 923 |         virtual void Print( FILE* cfile, int depth ) const; | 
|---|
 | 924 |  | 
|---|
 | 925 |         /*      Attribtue parsing starts: next char past '<' | 
|---|
 | 926 |                                                  returns: next char past '>' | 
|---|
 | 927 |         */ | 
|---|
 | 928 |         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); | 
|---|
 | 929 |  | 
|---|
 | 930 | protected: | 
|---|
 | 931 |  | 
|---|
 | 932 |         void CopyTo( TiXmlElement* target ) const; | 
|---|
 | 933 |         void ClearThis();       // like clear, but initializes 'this' object as well | 
|---|
 | 934 |  | 
|---|
 | 935 |         // Used to be public [internal use] | 
|---|
 | 936 |         #ifdef TIXML_USE_STL | 
|---|
 | 937 |             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); | 
|---|
 | 938 |         #endif | 
|---|
 | 939 |         virtual void StreamOut( TIXML_OSTREAM * out ) const; | 
|---|
 | 940 |  | 
|---|
 | 941 |         /*      [internal use] | 
|---|
 | 942 |                 Reads the "value" of the element -- another element, or text. | 
|---|
 | 943 |                 This should terminate with the current end tag. | 
|---|
 | 944 |         */ | 
|---|
 | 945 |         const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); | 
|---|
 | 946 |  | 
|---|
 | 947 | private: | 
|---|
 | 948 |  | 
|---|
 | 949 |         TiXmlAttributeSet attributeSet; | 
|---|
 | 950 | }; | 
|---|
 | 951 |  | 
|---|
 | 952 |  | 
|---|
 | 953 | /**     An XML comment. | 
|---|
 | 954 | */ | 
|---|
 | 955 | class TiXmlComment : public TiXmlNode | 
|---|
 | 956 | { | 
|---|
 | 957 | public: | 
|---|
 | 958 |         /// Constructs an empty comment. | 
|---|
 | 959 |         TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} | 
|---|
 | 960 |         TiXmlComment( const TiXmlComment& ); | 
|---|
 | 961 |         void operator=( const TiXmlComment& base ); | 
|---|
 | 962 |  | 
|---|
 | 963 |         virtual ~TiXmlComment() {} | 
|---|
 | 964 |  | 
|---|
 | 965 |         /// Returns a copy of this Comment. | 
|---|
 | 966 |         virtual TiXmlNode* Clone() const; | 
|---|
 | 967 |         /// Write this Comment to a FILE stream. | 
|---|
 | 968 |         virtual void Print( FILE* cfile, int depth ) const; | 
|---|
 | 969 |  | 
|---|
 | 970 |         /*      Attribtue parsing starts: at the ! of the !-- | 
|---|
 | 971 |                                                  returns: next char past '>' | 
|---|
 | 972 |         */ | 
|---|
 | 973 |         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); | 
|---|
 | 974 |  | 
|---|
 | 975 | protected: | 
|---|
 | 976 |         void CopyTo( TiXmlComment* target ) const; | 
|---|
 | 977 |  | 
|---|
 | 978 |         // used to be public | 
|---|
 | 979 |         #ifdef TIXML_USE_STL | 
|---|
 | 980 |             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); | 
|---|
 | 981 |         #endif | 
|---|
 | 982 |         virtual void StreamOut( TIXML_OSTREAM * out ) const; | 
|---|
 | 983 |  | 
|---|
 | 984 | private: | 
|---|
 | 985 |  | 
|---|
 | 986 | }; | 
|---|
 | 987 |  | 
|---|
 | 988 |  | 
|---|
 | 989 | /** XML text. Contained in an element. | 
|---|
 | 990 | */ | 
|---|
 | 991 | class TiXmlText : public TiXmlNode | 
|---|
 | 992 | { | 
|---|
 | 993 |         friend class TiXmlElement; | 
|---|
 | 994 | public: | 
|---|
 | 995 |         /// Constructor. | 
|---|
 | 996 |         TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT) | 
|---|
 | 997 |         { | 
|---|
 | 998 |                 SetValue( initValue ); | 
|---|
 | 999 |         } | 
|---|
 | 1000 |         virtual ~TiXmlText() {} | 
|---|
 | 1001 |  | 
|---|
 | 1002 |         #ifdef TIXML_USE_STL | 
|---|
 | 1003 |         /// Constructor. | 
|---|
 | 1004 |         TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) | 
|---|
 | 1005 |         { | 
|---|
 | 1006 |                 SetValue( initValue ); | 
|---|
 | 1007 |         } | 
|---|
 | 1008 |         #endif | 
|---|
 | 1009 |  | 
|---|
 | 1010 |         TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )       { copy.CopyTo( this ); } | 
|---|
 | 1011 |         void operator=( const TiXmlText& base )                                                         { base.CopyTo( this ); } | 
|---|
 | 1012 |  | 
|---|
 | 1013 |         /// Write this text object to a FILE stream. | 
|---|
 | 1014 |         virtual void Print( FILE* cfile, int depth ) const; | 
|---|
 | 1015 |  | 
|---|
 | 1016 |         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); | 
|---|
 | 1017 |  | 
|---|
 | 1018 | protected : | 
|---|
 | 1019 |         ///  [internal use] Creates a new Element and returns it. | 
|---|
 | 1020 |         virtual TiXmlNode* Clone() const; | 
|---|
 | 1021 |         void CopyTo( TiXmlText* target ) const; | 
|---|
 | 1022 |  | 
|---|
 | 1023 |         virtual void StreamOut ( TIXML_OSTREAM * out ) const; | 
|---|
 | 1024 |         bool Blank() const;     // returns true if all white space and new lines | 
|---|
 | 1025 |         // [internal use] | 
|---|
 | 1026 |         #ifdef TIXML_USE_STL | 
|---|
 | 1027 |             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); | 
|---|
 | 1028 |         #endif | 
|---|
 | 1029 |  | 
|---|
 | 1030 | private: | 
|---|
 | 1031 | }; | 
|---|
 | 1032 |  | 
|---|
 | 1033 |  | 
|---|
 | 1034 | /** In correct XML the declaration is the first entry in the file. | 
|---|
 | 1035 |         @verbatim | 
|---|
 | 1036 |                 <?xml version="1.0" standalone="yes"?> | 
|---|
 | 1037 |         @endverbatim | 
|---|
 | 1038 |  | 
|---|
 | 1039 |         TinyXml will happily read or write files without a declaration, | 
|---|
 | 1040 |         however. There are 3 possible attributes to the declaration: | 
|---|
 | 1041 |         version, encoding, and standalone. | 
|---|
 | 1042 |  | 
|---|
 | 1043 |         Note: In this version of the code, the attributes are | 
|---|
 | 1044 |         handled as special cases, not generic attributes, simply | 
|---|
 | 1045 |         because there can only be at most 3 and they are always the same. | 
|---|
 | 1046 | */ | 
|---|
 | 1047 | class TiXmlDeclaration : public TiXmlNode | 
|---|
 | 1048 | { | 
|---|
 | 1049 | public: | 
|---|
 | 1050 |         /// Construct an empty declaration. | 
|---|
 | 1051 |         TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {} | 
|---|
 | 1052 |  | 
|---|
 | 1053 | #ifdef TIXML_USE_STL | 
|---|
 | 1054 |         /// Constructor. | 
|---|
 | 1055 |         TiXmlDeclaration(       const std::string& _version, | 
|---|
 | 1056 |                                                 const std::string& _encoding, | 
|---|
 | 1057 |                                                 const std::string& _standalone ); | 
|---|
 | 1058 | #endif | 
|---|
 | 1059 |  | 
|---|
 | 1060 |         /// Construct. | 
|---|
 | 1061 |         TiXmlDeclaration(       const char* _version, | 
|---|
 | 1062 |                                                 const char* _encoding, | 
|---|
 | 1063 |                                                 const char* _standalone ); | 
|---|
 | 1064 |  | 
|---|
 | 1065 |         TiXmlDeclaration( const TiXmlDeclaration& copy ); | 
|---|
 | 1066 |         void operator=( const TiXmlDeclaration& copy ); | 
|---|
 | 1067 |  | 
|---|
 | 1068 |         virtual ~TiXmlDeclaration()     {} | 
|---|
 | 1069 |  | 
|---|
 | 1070 |         /// Version. Will return an empty string if none was found. | 
|---|
 | 1071 |         const char *Version() const                     { return version.c_str (); } | 
|---|
 | 1072 |         /// Encoding. Will return an empty string if none was found. | 
|---|
 | 1073 |         const char *Encoding() const            { return encoding.c_str (); } | 
|---|
 | 1074 |         /// Is this a standalone document? | 
|---|
 | 1075 |         const char *Standalone() const          { return standalone.c_str (); } | 
|---|
 | 1076 |  | 
|---|
 | 1077 |         /// Creates a copy of this Declaration and returns it. | 
|---|
 | 1078 |         virtual TiXmlNode* Clone() const; | 
|---|
 | 1079 |         /// Print this declaration to a FILE stream. | 
|---|
 | 1080 |         virtual void Print( FILE* cfile, int depth ) const; | 
|---|
 | 1081 |  | 
|---|
 | 1082 |         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); | 
|---|
 | 1083 |  | 
|---|
 | 1084 | protected: | 
|---|
 | 1085 |         void CopyTo( TiXmlDeclaration* target ) const; | 
|---|
 | 1086 |         // used to be public | 
|---|
 | 1087 |         #ifdef TIXML_USE_STL | 
|---|
 | 1088 |             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); | 
|---|
 | 1089 |         #endif | 
|---|
 | 1090 |         virtual void StreamOut ( TIXML_OSTREAM * out) const; | 
|---|
 | 1091 |  | 
|---|
 | 1092 | private: | 
|---|
 | 1093 |  | 
|---|
 | 1094 |         TIXML_STRING version; | 
|---|
 | 1095 |         TIXML_STRING encoding; | 
|---|
 | 1096 |         TIXML_STRING standalone; | 
|---|
 | 1097 | }; | 
|---|
 | 1098 |  | 
|---|
 | 1099 |  | 
|---|
 | 1100 | /** Any tag that tinyXml doesn't recognize is saved as an | 
|---|
 | 1101 |         unknown. It is a tag of text, but should not be modified. | 
|---|
 | 1102 |         It will be written back to the XML, unchanged, when the file | 
|---|
 | 1103 |         is saved. | 
|---|
 | 1104 |  | 
|---|
 | 1105 |         DTD tags get thrown into TiXmlUnknowns. | 
|---|
 | 1106 | */ | 
|---|
 | 1107 | class TiXmlUnknown : public TiXmlNode | 
|---|
 | 1108 | { | 
|---|
 | 1109 | public: | 
|---|
 | 1110 |         TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )        {} | 
|---|
 | 1111 |         virtual ~TiXmlUnknown() {} | 
|---|
 | 1112 |  | 
|---|
 | 1113 |         TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )              { copy.CopyTo( this ); } | 
|---|
 | 1114 |         void operator=( const TiXmlUnknown& copy )                                                                              { copy.CopyTo( this ); } | 
|---|
 | 1115 |  | 
|---|
 | 1116 |         /// Creates a copy of this Unknown and returns it. | 
|---|
 | 1117 |         virtual TiXmlNode* Clone() const; | 
|---|
 | 1118 |         /// Print this Unknown to a FILE stream. | 
|---|
 | 1119 |         virtual void Print( FILE* cfile, int depth ) const; | 
|---|
 | 1120 |  | 
|---|
 | 1121 |         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); | 
|---|
 | 1122 |  | 
|---|
 | 1123 | protected: | 
|---|
 | 1124 |         void CopyTo( TiXmlUnknown* target ) const; | 
|---|
 | 1125 |  | 
|---|
 | 1126 |         #ifdef TIXML_USE_STL | 
|---|
 | 1127 |             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); | 
|---|
 | 1128 |         #endif | 
|---|
 | 1129 |         virtual void StreamOut ( TIXML_OSTREAM * out ) const; | 
|---|
 | 1130 |  | 
|---|
 | 1131 | private: | 
|---|
 | 1132 |  | 
|---|
 | 1133 | }; | 
|---|
 | 1134 |  | 
|---|
 | 1135 |  | 
|---|
 | 1136 | /** Always the top level node. A document binds together all the | 
|---|
 | 1137 |         XML pieces. It can be saved, loaded, and printed to the screen. | 
|---|
 | 1138 |         The 'value' of a document node is the xml file name. | 
|---|
 | 1139 | */ | 
|---|
 | 1140 | class TiXmlDocument : public TiXmlNode | 
|---|
 | 1141 | { | 
|---|
 | 1142 | public: | 
|---|
 | 1143 |         /// Create an empty document, that has no name. | 
|---|
 | 1144 |         TiXmlDocument(); | 
|---|
 | 1145 |         /// Create a document with a name. The name of the document is also the filename of the xml. | 
|---|
 | 1146 |         TiXmlDocument( const char * documentName ); | 
|---|
 | 1147 |  | 
|---|
 | 1148 |         #ifdef TIXML_USE_STL | 
|---|
 | 1149 |         /// Constructor. | 
|---|
 | 1150 |         TiXmlDocument( const std::string& documentName ); | 
|---|
 | 1151 |         #endif | 
|---|
 | 1152 |  | 
|---|
 | 1153 |         TiXmlDocument( const TiXmlDocument& copy ); | 
|---|
 | 1154 |         void operator=( const TiXmlDocument& copy ); | 
|---|
 | 1155 |  | 
|---|
 | 1156 |         virtual ~TiXmlDocument() {} | 
|---|
 | 1157 |  | 
|---|
 | 1158 |         /** Load a file using the current document value. | 
|---|
 | 1159 |                 Returns true if successful. Will delete any existing | 
|---|
 | 1160 |                 document data before loading. | 
|---|
 | 1161 |         */ | 
|---|
 | 1162 |         bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); | 
|---|
 | 1163 |         /// Save a file using the current document value. Returns true if successful. | 
|---|
 | 1164 |         bool SaveFile() const; | 
|---|
 | 1165 |         /// Load a file using the given filename. Returns true if successful. | 
|---|
 | 1166 |         bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); | 
|---|
 | 1167 |         /// Save a file using the given filename. Returns true if successful. | 
|---|
 | 1168 |         bool SaveFile( const char * filename ) const; | 
|---|
 | 1169 |  | 
|---|
 | 1170 |         #ifdef TIXML_USE_STL | 
|---|
 | 1171 |         bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )                   ///< STL std::string version. | 
|---|
 | 1172 |         { | 
|---|
 | 1173 |                 StringToBuffer f( filename ); | 
|---|
 | 1174 |                 return ( f.buffer && LoadFile( f.buffer, encoding )); | 
|---|
 | 1175 |         } | 
|---|
 | 1176 |         bool SaveFile( const std::string& filename ) const              ///< STL std::string version. | 
|---|
 | 1177 |         { | 
|---|
 | 1178 |                 StringToBuffer f( filename ); | 
|---|
 | 1179 |                 return ( f.buffer && SaveFile( f.buffer )); | 
|---|
 | 1180 |         } | 
|---|
 | 1181 |         #endif | 
|---|
 | 1182 |  | 
|---|
 | 1183 |         /** Parse the given null terminated block of xml data. Passing in an encoding to this | 
|---|
 | 1184 |                 method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml | 
|---|
 | 1185 |                 to use that encoding, regardless of what TinyXml might otherwise try to detect. | 
|---|
 | 1186 |         */ | 
|---|
 | 1187 |         virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); | 
|---|
 | 1188 |  | 
|---|
 | 1189 |         /** Get the root element -- the only top level element -- of the document. | 
|---|
 | 1190 |                 In well formed XML, there should only be one. TinyXml is tolerant of | 
|---|
 | 1191 |                 multiple elements at the document level. | 
|---|
 | 1192 |         */ | 
|---|
 | 1193 |         const TiXmlElement* RootElement() const         { return FirstChildElement(); } | 
|---|
 | 1194 |         TiXmlElement* RootElement()                                     { return FirstChildElement(); } | 
|---|
 | 1195 |  | 
|---|
 | 1196 |         /** If an error occurs, Error will be set to true. Also, | 
|---|
 | 1197 |                 - The ErrorId() will contain the integer identifier of the error (not generally useful) | 
|---|
 | 1198 |                 - The ErrorDesc() method will return the name of the error. (very useful) | 
|---|
 | 1199 |                 - The ErrorRow() and ErrorCol() will return the location of the error (if known) | 
|---|
 | 1200 |         */       | 
|---|
 | 1201 |         bool Error() const                                              { return error; } | 
|---|
 | 1202 |  | 
|---|
 | 1203 |         /// Contains a textual (english) description of the error if one occurs. | 
|---|
 | 1204 |         const char * ErrorDesc() const  { return errorDesc.c_str (); } | 
|---|
 | 1205 |  | 
|---|
 | 1206 |         /** Generally, you probably want the error string ( ErrorDesc() ). But if you | 
|---|
 | 1207 |                 prefer the ErrorId, this function will fetch it. | 
|---|
 | 1208 |         */ | 
|---|
 | 1209 |         const int ErrorId()     const                           { return errorId; } | 
|---|
 | 1210 |  | 
|---|
 | 1211 |         /** Returns the location (if known) of the error. The first column is column 1,  | 
|---|
 | 1212 |                 and the first row is row 1. A value of 0 means the row and column wasn't applicable | 
|---|
 | 1213 |                 (memory errors, for example, have no row/column) or the parser lost the error. (An | 
|---|
 | 1214 |                 error in the error reporting, in that case.) | 
|---|
 | 1215 |  | 
|---|
 | 1216 |                 @sa SetTabSize, Row, Column | 
|---|
 | 1217 |         */ | 
|---|
 | 1218 |         int ErrorRow()  { return errorLocation.row+1; } | 
|---|
 | 1219 |         int ErrorCol()  { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() | 
|---|
 | 1220 |  | 
|---|
 | 1221 |         /** By calling this method, with a tab size | 
|---|
 | 1222 |                 greater than 0, the row and column of each node and attribute is stored | 
|---|
 | 1223 |                 when the file is loaded. Very useful for tracking the DOM back in to | 
|---|
 | 1224 |                 the source file. | 
|---|
 | 1225 |  | 
|---|
 | 1226 |                 The tab size is required for calculating the location of nodes. If not | 
|---|
 | 1227 |                 set, the default of 4 is used. The tabsize is set per document. Setting | 
|---|
 | 1228 |                 the tabsize to 0 disables row/column tracking. | 
|---|
 | 1229 |  | 
|---|
 | 1230 |                 Note that row and column tracking is not supported when using operator>>. | 
|---|
 | 1231 |  | 
|---|
 | 1232 |                 The tab size needs to be enabled before the parse or load. Correct usage: | 
|---|
 | 1233 |                 @verbatim | 
|---|
 | 1234 |                 TiXmlDocument doc; | 
|---|
 | 1235 |                 doc.SetTabSize( 8 ); | 
|---|
 | 1236 |                 doc.Load( "myfile.xml" ); | 
|---|
 | 1237 |                 @endverbatim | 
|---|
 | 1238 |  | 
|---|
 | 1239 |                 @sa Row, Column | 
|---|
 | 1240 |         */ | 
|---|
 | 1241 |         void SetTabSize( int _tabsize )         { tabsize = _tabsize; } | 
|---|
 | 1242 |  | 
|---|
 | 1243 |         int TabSize() const     { return tabsize; } | 
|---|
 | 1244 |  | 
|---|
 | 1245 |         /** If you have handled the error, it can be reset with this call. The error | 
|---|
 | 1246 |                 state is automatically cleared if you Parse a new XML block. | 
|---|
 | 1247 |         */ | 
|---|
 | 1248 |         void ClearError()                                               {       error = false;  | 
|---|
 | 1249 |                                                                                                 errorId = 0;  | 
|---|
 | 1250 |                                                                                                 errorDesc = "";  | 
|---|
 | 1251 |                                                                                                 errorLocation.row = errorLocation.col = 0;  | 
|---|
 | 1252 |                                                                                                 //errorLocation.last = 0;  | 
|---|
 | 1253 |                                                                                         } | 
|---|
 | 1254 |  | 
|---|
 | 1255 |         /** Dump the document to standard out. */ | 
|---|
 | 1256 |         void Print() const                                              { Print( stdout, 0 ); } | 
|---|
 | 1257 |  | 
|---|
 | 1258 |         /// Print this Document to a FILE stream. | 
|---|
 | 1259 |         virtual void Print( FILE* cfile, int depth = 0 ) const; | 
|---|
 | 1260 |         // [internal use] | 
|---|
 | 1261 |         void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); | 
|---|
 | 1262 |  | 
|---|
 | 1263 | protected : | 
|---|
 | 1264 |         virtual void StreamOut ( TIXML_OSTREAM * out) const; | 
|---|
 | 1265 |         // [internal use] | 
|---|
 | 1266 |         virtual TiXmlNode* Clone() const; | 
|---|
 | 1267 |         #ifdef TIXML_USE_STL | 
|---|
 | 1268 |             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); | 
|---|
 | 1269 |         #endif | 
|---|
 | 1270 |  | 
|---|
 | 1271 | private: | 
|---|
 | 1272 |         void CopyTo( TiXmlDocument* target ) const; | 
|---|
 | 1273 |  | 
|---|
 | 1274 |         bool error; | 
|---|
 | 1275 |         int  errorId; | 
|---|
 | 1276 |         TIXML_STRING errorDesc; | 
|---|
 | 1277 |         int tabsize; | 
|---|
 | 1278 |         TiXmlCursor errorLocation; | 
|---|
 | 1279 | }; | 
|---|
 | 1280 |  | 
|---|
 | 1281 |  | 
|---|
 | 1282 | /** | 
|---|
 | 1283 |         A TiXmlHandle is a class that wraps a node pointer with null checks; this is | 
|---|
 | 1284 |         an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml | 
|---|
 | 1285 |         DOM structure. It is a separate utility class. | 
|---|
 | 1286 |  | 
|---|
 | 1287 |         Take an example: | 
|---|
 | 1288 |         @verbatim | 
|---|
 | 1289 |         <Document> | 
|---|
 | 1290 |                 <Element attributeA = "valueA"> | 
|---|
 | 1291 |                         <Child attributeB = "value1" /> | 
|---|
 | 1292 |                         <Child attributeB = "value2" /> | 
|---|
 | 1293 |                 </Element> | 
|---|
 | 1294 |         <Document> | 
|---|
 | 1295 |         @endverbatim | 
|---|
 | 1296 |  | 
|---|
 | 1297 |         Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very  | 
|---|
 | 1298 |         easy to write a *lot* of code that looks like: | 
|---|
 | 1299 |  | 
|---|
 | 1300 |         @verbatim | 
|---|
 | 1301 |         TiXmlElement* root = document.FirstChildElement( "Document" ); | 
|---|
 | 1302 |         if ( root ) | 
|---|
 | 1303 |         { | 
|---|
 | 1304 |                 TiXmlElement* element = root->FirstChildElement( "Element" ); | 
|---|
 | 1305 |                 if ( element ) | 
|---|
 | 1306 |                 { | 
|---|
 | 1307 |                         TiXmlElement* child = element->FirstChildElement( "Child" ); | 
|---|
 | 1308 |                         if ( child ) | 
|---|
 | 1309 |                         { | 
|---|
 | 1310 |                                 TiXmlElement* child2 = child->NextSiblingElement( "Child" ); | 
|---|
 | 1311 |                                 if ( child2 ) | 
|---|
 | 1312 |                                 { | 
|---|
 | 1313 |                                         // Finally do something useful. | 
|---|
 | 1314 |         @endverbatim | 
|---|
 | 1315 |  | 
|---|
 | 1316 |         And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity | 
|---|
 | 1317 |         of such code. A TiXmlHandle checks for null     pointers so it is perfectly safe  | 
|---|
 | 1318 |         and correct to use: | 
|---|
 | 1319 |  | 
|---|
 | 1320 |         @verbatim | 
|---|
 | 1321 |         TiXmlHandle docHandle( &document ); | 
|---|
 | 1322 |         TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element(); | 
|---|
 | 1323 |         if ( child2 ) | 
|---|
 | 1324 |         { | 
|---|
 | 1325 |                 // do something useful | 
|---|
 | 1326 |         @endverbatim | 
|---|
 | 1327 |  | 
|---|
 | 1328 |         Which is MUCH more concise and useful. | 
|---|
 | 1329 |  | 
|---|
 | 1330 |         It is also safe to copy handles - internally they are nothing more than node pointers. | 
|---|
 | 1331 |         @verbatim | 
|---|
 | 1332 |         TiXmlHandle handleCopy = handle; | 
|---|
 | 1333 |         @endverbatim | 
|---|
 | 1334 |  | 
|---|
 | 1335 |         What they should not be used for is iteration: | 
|---|
 | 1336 |  | 
|---|
 | 1337 |         @verbatim | 
|---|
 | 1338 |         int i=0;  | 
|---|
 | 1339 |         while ( true ) | 
|---|
 | 1340 |         { | 
|---|
 | 1341 |                 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element(); | 
|---|
 | 1342 |                 if ( !child ) | 
|---|
 | 1343 |                         break; | 
|---|
 | 1344 |                 // do something | 
|---|
 | 1345 |                 ++i; | 
|---|
 | 1346 |         } | 
|---|
 | 1347 |         @endverbatim | 
|---|
 | 1348 |  | 
|---|
 | 1349 |         It seems reasonable, but it is in fact two embedded while loops. The Child method is  | 
|---|
 | 1350 |         a linear walk to find the element, so this code would iterate much more than it needs  | 
|---|
 | 1351 |         to. Instead, prefer: | 
|---|
 | 1352 |  | 
|---|
 | 1353 |         @verbatim | 
|---|
 | 1354 |         TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element(); | 
|---|
 | 1355 |  | 
|---|
 | 1356 |         for( child; child; child=child->NextSiblingElement() ) | 
|---|
 | 1357 |         { | 
|---|
 | 1358 |                 // do something | 
|---|
 | 1359 |         } | 
|---|
 | 1360 |         @endverbatim | 
|---|
 | 1361 | */ | 
|---|
 | 1362 | class TiXmlHandle | 
|---|
 | 1363 | { | 
|---|
 | 1364 | public: | 
|---|
 | 1365 |         /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. | 
|---|
 | 1366 |         TiXmlHandle( TiXmlNode* node )                                  { this->node = node; } | 
|---|
 | 1367 |         /// Copy constructor | 
|---|
 | 1368 |         TiXmlHandle( const TiXmlHandle& ref )                   { this->node = ref.node; } | 
|---|
 | 1369 |         TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } | 
|---|
 | 1370 |  | 
|---|
 | 1371 |         /// Return a handle to the first child node. | 
|---|
 | 1372 |         TiXmlHandle FirstChild() const; | 
|---|
 | 1373 |         /// Return a handle to the first child node with the given name. | 
|---|
 | 1374 |         TiXmlHandle FirstChild( const char * value ) const; | 
|---|
 | 1375 |         /// Return a handle to the first child element. | 
|---|
 | 1376 |         TiXmlHandle FirstChildElement() const; | 
|---|
 | 1377 |         /// Return a handle to the first child element with the given name. | 
|---|
 | 1378 |         TiXmlHandle FirstChildElement( const char * value ) const; | 
|---|
 | 1379 |  | 
|---|
 | 1380 |         /** Return a handle to the "index" child with the given name.  | 
|---|
 | 1381 |                 The first child is 0, the second 1, etc. | 
|---|
 | 1382 |         */ | 
|---|
 | 1383 |         TiXmlHandle Child( const char* value, int index ) const; | 
|---|
 | 1384 |         /** Return a handle to the "index" child.  | 
|---|
 | 1385 |                 The first child is 0, the second 1, etc. | 
|---|
 | 1386 |         */ | 
|---|
 | 1387 |         TiXmlHandle Child( int index ) const; | 
|---|
 | 1388 |         /** Return a handle to the "index" child element with the given name.  | 
|---|
 | 1389 |                 The first child element is 0, the second 1, etc. Note that only TiXmlElements | 
|---|
 | 1390 |                 are indexed: other types are not counted. | 
|---|
 | 1391 |         */ | 
|---|
 | 1392 |         TiXmlHandle ChildElement( const char* value, int index ) const; | 
|---|
 | 1393 |         /** Return a handle to the "index" child element.  | 
|---|
 | 1394 |                 The first child element is 0, the second 1, etc. Note that only TiXmlElements | 
|---|
 | 1395 |                 are indexed: other types are not counted. | 
|---|
 | 1396 |         */ | 
|---|
 | 1397 |         TiXmlHandle ChildElement( int index ) const; | 
|---|
 | 1398 |  | 
|---|
 | 1399 |         #ifdef TIXML_USE_STL | 
|---|
 | 1400 |         TiXmlHandle FirstChild( const std::string& _value ) const                               { return FirstChild( _value.c_str() ); } | 
|---|
 | 1401 |         TiXmlHandle FirstChildElement( const std::string& _value ) const                { return FirstChildElement( _value.c_str() ); } | 
|---|
 | 1402 |  | 
|---|
 | 1403 |         TiXmlHandle Child( const std::string& _value, int index ) const                 { return Child( _value.c_str(), index ); } | 
|---|
 | 1404 |         TiXmlHandle ChildElement( const std::string& _value, int index ) const  { return ChildElement( _value.c_str(), index ); } | 
|---|
 | 1405 |         #endif | 
|---|
 | 1406 |  | 
|---|
 | 1407 |         /// Return the handle as a TiXmlNode. This may return null. | 
|---|
 | 1408 |         TiXmlNode* Node() const                 { return node; }  | 
|---|
 | 1409 |         /// Return the handle as a TiXmlElement. This may return null. | 
|---|
 | 1410 |         TiXmlElement* Element() const   { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } | 
|---|
 | 1411 |         /// Return the handle as a TiXmlText. This may return null. | 
|---|
 | 1412 |         TiXmlText* Text() const                 { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } | 
|---|
 | 1413 |         /// Return the handle as a TiXmlUnknown. This may return null; | 
|---|
 | 1414 |         TiXmlUnknown* Unknown() const                   { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } | 
|---|
 | 1415 |  | 
|---|
 | 1416 | private: | 
|---|
 | 1417 |         TiXmlNode* node; | 
|---|
 | 1418 | }; | 
|---|
 | 1419 |  | 
|---|
 | 1420 |  | 
|---|
 | 1421 | #endif | 
|---|
 | 1422 |  | 
|---|