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