/src/logging-log4cxx/src/main/cpp/transcoder.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/transcoder.h> |
20 | | #include <log4cxx/helpers/pool.h> |
21 | | #include <stdlib.h> |
22 | | #include <log4cxx/helpers/exception.h> |
23 | | #include <log4cxx/private/bytebuffer_priv.h> |
24 | | #include <log4cxx/helpers/charsetdecoder.h> |
25 | | #include <log4cxx/helpers/charsetencoder.h> |
26 | | #include <log4cxx/helpers/stringhelper.h> |
27 | | #include <log4cxx/helpers/loglog.h> |
28 | | #include <vector> |
29 | | #include <cstring> |
30 | | #if !defined(LOG4CXX) |
31 | | #define LOG4CXX 1 |
32 | | #endif |
33 | | #include <log4cxx/private/log4cxx_private.h> |
34 | | |
35 | | #if LOG4CXX_CFSTRING_API |
36 | | #include <CoreFoundation/CFString.h> |
37 | | #endif |
38 | | |
39 | | using namespace LOG4CXX_NS; |
40 | | using namespace LOG4CXX_NS::helpers; |
41 | | |
42 | | void Transcoder::decodeUTF8(const std::string& src, LogString& dst) |
43 | 0 | { |
44 | 0 | std::string::const_iterator iter = src.begin(); |
45 | |
|
46 | 0 | while (iter != src.end()) |
47 | 0 | { |
48 | 0 | auto sv = getCodePoint(src, iter); |
49 | 0 | encode(sv, dst); |
50 | 0 | } |
51 | 0 | } |
52 | | |
53 | | void Transcoder::encodeUTF8(const LogString& src, std::string& dst) |
54 | 0 | { |
55 | | #if LOG4CXX_LOGCHAR_IS_UTF8 |
56 | | dst.append(src); |
57 | | #else |
58 | 0 | LogString::const_iterator iter = src.begin(); |
59 | |
|
60 | 0 | while (iter != src.end()) |
61 | 0 | { |
62 | 0 | unsigned int sv = getCodePoint(src, iter); |
63 | 0 | encode(sv, dst); |
64 | 0 | } |
65 | |
|
66 | 0 | #endif |
67 | 0 | } |
68 | | |
69 | | #if LOG4CXX_ABI_VERSION <= 15 |
70 | | char* Transcoder::encodeUTF8(const LogString& src, Pool& p) |
71 | 0 | { |
72 | | #if LOG4CXX_LOGCHAR_IS_UTF8 |
73 | | return p.pstrdup(src); |
74 | | #else |
75 | 0 | std::string tmp; |
76 | 0 | encodeUTF8(src, tmp); |
77 | 0 | return p.pstrdup(tmp); |
78 | 0 | #endif |
79 | 0 | } |
80 | | #endif |
81 | | |
82 | | void Transcoder::encodeUTF8(unsigned int sv, ByteBuffer& dst) |
83 | 0 | { |
84 | 0 | dst.increment_position(CharsetEncoder::putUTF8CodePoint(sv, dst.current())); |
85 | 0 | } |
86 | | |
87 | | void Transcoder::encodeUTF16BE(unsigned int sv, ByteBuffer& dst) |
88 | 0 | { |
89 | 0 | dst.increment_position(CharsetEncoder::putUTF16BECodePoint(sv, dst.current())); |
90 | 0 | } |
91 | | |
92 | | void Transcoder::encodeUTF16LE(unsigned int sv, ByteBuffer& dst) |
93 | 0 | { |
94 | 0 | dst.increment_position(CharsetEncoder::putUTF16LECodePoint(sv, dst.current())); |
95 | 0 | } |
96 | | |
97 | | unsigned int Transcoder::decode(const std::string& src, |
98 | | std::string::const_iterator& iter) |
99 | 0 | { |
100 | 0 | auto offset = iter - src.begin(); |
101 | 0 | auto remaining = src.size() - offset; |
102 | 0 | ByteBufferPriv buf(const_cast<char*>(src.data() + offset), remaining); |
103 | 0 | auto result = CharsetDecoder::getUTF8CodePoint(buf); |
104 | 0 | iter += remaining - buf.remaining(); |
105 | 0 | return result; |
106 | 0 | } |
107 | | |
108 | | template <typename T> |
109 | | unsigned int decodeCodePoint(const typename std::basic_string<T>& str, typename std::basic_string<T>::const_iterator& nextCodePoint) |
110 | 45.1k | { |
111 | 45.1k | auto lastCodePoint = nextCodePoint; |
112 | 45.1k | auto ch = Transcoder::decode(str, nextCodePoint); |
113 | 45.1k | if (nextCodePoint == lastCodePoint) // failed to decode input? |
114 | 0 | { |
115 | | // Skip the undecodable run and keep escaping the remaining input |
116 | | // instead of discarding it; the run collapses to one replacement. |
117 | 0 | for (++nextCodePoint; nextCodePoint != str.end(); ++nextCodePoint) |
118 | 0 | { |
119 | 0 | auto probe = nextCodePoint; |
120 | 0 | Transcoder::decode(str, probe); |
121 | 0 | if (probe != nextCodePoint) // next unit starts a decodable sequence |
122 | 0 | break; |
123 | 0 | } |
124 | 0 | ch = 0xFFFD; // The Unicode replacement character |
125 | 0 | } |
126 | 45.1k | else if ( (0xD800 <= ch && ch <= 0xDFFF) // UTF-16 surrogate-range |
127 | 45.1k | || 0xFFFF == ch || 0x10FFFF < ch) |
128 | 0 | { |
129 | 0 | ch = 0xFFFD; // The Unicode replacement character |
130 | 0 | } |
131 | 45.1k | return ch; |
132 | 45.1k | } Unexecuted instantiation: unsigned int decodeCodePoint<char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::const_iterator&) unsigned int decodeCodePoint<wchar_t>(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >::const_iterator&) Line | Count | Source | 110 | 45.1k | { | 111 | 45.1k | auto lastCodePoint = nextCodePoint; | 112 | 45.1k | auto ch = Transcoder::decode(str, nextCodePoint); | 113 | 45.1k | if (nextCodePoint == lastCodePoint) // failed to decode input? | 114 | 0 | { | 115 | | // Skip the undecodable run and keep escaping the remaining input | 116 | | // instead of discarding it; the run collapses to one replacement. | 117 | 0 | for (++nextCodePoint; nextCodePoint != str.end(); ++nextCodePoint) | 118 | 0 | { | 119 | 0 | auto probe = nextCodePoint; | 120 | 0 | Transcoder::decode(str, probe); | 121 | 0 | if (probe != nextCodePoint) // next unit starts a decodable sequence | 122 | 0 | break; | 123 | 0 | } | 124 | 0 | ch = 0xFFFD; // The Unicode replacement character | 125 | 0 | } | 126 | 45.1k | else if ( (0xD800 <= ch && ch <= 0xDFFF) // UTF-16 surrogate-range | 127 | 45.1k | || 0xFFFF == ch || 0x10FFFF < ch) | 128 | 0 | { | 129 | 0 | ch = 0xFFFD; // The Unicode replacement character | 130 | 0 | } | 131 | 45.1k | return ch; | 132 | 45.1k | } |
|
133 | | |
134 | | unsigned int Transcoder::getCodePoint(const std::string& str, std::string::const_iterator& nextCodePoint) |
135 | 0 | { |
136 | 0 | return decodeCodePoint<char>(str, nextCodePoint); |
137 | 0 | } |
138 | | |
139 | | void Transcoder::encode(unsigned int sv, std::string& dst) |
140 | 0 | { |
141 | 0 | char tmp[8]; |
142 | 0 | size_t bytes = CharsetEncoder::putUTF8CodePoint(sv, tmp); |
143 | 0 | dst.append(tmp, bytes); |
144 | 0 | } |
145 | | |
146 | | /// Does \c str contain the Unicode replacement character |
147 | | bool Transcoder::hasReplacementCharacter(const std::string& str) |
148 | 0 | { |
149 | 0 | return str.npos != str.find("\xEF\xBF\xBD"); |
150 | 0 | } |
151 | | |
152 | | void Transcoder::decode(const std::string& src, LogString& dst) |
153 | 18.6k | { |
154 | | #if LOG4CXX_CHARSET_UTF8 && LOG4CXX_LOGCHAR_IS_UTF8 |
155 | | dst.append(src); |
156 | | #else |
157 | 18.6k | static CharsetDecoderPtr decoder(CharsetDecoder::getDefaultDecoder()); |
158 | 18.6k | dst.reserve(dst.size() + src.size()); |
159 | 18.6k | std::string::const_iterator iter = src.begin(); |
160 | 18.6k | #if !LOG4CXX_CHARSET_EBCDIC |
161 | | |
162 | 18.6k | for (; |
163 | 186k | iter != src.end() && ((unsigned char) *iter) < 0x80; |
164 | 168k | iter++) |
165 | 168k | { |
166 | 168k | dst.append(1, *iter); |
167 | 168k | } |
168 | | |
169 | 18.6k | #endif |
170 | | |
171 | 18.6k | if (iter != src.end()) |
172 | 2.66k | { |
173 | 2.66k | size_t offset = iter - src.begin(); |
174 | 2.66k | ByteBuffer buf(const_cast<char*>(src.data() + offset), src.size() - offset); |
175 | | |
176 | 121k | while (buf.remaining() > 0) |
177 | 118k | { |
178 | 118k | log4cxx_status_t stat = decoder->decode(buf, dst); |
179 | | |
180 | 118k | if (CharsetDecoder::isError(stat)) |
181 | 116k | { |
182 | 116k | encode(LOSSCHAR, dst); |
183 | 116k | buf.increment_position(1); |
184 | 116k | } |
185 | 118k | } |
186 | | |
187 | 2.66k | decoder->decode(buf, dst); |
188 | 2.66k | } |
189 | | |
190 | 18.6k | #endif |
191 | 18.6k | } |
192 | | |
193 | | #if LOG4CXX_ABI_VERSION <= 15 |
194 | | char* Transcoder::encode(const LogString& src, Pool& p) |
195 | 0 | { |
196 | | #if LOG4CXX_CHARSET_UTF8 && LOG4CXX_LOGCHAR_IS_UTF8 |
197 | | return p.pstrdup(src); |
198 | | #else |
199 | 0 | std::string tmp; |
200 | 0 | encode(src, tmp); |
201 | 0 | return p.pstrdup(tmp); |
202 | 0 | #endif |
203 | 0 | } |
204 | | #endif |
205 | | |
206 | | |
207 | | void Transcoder::encode(const LogString& src, std::string& dst) |
208 | 1.15k | { |
209 | | #if LOG4CXX_CHARSET_UTF8 && LOG4CXX_LOGCHAR_IS_UTF8 |
210 | | dst.append(src); |
211 | | #else |
212 | 1.15k | static CharsetEncoderPtr encoder(CharsetEncoder::getDefaultEncoder()); |
213 | 1.15k | dst.reserve(dst.size() + src.size()); |
214 | 1.15k | LogString::const_iterator iter = src.begin(); |
215 | 1.15k | #if !LOG4CXX_CHARSET_EBCDIC |
216 | | |
217 | 1.15k | for (; |
218 | 45.4k | iter != src.end() && ((unsigned int) *iter) < 0x80; |
219 | 44.3k | iter++) |
220 | 44.3k | { |
221 | 44.3k | dst.append(1, static_cast<char>(*iter)); |
222 | 44.3k | } |
223 | | |
224 | 1.15k | #endif |
225 | 1.15k | if (iter != src.end()) |
226 | 421 | { |
227 | 421 | static const int BUFSIZE = 256; |
228 | 421 | char buf[BUFSIZE]; |
229 | 421 | ByteBuffer out(buf, BUFSIZE); |
230 | | |
231 | 1.15k | while (iter != src.end()) |
232 | 735 | { |
233 | 735 | log4cxx_status_t stat = encoder->encode(src, iter, out); |
234 | 735 | out.flip(); |
235 | 735 | dst.append(out.data(), out.limit()); |
236 | 735 | out.clear(); |
237 | | |
238 | 735 | if (CharsetEncoder::isError(stat)) |
239 | 0 | { |
240 | 0 | encode(LOSSCHAR, dst); |
241 | 0 | iter++; |
242 | 0 | } |
243 | 735 | } |
244 | | |
245 | 421 | encoder->encode(src, iter, out); |
246 | 421 | } |
247 | | |
248 | 1.15k | #endif |
249 | 1.15k | } |
250 | | |
251 | | |
252 | | template<class String, class Iterator> |
253 | | static unsigned int decodeUTF16(const String& in, Iterator& iter) |
254 | | { |
255 | | unsigned int ch1 = *iter; |
256 | | |
257 | | // |
258 | | // if not surrogate pair |
259 | | // |
260 | | if (ch1 < 0xD800 || ch1 > 0xDFFF) |
261 | | { |
262 | | // |
263 | | // then advance iterator and return wchar_t value |
264 | | // |
265 | | if (ch1 != 0xFFFF) |
266 | | { |
267 | | iter++; |
268 | | } |
269 | | |
270 | | return ch1; |
271 | | } |
272 | | else if (ch1 < 0xDC00) |
273 | | { |
274 | | // |
275 | | // started with high-surrogate value |
276 | | // if there is an additional wchar_t |
277 | | Iterator iter2 = iter + 1; |
278 | | |
279 | | if (iter2 != in.end()) |
280 | | { |
281 | | unsigned int ch2 = *iter2; |
282 | | |
283 | | // |
284 | | // if it is a matching low surrogate then |
285 | | // advance the iterator and return the scalar value |
286 | | if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) |
287 | | { |
288 | | iter += 2; |
289 | | return (ch1 - 0xD800) * 0x400 + (ch2 - 0xDC00) + 0x10000; |
290 | | } |
291 | | } |
292 | | } |
293 | | |
294 | | // |
295 | | // unrecognized value, do not advance iterator |
296 | | // |
297 | | return 0xFFFF; |
298 | | } |
299 | | |
300 | | template<class String> |
301 | | static void encodeUTF16(unsigned int sv, String& dst) |
302 | | { |
303 | | if (sv < 0x10000) |
304 | | { |
305 | | dst.append(1, sv); |
306 | | } |
307 | | else |
308 | | { |
309 | | unsigned char u = (unsigned char) (sv >> 16); |
310 | | unsigned char w = (unsigned char) (u - 1); |
311 | | unsigned short hs = (0xD800 + ((w & 0xF) << 6) + ((sv & 0xFFFF) >> 10)); |
312 | | unsigned short ls = (0xDC00 + (sv & 0x3FF)); |
313 | | dst.append(1, hs); |
314 | | dst.append(1, ls); |
315 | | } |
316 | | } |
317 | | |
318 | | |
319 | | |
320 | | #if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR || defined(WIN32) || defined(_WIN32) |
321 | | void Transcoder::decode(const std::wstring& src, LogString& dst) |
322 | 62.7k | { |
323 | 62.7k | #if LOG4CXX_LOGCHAR_IS_WCHAR |
324 | 62.7k | dst.append(src); |
325 | | #else |
326 | | std::wstring::const_iterator i = src.begin(); |
327 | | |
328 | | while (i != src.end()) |
329 | | { |
330 | | auto cp = getCodePoint(src, i); |
331 | | encode(cp, dst); |
332 | | } |
333 | | |
334 | | #endif |
335 | 62.7k | } |
336 | | |
337 | | void Transcoder::encode(const LogString& src, std::wstring& dst) |
338 | 0 | { |
339 | 0 | #if LOG4CXX_LOGCHAR_IS_WCHAR |
340 | 0 | dst.append(src); |
341 | | #else |
342 | | |
343 | | for (LogString::const_iterator i = src.begin(); i != src.end();) |
344 | | { |
345 | | unsigned int cp = getCodePoint(src, i); |
346 | | encode(cp, dst); |
347 | | } |
348 | | |
349 | | #endif |
350 | 0 | } |
351 | | |
352 | | #if LOG4CXX_ABI_VERSION <= 15 |
353 | | wchar_t* Transcoder::wencode(const LogString& src, Pool& p) |
354 | 0 | { |
355 | 0 | #if LOG4CXX_LOGCHAR_IS_WCHAR |
356 | 0 | const std::wstring& tmp = src; |
357 | | #else |
358 | | std::wstring tmp; |
359 | | encode(src, tmp); |
360 | | #endif |
361 | 0 | wchar_t* dst = (wchar_t*) p.palloc((tmp.length() + 1) * sizeof(wchar_t)); |
362 | 0 | dst[tmp.length()] = 0; |
363 | 0 | std::memcpy(dst, tmp.data(), tmp.length() * sizeof(wchar_t)); |
364 | 0 | return dst; |
365 | 0 | } |
366 | | #endif |
367 | | |
368 | | unsigned int Transcoder::decode(const std::wstring& in, |
369 | | std::wstring::const_iterator& iter) |
370 | 45.1k | { |
371 | 45.1k | #if defined(__STDC_ISO_10646__) |
372 | 45.1k | return *(iter++); |
373 | | #else |
374 | | return decodeUTF16(in, iter); |
375 | | #endif |
376 | 45.1k | } |
377 | | |
378 | | unsigned int Transcoder::getCodePoint(const std::wstring& str, std::wstring::const_iterator& nextCodePoint) |
379 | 45.1k | { |
380 | 45.1k | return decodeCodePoint<wchar_t>(str, nextCodePoint); |
381 | 45.1k | } |
382 | | |
383 | | void Transcoder::encode(unsigned int sv, std::wstring& dst) |
384 | 336k | { |
385 | 336k | #if defined(__STDC_ISO_10646__) |
386 | 336k | dst.append(1, sv); |
387 | | #else |
388 | | |
389 | | if (sizeof(wchar_t) == 4) |
390 | | { |
391 | | dst.append(1, sv); |
392 | | } |
393 | | else |
394 | | { |
395 | | encodeUTF16(sv, dst); |
396 | | } |
397 | | |
398 | | #endif |
399 | 336k | } |
400 | | |
401 | | /// Does \c str contain the Unicode replacement character |
402 | | bool Transcoder::hasReplacementCharacter(const std::wstring& str) |
403 | 0 | { |
404 | 0 | return str.npos != str.find(LOSSCHAR); |
405 | 0 | } |
406 | | #endif |
407 | | |
408 | | |
409 | | |
410 | | #if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR |
411 | | void Transcoder::decode(const std::basic_string<UniChar>& src, LogString& dst) |
412 | | { |
413 | | #if LOG4CXX_LOGCHAR_IS_UNICHAR |
414 | | dst.append(src); |
415 | | #else |
416 | | |
417 | | for (std::basic_string<UniChar>::const_iterator i = src.begin(); |
418 | | i != src.end();) |
419 | | { |
420 | | std::basic_string<UniChar>::const_iterator start = i; |
421 | | unsigned int cp = decode(src, i); |
422 | | |
423 | | if (cp != 0xFFFF) |
424 | | { |
425 | | encode(cp, dst); |
426 | | } |
427 | | else |
428 | | { |
429 | | encode(LOSSCHAR, dst); |
430 | | if (i == start) |
431 | | { |
432 | | i++; |
433 | | } |
434 | | } |
435 | | } |
436 | | |
437 | | #endif |
438 | | } |
439 | | |
440 | | void Transcoder::encode(const LogString& src, std::basic_string<UniChar>& dst) |
441 | | { |
442 | | #if LOG4CXX_LOGCHAR_IS_UNICHAR |
443 | | dst.append(src); |
444 | | #else |
445 | | |
446 | | for (LogString::const_iterator i = src.begin(); |
447 | | i != src.end();) |
448 | | { |
449 | | LogString::const_iterator start = i; |
450 | | unsigned int cp = decode(src, i); |
451 | | |
452 | | if (cp != 0xFFFF) |
453 | | { |
454 | | encode(cp, dst); |
455 | | } |
456 | | else |
457 | | { |
458 | | encode(LOSSCHAR, dst); |
459 | | if (i == start) |
460 | | { |
461 | | i++; |
462 | | } |
463 | | } |
464 | | } |
465 | | |
466 | | #endif |
467 | | } |
468 | | |
469 | | unsigned int Transcoder::decode(const std::basic_string<UniChar>& in, |
470 | | std::basic_string<UniChar>::const_iterator& iter) |
471 | | { |
472 | | return decodeUTF16(in, iter); |
473 | | } |
474 | | |
475 | | unsigned int Transcoder::getCodePoint(const std::basic_string<UniChar>& str, std::basic_string<UniChar>::const_iterator& nextCodePoint) |
476 | | { |
477 | | return decodeCodePoint<UniChar>(str, nextCodePoint); |
478 | | } |
479 | | |
480 | | void Transcoder::encode(unsigned int sv, std::basic_string<UniChar>& dst) |
481 | | { |
482 | | encodeUTF16(sv, dst); |
483 | | } |
484 | | |
485 | | /// Does \c str contain the Unicode replacement character |
486 | | bool Transcoder::hasReplacementCharacter(const std::basic_string<UniChar>& str) |
487 | | { |
488 | | return str.npos != str.find(LOSSCHAR); |
489 | | } |
490 | | #endif |
491 | | |
492 | | #if LOG4CXX_CFSTRING_API |
493 | | void Transcoder::decode(const CFStringRef& src, LogString& dst) |
494 | | { |
495 | | auto length = CFStringGetLength(src); |
496 | | #if defined(_DEBUG) |
497 | | if (LogLog::isDebugEnabled()) |
498 | | { |
499 | | LogString msg(LOG4CXX_STR("Transcoder::decodeCFString")); |
500 | | msg += LOG4CXX_STR(" length "); |
501 | | StringHelper::toString((size_t)length, msg); |
502 | | LogLog::debug(msg); |
503 | | } |
504 | | #endif |
505 | | |
506 | | if (length > 0) |
507 | | { |
508 | | std::vector<unsigned short> tmp(length); |
509 | | CFStringGetCharacters(src, CFRangeMake(0, length), &tmp[0]); |
510 | | for (auto i = tmp.begin(); i != tmp.end(); ) |
511 | | { |
512 | | auto start = i; |
513 | | unsigned int cp = decodeUTF16(tmp, i); |
514 | | if (cp != 0xFFFF) |
515 | | { |
516 | | encode(cp, dst); |
517 | | } |
518 | | else |
519 | | { |
520 | | encode(LOSSCHAR, dst); |
521 | | if (i == start) |
522 | | { |
523 | | i++; |
524 | | } |
525 | | } |
526 | | } |
527 | | } |
528 | | } |
529 | | |
530 | | CFStringRef Transcoder::encode(const LogString& src) |
531 | | { |
532 | | std::basic_string<unsigned short> tmp; |
533 | | for (auto ch : src) |
534 | | encodeUTF16(ch, tmp); |
535 | | return CFStringCreateWithCharacters(kCFAllocatorDefault, tmp.data(), tmp.size()); |
536 | | } |
537 | | #endif // #if LOG4CXX_CFSTRING_API |
538 | | |
539 | | |
540 | | logchar Transcoder::decode(char val) |
541 | 0 | { |
542 | | #if LOG4CXX_CHARSET_EBCDIC |
543 | | LogString dst; |
544 | | Transcoder::decode(std::string(1, val), dst); |
545 | | return dst[0]; |
546 | | #else |
547 | 0 | return val; |
548 | 0 | #endif |
549 | 0 | } |
550 | | |
551 | | LogString Transcoder::decode(const char* val) |
552 | 2 | { |
553 | | #if LOG4CXX_LOGCHAR_IS_UTF8 && !LOG4CXX_CHARSET_EBCDIC |
554 | | return val; |
555 | | #else |
556 | 2 | LogString dst; |
557 | 2 | Transcoder::decode(val, dst); |
558 | 2 | return dst; |
559 | 2 | #endif |
560 | 2 | } |
561 | | |
562 | | |
563 | | std::string Transcoder::encodeCharsetName(const LogString& val) |
564 | 0 | { |
565 | 0 | char asciiTable[] = { ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', |
566 | 0 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', |
567 | 0 | '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', |
568 | 0 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', |
569 | 0 | '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', |
570 | 0 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~' |
571 | 0 | }; |
572 | 0 | std::string out; |
573 | |
|
574 | 0 | for (auto& item : val) |
575 | 0 | { |
576 | 0 | if (item >= 0x20 && item < 0x7F) |
577 | 0 | { |
578 | 0 | out.append(1, asciiTable[item - 0x20]); |
579 | 0 | } |
580 | 0 | else |
581 | 0 | { |
582 | 0 | out.append(1, '?'); |
583 | 0 | } |
584 | 0 | } |
585 | |
|
586 | 0 | return out; |
587 | 0 | } |