/src/logging-log4cxx/src/main/cpp/transform.cpp
Line | Count | Source |
1 | | /* |
2 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
3 | | * contributor license agreements. See the NOTICE file distributed with |
4 | | * this work for additional information regarding copyright ownership. |
5 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
6 | | * (the "License"); you may not use this file except in compliance with |
7 | | * the License. You may obtain a copy of the License at |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | */ |
17 | | |
18 | | #include <log4cxx/logstring.h> |
19 | | #include <log4cxx/helpers/transform.h> |
20 | | #include <log4cxx/helpers/widelife.h> |
21 | | #include <functional> |
22 | | |
23 | | using namespace LOG4CXX_NS; |
24 | | using namespace LOG4CXX_NS::helpers; |
25 | | |
26 | | namespace |
27 | | { |
28 | | using CharProcessor = std::function<void(LogString&, int)>; |
29 | | |
30 | | void appendValidCharacters(LogString& buf, const LogString& input, CharProcessor handler = {}) |
31 | 67.5k | { |
32 | 67.5k | static const logchar specials[] = |
33 | 67.5k | { 0x22 /* " */ |
34 | 67.5k | , 0x26 /* & */ |
35 | 67.5k | , 0x3C /* < */ |
36 | 67.5k | , 0x3E /* > */ |
37 | 67.5k | , 0x00 |
38 | 67.5k | }; |
39 | 67.5k | size_t start = 0; |
40 | 298M | for (size_t index = 0; index < input.size(); ++index) |
41 | 298M | { |
42 | 298M | int ch = input[index]; |
43 | | // Allowable XML 1.0 characters are: |
44 | | // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] |
45 | 298M | if (0x20 <= ch && ch <= 0xD7FF) |
46 | 217M | { |
47 | 217M | auto pSpecial = &specials[0]; |
48 | 498M | while (*pSpecial && *pSpecial != ch) |
49 | 281M | ++pSpecial; |
50 | 217M | if (!*pSpecial) |
51 | 65.4M | continue; |
52 | 217M | } |
53 | 81.0M | else if (0x9 == ch || 0xA == ch || 0xD == ch || |
54 | 79.9M | (0xE000 <= ch && ch <= 0xFFFD) || |
55 | 79.9M | (0x10000 <= ch && ch <= 0x10FFFF)) |
56 | 1.09M | { |
57 | 1.09M | continue; |
58 | 1.09M | } |
59 | | |
60 | 232M | if (start < index) |
61 | 8.51M | buf.append(input, start, index - start); |
62 | 232M | start = index + 1; |
63 | 232M | switch (ch) |
64 | 232M | { |
65 | 26.7M | case 0: // Do not output a NUL character |
66 | 26.7M | break; |
67 | 143M | case 0x22: |
68 | 143M | buf.append(LOG4CXX_STR(""")); |
69 | 143M | break; |
70 | | |
71 | 204k | case 0x26: |
72 | 204k | buf.append(LOG4CXX_STR("&")); |
73 | 204k | break; |
74 | | |
75 | 5.65M | case 0x3C: |
76 | 5.65M | buf.append(LOG4CXX_STR("<")); |
77 | 5.65M | break; |
78 | | |
79 | 2.53M | case 0x3E: |
80 | 2.53M | buf.append(LOG4CXX_STR(">")); |
81 | 2.53M | break; |
82 | | |
83 | 53.1M | default: |
84 | 53.1M | if (handler) |
85 | 51.7M | handler(buf, ch); |
86 | 53.1M | break; |
87 | 232M | } |
88 | 232M | } |
89 | | |
90 | 67.5k | if (start < input.size()) |
91 | 46.1k | { |
92 | 46.1k | buf.append(input, start, input.size() - start); |
93 | 46.1k | } |
94 | 67.5k | } |
95 | | |
96 | | } // namespace |
97 | | |
98 | | void Transform::appendEscapingCDATA( |
99 | | LogString& buf, const LogString& input) |
100 | 0 | { |
101 | 0 | static const LogString CDATA_END(LOG4CXX_STR("]]>")); |
102 | 0 | const LogString::size_type CDATA_END_LEN = 3; |
103 | 0 | static const LogString CDATA_EMBEDED_END(LOG4CXX_STR("]]><![CDATA[")); |
104 | 0 | size_t start = 0; |
105 | 0 | for (size_t index = 0; index < input.size(); ++index) |
106 | 0 | { |
107 | 0 | int ch = input[index]; |
108 | 0 | bool cdataEnd = false; |
109 | | // Allowable XML 1.0 characters are: |
110 | | // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] |
111 | 0 | if (0x20 <= ch && ch <= 0xD7FF) |
112 | 0 | { |
113 | 0 | if (CDATA_END[0] == ch && |
114 | 0 | index + CDATA_END_LEN <= input.size() && |
115 | 0 | 0 == input.compare(index, CDATA_END_LEN, CDATA_END)) |
116 | 0 | { |
117 | 0 | index += CDATA_END_LEN; |
118 | 0 | cdataEnd = true; |
119 | 0 | } |
120 | 0 | else |
121 | 0 | { |
122 | 0 | continue; |
123 | 0 | } |
124 | 0 | } |
125 | 0 | else if (0x9 == ch || 0xA == ch || 0xD == ch || |
126 | 0 | (0xE000 <= ch && ch <= 0xFFFD) || |
127 | 0 | (0x10000 <= ch && ch <= 0x10FFFF)) |
128 | 0 | { |
129 | 0 | continue; |
130 | 0 | } |
131 | | |
132 | 0 | if (start < index) |
133 | 0 | buf.append(input, start, index - start); |
134 | 0 | if (cdataEnd) |
135 | 0 | { |
136 | 0 | buf.append(CDATA_EMBEDED_END); |
137 | 0 | --index; |
138 | 0 | } |
139 | 0 | else if (0 != ch) |
140 | 0 | appendCharacterReference(buf, ch); |
141 | 0 | start = index + 1; |
142 | 0 | } |
143 | |
|
144 | 0 | if (start < input.size()) |
145 | 0 | buf.append(input, start, input.size() - start); |
146 | 0 | } |
147 | | |
148 | | void Transform::appendCharacterReference(LogString& buf, int ch) |
149 | 51.7M | { |
150 | 51.7M | auto toHexDigit = [](int ch) -> int |
151 | 62.3M | { |
152 | 62.3M | return (10 <= ch ? (0x61 - 10) : 0x30) + ch; |
153 | 62.3M | }; |
154 | 51.7M | buf.push_back('&'); |
155 | 51.7M | buf.push_back('#'); |
156 | 51.7M | buf.push_back('x'); |
157 | 51.7M | if (0xFFFFFFF < ch) |
158 | 0 | buf.push_back(toHexDigit((ch & 0x70000000) >> 28)); |
159 | 51.7M | if (0xFFFFFF < ch) |
160 | 0 | buf.push_back(toHexDigit((ch & 0xF000000) >> 24)); |
161 | 51.7M | if (0xFFFFF < ch) |
162 | 0 | buf.push_back(toHexDigit((ch & 0xF00000) >> 20)); |
163 | 51.7M | if (0xFFFF < ch) |
164 | 0 | buf.push_back(toHexDigit((ch & 0xF0000) >> 16)); |
165 | 51.7M | if (0xFFF < ch) |
166 | 0 | buf.push_back(toHexDigit((ch & 0xF000) >> 12)); |
167 | 51.7M | if (0xFF < ch) |
168 | 0 | buf.push_back(toHexDigit((ch & 0xF00) >> 8)); |
169 | 51.7M | if (0xF < ch) |
170 | 10.6M | buf.push_back(toHexDigit((ch & 0xF0) >> 4)); |
171 | 51.7M | buf.push_back(toHexDigit(ch & 0xF)); |
172 | 51.7M | buf.push_back(';'); |
173 | 51.7M | } |
174 | | |
175 | | void Transform::appendEscapingTags(LogString& buf, const LogString& input) |
176 | 48.1k | { |
177 | 48.1k | appendValidCharacters(buf, input, appendCharacterReference); |
178 | 48.1k | } |
179 | | |
180 | | void Transform::appendLegalCharacters(LogString& buf, const LogString& input) |
181 | 19.3k | { |
182 | 19.3k | appendValidCharacters(buf, input); |
183 | 19.3k | } |