| 570 | |
| 571 | template <bool insertBr> |
| 572 | void EscapeHtmlChars(TUtf16String& str) { |
| 573 | static const TUtf16String lt(LT, Y_ARRAY_SIZE(LT)); |
| 574 | static const TUtf16String gt(GT, Y_ARRAY_SIZE(GT)); |
| 575 | static const TUtf16String amp(AMP, Y_ARRAY_SIZE(AMP)); |
| 576 | static const TUtf16String br(BR, Y_ARRAY_SIZE(BR)); |
| 577 | static const TUtf16String quot(QUOT, Y_ARRAY_SIZE(QUOT)); |
| 578 | |
| 579 | size_t escapedLen = 0; |
| 580 | |
| 581 | const TUtf16String& cs = str; |
| 582 | |
| 583 | for (size_t i = 0; i < cs.size(); ++i) { |
| 584 | escapedLen += EscapedLen<insertBr>(cs[i]); |
| 585 | } |
| 586 | |
| 587 | if (escapedLen == cs.size()) { |
| 588 | return; |
| 589 | } |
| 590 | |
| 591 | TUtf16String res; |
| 592 | res.reserve(escapedLen); |
| 593 | |
| 594 | size_t start = 0; |
| 595 | |
| 596 | for (size_t i = 0; i < cs.size(); ++i) { |
| 597 | const TUtf16String* ent = nullptr; |
| 598 | switch (cs[i]) { |
| 599 | case '<': |
| 600 | ent = < |
| 601 | break; |
| 602 | case '>': |
| 603 | ent = > |
| 604 | break; |
| 605 | case '&': |
| 606 | ent = & |
| 607 | break; |
| 608 | case '\"': |
| 609 | ent = " |
| 610 | break; |
| 611 | default: |
| 612 | if (insertBr && (cs[i] == '\r' || cs[i] == '\n')) { |
| 613 | ent = &br; |
| 614 | break; |
| 615 | } else { |
| 616 | continue; |
| 617 | } |
| 618 | } |
| 619 | |
| 620 | res.append(cs.begin() + start, cs.begin() + i); |
| 621 | res.append(ent->begin(), ent->end()); |
| 622 | start = i + 1; |
| 623 | } |
| 624 | |
| 625 | res.append(cs.begin() + start, cs.end()); |
| 626 | res.swap(str); |
| 627 | } |
| 628 | |
| 629 | template void EscapeHtmlChars<false>(TUtf16String& str); |