| 2489 | |
| 2490 | |
| 2491 | void XMLPrinter::PrintString( const char* p, bool restricted ) |
| 2492 | { |
| 2493 | // Look for runs of bytes between entities to print. |
| 2494 | const char* q = p; |
| 2495 | |
| 2496 | if ( _processEntities ) { |
| 2497 | const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag; |
| 2498 | while ( *q ) { |
| 2499 | TIXMLASSERT( p <= q ); |
| 2500 | // Remember, char is sometimes signed. (How many times has that bitten me?) |
| 2501 | if ( *q > 0 && *q < ENTITY_RANGE ) { |
| 2502 | // Check for entities. If one is found, flush |
| 2503 | // the stream up until the entity, write the |
| 2504 | // entity, and keep looking. |
| 2505 | if ( flag[(unsigned char)(*q)] ) { |
| 2506 | while ( p < q ) { |
| 2507 | const size_t delta = q - p; |
| 2508 | const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta; |
| 2509 | Write( p, toPrint ); |
| 2510 | p += toPrint; |
| 2511 | } |
| 2512 | bool entityPatternPrinted = false; |
| 2513 | for( int i=0; i<NUM_ENTITIES; ++i ) { |
| 2514 | if ( entities[i].value == *q ) { |
| 2515 | Putc( '&' ); |
| 2516 | Write( entities[i].pattern, entities[i].length ); |
| 2517 | Putc( ';' ); |
| 2518 | entityPatternPrinted = true; |
| 2519 | break; |
| 2520 | } |
| 2521 | } |
| 2522 | if ( !entityPatternPrinted ) { |
| 2523 | // TIXMLASSERT( entityPatternPrinted ) causes gcc -Wunused-but-set-variable in release |
| 2524 | TIXMLASSERT( false ); |
| 2525 | } |
| 2526 | ++p; |
| 2527 | } |
| 2528 | } |
| 2529 | ++q; |
| 2530 | TIXMLASSERT( p <= q ); |
| 2531 | } |
| 2532 | // Flush the remaining string. This will be the entire |
| 2533 | // string if an entity wasn't found. |
| 2534 | if ( p < q ) { |
| 2535 | const size_t delta = q - p; |
| 2536 | const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta; |
| 2537 | Write( p, toPrint ); |
| 2538 | } |
| 2539 | } |
| 2540 | else { |
| 2541 | Write( p ); |
| 2542 | } |
| 2543 | } |
| 2544 | |
| 2545 | |
| 2546 | void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) |