pcdata.cpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include "pcdata.h"
  2. #include <util/string/strspn.h>
  3. static TCompactStrSpn sspn("\"<>&'");
  4. static void EncodeHtmlPcdataAppendInternal(const TStringBuf str, TString& strout, bool qAmp) {
  5. const char* s = str.data();
  6. const char* e = s + str.length();
  7. for (;;) {
  8. const char* next = sspn.FindFirstOf(s, e);
  9. strout.AppendNoAlias(s, next - s);
  10. s = next;
  11. if (s == e)
  12. break;
  13. switch (*s) {
  14. case '\"':
  15. strout += TStringBuf("&quot;");
  16. ++s;
  17. break;
  18. case '<':
  19. strout += TStringBuf("&lt;");
  20. ++s;
  21. break;
  22. case '>':
  23. strout += TStringBuf("&gt;");
  24. ++s;
  25. break;
  26. case '\'':
  27. strout += TStringBuf("&#39;");
  28. ++s;
  29. break;
  30. case '&':
  31. if (qAmp)
  32. strout += TStringBuf("&amp;");
  33. else
  34. strout += TStringBuf("&");
  35. ++s;
  36. break;
  37. }
  38. }
  39. }
  40. void EncodeHtmlPcdataAppend(const TStringBuf str, TString& strout) {
  41. EncodeHtmlPcdataAppendInternal(str, strout, true);
  42. }
  43. TString EncodeHtmlPcdata(const TStringBuf str, bool qAmp) {
  44. TString strout;
  45. EncodeHtmlPcdataAppendInternal(str, strout, qAmp);
  46. return strout;
  47. }
  48. TString DecodeHtmlPcdata(const TString& sz) {
  49. TString res;
  50. const char* codes[] = {"&quot;", "&lt;", "&gt;", "&#39;", "&#039;", "&amp;", "&apos;", nullptr};
  51. const char chars[] = {'\"', '<', '>', '\'', '\'', '&', '\''};
  52. for (size_t i = 0; i < sz.length(); ++i) {
  53. char c = sz[i];
  54. if (c == '&') {
  55. for (const char** p = codes; *p; ++p) {
  56. size_t len = strlen(*p);
  57. if (strncmp(sz.c_str() + i, *p, len) == 0) {
  58. i += len - 1;
  59. c = chars[p - codes];
  60. break;
  61. }
  62. }
  63. }
  64. res += c;
  65. }
  66. return res;
  67. }