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