annotate 3rdparty/tinyxml/tinyxml.cpp @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
rev   line source
ferencd@0 1 /*
ferencd@0 2 www.sourceforge.net/projects/tinyxml
ferencd@0 3 Original code by Lee Thomason (www.grinninglizard.com)
ferencd@0 4
ferencd@0 5 This software is provided 'as-is', without any express or implied
ferencd@0 6 warranty. In no event will the authors be held liable for any
ferencd@0 7 damages arising from the use of this software.
ferencd@0 8
ferencd@0 9 Permission is granted to anyone to use this software for any
ferencd@0 10 purpose, including commercial applications, and to alter it and
ferencd@0 11 redistribute it freely, subject to the following restrictions:
ferencd@0 12
ferencd@0 13 1. The origin of this software must not be misrepresented; you must
ferencd@0 14 not claim that you wrote the original software. If you use this
ferencd@0 15 software in a product, an acknowledgment in the product documentation
ferencd@0 16 would be appreciated but is not required.
ferencd@0 17
ferencd@0 18 2. Altered source versions must be plainly marked as such, and
ferencd@0 19 must not be misrepresented as being the original software.
ferencd@0 20
ferencd@0 21 3. This notice may not be removed or altered from any source
ferencd@0 22 distribution.
ferencd@0 23 */
ferencd@0 24 #ifdef _MSC_VER
ferencd@0 25 #define _CRT_SECURE_NO_WARNINGS
ferencd@0 26 #define _CRT_SECURE_NO_DEPRECATE
ferencd@0 27 #endif
ferencd@0 28
ferencd@0 29 #include <ctype.h>
ferencd@0 30
ferencd@0 31 #ifdef TIXML_USE_STL
ferencd@0 32 #include <sstream>
ferencd@0 33 #include <iostream>
ferencd@0 34 #endif
ferencd@0 35
ferencd@0 36 #include "tinyxml.h"
ferencd@0 37
ferencd@0 38 FILE* TiXmlFOpen( const char* filename, const char* mode );
ferencd@0 39
ferencd@0 40 bool TiXmlBase::condenseWhiteSpace = true;
ferencd@0 41
ferencd@0 42 // Microsoft compiler security
ferencd@0 43 FILE* TiXmlFOpen( const char* filename, const char* mode )
ferencd@0 44 {
ferencd@0 45 #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
ferencd@0 46 FILE* fp = 0;
ferencd@0 47 errno_t err = fopen_s( &fp, filename, mode );
ferencd@0 48 if ( !err && fp )
ferencd@0 49 return fp;
ferencd@0 50 return 0;
ferencd@0 51 #else
ferencd@0 52 return fopen( filename, mode );
ferencd@0 53 #endif
ferencd@0 54 }
ferencd@0 55
ferencd@0 56 void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
ferencd@0 57 {
ferencd@0 58 int i=0;
ferencd@0 59
ferencd@0 60 while( i<static_cast<int>(str.length()) )
ferencd@0 61 {
ferencd@0 62 unsigned char c = static_cast<unsigned char>(str[i]);
ferencd@0 63
ferencd@0 64 if ( c == '&'
ferencd@0 65 && i < ( static_cast<int>(str.length()) - 2 )
ferencd@0 66 && str[i+1] == '#'
ferencd@0 67 && str[i+2] == 'x' )
ferencd@0 68 {
ferencd@0 69 // Hexadecimal character reference.
ferencd@0 70 // Pass through unchanged.
ferencd@0 71 // &#xA9; -- copyright symbol, for example.
ferencd@0 72 //
ferencd@0 73 // The -1 is a bug fix from Rob Laveaux. It keeps
ferencd@0 74 // an overflow from happening if there is no ';'.
ferencd@0 75 // There are actually 2 ways to exit this loop -
ferencd@0 76 // while fails (error case) and break (semicolon found).
ferencd@0 77 // However, there is no mechanism (currently) for
ferencd@0 78 // this function to return an error.
ferencd@0 79 while ( i<static_cast<int>(str.length()) -1 )
ferencd@0 80 {
ferencd@0 81 outString->append( str.c_str() + i, 1 );
ferencd@0 82 ++i;
ferencd@0 83 if ( str[i] == ';' )
ferencd@0 84 break;
ferencd@0 85 }
ferencd@0 86 }
ferencd@0 87 else if ( c == '&' )
ferencd@0 88 {
ferencd@0 89 outString->append( entity[0].str, entity[0].strLength );
ferencd@0 90 ++i;
ferencd@0 91 }
ferencd@0 92 else if ( c == '<' )
ferencd@0 93 {
ferencd@0 94 outString->append( entity[1].str, entity[1].strLength );
ferencd@0 95 ++i;
ferencd@0 96 }
ferencd@0 97 else if ( c == '>' )
ferencd@0 98 {
ferencd@0 99 outString->append( entity[2].str, entity[2].strLength );
ferencd@0 100 ++i;
ferencd@0 101 }
ferencd@0 102 else if ( c == '\"' )
ferencd@0 103 {
ferencd@0 104 outString->append( entity[3].str, entity[3].strLength );
ferencd@0 105 ++i;
ferencd@0 106 }
ferencd@0 107 else if ( c == '\'' )
ferencd@0 108 {
ferencd@0 109 outString->append( entity[4].str, entity[4].strLength );
ferencd@0 110 ++i;
ferencd@0 111 }
ferencd@0 112 else if ( c < 32 )
ferencd@0 113 {
ferencd@0 114 // Easy pass at non-alpha/numeric/symbol
ferencd@0 115 // Below 32 is symbolic.
ferencd@0 116 char buf[ 32 ];
ferencd@0 117
ferencd@0 118 #if defined(TIXML_SNPRINTF)
ferencd@0 119 TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", static_cast<unsigned> ( c & 0xff ) );
ferencd@0 120 #else
ferencd@0 121 sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
ferencd@0 122 #endif
ferencd@0 123
ferencd@0 124 //*ME: warning C4267: convert 'size_t' to 'int'
ferencd@0 125 //*ME: Int-Cast to make compiler happy ...
ferencd@0 126 outString->append( buf, static_cast<int>(strlen(buf)) );
ferencd@0 127 ++i;
ferencd@0 128 }
ferencd@0 129 else
ferencd@0 130 {
ferencd@0 131 //char realc = (char) c;
ferencd@0 132 //outString->append( &realc, 1 );
ferencd@0 133 *outString += static_cast<char>(c); // somewhat more efficient function call.
ferencd@0 134 ++i;
ferencd@0 135 }
ferencd@0 136 }
ferencd@0 137 }
ferencd@0 138
ferencd@0 139
ferencd@0 140 TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
ferencd@0 141 {
ferencd@0 142 parent = 0;
ferencd@0 143 type = _type;
ferencd@0 144 firstChild = 0;
ferencd@0 145 lastChild = 0;
ferencd@0 146 prev = 0;
ferencd@0 147 next = 0;
ferencd@0 148 }
ferencd@0 149
ferencd@0 150
ferencd@0 151 TiXmlNode::~TiXmlNode()
ferencd@0 152 {
ferencd@0 153 TiXmlNode* node = firstChild;
ferencd@0 154 TiXmlNode* temp = 0;
ferencd@0 155
ferencd@0 156 while ( node )
ferencd@0 157 {
ferencd@0 158 temp = node;
ferencd@0 159 node = node->next;
ferencd@0 160 delete temp;
ferencd@0 161 }
ferencd@0 162 }
ferencd@0 163
ferencd@0 164
ferencd@0 165 void TiXmlNode::CopyTo( TiXmlNode* target ) const
ferencd@0 166 {
ferencd@0 167 target->SetValue (value.c_str() );
ferencd@0 168 target->userData = userData;
ferencd@0 169 target->location = location;
ferencd@0 170 }
ferencd@0 171
ferencd@0 172
ferencd@0 173 void TiXmlNode::Clear()
ferencd@0 174 {
ferencd@0 175 TiXmlNode* node = firstChild;
ferencd@0 176 TiXmlNode* temp = 0;
ferencd@0 177
ferencd@0 178 while ( node )
ferencd@0 179 {
ferencd@0 180 temp = node;
ferencd@0 181 node = node->next;
ferencd@0 182 delete temp;
ferencd@0 183 }
ferencd@0 184
ferencd@0 185 firstChild = 0;
ferencd@0 186 lastChild = 0;
ferencd@0 187 }
ferencd@0 188
ferencd@0 189
ferencd@0 190 TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
ferencd@0 191 {
ferencd@0 192 assert( node->parent == 0 || node->parent == this );
ferencd@0 193 assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
ferencd@0 194
ferencd@0 195 if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
ferencd@0 196 {
ferencd@0 197 delete node;
ferencd@0 198 if ( GetDocument() )
ferencd@0 199 GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
ferencd@0 200 return 0;
ferencd@0 201 }
ferencd@0 202
ferencd@0 203 node->parent = this;
ferencd@0 204
ferencd@0 205 node->prev = lastChild;
ferencd@0 206 node->next = 0;
ferencd@0 207
ferencd@0 208 if ( lastChild )
ferencd@0 209 lastChild->next = node;
ferencd@0 210 else
ferencd@0 211 firstChild = node; // it was an empty list.
ferencd@0 212
ferencd@0 213 lastChild = node;
ferencd@0 214 return node;
ferencd@0 215 }
ferencd@0 216
ferencd@0 217
ferencd@0 218 TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
ferencd@0 219 {
ferencd@0 220 if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
ferencd@0 221 {
ferencd@0 222 if ( GetDocument() )
ferencd@0 223 GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
ferencd@0 224 return 0;
ferencd@0 225 }
ferencd@0 226 TiXmlNode* node = addThis.Clone();
ferencd@0 227 if ( !node )
ferencd@0 228 return 0;
ferencd@0 229
ferencd@0 230 return LinkEndChild( node );
ferencd@0 231 }
ferencd@0 232
ferencd@0 233
ferencd@0 234 TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
ferencd@0 235 {
ferencd@0 236 if ( !beforeThis || beforeThis->parent != this ) {
ferencd@0 237 return 0;
ferencd@0 238 }
ferencd@0 239 if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
ferencd@0 240 {
ferencd@0 241 if ( GetDocument() )
ferencd@0 242 GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
ferencd@0 243 return 0;
ferencd@0 244 }
ferencd@0 245
ferencd@0 246 TiXmlNode* node = addThis.Clone();
ferencd@0 247 if ( !node )
ferencd@0 248 return 0;
ferencd@0 249 node->parent = this;
ferencd@0 250
ferencd@0 251 node->next = beforeThis;
ferencd@0 252 node->prev = beforeThis->prev;
ferencd@0 253 if ( beforeThis->prev )
ferencd@0 254 {
ferencd@0 255 beforeThis->prev->next = node;
ferencd@0 256 }
ferencd@0 257 else
ferencd@0 258 {
ferencd@0 259 assert( firstChild == beforeThis );
ferencd@0 260 firstChild = node;
ferencd@0 261 }
ferencd@0 262 beforeThis->prev = node;
ferencd@0 263 return node;
ferencd@0 264 }
ferencd@0 265
ferencd@0 266
ferencd@0 267 TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
ferencd@0 268 {
ferencd@0 269 if ( !afterThis || afterThis->parent != this ) {
ferencd@0 270 return 0;
ferencd@0 271 }
ferencd@0 272 if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
ferencd@0 273 {
ferencd@0 274 if ( GetDocument() )
ferencd@0 275 GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
ferencd@0 276 return 0;
ferencd@0 277 }
ferencd@0 278
ferencd@0 279 TiXmlNode* node = addThis.Clone();
ferencd@0 280 if ( !node )
ferencd@0 281 return 0;
ferencd@0 282 node->parent = this;
ferencd@0 283
ferencd@0 284 node->prev = afterThis;
ferencd@0 285 node->next = afterThis->next;
ferencd@0 286 if ( afterThis->next )
ferencd@0 287 {
ferencd@0 288 afterThis->next->prev = node;
ferencd@0 289 }
ferencd@0 290 else
ferencd@0 291 {
ferencd@0 292 assert( lastChild == afterThis );
ferencd@0 293 lastChild = node;
ferencd@0 294 }
ferencd@0 295 afterThis->next = node;
ferencd@0 296 return node;
ferencd@0 297 }
ferencd@0 298
ferencd@0 299
ferencd@0 300 TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
ferencd@0 301 {
ferencd@0 302 if ( !replaceThis )
ferencd@0 303 return 0;
ferencd@0 304
ferencd@0 305 if ( replaceThis->parent != this )
ferencd@0 306 return 0;
ferencd@0 307
ferencd@0 308 if ( withThis.ToDocument() ) {
ferencd@0 309 // A document can never be a child. Thanks to Noam.
ferencd@0 310 TiXmlDocument* document = GetDocument();
ferencd@0 311 if ( document )
ferencd@0 312 document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
ferencd@0 313 return 0;
ferencd@0 314 }
ferencd@0 315
ferencd@0 316 TiXmlNode* node = withThis.Clone();
ferencd@0 317 if ( !node )
ferencd@0 318 return 0;
ferencd@0 319
ferencd@0 320 node->next = replaceThis->next;
ferencd@0 321 node->prev = replaceThis->prev;
ferencd@0 322
ferencd@0 323 if ( replaceThis->next )
ferencd@0 324 replaceThis->next->prev = node;
ferencd@0 325 else
ferencd@0 326 lastChild = node;
ferencd@0 327
ferencd@0 328 if ( replaceThis->prev )
ferencd@0 329 replaceThis->prev->next = node;
ferencd@0 330 else
ferencd@0 331 firstChild = node;
ferencd@0 332
ferencd@0 333 delete replaceThis;
ferencd@0 334 node->parent = this;
ferencd@0 335 return node;
ferencd@0 336 }
ferencd@0 337
ferencd@0 338
ferencd@0 339 bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
ferencd@0 340 {
ferencd@0 341 if ( !removeThis ) {
ferencd@0 342 return false;
ferencd@0 343 }
ferencd@0 344
ferencd@0 345 if ( removeThis->parent != this )
ferencd@0 346 {
ferencd@0 347 assert( 0 );
ferencd@0 348 return false;
ferencd@0 349 }
ferencd@0 350
ferencd@0 351 if ( removeThis->next )
ferencd@0 352 removeThis->next->prev = removeThis->prev;
ferencd@0 353 else
ferencd@0 354 lastChild = removeThis->prev;
ferencd@0 355
ferencd@0 356 if ( removeThis->prev )
ferencd@0 357 removeThis->prev->next = removeThis->next;
ferencd@0 358 else
ferencd@0 359 firstChild = removeThis->next;
ferencd@0 360
ferencd@0 361 delete removeThis;
ferencd@0 362 return true;
ferencd@0 363 }
ferencd@0 364
ferencd@0 365 const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
ferencd@0 366 {
ferencd@0 367 const TiXmlNode* node;
ferencd@0 368 for ( node = firstChild; node; node = node->next )
ferencd@0 369 {
ferencd@0 370 if ( strcmp( node->Value(), _value ) == 0 )
ferencd@0 371 return node;
ferencd@0 372 }
ferencd@0 373 return 0;
ferencd@0 374 }
ferencd@0 375
ferencd@0 376
ferencd@0 377 const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
ferencd@0 378 {
ferencd@0 379 const TiXmlNode* node;
ferencd@0 380 for ( node = lastChild; node; node = node->prev )
ferencd@0 381 {
ferencd@0 382 if ( strcmp( node->Value(), _value ) == 0 )
ferencd@0 383 return node;
ferencd@0 384 }
ferencd@0 385 return 0;
ferencd@0 386 }
ferencd@0 387
ferencd@0 388
ferencd@0 389 const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
ferencd@0 390 {
ferencd@0 391 if ( !previous )
ferencd@0 392 {
ferencd@0 393 return FirstChild();
ferencd@0 394 }
ferencd@0 395 else
ferencd@0 396 {
ferencd@0 397 assert( previous->parent == this );
ferencd@0 398 return previous->NextSibling();
ferencd@0 399 }
ferencd@0 400 }
ferencd@0 401
ferencd@0 402
ferencd@0 403 const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
ferencd@0 404 {
ferencd@0 405 if ( !previous )
ferencd@0 406 {
ferencd@0 407 return FirstChild( val );
ferencd@0 408 }
ferencd@0 409 else
ferencd@0 410 {
ferencd@0 411 assert( previous->parent == this );
ferencd@0 412 return previous->NextSibling( val );
ferencd@0 413 }
ferencd@0 414 }
ferencd@0 415
ferencd@0 416
ferencd@0 417 const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
ferencd@0 418 {
ferencd@0 419 const TiXmlNode* node;
ferencd@0 420 for ( node = next; node; node = node->next )
ferencd@0 421 {
ferencd@0 422 if ( strcmp( node->Value(), _value ) == 0 )
ferencd@0 423 return node;
ferencd@0 424 }
ferencd@0 425 return 0;
ferencd@0 426 }
ferencd@0 427
ferencd@0 428
ferencd@0 429 const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
ferencd@0 430 {
ferencd@0 431 const TiXmlNode* node;
ferencd@0 432 for ( node = prev; node; node = node->prev )
ferencd@0 433 {
ferencd@0 434 if ( strcmp( node->Value(), _value ) == 0 )
ferencd@0 435 return node;
ferencd@0 436 }
ferencd@0 437 return 0;
ferencd@0 438 }
ferencd@0 439
ferencd@0 440
ferencd@0 441 void TiXmlElement::RemoveAttribute( const char * name )
ferencd@0 442 {
ferencd@0 443 #ifdef TIXML_USE_STL
ferencd@0 444 TIXML_STRING str( name );
ferencd@0 445 TiXmlAttribute* node = attributeSet.Find( str );
ferencd@0 446 #else
ferencd@0 447 TiXmlAttribute* node = attributeSet.Find( name );
ferencd@0 448 #endif
ferencd@0 449 if ( node )
ferencd@0 450 {
ferencd@0 451 attributeSet.Remove( node );
ferencd@0 452 delete node;
ferencd@0 453 }
ferencd@0 454 }
ferencd@0 455
ferencd@0 456 const TiXmlElement* TiXmlNode::FirstChildElement() const
ferencd@0 457 {
ferencd@0 458 const TiXmlNode* node;
ferencd@0 459
ferencd@0 460 for ( node = FirstChild();
ferencd@0 461 node;
ferencd@0 462 node = node->NextSibling() )
ferencd@0 463 {
ferencd@0 464 if ( node->ToElement() )
ferencd@0 465 return node->ToElement();
ferencd@0 466 }
ferencd@0 467 return 0;
ferencd@0 468 }
ferencd@0 469
ferencd@0 470
ferencd@0 471 const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
ferencd@0 472 {
ferencd@0 473 const TiXmlNode* node;
ferencd@0 474
ferencd@0 475 for ( node = FirstChild( _value );
ferencd@0 476 node;
ferencd@0 477 node = node->NextSibling( _value ) )
ferencd@0 478 {
ferencd@0 479 if ( node->ToElement() )
ferencd@0 480 return node->ToElement();
ferencd@0 481 }
ferencd@0 482 return 0;
ferencd@0 483 }
ferencd@0 484
ferencd@0 485
ferencd@0 486 const TiXmlElement* TiXmlNode::NextSiblingElement() const
ferencd@0 487 {
ferencd@0 488 const TiXmlNode* node;
ferencd@0 489
ferencd@0 490 for ( node = NextSibling();
ferencd@0 491 node;
ferencd@0 492 node = node->NextSibling() )
ferencd@0 493 {
ferencd@0 494 if ( node->ToElement() )
ferencd@0 495 return node->ToElement();
ferencd@0 496 }
ferencd@0 497 return 0;
ferencd@0 498 }
ferencd@0 499
ferencd@0 500
ferencd@0 501 const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
ferencd@0 502 {
ferencd@0 503 const TiXmlNode* node;
ferencd@0 504
ferencd@0 505 for ( node = NextSibling( _value );
ferencd@0 506 node;
ferencd@0 507 node = node->NextSibling( _value ) )
ferencd@0 508 {
ferencd@0 509 if ( node->ToElement() )
ferencd@0 510 return node->ToElement();
ferencd@0 511 }
ferencd@0 512 return 0;
ferencd@0 513 }
ferencd@0 514
ferencd@0 515
ferencd@0 516 const TiXmlDocument* TiXmlNode::GetDocument() const
ferencd@0 517 {
ferencd@0 518 const TiXmlNode* node;
ferencd@0 519
ferencd@0 520 for( node = this; node; node = node->parent )
ferencd@0 521 {
ferencd@0 522 if ( node->ToDocument() )
ferencd@0 523 return node->ToDocument();
ferencd@0 524 }
ferencd@0 525 return 0;
ferencd@0 526 }
ferencd@0 527
ferencd@0 528
ferencd@0 529 TiXmlElement::TiXmlElement (const char * _value)
ferencd@0 530 : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
ferencd@0 531 {
ferencd@0 532 firstChild = lastChild = 0;
ferencd@0 533 value = _value;
ferencd@0 534 }
ferencd@0 535
ferencd@0 536
ferencd@0 537 #ifdef TIXML_USE_STL
ferencd@0 538 TiXmlElement::TiXmlElement( const std::string& _value )
ferencd@0 539 : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
ferencd@0 540 {
ferencd@0 541 firstChild = lastChild = 0;
ferencd@0 542 value = _value;
ferencd@0 543 }
ferencd@0 544 #endif
ferencd@0 545
ferencd@0 546
ferencd@0 547 TiXmlElement::TiXmlElement( const TiXmlElement& copy)
ferencd@0 548 : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
ferencd@0 549 {
ferencd@0 550 firstChild = lastChild = 0;
ferencd@0 551 copy.CopyTo( this );
ferencd@0 552 }
ferencd@0 553
ferencd@0 554
ferencd@0 555 TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base )
ferencd@0 556 {
ferencd@0 557 ClearThis();
ferencd@0 558 base.CopyTo( this );
ferencd@0 559 return *this;
ferencd@0 560 }
ferencd@0 561
ferencd@0 562
ferencd@0 563 TiXmlElement::~TiXmlElement()
ferencd@0 564 {
ferencd@0 565 ClearThis();
ferencd@0 566 }
ferencd@0 567
ferencd@0 568
ferencd@0 569 void TiXmlElement::ClearThis()
ferencd@0 570 {
ferencd@0 571 Clear();
ferencd@0 572 while( attributeSet.First() )
ferencd@0 573 {
ferencd@0 574 TiXmlAttribute* node = attributeSet.First();
ferencd@0 575 attributeSet.Remove( node );
ferencd@0 576 delete node;
ferencd@0 577 }
ferencd@0 578 }
ferencd@0 579
ferencd@0 580
ferencd@0 581 const char* TiXmlElement::Attribute( const char* name ) const
ferencd@0 582 {
ferencd@0 583 const TiXmlAttribute* node = attributeSet.Find( name );
ferencd@0 584 if ( node )
ferencd@0 585 return node->Value();
ferencd@0 586 return 0;
ferencd@0 587 }
ferencd@0 588
ferencd@0 589
ferencd@0 590 #ifdef TIXML_USE_STL
ferencd@0 591 const std::string* TiXmlElement::Attribute( const std::string& name ) const
ferencd@0 592 {
ferencd@0 593 const TiXmlAttribute* attrib = attributeSet.Find( name );
ferencd@0 594 if ( attrib )
ferencd@0 595 return &attrib->ValueStr();
ferencd@0 596 return 0;
ferencd@0 597 }
ferencd@0 598 #endif
ferencd@0 599
ferencd@0 600
ferencd@0 601 const char* TiXmlElement::Attribute( const char* name, int* i ) const
ferencd@0 602 {
ferencd@0 603 const TiXmlAttribute* attrib = attributeSet.Find( name );
ferencd@0 604 const char* result = 0;
ferencd@0 605
ferencd@0 606 if ( attrib ) {
ferencd@0 607 result = attrib->Value();
ferencd@0 608 if ( i ) {
ferencd@0 609 attrib->QueryIntValue( i );
ferencd@0 610 }
ferencd@0 611 }
ferencd@0 612 return result;
ferencd@0 613 }
ferencd@0 614
ferencd@0 615
ferencd@0 616 #ifdef TIXML_USE_STL
ferencd@0 617 const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
ferencd@0 618 {
ferencd@0 619 const TiXmlAttribute* attrib = attributeSet.Find( name );
ferencd@0 620 const std::string* result = 0;
ferencd@0 621
ferencd@0 622 if ( attrib ) {
ferencd@0 623 result = &attrib->ValueStr();
ferencd@0 624 if ( i ) {
ferencd@0 625 attrib->QueryIntValue( i );
ferencd@0 626 }
ferencd@0 627 }
ferencd@0 628 return result;
ferencd@0 629 }
ferencd@0 630 #endif
ferencd@0 631
ferencd@0 632
ferencd@0 633 const char* TiXmlElement::Attribute( const char* name, double* d ) const
ferencd@0 634 {
ferencd@0 635 const TiXmlAttribute* attrib = attributeSet.Find( name );
ferencd@0 636 const char* result = 0;
ferencd@0 637
ferencd@0 638 if ( attrib ) {
ferencd@0 639 result = attrib->Value();
ferencd@0 640 if ( d ) {
ferencd@0 641 attrib->QueryDoubleValue( d );
ferencd@0 642 }
ferencd@0 643 }
ferencd@0 644 return result;
ferencd@0 645 }
ferencd@0 646
ferencd@0 647
ferencd@0 648 #ifdef TIXML_USE_STL
ferencd@0 649 const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
ferencd@0 650 {
ferencd@0 651 const TiXmlAttribute* attrib = attributeSet.Find( name );
ferencd@0 652 const std::string* result = 0;
ferencd@0 653
ferencd@0 654 if ( attrib ) {
ferencd@0 655 result = &attrib->ValueStr();
ferencd@0 656 if ( d ) {
ferencd@0 657 attrib->QueryDoubleValue( d );
ferencd@0 658 }
ferencd@0 659 }
ferencd@0 660 return result;
ferencd@0 661 }
ferencd@0 662 #endif
ferencd@0 663
ferencd@0 664
ferencd@0 665 int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
ferencd@0 666 {
ferencd@0 667 const TiXmlAttribute* attrib = attributeSet.Find( name );
ferencd@0 668 if ( !attrib )
ferencd@0 669 return TIXML_NO_ATTRIBUTE;
ferencd@0 670 return attrib->QueryIntValue( ival );
ferencd@0 671 }
ferencd@0 672
ferencd@0 673
ferencd@0 674 int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* pvalue ) const
ferencd@0 675 {
ferencd@0 676 const TiXmlAttribute* node = attributeSet.Find( name );
ferencd@0 677 if ( !node )
ferencd@0 678 return TIXML_NO_ATTRIBUTE;
ferencd@0 679
ferencd@0 680 int ival = 0;
ferencd@0 681 int result = node->QueryIntValue( &ival );
ferencd@0 682 *pvalue = static_cast<unsigned>(ival);
ferencd@0 683 return result;
ferencd@0 684 }
ferencd@0 685
ferencd@0 686
ferencd@0 687 int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const
ferencd@0 688 {
ferencd@0 689 const TiXmlAttribute* node = attributeSet.Find( name );
ferencd@0 690 if ( !node )
ferencd@0 691 return TIXML_NO_ATTRIBUTE;
ferencd@0 692
ferencd@0 693 int result = TIXML_WRONG_TYPE;
ferencd@0 694 if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN )
ferencd@0 695 || StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN )
ferencd@0 696 || StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) )
ferencd@0 697 {
ferencd@0 698 *bval = true;
ferencd@0 699 result = TIXML_SUCCESS;
ferencd@0 700 }
ferencd@0 701 else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN )
ferencd@0 702 || StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN )
ferencd@0 703 || StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) )
ferencd@0 704 {
ferencd@0 705 *bval = false;
ferencd@0 706 result = TIXML_SUCCESS;
ferencd@0 707 }
ferencd@0 708 return result;
ferencd@0 709 }
ferencd@0 710
ferencd@0 711
ferencd@0 712
ferencd@0 713 #ifdef TIXML_USE_STL
ferencd@0 714 int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
ferencd@0 715 {
ferencd@0 716 const TiXmlAttribute* attrib = attributeSet.Find( name );
ferencd@0 717 if ( !attrib )
ferencd@0 718 return TIXML_NO_ATTRIBUTE;
ferencd@0 719 return attrib->QueryIntValue( ival );
ferencd@0 720 }
ferencd@0 721 #endif
ferencd@0 722
ferencd@0 723
ferencd@0 724 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
ferencd@0 725 {
ferencd@0 726 const TiXmlAttribute* attrib = attributeSet.Find( name );
ferencd@0 727 if ( !attrib )
ferencd@0 728 return TIXML_NO_ATTRIBUTE;
ferencd@0 729 return attrib->QueryDoubleValue( dval );
ferencd@0 730 }
ferencd@0 731
ferencd@0 732
ferencd@0 733 #ifdef TIXML_USE_STL
ferencd@0 734 int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
ferencd@0 735 {
ferencd@0 736 const TiXmlAttribute* attrib = attributeSet.Find( name );
ferencd@0 737 if ( !attrib )
ferencd@0 738 return TIXML_NO_ATTRIBUTE;
ferencd@0 739 return attrib->QueryDoubleValue( dval );
ferencd@0 740 }
ferencd@0 741 #endif
ferencd@0 742
ferencd@0 743
ferencd@0 744 void TiXmlElement::SetAttribute( const char * name, int val )
ferencd@0 745 {
ferencd@0 746 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
ferencd@0 747 if ( attrib ) {
ferencd@0 748 attrib->SetIntValue( val );
ferencd@0 749 }
ferencd@0 750 }
ferencd@0 751
ferencd@0 752
ferencd@0 753 #ifdef TIXML_USE_STL
ferencd@0 754 void TiXmlElement::SetAttribute( const std::string& name, int val )
ferencd@0 755 {
ferencd@0 756 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
ferencd@0 757 if ( attrib ) {
ferencd@0 758 attrib->SetIntValue( val );
ferencd@0 759 }
ferencd@0 760 }
ferencd@0 761 #endif
ferencd@0 762
ferencd@0 763
ferencd@0 764 void TiXmlElement::SetDoubleAttribute( const char * name, double val )
ferencd@0 765 {
ferencd@0 766 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
ferencd@0 767 if ( attrib ) {
ferencd@0 768 attrib->SetDoubleValue( val );
ferencd@0 769 }
ferencd@0 770 }
ferencd@0 771
ferencd@0 772
ferencd@0 773 #ifdef TIXML_USE_STL
ferencd@0 774 void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
ferencd@0 775 {
ferencd@0 776 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
ferencd@0 777 if ( attrib ) {
ferencd@0 778 attrib->SetDoubleValue( val );
ferencd@0 779 }
ferencd@0 780 }
ferencd@0 781 #endif
ferencd@0 782
ferencd@0 783
ferencd@0 784 void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
ferencd@0 785 {
ferencd@0 786 TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
ferencd@0 787 if ( attrib ) {
ferencd@0 788 attrib->SetValue( cvalue );
ferencd@0 789 }
ferencd@0 790 }
ferencd@0 791
ferencd@0 792
ferencd@0 793 #ifdef TIXML_USE_STL
ferencd@0 794 void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
ferencd@0 795 {
ferencd@0 796 TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
ferencd@0 797 if ( attrib ) {
ferencd@0 798 attrib->SetValue( _value );
ferencd@0 799 }
ferencd@0 800 }
ferencd@0 801 #endif
ferencd@0 802
ferencd@0 803
ferencd@0 804 void TiXmlElement::Print( FILE* cfile, int depth ) const
ferencd@0 805 {
ferencd@0 806 int i;
ferencd@0 807 assert( cfile );
ferencd@0 808 for ( i=0; i<depth; i++ ) {
ferencd@0 809 fprintf( cfile, " " );
ferencd@0 810 }
ferencd@0 811
ferencd@0 812 fprintf( cfile, "<%s", value.c_str() );
ferencd@0 813
ferencd@0 814 const TiXmlAttribute* attrib;
ferencd@0 815 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
ferencd@0 816 {
ferencd@0 817 fprintf( cfile, " " );
ferencd@0 818 attrib->Print( cfile, depth );
ferencd@0 819 }
ferencd@0 820
ferencd@0 821 // There are 3 different formatting approaches:
ferencd@0 822 // 1) An element without children is printed as a <foo /> node
ferencd@0 823 // 2) An element with only a text child is printed as <foo> text </foo>
ferencd@0 824 // 3) An element with children is printed on multiple lines.
ferencd@0 825 TiXmlNode* node;
ferencd@0 826 if ( !firstChild )
ferencd@0 827 {
ferencd@0 828 fprintf( cfile, " />" );
ferencd@0 829 }
ferencd@0 830 else if ( firstChild == lastChild && firstChild->ToText() )
ferencd@0 831 {
ferencd@0 832 fprintf( cfile, ">" );
ferencd@0 833 firstChild->Print( cfile, depth + 1 );
ferencd@0 834 fprintf( cfile, "</%s>", value.c_str() );
ferencd@0 835 }
ferencd@0 836 else
ferencd@0 837 {
ferencd@0 838 fprintf( cfile, ">" );
ferencd@0 839
ferencd@0 840 for ( node = firstChild; node; node=node->NextSibling() )
ferencd@0 841 {
ferencd@0 842 if ( !node->ToText() )
ferencd@0 843 {
ferencd@0 844 fprintf( cfile, "\n" );
ferencd@0 845 }
ferencd@0 846 node->Print( cfile, depth+1 );
ferencd@0 847 }
ferencd@0 848 fprintf( cfile, "\n" );
ferencd@0 849 for( i=0; i<depth; ++i ) {
ferencd@0 850 fprintf( cfile, " " );
ferencd@0 851 }
ferencd@0 852 fprintf( cfile, "</%s>", value.c_str() );
ferencd@0 853 }
ferencd@0 854 }
ferencd@0 855
ferencd@0 856 void TiXmlElement::Print(std::string &target, int depth) const
ferencd@0 857 {
ferencd@0 858 int i;
ferencd@0 859 for ( i=0; i<depth; i++ ) {
ferencd@0 860 target += " ";
ferencd@0 861 }
ferencd@0 862
ferencd@0 863 std::stringstream ss;
ferencd@0 864 ss << "<" << value.c_str();
ferencd@0 865 target += ss.str();
ferencd@0 866
ferencd@0 867 const TiXmlAttribute* attrib;
ferencd@0 868 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
ferencd@0 869 {
ferencd@0 870 target += " ";
ferencd@0 871 std::string temp;
ferencd@0 872 attrib->Print( temp, depth );
ferencd@0 873 target += temp;
ferencd@0 874 }
ferencd@0 875
ferencd@0 876 // There are 3 different formatting approaches:
ferencd@0 877 // 1) An element without children is printed as a <foo /> node
ferencd@0 878 // 2) An element with only a text child is printed as <foo> text </foo>
ferencd@0 879 // 3) An element with children is printed on multiple lines.
ferencd@0 880 TiXmlNode* node;
ferencd@0 881 if ( !firstChild )
ferencd@0 882 {
ferencd@0 883 target += " />" ;
ferencd@0 884 }
ferencd@0 885 else if ( firstChild == lastChild && firstChild->ToText() )
ferencd@0 886 {
ferencd@0 887 target += ">";
ferencd@0 888 std::string temp;
ferencd@0 889 firstChild->Print( temp, depth + 1 );
ferencd@0 890 target += temp;
ferencd@0 891 target += "<";
ferencd@0 892 target += value.c_str();
ferencd@0 893 target += ">";
ferencd@0 894 }
ferencd@0 895 else
ferencd@0 896 {
ferencd@0 897 target += ">";
ferencd@0 898
ferencd@0 899 for ( node = firstChild; node; node=node->NextSibling() )
ferencd@0 900 {
ferencd@0 901 if ( !node->ToText() )
ferencd@0 902 {
ferencd@0 903 target += "\n";
ferencd@0 904 }
ferencd@0 905 std::string temp;
ferencd@0 906 node->Print( temp, depth+1 );
ferencd@0 907 target += temp;
ferencd@0 908 }
ferencd@0 909 target += "\n";
ferencd@0 910 for( i=0; i<depth; ++i )
ferencd@0 911 {
ferencd@0 912 target += " ";
ferencd@0 913 }
ferencd@0 914 target += "<";
ferencd@0 915 target += value.c_str();
ferencd@0 916 target += ">";
ferencd@0 917 }
ferencd@0 918 }
ferencd@0 919
ferencd@0 920
ferencd@0 921 void TiXmlElement::CopyTo( TiXmlElement* target ) const
ferencd@0 922 {
ferencd@0 923 // superclass:
ferencd@0 924 TiXmlNode::CopyTo( target );
ferencd@0 925
ferencd@0 926 // Element class:
ferencd@0 927 // Clone the attributes, then clone the children.
ferencd@0 928 const TiXmlAttribute* attribute = 0;
ferencd@0 929 for( attribute = attributeSet.First();
ferencd@0 930 attribute;
ferencd@0 931 attribute = attribute->Next() )
ferencd@0 932 {
ferencd@0 933 target->SetAttribute( attribute->Name(), attribute->Value() );
ferencd@0 934 }
ferencd@0 935
ferencd@0 936 TiXmlNode* node = 0;
ferencd@0 937 for ( node = firstChild; node; node = node->NextSibling() )
ferencd@0 938 {
ferencd@0 939 target->LinkEndChild( node->Clone() );
ferencd@0 940 }
ferencd@0 941 }
ferencd@0 942
ferencd@0 943 bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
ferencd@0 944 {
ferencd@0 945 if ( visitor->VisitEnter( *this, attributeSet.First() ) )
ferencd@0 946 {
ferencd@0 947 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
ferencd@0 948 {
ferencd@0 949 if ( !node->Accept( visitor ) )
ferencd@0 950 break;
ferencd@0 951 }
ferencd@0 952 }
ferencd@0 953 return visitor->VisitExit( *this );
ferencd@0 954 }
ferencd@0 955
ferencd@0 956
ferencd@0 957 TiXmlNode* TiXmlElement::Clone() const
ferencd@0 958 {
ferencd@0 959 TiXmlElement* clone = new TiXmlElement( Value() );
ferencd@0 960 if ( !clone )
ferencd@0 961 return 0;
ferencd@0 962
ferencd@0 963 CopyTo( clone );
ferencd@0 964 return clone;
ferencd@0 965 }
ferencd@0 966
ferencd@0 967
ferencd@0 968 const char* TiXmlElement::GetText() const
ferencd@0 969 {
ferencd@0 970 const TiXmlNode* child = this->FirstChild();
ferencd@0 971 if ( child ) {
ferencd@0 972 const TiXmlText* childText = child->ToText();
ferencd@0 973 if ( childText ) {
ferencd@0 974 return childText->Value();
ferencd@0 975 }
ferencd@0 976 }
ferencd@0 977 return 0;
ferencd@0 978 }
ferencd@0 979
ferencd@0 980
ferencd@0 981 TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
ferencd@0 982 {
ferencd@0 983 tabsize = 4;
ferencd@0 984 useMicrosoftBOM = false;
ferencd@0 985 ClearError();
ferencd@0 986 }
ferencd@0 987
ferencd@0 988 TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
ferencd@0 989 {
ferencd@0 990 tabsize = 4;
ferencd@0 991 useMicrosoftBOM = false;
ferencd@0 992 value = documentName;
ferencd@0 993 ClearError();
ferencd@0 994 }
ferencd@0 995
ferencd@0 996
ferencd@0 997 #ifdef TIXML_USE_STL
ferencd@0 998 TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
ferencd@0 999 {
ferencd@0 1000 tabsize = 4;
ferencd@0 1001 useMicrosoftBOM = false;
ferencd@0 1002 value = documentName;
ferencd@0 1003 ClearError();
ferencd@0 1004 }
ferencd@0 1005 #endif
ferencd@0 1006
ferencd@0 1007
ferencd@0 1008 TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
ferencd@0 1009 {
ferencd@0 1010 copy.CopyTo( this );
ferencd@0 1011 }
ferencd@0 1012
ferencd@0 1013
ferencd@0 1014 TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy )
ferencd@0 1015 {
ferencd@0 1016 Clear();
ferencd@0 1017 copy.CopyTo( this );
ferencd@0 1018 return *this;
ferencd@0 1019 }
ferencd@0 1020
ferencd@0 1021
ferencd@0 1022 bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
ferencd@0 1023 {
ferencd@0 1024 return LoadFile( Value(), encoding );
ferencd@0 1025 }
ferencd@0 1026
ferencd@0 1027
ferencd@0 1028 bool TiXmlDocument::SaveFile() const
ferencd@0 1029 {
ferencd@0 1030 return SaveFile( Value() );
ferencd@0 1031 }
ferencd@0 1032
ferencd@0 1033 bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
ferencd@0 1034 {
ferencd@0 1035 TIXML_STRING filename( _filename );
ferencd@0 1036 value = filename;
ferencd@0 1037
ferencd@0 1038 // reading in binary mode so that tinyxml can normalize the EOL
ferencd@0 1039 FILE* file = TiXmlFOpen( value.c_str (), "rb" );
ferencd@0 1040
ferencd@0 1041 if ( file )
ferencd@0 1042 {
ferencd@0 1043 bool result = LoadFile( file, encoding );
ferencd@0 1044 fclose( file );
ferencd@0 1045 return result;
ferencd@0 1046 }
ferencd@0 1047 else
ferencd@0 1048 {
ferencd@0 1049 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
ferencd@0 1050 return false;
ferencd@0 1051 }
ferencd@0 1052 }
ferencd@0 1053
ferencd@0 1054 bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
ferencd@0 1055 {
ferencd@0 1056 if ( !file )
ferencd@0 1057 {
ferencd@0 1058 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
ferencd@0 1059 return false;
ferencd@0 1060 }
ferencd@0 1061
ferencd@0 1062 // Delete the existing data:
ferencd@0 1063 Clear();
ferencd@0 1064 location.Clear();
ferencd@0 1065
ferencd@0 1066 // Get the file size, so we can pre-allocate the string. HUGE speed impact.
ferencd@0 1067 long length = 0;
ferencd@0 1068 fseek( file, 0, SEEK_END );
ferencd@0 1069 length = ftell( file );
ferencd@0 1070 fseek( file, 0, SEEK_SET );
ferencd@0 1071
ferencd@0 1072 // Strange case, but good to handle up front.
ferencd@0 1073 if ( length <= 0 )
ferencd@0 1074 {
ferencd@0 1075 SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
ferencd@0 1076 return false;
ferencd@0 1077 }
ferencd@0 1078
ferencd@0 1079 // Subtle bug here. TinyXml did use fgets. But from the XML spec:
ferencd@0 1080 // 2.11 End-of-Line Handling
ferencd@0 1081 // <snip>
ferencd@0 1082 // <quote>
ferencd@0 1083 // ...the XML processor MUST behave as if it normalized all line breaks in external
ferencd@0 1084 // parsed entities (including the document entity) on input, before parsing, by translating
ferencd@0 1085 // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
ferencd@0 1086 // a single #xA character.
ferencd@0 1087 // </quote>
ferencd@0 1088 //
ferencd@0 1089 // It is not clear fgets does that, and certainly isn't clear it works cross platform.
ferencd@0 1090 // Generally, you expect fgets to translate from the convention of the OS to the c/unix
ferencd@0 1091 // convention, and not work generally.
ferencd@0 1092
ferencd@0 1093 /*
ferencd@0 1094 while( fgets( buf, sizeof(buf), file ) )
ferencd@0 1095 {
ferencd@0 1096 data += buf;
ferencd@0 1097 }
ferencd@0 1098 */
ferencd@0 1099
ferencd@0 1100 char* buf = new char[ length+1 ];
ferencd@0 1101 buf[0] = 0;
ferencd@0 1102
ferencd@0 1103 if ( fread( buf, length, 1, file ) != 1 ) {
ferencd@0 1104 delete [] buf;
ferencd@0 1105 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
ferencd@0 1106 return false;
ferencd@0 1107 }
ferencd@0 1108
ferencd@0 1109 // Process the buffer in place to normalize new lines. (See comment above.)
ferencd@0 1110 // Copies from the 'p' to 'q' pointer, where p can advance faster if
ferencd@0 1111 // a newline-carriage return is hit.
ferencd@0 1112 //
ferencd@0 1113 // Wikipedia:
ferencd@0 1114 // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or
ferencd@0 1115 // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)...
ferencd@0 1116 // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
ferencd@0 1117 // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
ferencd@0 1118 // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9
ferencd@0 1119
ferencd@0 1120 buf[length] = 0;
ferencd@0 1121 FixLineFeeds(buf, length);
ferencd@0 1122
ferencd@0 1123 Parse( buf, 0, encoding );
ferencd@0 1124
ferencd@0 1125 delete [] buf;
ferencd@0 1126 return !Error();
ferencd@0 1127 }
ferencd@0 1128
ferencd@0 1129 char* TiXmlDocument::FixLineFeeds(char *buf, size_t length)
ferencd@0 1130 {
ferencd@0 1131 const char* p = buf; // the read head
ferencd@0 1132 char* q = buf; // the write head
ferencd@0 1133 const char CR = 0x0d;
ferencd@0 1134 const char LF = 0x0a;
ferencd@0 1135
ferencd@0 1136 while( *p ) {
ferencd@0 1137 assert( p < (buf+length) );
ferencd@0 1138 assert( q <= (buf+length) );
ferencd@0 1139 assert( q <= p );
ferencd@0 1140
ferencd@0 1141 if ( *p == CR ) {
ferencd@0 1142 *q++ = LF;
ferencd@0 1143 p++;
ferencd@0 1144 if ( *p == LF ) { // check for CR+LF (and skip LF)
ferencd@0 1145 p++;
ferencd@0 1146 }
ferencd@0 1147 }
ferencd@0 1148 else {
ferencd@0 1149 *q++ = *p++;
ferencd@0 1150 }
ferencd@0 1151 }
ferencd@0 1152 assert( q <= (buf+length) );
ferencd@0 1153 *q = 0;
ferencd@0 1154 return q;
ferencd@0 1155
ferencd@0 1156 }
ferencd@0 1157
ferencd@0 1158 bool TiXmlDocument::FromMemory(const char* source, TiXmlEncoding encoding)
ferencd@0 1159 {
ferencd@0 1160 size_t len = strlen(source);
ferencd@0 1161 char *tmp = reinterpret_cast<char*>(calloc(sizeof(char), len + 1));
ferencd@0 1162 strncpy(tmp, source, len);
ferencd@0 1163 FixLineFeeds(tmp, len);
ferencd@0 1164 Parse( tmp, 0, encoding );
ferencd@0 1165 free (tmp);
ferencd@0 1166 return !Error();
ferencd@0 1167 }
ferencd@0 1168
ferencd@0 1169 bool TiXmlDocument::SaveFile( const char * filename ) const
ferencd@0 1170 {
ferencd@0 1171 // The old c stuff lives on...
ferencd@0 1172 FILE* fp = TiXmlFOpen( filename, "w" );
ferencd@0 1173 if ( fp )
ferencd@0 1174 {
ferencd@0 1175 bool result = SaveFile( fp );
ferencd@0 1176 fclose( fp );
ferencd@0 1177 return result;
ferencd@0 1178 }
ferencd@0 1179 return false;
ferencd@0 1180 }
ferencd@0 1181
ferencd@0 1182
ferencd@0 1183 bool TiXmlDocument::SaveFile( FILE* fp ) const
ferencd@0 1184 {
ferencd@0 1185 if ( useMicrosoftBOM )
ferencd@0 1186 {
ferencd@0 1187 const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
ferencd@0 1188 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
ferencd@0 1189 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
ferencd@0 1190
ferencd@0 1191 fputc( TIXML_UTF_LEAD_0, fp );
ferencd@0 1192 fputc( TIXML_UTF_LEAD_1, fp );
ferencd@0 1193 fputc( TIXML_UTF_LEAD_2, fp );
ferencd@0 1194 }
ferencd@0 1195 Print( fp, 0 );
ferencd@0 1196 return (ferror(fp) == 0);
ferencd@0 1197 }
ferencd@0 1198
ferencd@0 1199
ferencd@0 1200 void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
ferencd@0 1201 {
ferencd@0 1202 TiXmlNode::CopyTo( target );
ferencd@0 1203
ferencd@0 1204 target->error = error;
ferencd@0 1205 target->errorId = errorId;
ferencd@0 1206 target->errorDesc = errorDesc;
ferencd@0 1207 target->tabsize = tabsize;
ferencd@0 1208 target->errorLocation = errorLocation;
ferencd@0 1209 target->useMicrosoftBOM = useMicrosoftBOM;
ferencd@0 1210
ferencd@0 1211 TiXmlNode* node = 0;
ferencd@0 1212 for ( node = firstChild; node; node = node->NextSibling() )
ferencd@0 1213 {
ferencd@0 1214 target->LinkEndChild( node->Clone() );
ferencd@0 1215 }
ferencd@0 1216 }
ferencd@0 1217
ferencd@0 1218
ferencd@0 1219 TiXmlNode* TiXmlDocument::Clone() const
ferencd@0 1220 {
ferencd@0 1221 TiXmlDocument* clone = new TiXmlDocument();
ferencd@0 1222 if ( !clone )
ferencd@0 1223 return 0;
ferencd@0 1224
ferencd@0 1225 CopyTo( clone );
ferencd@0 1226 return clone;
ferencd@0 1227 }
ferencd@0 1228
ferencd@0 1229
ferencd@0 1230 void TiXmlDocument::Print( FILE* cfile, int depth ) const
ferencd@0 1231 {
ferencd@0 1232 assert( cfile );
ferencd@0 1233 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
ferencd@0 1234 {
ferencd@0 1235 node->Print( cfile, depth );
ferencd@0 1236 fprintf( cfile, "\n" );
ferencd@0 1237 }
ferencd@0 1238 }
ferencd@0 1239
ferencd@0 1240 void TiXmlDocument::Print( std::string& target, int depth ) const
ferencd@0 1241 {
ferencd@0 1242
ferencd@0 1243 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
ferencd@0 1244 {
ferencd@0 1245 std::string temp;
ferencd@0 1246 node->Print( temp, depth );
ferencd@0 1247 temp += "\n";
ferencd@0 1248 target += temp;
ferencd@0 1249 }
ferencd@0 1250 }
ferencd@0 1251
ferencd@0 1252
ferencd@0 1253 bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
ferencd@0 1254 {
ferencd@0 1255 if ( visitor->VisitEnter( *this ) )
ferencd@0 1256 {
ferencd@0 1257 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
ferencd@0 1258 {
ferencd@0 1259 if ( !node->Accept( visitor ) )
ferencd@0 1260 break;
ferencd@0 1261 }
ferencd@0 1262 }
ferencd@0 1263 return visitor->VisitExit( *this );
ferencd@0 1264 }
ferencd@0 1265
ferencd@0 1266
ferencd@0 1267 const TiXmlAttribute* TiXmlAttribute::Next() const
ferencd@0 1268 {
ferencd@0 1269 // We are using knowledge of the sentinel. The sentinel
ferencd@0 1270 // have a value or name.
ferencd@0 1271 if ( next->value.empty() && next->name.empty() )
ferencd@0 1272 return 0;
ferencd@0 1273 return next;
ferencd@0 1274 }
ferencd@0 1275
ferencd@0 1276 /*
ferencd@0 1277 TiXmlAttribute* TiXmlAttribute::Next()
ferencd@0 1278 {
ferencd@0 1279 // We are using knowledge of the sentinel. The sentinel
ferencd@0 1280 // have a value or name.
ferencd@0 1281 if ( next->value.empty() && next->name.empty() )
ferencd@0 1282 return 0;
ferencd@0 1283 return next;
ferencd@0 1284 }
ferencd@0 1285 */
ferencd@0 1286
ferencd@0 1287 const TiXmlAttribute* TiXmlAttribute::Previous() const
ferencd@0 1288 {
ferencd@0 1289 // We are using knowledge of the sentinel. The sentinel
ferencd@0 1290 // have a value or name.
ferencd@0 1291 if ( prev->value.empty() && prev->name.empty() )
ferencd@0 1292 return 0;
ferencd@0 1293 return prev;
ferencd@0 1294 }
ferencd@0 1295
ferencd@0 1296 /*
ferencd@0 1297 TiXmlAttribute* TiXmlAttribute::Previous()
ferencd@0 1298 {
ferencd@0 1299 // We are using knowledge of the sentinel. The sentinel
ferencd@0 1300 // have a value or name.
ferencd@0 1301 if ( prev->value.empty() && prev->name.empty() )
ferencd@0 1302 return 0;
ferencd@0 1303 return prev;
ferencd@0 1304 }
ferencd@0 1305 */
ferencd@0 1306
ferencd@0 1307 void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
ferencd@0 1308 {
ferencd@0 1309 TIXML_STRING n, v;
ferencd@0 1310
ferencd@0 1311 EncodeString( name, &n );
ferencd@0 1312 EncodeString( value, &v );
ferencd@0 1313
ferencd@0 1314 if (value.find ('\"') == TIXML_STRING::npos) {
ferencd@0 1315 if ( cfile ) {
ferencd@0 1316 fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
ferencd@0 1317 }
ferencd@0 1318 if ( str ) {
ferencd@0 1319 (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
ferencd@0 1320 }
ferencd@0 1321 }
ferencd@0 1322 else {
ferencd@0 1323 if ( cfile ) {
ferencd@0 1324 fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
ferencd@0 1325 }
ferencd@0 1326 if ( str ) {
ferencd@0 1327 (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
ferencd@0 1328 }
ferencd@0 1329 }
ferencd@0 1330 }
ferencd@0 1331
ferencd@0 1332 void TiXmlAttribute::Print( std::string& target, int /*depth*/) const
ferencd@0 1333 {
ferencd@0 1334 TIXML_STRING n, v;
ferencd@0 1335
ferencd@0 1336 EncodeString( name, &n );
ferencd@0 1337 EncodeString( value, &v );
ferencd@0 1338
ferencd@0 1339 if (value.find ('\"') == TIXML_STRING::npos)
ferencd@0 1340 {
ferencd@0 1341 {
ferencd@0 1342 std::stringstream ss;
ferencd@0 1343 ss << n.c_str() << "=\"" <<v.c_str() <<"\"";
ferencd@0 1344 target += ss.str();
ferencd@0 1345 }
ferencd@0 1346 }
ferencd@0 1347 else
ferencd@0 1348 {
ferencd@0 1349 {
ferencd@0 1350 std::stringstream ss;
ferencd@0 1351 ss << n.c_str() << "='" << v.c_str() << "'";
ferencd@0 1352 }
ferencd@0 1353 }
ferencd@0 1354 }
ferencd@0 1355
ferencd@0 1356 int TiXmlAttribute::QueryIntValue( int* ival ) const
ferencd@0 1357 {
ferencd@0 1358 if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
ferencd@0 1359 return TIXML_SUCCESS;
ferencd@0 1360 return TIXML_WRONG_TYPE;
ferencd@0 1361 }
ferencd@0 1362
ferencd@0 1363 int TiXmlAttribute::QueryDoubleValue( double* dval ) const
ferencd@0 1364 {
ferencd@0 1365 if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
ferencd@0 1366 return TIXML_SUCCESS;
ferencd@0 1367 return TIXML_WRONG_TYPE;
ferencd@0 1368 }
ferencd@0 1369
ferencd@0 1370 void TiXmlAttribute::SetIntValue( int _value )
ferencd@0 1371 {
ferencd@0 1372 char buf [64];
ferencd@0 1373 #if defined(TIXML_SNPRINTF)
ferencd@0 1374 TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
ferencd@0 1375 #else
ferencd@0 1376 sprintf (buf, "%d", _value);
ferencd@0 1377 #endif
ferencd@0 1378 SetValue (buf);
ferencd@0 1379 }
ferencd@0 1380
ferencd@0 1381 void TiXmlAttribute::SetDoubleValue( double _value )
ferencd@0 1382 {
ferencd@0 1383 char buf [256];
ferencd@0 1384 #if defined(TIXML_SNPRINTF)
ferencd@0 1385 TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
ferencd@0 1386 #else
ferencd@0 1387 sprintf (buf, "%g", _value);
ferencd@0 1388 #endif
ferencd@0 1389 SetValue (buf);
ferencd@0 1390 }
ferencd@0 1391
ferencd@0 1392 int TiXmlAttribute::IntValue() const
ferencd@0 1393 {
ferencd@0 1394 return atoi (value.c_str ());
ferencd@0 1395 }
ferencd@0 1396
ferencd@0 1397 double TiXmlAttribute::DoubleValue() const
ferencd@0 1398 {
ferencd@0 1399 return atof (value.c_str ());
ferencd@0 1400 }
ferencd@0 1401
ferencd@0 1402
ferencd@0 1403 TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
ferencd@0 1404 {
ferencd@0 1405 copy.CopyTo( this );
ferencd@0 1406 }
ferencd@0 1407
ferencd@0 1408
ferencd@0 1409 TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base )
ferencd@0 1410 {
ferencd@0 1411 Clear();
ferencd@0 1412 base.CopyTo( this );
ferencd@0 1413 return *this;
ferencd@0 1414 }
ferencd@0 1415
ferencd@0 1416
ferencd@0 1417 void TiXmlComment::Print( FILE* cfile, int depth ) const
ferencd@0 1418 {
ferencd@0 1419 assert( cfile );
ferencd@0 1420 for ( int i=0; i<depth; i++ )
ferencd@0 1421 {
ferencd@0 1422 fprintf( cfile, " " );
ferencd@0 1423 }
ferencd@0 1424 fprintf( cfile, "<!--%s-->", value.c_str() );
ferencd@0 1425 }
ferencd@0 1426
ferencd@0 1427 void TiXmlComment::Print( std::string& target, int depth ) const
ferencd@0 1428 {
ferencd@0 1429
ferencd@0 1430 for ( int i=0; i<depth; i++ )
ferencd@0 1431 {
ferencd@0 1432 target += " " ;
ferencd@0 1433 }
ferencd@0 1434 target += "<!--";
ferencd@0 1435 target += value.c_str();
ferencd@0 1436 target += "-->";
ferencd@0 1437 }
ferencd@0 1438
ferencd@0 1439 void TiXmlComment::CopyTo( TiXmlComment* target ) const
ferencd@0 1440 {
ferencd@0 1441 TiXmlNode::CopyTo( target );
ferencd@0 1442 }
ferencd@0 1443
ferencd@0 1444
ferencd@0 1445 bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
ferencd@0 1446 {
ferencd@0 1447 return visitor->Visit( *this );
ferencd@0 1448 }
ferencd@0 1449
ferencd@0 1450
ferencd@0 1451 TiXmlNode* TiXmlComment::Clone() const
ferencd@0 1452 {
ferencd@0 1453 TiXmlComment* clone = new TiXmlComment();
ferencd@0 1454
ferencd@0 1455 if ( !clone )
ferencd@0 1456 return 0;
ferencd@0 1457
ferencd@0 1458 CopyTo( clone );
ferencd@0 1459 return clone;
ferencd@0 1460 }
ferencd@0 1461
ferencd@0 1462
ferencd@0 1463 void TiXmlText::Print( FILE* cfile, int depth ) const
ferencd@0 1464 {
ferencd@0 1465 assert( cfile );
ferencd@0 1466 if ( cdata )
ferencd@0 1467 {
ferencd@0 1468 int i;
ferencd@0 1469 fprintf( cfile, "\n" );
ferencd@0 1470 for ( i=0; i<depth; i++ ) {
ferencd@0 1471 fprintf( cfile, " " );
ferencd@0 1472 }
ferencd@0 1473 fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() ); // unformatted output
ferencd@0 1474 }
ferencd@0 1475 else
ferencd@0 1476 {
ferencd@0 1477 TIXML_STRING buffer;
ferencd@0 1478 EncodeString( value, &buffer );
ferencd@0 1479 fprintf( cfile, "%s", buffer.c_str() );
ferencd@0 1480 }
ferencd@0 1481 }
ferencd@0 1482
ferencd@0 1483 void TiXmlText::Print(std::string& target, int depth ) const
ferencd@0 1484 {
ferencd@0 1485 if ( cdata )
ferencd@0 1486 {
ferencd@0 1487 int i;
ferencd@0 1488 target += "\n";
ferencd@0 1489 for ( i=0; i<depth; i++ )
ferencd@0 1490 {
ferencd@0 1491 target += " " ;
ferencd@0 1492 }
ferencd@0 1493 target += std::string("<![CDATA[") + value.c_str() + "]]>\n";
ferencd@0 1494 }
ferencd@0 1495 else
ferencd@0 1496 {
ferencd@0 1497 TIXML_STRING buffer;
ferencd@0 1498 EncodeString( value, &buffer );
ferencd@0 1499 target += buffer.c_str() ;
ferencd@0 1500 }
ferencd@0 1501 }
ferencd@0 1502
ferencd@0 1503
ferencd@0 1504 void TiXmlText::CopyTo( TiXmlText* target ) const
ferencd@0 1505 {
ferencd@0 1506 TiXmlNode::CopyTo( target );
ferencd@0 1507 target->cdata = cdata;
ferencd@0 1508 }
ferencd@0 1509
ferencd@0 1510
ferencd@0 1511 bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
ferencd@0 1512 {
ferencd@0 1513 return visitor->Visit( *this );
ferencd@0 1514 }
ferencd@0 1515
ferencd@0 1516
ferencd@0 1517 TiXmlNode* TiXmlText::Clone() const
ferencd@0 1518 {
ferencd@0 1519 TiXmlText* clone = 0;
ferencd@0 1520 clone = new TiXmlText( "" );
ferencd@0 1521
ferencd@0 1522 if ( !clone )
ferencd@0 1523 return 0;
ferencd@0 1524
ferencd@0 1525 CopyTo( clone );
ferencd@0 1526 return clone;
ferencd@0 1527 }
ferencd@0 1528
ferencd@0 1529
ferencd@0 1530 TiXmlDeclaration::TiXmlDeclaration( const char * _version,
ferencd@0 1531 const char * _encoding,
ferencd@0 1532 const char * _standalone )
ferencd@0 1533 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
ferencd@0 1534 {
ferencd@0 1535 version = _version;
ferencd@0 1536 encoding = _encoding;
ferencd@0 1537 standalone = _standalone;
ferencd@0 1538 }
ferencd@0 1539
ferencd@0 1540
ferencd@0 1541 #ifdef TIXML_USE_STL
ferencd@0 1542 TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
ferencd@0 1543 const std::string& _encoding,
ferencd@0 1544 const std::string& _standalone )
ferencd@0 1545 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
ferencd@0 1546 {
ferencd@0 1547 version = _version;
ferencd@0 1548 encoding = _encoding;
ferencd@0 1549 standalone = _standalone;
ferencd@0 1550 }
ferencd@0 1551 #endif
ferencd@0 1552
ferencd@0 1553
ferencd@0 1554 TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
ferencd@0 1555 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
ferencd@0 1556 {
ferencd@0 1557 copy.CopyTo( this );
ferencd@0 1558 }
ferencd@0 1559
ferencd@0 1560
ferencd@0 1561 TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
ferencd@0 1562 {
ferencd@0 1563 Clear();
ferencd@0 1564 copy.CopyTo( this );
ferencd@0 1565 return *this;
ferencd@0 1566 }
ferencd@0 1567
ferencd@0 1568
ferencd@0 1569 void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
ferencd@0 1570 {
ferencd@0 1571 if ( cfile ) fprintf( cfile, "<?xml " );
ferencd@0 1572 if ( str ) (*str) += "<?xml ";
ferencd@0 1573
ferencd@0 1574 if ( !version.empty() ) {
ferencd@0 1575 if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
ferencd@0 1576 if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
ferencd@0 1577 }
ferencd@0 1578 if ( !encoding.empty() ) {
ferencd@0 1579 if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
ferencd@0 1580 if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
ferencd@0 1581 }
ferencd@0 1582 if ( !standalone.empty() ) {
ferencd@0 1583 if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
ferencd@0 1584 if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
ferencd@0 1585 }
ferencd@0 1586 if ( cfile ) fprintf( cfile, "?>" );
ferencd@0 1587 if ( str ) (*str) += "?>";
ferencd@0 1588 }
ferencd@0 1589
ferencd@0 1590 void TiXmlDeclaration::Print( std::string& target, int /*depth*/) const
ferencd@0 1591 {
ferencd@0 1592 target += "<?xml ";
ferencd@0 1593
ferencd@0 1594 if ( !version.empty() )
ferencd@0 1595 {
ferencd@0 1596 target += "version=\""; target += version; target += "\" ";
ferencd@0 1597 }
ferencd@0 1598 if ( !encoding.empty() ) {
ferencd@0 1599 target += "encoding=\""; target += encoding; target += "\" ";
ferencd@0 1600 }
ferencd@0 1601 if ( !standalone.empty() ) {
ferencd@0 1602 target += "standalone=\""; target += standalone; target += "\" ";
ferencd@0 1603 }
ferencd@0 1604 target += "?>";
ferencd@0 1605 }
ferencd@0 1606
ferencd@0 1607
ferencd@0 1608 void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
ferencd@0 1609 {
ferencd@0 1610 TiXmlNode::CopyTo( target );
ferencd@0 1611
ferencd@0 1612 target->version = version;
ferencd@0 1613 target->encoding = encoding;
ferencd@0 1614 target->standalone = standalone;
ferencd@0 1615 }
ferencd@0 1616
ferencd@0 1617
ferencd@0 1618 bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
ferencd@0 1619 {
ferencd@0 1620 return visitor->Visit( *this );
ferencd@0 1621 }
ferencd@0 1622
ferencd@0 1623
ferencd@0 1624 TiXmlNode* TiXmlDeclaration::Clone() const
ferencd@0 1625 {
ferencd@0 1626 TiXmlDeclaration* clone = new TiXmlDeclaration();
ferencd@0 1627
ferencd@0 1628 if ( !clone )
ferencd@0 1629 return 0;
ferencd@0 1630
ferencd@0 1631 CopyTo( clone );
ferencd@0 1632 return clone;
ferencd@0 1633 }
ferencd@0 1634
ferencd@0 1635
ferencd@0 1636 void TiXmlUnknown::Print( FILE* cfile, int depth ) const
ferencd@0 1637 {
ferencd@0 1638 for ( int i=0; i<depth; i++ )
ferencd@0 1639 fprintf( cfile, " " );
ferencd@0 1640 fprintf( cfile, "<%s>", value.c_str() );
ferencd@0 1641 }
ferencd@0 1642
ferencd@0 1643 void TiXmlUnknown::Print( std::string& target, int depth ) const
ferencd@0 1644 {
ferencd@0 1645 for ( int i=0; i<depth; i++ )
ferencd@0 1646 target += " " ;
ferencd@0 1647 target += std::string("<") + value.c_str()+ ">";
ferencd@0 1648 }
ferencd@0 1649
ferencd@0 1650 void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
ferencd@0 1651 {
ferencd@0 1652 TiXmlNode::CopyTo( target );
ferencd@0 1653 }
ferencd@0 1654
ferencd@0 1655
ferencd@0 1656 bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
ferencd@0 1657 {
ferencd@0 1658 return visitor->Visit( *this );
ferencd@0 1659 }
ferencd@0 1660
ferencd@0 1661
ferencd@0 1662 TiXmlNode* TiXmlUnknown::Clone() const
ferencd@0 1663 {
ferencd@0 1664 TiXmlUnknown* clone = new TiXmlUnknown();
ferencd@0 1665
ferencd@0 1666 if ( !clone )
ferencd@0 1667 return 0;
ferencd@0 1668
ferencd@0 1669 CopyTo( clone );
ferencd@0 1670 return clone;
ferencd@0 1671 }
ferencd@0 1672
ferencd@0 1673
ferencd@0 1674 TiXmlAttributeSet::TiXmlAttributeSet()
ferencd@0 1675 {
ferencd@0 1676 sentinel.next = &sentinel;
ferencd@0 1677 sentinel.prev = &sentinel;
ferencd@0 1678 }
ferencd@0 1679
ferencd@0 1680
ferencd@0 1681 TiXmlAttributeSet::~TiXmlAttributeSet()
ferencd@0 1682 {
ferencd@0 1683 assert( sentinel.next == &sentinel );
ferencd@0 1684 assert( sentinel.prev == &sentinel );
ferencd@0 1685 }
ferencd@0 1686
ferencd@0 1687
ferencd@0 1688 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
ferencd@0 1689 {
ferencd@0 1690 #ifdef TIXML_USE_STL
ferencd@0 1691 assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set.
ferencd@0 1692 #else
ferencd@0 1693 assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set.
ferencd@0 1694 #endif
ferencd@0 1695
ferencd@0 1696 addMe->next = &sentinel;
ferencd@0 1697 addMe->prev = sentinel.prev;
ferencd@0 1698
ferencd@0 1699 sentinel.prev->next = addMe;
ferencd@0 1700 sentinel.prev = addMe;
ferencd@0 1701 }
ferencd@0 1702
ferencd@0 1703 void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
ferencd@0 1704 {
ferencd@0 1705 TiXmlAttribute* node;
ferencd@0 1706
ferencd@0 1707 for( node = sentinel.next; node && node != &sentinel; node = node->next )
ferencd@0 1708 {
ferencd@0 1709 if ( node == removeMe && node)
ferencd@0 1710 {
ferencd@0 1711 node->prev->next = node->next;
ferencd@0 1712 node->next->prev = node->prev;
ferencd@0 1713 node->next = 0;
ferencd@0 1714 node->prev = 0;
ferencd@0 1715 return;
ferencd@0 1716 }
ferencd@0 1717 }
ferencd@0 1718 assert( 0 ); // we tried to remove a non-linked attribute.
ferencd@0 1719 }
ferencd@0 1720
ferencd@0 1721
ferencd@0 1722 #ifdef TIXML_USE_STL
ferencd@0 1723 TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
ferencd@0 1724 {
ferencd@0 1725 for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
ferencd@0 1726 {
ferencd@0 1727 if ( node->name == name )
ferencd@0 1728 return node;
ferencd@0 1729 }
ferencd@0 1730 return 0;
ferencd@0 1731 }
ferencd@0 1732
ferencd@0 1733 TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
ferencd@0 1734 {
ferencd@0 1735 TiXmlAttribute* attrib = Find( _name );
ferencd@0 1736 if ( !attrib ) {
ferencd@0 1737 attrib = new TiXmlAttribute();
ferencd@0 1738 Add( attrib );
ferencd@0 1739 attrib->SetName( _name );
ferencd@0 1740 }
ferencd@0 1741 return attrib;
ferencd@0 1742 }
ferencd@0 1743 #endif
ferencd@0 1744
ferencd@0 1745
ferencd@0 1746 TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
ferencd@0 1747 {
ferencd@0 1748 for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
ferencd@0 1749 {
ferencd@0 1750 if ( strcmp( node->name.c_str(), name ) == 0 )
ferencd@0 1751 return node;
ferencd@0 1752 }
ferencd@0 1753 return 0;
ferencd@0 1754 }
ferencd@0 1755
ferencd@0 1756
ferencd@0 1757 TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
ferencd@0 1758 {
ferencd@0 1759 TiXmlAttribute* attrib = Find( _name );
ferencd@0 1760 if ( !attrib ) {
ferencd@0 1761 attrib = new TiXmlAttribute();
ferencd@0 1762 Add( attrib );
ferencd@0 1763 attrib->SetName( _name );
ferencd@0 1764 }
ferencd@0 1765 return attrib;
ferencd@0 1766 }
ferencd@0 1767
ferencd@0 1768
ferencd@0 1769 #ifdef TIXML_USE_STL
ferencd@0 1770 std::istream& operator>> (std::istream & in, TiXmlNode & base)
ferencd@0 1771 {
ferencd@0 1772 TIXML_STRING tag;
ferencd@0 1773 tag.reserve( 8 * 1000 );
ferencd@0 1774 base.StreamIn( &in, &tag );
ferencd@0 1775
ferencd@0 1776 base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
ferencd@0 1777 return in;
ferencd@0 1778 }
ferencd@0 1779 #endif
ferencd@0 1780
ferencd@0 1781
ferencd@0 1782 #ifdef TIXML_USE_STL
ferencd@0 1783 std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
ferencd@0 1784 {
ferencd@0 1785 TiXmlPrinter printer;
ferencd@0 1786 printer.SetStreamPrinting();
ferencd@0 1787 base.Accept( &printer );
ferencd@0 1788 out << printer.Str();
ferencd@0 1789
ferencd@0 1790 return out;
ferencd@0 1791 }
ferencd@0 1792
ferencd@0 1793
ferencd@0 1794 std::string& operator<< (std::string& out, const TiXmlNode& base )
ferencd@0 1795 {
ferencd@0 1796 TiXmlPrinter printer;
ferencd@0 1797 printer.SetStreamPrinting();
ferencd@0 1798 base.Accept( &printer );
ferencd@0 1799 out.append( printer.Str() );
ferencd@0 1800
ferencd@0 1801 return out;
ferencd@0 1802 }
ferencd@0 1803 #endif
ferencd@0 1804
ferencd@0 1805
ferencd@0 1806 TiXmlHandle TiXmlHandle::FirstChild() const
ferencd@0 1807 {
ferencd@0 1808 if ( node )
ferencd@0 1809 {
ferencd@0 1810 TiXmlNode* child = node->FirstChild();
ferencd@0 1811 if ( child )
ferencd@0 1812 return TiXmlHandle( child );
ferencd@0 1813 }
ferencd@0 1814 return TiXmlHandle( 0 );
ferencd@0 1815 }
ferencd@0 1816
ferencd@0 1817
ferencd@0 1818 TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
ferencd@0 1819 {
ferencd@0 1820 if ( node )
ferencd@0 1821 {
ferencd@0 1822 TiXmlNode* child = node->FirstChild( value );
ferencd@0 1823 if ( child )
ferencd@0 1824 return TiXmlHandle( child );
ferencd@0 1825 }
ferencd@0 1826 return TiXmlHandle( 0 );
ferencd@0 1827 }
ferencd@0 1828
ferencd@0 1829
ferencd@0 1830 TiXmlHandle TiXmlHandle::FirstChildElement() const
ferencd@0 1831 {
ferencd@0 1832 if ( node )
ferencd@0 1833 {
ferencd@0 1834 TiXmlElement* child = node->FirstChildElement();
ferencd@0 1835 if ( child )
ferencd@0 1836 return TiXmlHandle( child );
ferencd@0 1837 }
ferencd@0 1838 return TiXmlHandle( 0 );
ferencd@0 1839 }
ferencd@0 1840
ferencd@0 1841
ferencd@0 1842 TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
ferencd@0 1843 {
ferencd@0 1844 if ( node )
ferencd@0 1845 {
ferencd@0 1846 TiXmlElement* child = node->FirstChildElement( value );
ferencd@0 1847 if ( child )
ferencd@0 1848 return TiXmlHandle( child );
ferencd@0 1849 }
ferencd@0 1850 return TiXmlHandle( 0 );
ferencd@0 1851 }
ferencd@0 1852
ferencd@0 1853
ferencd@0 1854 TiXmlHandle TiXmlHandle::Child( int count ) const
ferencd@0 1855 {
ferencd@0 1856 if ( node )
ferencd@0 1857 {
ferencd@0 1858 int i;
ferencd@0 1859 TiXmlNode* child = node->FirstChild();
ferencd@0 1860 for ( i=0;
ferencd@0 1861 child && i<count;
ferencd@0 1862 child = child->NextSibling(), ++i )
ferencd@0 1863 {
ferencd@0 1864 // nothing
ferencd@0 1865 }
ferencd@0 1866 if ( child )
ferencd@0 1867 return TiXmlHandle( child );
ferencd@0 1868 }
ferencd@0 1869 return TiXmlHandle( 0 );
ferencd@0 1870 }
ferencd@0 1871
ferencd@0 1872
ferencd@0 1873 TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
ferencd@0 1874 {
ferencd@0 1875 if ( node )
ferencd@0 1876 {
ferencd@0 1877 int i;
ferencd@0 1878 TiXmlNode* child = node->FirstChild( value );
ferencd@0 1879 for ( i=0;
ferencd@0 1880 child && i<count;
ferencd@0 1881 child = child->NextSibling( value ), ++i )
ferencd@0 1882 {
ferencd@0 1883 // nothing
ferencd@0 1884 }
ferencd@0 1885 if ( child )
ferencd@0 1886 return TiXmlHandle( child );
ferencd@0 1887 }
ferencd@0 1888 return TiXmlHandle( 0 );
ferencd@0 1889 }
ferencd@0 1890
ferencd@0 1891
ferencd@0 1892 TiXmlHandle TiXmlHandle::ChildElement( int count ) const
ferencd@0 1893 {
ferencd@0 1894 if ( node )
ferencd@0 1895 {
ferencd@0 1896 int i;
ferencd@0 1897 TiXmlElement* child = node->FirstChildElement();
ferencd@0 1898 for ( i=0;
ferencd@0 1899 child && i<count;
ferencd@0 1900 child = child->NextSiblingElement(), ++i )
ferencd@0 1901 {
ferencd@0 1902 // nothing
ferencd@0 1903 }
ferencd@0 1904 if ( child )
ferencd@0 1905 return TiXmlHandle( child );
ferencd@0 1906 }
ferencd@0 1907 return TiXmlHandle( 0 );
ferencd@0 1908 }
ferencd@0 1909
ferencd@0 1910
ferencd@0 1911 TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
ferencd@0 1912 {
ferencd@0 1913 if ( node )
ferencd@0 1914 {
ferencd@0 1915 int i;
ferencd@0 1916 TiXmlElement* child = node->FirstChildElement( value );
ferencd@0 1917 for ( i=0;
ferencd@0 1918 child && i<count;
ferencd@0 1919 child = child->NextSiblingElement( value ), ++i )
ferencd@0 1920 {
ferencd@0 1921 // nothing
ferencd@0 1922 }
ferencd@0 1923 if ( child )
ferencd@0 1924 return TiXmlHandle( child );
ferencd@0 1925 }
ferencd@0 1926 return TiXmlHandle( 0 );
ferencd@0 1927 }
ferencd@0 1928
ferencd@0 1929
ferencd@0 1930 bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
ferencd@0 1931 {
ferencd@0 1932 return true;
ferencd@0 1933 }
ferencd@0 1934
ferencd@0 1935 bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
ferencd@0 1936 {
ferencd@0 1937 return true;
ferencd@0 1938 }
ferencd@0 1939
ferencd@0 1940 bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
ferencd@0 1941 {
ferencd@0 1942 DoIndent();
ferencd@0 1943 buffer += "<";
ferencd@0 1944 buffer += element.Value();
ferencd@0 1945
ferencd@0 1946 for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
ferencd@0 1947 {
ferencd@0 1948 buffer += " ";
ferencd@0 1949 attrib->Print( 0, 0, &buffer );
ferencd@0 1950 }
ferencd@0 1951
ferencd@0 1952 if ( !element.FirstChild() )
ferencd@0 1953 {
ferencd@0 1954 buffer += " />";
ferencd@0 1955 DoLineBreak();
ferencd@0 1956 }
ferencd@0 1957 else
ferencd@0 1958 {
ferencd@0 1959 buffer += ">";
ferencd@0 1960 if ( element.FirstChild()->ToText()
ferencd@0 1961 && element.LastChild() == element.FirstChild()
ferencd@0 1962 && element.FirstChild()->ToText()->CDATA() == false )
ferencd@0 1963 {
ferencd@0 1964 simpleTextPrint = true;
ferencd@0 1965 // no DoLineBreak()!
ferencd@0 1966 }
ferencd@0 1967 else
ferencd@0 1968 {
ferencd@0 1969 DoLineBreak();
ferencd@0 1970 }
ferencd@0 1971 }
ferencd@0 1972 ++depth;
ferencd@0 1973 return true;
ferencd@0 1974 }
ferencd@0 1975
ferencd@0 1976
ferencd@0 1977 bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
ferencd@0 1978 {
ferencd@0 1979 --depth;
ferencd@0 1980 if ( !element.FirstChild() )
ferencd@0 1981 {
ferencd@0 1982 // nothing.
ferencd@0 1983 }
ferencd@0 1984 else
ferencd@0 1985 {
ferencd@0 1986 if ( simpleTextPrint )
ferencd@0 1987 {
ferencd@0 1988 simpleTextPrint = false;
ferencd@0 1989 }
ferencd@0 1990 else
ferencd@0 1991 {
ferencd@0 1992 DoIndent();
ferencd@0 1993 }
ferencd@0 1994 buffer += "</";
ferencd@0 1995 buffer += element.Value();
ferencd@0 1996 buffer += ">";
ferencd@0 1997 DoLineBreak();
ferencd@0 1998 }
ferencd@0 1999 return true;
ferencd@0 2000 }
ferencd@0 2001
ferencd@0 2002
ferencd@0 2003 bool TiXmlPrinter::Visit( const TiXmlText& text )
ferencd@0 2004 {
ferencd@0 2005 if ( text.CDATA() )
ferencd@0 2006 {
ferencd@0 2007 DoIndent();
ferencd@0 2008 buffer += "<![CDATA[";
ferencd@0 2009 buffer += text.Value();
ferencd@0 2010 buffer += "]]>";
ferencd@0 2011 DoLineBreak();
ferencd@0 2012 }
ferencd@0 2013 else if ( simpleTextPrint )
ferencd@0 2014 {
ferencd@0 2015 TIXML_STRING str;
ferencd@0 2016 TiXmlBase::EncodeString( text.ValueTStr(), &str );
ferencd@0 2017 buffer += str;
ferencd@0 2018 }
ferencd@0 2019 else
ferencd@0 2020 {
ferencd@0 2021 DoIndent();
ferencd@0 2022 TIXML_STRING str;
ferencd@0 2023 TiXmlBase::EncodeString( text.ValueTStr(), &str );
ferencd@0 2024 buffer += str;
ferencd@0 2025 DoLineBreak();
ferencd@0 2026 }
ferencd@0 2027 return true;
ferencd@0 2028 }
ferencd@0 2029
ferencd@0 2030
ferencd@0 2031 bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
ferencd@0 2032 {
ferencd@0 2033 DoIndent();
ferencd@0 2034 declaration.Print( 0, 0, &buffer );
ferencd@0 2035 DoLineBreak();
ferencd@0 2036 return true;
ferencd@0 2037 }
ferencd@0 2038
ferencd@0 2039
ferencd@0 2040 bool TiXmlPrinter::Visit( const TiXmlComment& comment )
ferencd@0 2041 {
ferencd@0 2042 DoIndent();
ferencd@0 2043 buffer += "<!--";
ferencd@0 2044 buffer += comment.Value();
ferencd@0 2045 buffer += "-->";
ferencd@0 2046 DoLineBreak();
ferencd@0 2047 return true;
ferencd@0 2048 }
ferencd@0 2049
ferencd@0 2050
ferencd@0 2051 bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
ferencd@0 2052 {
ferencd@0 2053 DoIndent();
ferencd@0 2054 buffer += "<";
ferencd@0 2055 buffer += unknown.Value();
ferencd@0 2056 buffer += ">";
ferencd@0 2057 DoLineBreak();
ferencd@0 2058 return true;
ferencd@0 2059 }
ferencd@0 2060