Coverage Report

Created: 2026-07-30 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/charsetencoder.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
#include <log4cxx/logstring.h>
18
#include <log4cxx/helpers/charsetencoder.h>
19
#include <log4cxx/helpers/bytebuffer.h>
20
#include <log4cxx/helpers/exception.h>
21
#include <apr_xlate.h>
22
#include <log4cxx/helpers/stringhelper.h>
23
#include <log4cxx/helpers/transcoder.h>
24
#include <algorithm>
25
26
#if !defined(LOG4CXX)
27
  #define LOG4CXX 1
28
#endif
29
30
#include <log4cxx/private/log4cxx_private.h>
31
#include <apr_portable.h>
32
#include <mutex>
33
34
#ifdef LOG4CXX_HAS_WCSTOMBS
35
  #include <stdlib.h>
36
#endif
37
38
using namespace LOG4CXX_NS;
39
using namespace LOG4CXX_NS::helpers;
40
41
IMPLEMENT_LOG4CXX_OBJECT(CharsetEncoder)
42
43
namespace LOG4CXX_NS
44
{
45
46
namespace helpers
47
{
48
49
#if APR_HAS_XLATE
50
/**
51
* A character encoder implemented using apr_xlate.
52
*/
53
class APRCharsetEncoder : public CharsetEncoder
54
{
55
  public:
56
0
    APRCharsetEncoder(const LogString& topage) : pool()
57
0
    {
58
#if LOG4CXX_LOGCHAR_IS_WCHAR
59
      const char* frompage = "WCHAR_T";
60
#endif
61
#if LOG4CXX_LOGCHAR_IS_UTF8
62
      const char* frompage = "UTF-8";
63
#endif
64
#if LOG4CXX_LOGCHAR_IS_UNICHAR
65
      const char* frompage = "UTF-16";
66
#endif
67
0
      std::string tpage(Transcoder::encodeCharsetName(topage));
68
0
      apr_status_t stat = apr_xlate_open(&convset,
69
0
          tpage.c_str(),
70
0
          frompage,
71
0
          pool.getAPRPool());
72
73
0
      if (stat != APR_SUCCESS)
74
0
      {
75
0
        throw IllegalArgumentException(topage);
76
0
      }
77
0
    }
Unexecuted instantiation: log4cxx::helpers::APRCharsetEncoder::APRCharsetEncoder(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: log4cxx::helpers::APRCharsetEncoder::APRCharsetEncoder(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
78
79
    virtual ~APRCharsetEncoder()
80
0
    {
81
0
    }
82
83
    virtual log4cxx_status_t encode(const LogString& in,
84
      LogString::const_iterator& iter,
85
      ByteBuffer& out)
86
0
    {
87
0
      apr_status_t stat;
88
0
      size_t outbytes_left = out.remaining();
89
0
      size_t initial_outbytes_left = outbytes_left;
90
0
      size_t position = out.position();
91
92
0
      if (iter == in.end())
93
0
      {
94
0
        std::lock_guard<std::mutex> lock(mutex);
95
0
        stat = apr_xlate_conv_buffer(convset, NULL, NULL,
96
0
            out.data() + position, &outbytes_left);
97
0
      }
98
0
      else
99
0
      {
100
0
        LogString::size_type inOffset = (iter - in.begin());
101
0
        apr_size_t inbytes_left =
102
0
          (in.size() - inOffset) * sizeof(LogString::value_type);
103
0
        apr_size_t initial_inbytes_left = inbytes_left;
104
0
        {
105
0
          std::lock_guard<std::mutex> lock(mutex);
106
0
          stat = apr_xlate_conv_buffer(convset,
107
0
              (const char*) (in.data() + inOffset),
108
0
              &inbytes_left,
109
0
              out.data() + position,
110
0
              &outbytes_left);
111
0
        }
112
0
        iter += ((initial_inbytes_left - inbytes_left) / sizeof(LogString::value_type));
113
0
      }
114
115
0
      out.increment_position((initial_outbytes_left - outbytes_left));
116
0
      return stat;
117
0
    }
Unexecuted instantiation: log4cxx::helpers::APRCharsetEncoder::encode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::__wrap_iter<char const*>&, log4cxx::helpers::ByteBuffer&)
Unexecuted instantiation: log4cxx::helpers::APRCharsetEncoder::encode(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::__wrap_iter<wchar_t const*>&, log4cxx::helpers::ByteBuffer&)
118
119
  private:
120
    APRCharsetEncoder(const APRCharsetEncoder&);
121
    APRCharsetEncoder& operator=(const APRCharsetEncoder&);
122
    Pool pool;
123
    std::mutex mutex;
124
    apr_xlate_t* convset;
125
};
126
#endif
127
128
#if LOG4CXX_LOGCHAR_IS_WCHAR && LOG4CXX_HAS_WCSTOMBS
129
/**
130
 *  A character encoder implemented using wcstombs.
131
*/
132
class WcstombsCharsetEncoder : public CharsetEncoder
133
{
134
  public:
135
    WcstombsCharsetEncoder()
136
0
    {
137
0
    }
138
139
    /**
140
     *   Converts a wchar_t to the default external multibyte encoding.
141
     */
142
    log4cxx_status_t encode(const LogString& in,
143
      LogString::const_iterator& iter,
144
      ByteBuffer& out)
145
0
    {
146
0
      log4cxx_status_t stat = APR_SUCCESS;
147
0
148
0
      if (iter != in.end())
149
0
      {
150
0
        size_t outbytes_left = out.remaining();
151
0
        size_t position = out.position();
152
0
        std::wstring::size_type inOffset = (iter - in.begin());
153
0
        enum { BUFSIZE = 256 };
154
0
        wchar_t buf[BUFSIZE];
155
0
        size_t chunkSize = BUFSIZE - 1;
156
0
157
0
        if (chunkSize * MB_LEN_MAX > outbytes_left)
158
0
        {
159
0
          chunkSize = outbytes_left / MB_LEN_MAX;
160
0
        }
161
0
162
0
        if (chunkSize > in.length() - inOffset)
163
0
        {
164
0
          chunkSize = in.length() - inOffset;
165
0
        }
166
0
167
0
        memset(buf, 0, BUFSIZE * sizeof(wchar_t));
168
0
        memcpy(buf,
169
0
          in.data() + inOffset,
170
0
          chunkSize * sizeof(wchar_t));
171
0
        size_t converted = wcstombs(out.data() + position, buf, outbytes_left);
172
0
173
0
        if (converted == (size_t) -1)
174
0
        {
175
0
          stat = APR_BADARG;
176
0
177
0
          //
178
0
          //   if unconvertable character was encountered
179
0
          //       repeatedly halve source to get fragment that
180
0
          //       can be converted
181
0
          for (chunkSize /= 2;
182
0
            chunkSize > 0;
183
0
            chunkSize /= 2)
184
0
          {
185
0
            buf[chunkSize] = 0;
186
0
            converted = wcstombs(out.data() + position, buf, outbytes_left);
187
0
188
0
            if (converted != (size_t) -1)
189
0
            {
190
0
              iter += chunkSize;
191
0
              out.increment_position(converted);
192
0
              break;
193
0
            }
194
0
          }
195
0
        }
196
0
        else
197
0
        {
198
0
          iter += chunkSize;
199
0
          out.increment_position(converted);
200
0
        }
201
0
      }
202
0
203
0
      return stat;
204
0
    }
205
206
207
208
  private:
209
    WcstombsCharsetEncoder(const WcstombsCharsetEncoder&);
210
    WcstombsCharsetEncoder& operator=(const WcstombsCharsetEncoder&);
211
};
212
#endif
213
214
215
/**
216
*   Encodes a LogString to US-ASCII.
217
*/
218
class USASCIICharsetEncoder : public CharsetEncoder
219
{
220
  public:
221
    USASCIICharsetEncoder()
222
494
    {
223
494
    }
224
225
    virtual log4cxx_status_t encode(const LogString& in,
226
      LogString::const_iterator& iter,
227
      ByteBuffer& out)
228
41.9k
    {
229
41.9k
      log4cxx_status_t stat = APR_SUCCESS;
230
231
41.9k
      if (iter != in.end())
232
41.9k
      {
233
2.40M
        while (out.remaining() > 0 && iter != in.end())
234
2.38M
        {
235
2.38M
          LogString::const_iterator prev(iter);
236
2.38M
          unsigned int sv = Transcoder::decode(in, iter);
237
238
2.38M
          if (sv <= 0x7F)
239
2.36M
          {
240
2.36M
            out.put((char) sv);
241
2.36M
          }
242
25.5k
          else
243
25.5k
          {
244
25.5k
            iter = prev;
245
25.5k
            stat = APR_BADARG;
246
25.5k
            break;
247
25.5k
          }
248
2.38M
        }
249
41.9k
      }
250
251
41.9k
      return stat;
252
41.9k
    }
log4cxx::helpers::USASCIICharsetEncoder::encode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::__wrap_iter<char const*>&, log4cxx::helpers::ByteBuffer&)
Line
Count
Source
228
27.0k
    {
229
27.0k
      log4cxx_status_t stat = APR_SUCCESS;
230
231
27.0k
      if (iter != in.end())
232
27.0k
      {
233
1.03M
        while (out.remaining() > 0 && iter != in.end())
234
1.02M
        {
235
1.02M
          LogString::const_iterator prev(iter);
236
1.02M
          unsigned int sv = Transcoder::decode(in, iter);
237
238
1.02M
          if (sv <= 0x7F)
239
1.00M
          {
240
1.00M
            out.put((char) sv);
241
1.00M
          }
242
20.4k
          else
243
20.4k
          {
244
20.4k
            iter = prev;
245
20.4k
            stat = APR_BADARG;
246
20.4k
            break;
247
20.4k
          }
248
1.02M
        }
249
27.0k
      }
250
251
27.0k
      return stat;
252
27.0k
    }
log4cxx::helpers::USASCIICharsetEncoder::encode(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::__wrap_iter<wchar_t const*>&, log4cxx::helpers::ByteBuffer&)
Line
Count
Source
228
14.8k
    {
229
14.8k
      log4cxx_status_t stat = APR_SUCCESS;
230
231
14.8k
      if (iter != in.end())
232
14.8k
      {
233
1.36M
        while (out.remaining() > 0 && iter != in.end())
234
1.36M
        {
235
1.36M
          LogString::const_iterator prev(iter);
236
1.36M
          unsigned int sv = Transcoder::decode(in, iter);
237
238
1.36M
          if (sv <= 0x7F)
239
1.35M
          {
240
1.35M
            out.put((char) sv);
241
1.35M
          }
242
5.16k
          else
243
5.16k
          {
244
5.16k
            iter = prev;
245
5.16k
            stat = APR_BADARG;
246
5.16k
            break;
247
5.16k
          }
248
1.36M
        }
249
14.8k
      }
250
251
14.8k
      return stat;
252
14.8k
    }
253
254
  private:
255
    USASCIICharsetEncoder(const USASCIICharsetEncoder&);
256
    USASCIICharsetEncoder& operator=(const USASCIICharsetEncoder&);
257
};
258
259
/**
260
*   Converts a LogString to ISO-8859-1.
261
*/
262
class ISOLatinCharsetEncoder : public CharsetEncoder
263
{
264
  public:
265
    ISOLatinCharsetEncoder()
266
469
    {
267
469
    }
268
269
    virtual log4cxx_status_t encode(const LogString& in,
270
      LogString::const_iterator& iter,
271
      ByteBuffer& out)
272
64.8k
    {
273
64.8k
      log4cxx_status_t stat = APR_SUCCESS;
274
275
64.8k
      if (iter != in.end())
276
64.8k
      {
277
2.02M
        while (out.remaining() > 0 && iter != in.end())
278
2.01M
        {
279
2.01M
          LogString::const_iterator prev(iter);
280
2.01M
          unsigned int sv = Transcoder::decode(in, iter);
281
282
2.01M
          if (sv <= 0xFF)
283
1.96M
          {
284
1.96M
            out.put((char) sv);
285
1.96M
          }
286
52.9k
          else
287
52.9k
          {
288
52.9k
            iter = prev;
289
52.9k
            stat = APR_BADARG;
290
52.9k
            break;
291
52.9k
          }
292
2.01M
        }
293
64.8k
      }
294
295
64.8k
      return stat;
296
64.8k
    }
log4cxx::helpers::ISOLatinCharsetEncoder::encode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::__wrap_iter<char const*>&, log4cxx::helpers::ByteBuffer&)
Line
Count
Source
272
51.5k
    {
273
51.5k
      log4cxx_status_t stat = APR_SUCCESS;
274
275
51.5k
      if (iter != in.end())
276
51.5k
      {
277
781k
        while (out.remaining() > 0 && iter != in.end())
278
778k
        {
279
778k
          LogString::const_iterator prev(iter);
280
778k
          unsigned int sv = Transcoder::decode(in, iter);
281
282
778k
          if (sv <= 0xFF)
283
729k
          {
284
729k
            out.put((char) sv);
285
729k
          }
286
48.8k
          else
287
48.8k
          {
288
48.8k
            iter = prev;
289
48.8k
            stat = APR_BADARG;
290
48.8k
            break;
291
48.8k
          }
292
778k
        }
293
51.5k
      }
294
295
51.5k
      return stat;
296
51.5k
    }
log4cxx::helpers::ISOLatinCharsetEncoder::encode(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::__wrap_iter<wchar_t const*>&, log4cxx::helpers::ByteBuffer&)
Line
Count
Source
272
13.3k
    {
273
13.3k
      log4cxx_status_t stat = APR_SUCCESS;
274
275
13.3k
      if (iter != in.end())
276
13.3k
      {
277
1.24M
        while (out.remaining() > 0 && iter != in.end())
278
1.23M
        {
279
1.23M
          LogString::const_iterator prev(iter);
280
1.23M
          unsigned int sv = Transcoder::decode(in, iter);
281
282
1.23M
          if (sv <= 0xFF)
283
1.23M
          {
284
1.23M
            out.put((char) sv);
285
1.23M
          }
286
4.08k
          else
287
4.08k
          {
288
4.08k
            iter = prev;
289
4.08k
            stat = APR_BADARG;
290
4.08k
            break;
291
4.08k
          }
292
1.23M
        }
293
13.3k
      }
294
295
13.3k
      return stat;
296
13.3k
    }
297
298
  private:
299
    ISOLatinCharsetEncoder(const ISOLatinCharsetEncoder&);
300
    ISOLatinCharsetEncoder& operator=(const ISOLatinCharsetEncoder&);
301
};
302
303
/**
304
*   Encodes a LogString to a byte array when the encodings are identical.
305
*/
306
class TrivialCharsetEncoder : public CharsetEncoder
307
{
308
  public:
309
    TrivialCharsetEncoder()
310
138
    {
311
138
    }
312
313
314
    virtual log4cxx_status_t encode(const LogString& in,
315
      LogString::const_iterator& iter,
316
      ByteBuffer& out)
317
11.7k
    {
318
11.7k
      if (iter != in.end())
319
11.7k
      {
320
11.7k
        size_t requested = in.length() - (iter - in.begin());
321
322
11.7k
        if (requested > out.remaining() / sizeof(logchar))
323
11.6k
        {
324
11.6k
          requested = out.remaining() / sizeof(logchar);
325
11.6k
        }
326
327
11.7k
        memcpy(out.current(),
328
11.7k
          (const char*) in.data() + (iter - in.begin()),
329
11.7k
          requested * sizeof(logchar));
330
11.7k
        iter += requested;
331
11.7k
        out.increment_position(requested * sizeof(logchar));
332
11.7k
      }
333
334
11.7k
      return APR_SUCCESS;
335
11.7k
    }
log4cxx::helpers::TrivialCharsetEncoder::encode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::__wrap_iter<char const*>&, log4cxx::helpers::ByteBuffer&)
Line
Count
Source
317
11.7k
    {
318
11.7k
      if (iter != in.end())
319
11.7k
      {
320
11.7k
        size_t requested = in.length() - (iter - in.begin());
321
322
11.7k
        if (requested > out.remaining() / sizeof(logchar))
323
11.6k
        {
324
11.6k
          requested = out.remaining() / sizeof(logchar);
325
11.6k
        }
326
327
11.7k
        memcpy(out.current(),
328
11.7k
          (const char*) in.data() + (iter - in.begin()),
329
11.7k
          requested * sizeof(logchar));
330
11.7k
        iter += requested;
331
11.7k
        out.increment_position(requested * sizeof(logchar));
332
11.7k
      }
333
334
11.7k
      return APR_SUCCESS;
335
11.7k
    }
Unexecuted instantiation: log4cxx::helpers::TrivialCharsetEncoder::encode(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::__wrap_iter<wchar_t const*>&, log4cxx::helpers::ByteBuffer&)
336
337
  private:
338
    TrivialCharsetEncoder(const TrivialCharsetEncoder&);
339
    TrivialCharsetEncoder& operator=(const TrivialCharsetEncoder&);
340
};
341
342
#if LOG4CXX_LOGCHAR_IS_UTF8
343
typedef TrivialCharsetEncoder UTF8CharsetEncoder;
344
#else
345
/**
346
 *  Converts a LogString to UTF-8.
347
 */
348
class UTF8CharsetEncoder : public CharsetEncoder
349
{
350
  public:
351
    UTF8CharsetEncoder()
352
281
    {
353
281
    }
354
355
    virtual log4cxx_status_t encode(const LogString& in,
356
      LogString::const_iterator& iter,
357
      ByteBuffer& out)
358
149k
    {
359
97.4M
      while (iter != in.end() && out.remaining() >= 8)
360
97.3M
      {
361
97.3M
        unsigned int sv = Transcoder::decode(in, iter);
362
363
97.3M
        if (sv == 0xFFFF)
364
0
        {
365
0
          return APR_BADARG;
366
0
        }
367
368
97.3M
        Transcoder::encodeUTF8(sv, out);
369
97.3M
      }
370
371
149k
      return APR_SUCCESS;
372
149k
    }
373
374
  private:
375
    UTF8CharsetEncoder(const UTF8CharsetEncoder&);
376
    UTF8CharsetEncoder& operator=(const UTF8CharsetEncoder&);
377
};
378
#endif
379
380
/**
381
 *   Encodes a LogString to UTF16-BE.
382
 */
383
class UTF16BECharsetEncoder : public CharsetEncoder
384
{
385
  public:
386
    UTF16BECharsetEncoder()
387
411
    {
388
411
    }
389
390
    virtual log4cxx_status_t encode(const LogString& in,
391
      LogString::const_iterator& iter,
392
      ByteBuffer& out)
393
18.9k
    {
394
1.18M
      while (iter != in.end() && out.remaining() >= 4)
395
1.16M
      {
396
1.16M
        unsigned int sv = Transcoder::decode(in, iter);
397
398
1.16M
        if (sv == 0xFFFF)
399
0
        {
400
0
          return APR_BADARG;
401
0
        }
402
403
1.16M
        Transcoder::encodeUTF16BE(sv, out);
404
1.16M
      }
405
406
18.9k
      return APR_SUCCESS;
407
18.9k
    }
log4cxx::helpers::UTF16BECharsetEncoder::encode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::__wrap_iter<char const*>&, log4cxx::helpers::ByteBuffer&)
Line
Count
Source
393
8.06k
    {
394
502k
      while (iter != in.end() && out.remaining() >= 4)
395
494k
      {
396
494k
        unsigned int sv = Transcoder::decode(in, iter);
397
398
494k
        if (sv == 0xFFFF)
399
0
        {
400
0
          return APR_BADARG;
401
0
        }
402
403
494k
        Transcoder::encodeUTF16BE(sv, out);
404
494k
      }
405
406
8.06k
      return APR_SUCCESS;
407
8.06k
    }
log4cxx::helpers::UTF16BECharsetEncoder::encode(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::__wrap_iter<wchar_t const*>&, log4cxx::helpers::ByteBuffer&)
Line
Count
Source
393
10.8k
    {
394
682k
      while (iter != in.end() && out.remaining() >= 4)
395
671k
      {
396
671k
        unsigned int sv = Transcoder::decode(in, iter);
397
398
671k
        if (sv == 0xFFFF)
399
0
        {
400
0
          return APR_BADARG;
401
0
        }
402
403
671k
        Transcoder::encodeUTF16BE(sv, out);
404
671k
      }
405
406
10.8k
      return APR_SUCCESS;
407
10.8k
    }
408
409
  private:
410
    UTF16BECharsetEncoder(const UTF16BECharsetEncoder&);
411
    UTF16BECharsetEncoder& operator=(const UTF16BECharsetEncoder&);
412
};
413
414
/**
415
 *   Encodes a LogString to UTF16-LE.
416
 */
417
class UTF16LECharsetEncoder : public CharsetEncoder
418
{
419
  public:
420
    UTF16LECharsetEncoder()
421
403
    {
422
403
    }
423
424
425
    virtual log4cxx_status_t encode(const LogString& in,
426
      LogString::const_iterator& iter,
427
      ByteBuffer& out)
428
33.4k
    {
429
2.12M
      while (iter != in.end() && out.remaining() >= 4)
430
2.08M
      {
431
2.08M
        unsigned int sv = Transcoder::decode(in, iter);
432
433
2.08M
        if (sv == 0xFFFF)
434
0
        {
435
0
          return APR_BADARG;
436
0
        }
437
438
2.08M
        Transcoder::encodeUTF16LE(sv, out);
439
2.08M
      }
440
441
33.4k
      return APR_SUCCESS;
442
33.4k
    }
log4cxx::helpers::UTF16LECharsetEncoder::encode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::__wrap_iter<char const*>&, log4cxx::helpers::ByteBuffer&)
Line
Count
Source
428
20.7k
    {
429
1.31M
      while (iter != in.end() && out.remaining() >= 4)
430
1.29M
      {
431
1.29M
        unsigned int sv = Transcoder::decode(in, iter);
432
433
1.29M
        if (sv == 0xFFFF)
434
0
        {
435
0
          return APR_BADARG;
436
0
        }
437
438
1.29M
        Transcoder::encodeUTF16LE(sv, out);
439
1.29M
      }
440
441
20.7k
      return APR_SUCCESS;
442
20.7k
    }
log4cxx::helpers::UTF16LECharsetEncoder::encode(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::__wrap_iter<wchar_t const*>&, log4cxx::helpers::ByteBuffer&)
Line
Count
Source
428
12.7k
    {
429
805k
      while (iter != in.end() && out.remaining() >= 4)
430
792k
      {
431
792k
        unsigned int sv = Transcoder::decode(in, iter);
432
433
792k
        if (sv == 0xFFFF)
434
0
        {
435
0
          return APR_BADARG;
436
0
        }
437
438
792k
        Transcoder::encodeUTF16LE(sv, out);
439
792k
      }
440
441
12.7k
      return APR_SUCCESS;
442
12.7k
    }
443
  private:
444
    UTF16LECharsetEncoder(const UTF16LECharsetEncoder&);
445
    UTF16LECharsetEncoder& operator=(const UTF16LECharsetEncoder&);
446
};
447
448
/**
449
 *    Charset encoder that uses current locale settings.
450
 */
451
class LocaleCharsetEncoder : public CharsetEncoder
452
{
453
  public:
454
0
    LocaleCharsetEncoder() : state()
455
0
    {
456
0
    }
457
    log4cxx_status_t encode
458
      ( const LogString&           in
459
      , LogString::const_iterator& nextCodePoint
460
      , ByteBuffer&                out
461
      ) override
462
0
    {
463
0
      log4cxx_status_t result = APR_SUCCESS;
464
0
#if !LOG4CXX_CHARSET_EBCDIC
465
0
      char* current = out.current();
466
0
      size_t availableByteCount = out.remaining();
467
0
      size_t byteCount = 0;
468
0
      if (std::mbsinit(&this->state)) // ByteBuffer not partially encoded?
469
0
      {
470
        // Copy single byte characters
471
0
        for (;
472
0
          nextCodePoint != in.end() && byteCount < availableByteCount && static_cast<unsigned int>(*nextCodePoint) < 0x80;
473
0
          ++nextCodePoint, ++byteCount, ++current)
474
0
        {
475
0
          *current = static_cast<char>(*nextCodePoint);
476
0
        }
477
0
      }
478
0
#endif
479
      // Encode characters that may require multiple bytes
480
0
      while (nextCodePoint != in.end() && byteCount < availableByteCount && MB_CUR_MAX <= (availableByteCount - byteCount))
481
0
      {
482
0
        LogString::const_iterator lastCodePoint = nextCodePoint;
483
0
        auto ch = Transcoder::decode(in, nextCodePoint);
484
0
        if (nextCodePoint == lastCodePoint) // invalid input sequence?
485
0
          nextCodePoint = in.end();
486
0
        auto n = std::wcrtomb(current, ch, &this->state);
487
0
        if (static_cast<std::size_t>(-1) == n) // not a valid wide character?
488
0
        {
489
0
          result = APR_BADARG;
490
0
          break;
491
0
        }
492
0
        byteCount += n;
493
0
        current += n;
494
0
      }
495
0
      out.increment_position(byteCount);
496
0
      return result;
497
0
    }
Unexecuted instantiation: log4cxx::helpers::LocaleCharsetEncoder::encode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::__wrap_iter<char const*>&, log4cxx::helpers::ByteBuffer&)
Unexecuted instantiation: log4cxx::helpers::LocaleCharsetEncoder::encode(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::__wrap_iter<wchar_t const*>&, log4cxx::helpers::ByteBuffer&)
498
499
  private:
500
    std::mbstate_t state;
501
};
502
503
504
} // namespace helpers
505
506
}  //namespace log4cxx
507
508
509
510
CharsetEncoder::CharsetEncoder()
511
2.19k
{
512
2.19k
}
513
514
CharsetEncoder::~CharsetEncoder()
515
2.19k
{
516
2.19k
}
517
518
CharsetEncoderPtr CharsetEncoder::getDefaultEncoder()
519
2.73k
{
520
2.73k
  static WideLife<CharsetEncoderPtr> encoder(createDefaultEncoder());
521
522
  //
523
  //  if invoked after static variable destruction
524
  //     (if logging is called in the destructor of a static object)
525
  //     then create a new decoder.
526
  //
527
2.73k
  if (encoder.value() == 0)
528
0
  {
529
0
    return CharsetEncoderPtr( createDefaultEncoder() );
530
0
  }
531
532
2.73k
  return encoder;
533
2.73k
}
534
535
CharsetEncoder* CharsetEncoder::createDefaultEncoder()
536
7
{
537
7
#if LOG4CXX_CHARSET_UTF8
538
7
  return new UTF8CharsetEncoder();
539
#elif LOG4CXX_CHARSET_ISO88591
540
  return new ISOLatinCharsetEncoder();
541
#elif LOG4CXX_CHARSET_USASCII
542
  return new USASCIICharsetEncoder();
543
#elif LOG4CXX_LOGCHAR_IS_WCHAR && LOG4CXX_HAS_WCSTOMBS
544
  return new WcstombsCharsetEncoder();
545
#else
546
  return new LocaleCharsetEncoder();
547
#endif
548
7
}
549
550
551
CharsetEncoderPtr CharsetEncoder::getUTF8Encoder()
552
0
{
553
0
  return std::make_shared<UTF8CharsetEncoder>();
554
0
}
555
556
557
558
CharsetEncoderPtr CharsetEncoder::getEncoder(const LogString& charset)
559
2.18k
{
560
2.18k
  if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-8"), LOG4CXX_STR("utf-8"))
561
1.77k
    || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP65001"), LOG4CXX_STR("cp65001")))
562
412
  {
563
412
    return std::make_shared<UTF8CharsetEncoder>();
564
412
  }
565
1.77k
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("C"), LOG4CXX_STR("c")) ||
566
1.77k
    charset == LOG4CXX_STR("646") ||
567
1.77k
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("US-ASCII"), LOG4CXX_STR("us-ascii")) ||
568
1.28k
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO646-US"), LOG4CXX_STR("iso646-US")) ||
569
1.28k
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ANSI_X3.4-1968"), LOG4CXX_STR("ansi_x3.4-1968")) ||
570
1.28k
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP20127"), LOG4CXX_STR("cp20127")))
571
494
  {
572
494
    return std::make_shared<USASCIICharsetEncoder>();
573
494
  }
574
1.28k
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-8859-1"), LOG4CXX_STR("iso-8859-1")) ||
575
814
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-LATIN-1"), LOG4CXX_STR("iso-latin-1")) ||
576
814
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP1252"), LOG4CXX_STR("cp1252")))
577
469
  {
578
469
    return std::make_shared<ISOLatinCharsetEncoder>();
579
469
  }
580
814
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16BE"), LOG4CXX_STR("utf-16be"))
581
403
    || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16"), LOG4CXX_STR("utf-16"))
582
403
    || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP1200"), LOG4CXX_STR("cp1200")))
583
411
  {
584
411
    return std::make_shared<UTF16BECharsetEncoder>();
585
411
  }
586
403
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16LE"), LOG4CXX_STR("utf-16le")))
587
403
  {
588
403
    return std::make_shared<UTF16LECharsetEncoder>();
589
403
  }
590
0
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("LOCALE"), LOG4CXX_STR("locale")))
591
0
  {
592
0
    return std::make_shared<LocaleCharsetEncoder>();
593
0
  }
594
595
0
#if APR_HAS_XLATE
596
0
  return std::make_shared<APRCharsetEncoder>(charset);
597
#else
598
  throw IllegalArgumentException(charset);
599
#endif
600
2.18k
}
log4cxx::helpers::CharsetEncoder::getEncoder(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
559
1.02k
{
560
1.02k
  if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-8"), LOG4CXX_STR("utf-8"))
561
890
    || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP65001"), LOG4CXX_STR("cp65001")))
562
137
  {
563
137
    return std::make_shared<UTF8CharsetEncoder>();
564
137
  }
565
890
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("C"), LOG4CXX_STR("c")) ||
566
890
    charset == LOG4CXX_STR("646") ||
567
890
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("US-ASCII"), LOG4CXX_STR("us-ascii")) ||
568
647
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO646-US"), LOG4CXX_STR("iso646-US")) ||
569
647
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ANSI_X3.4-1968"), LOG4CXX_STR("ansi_x3.4-1968")) ||
570
647
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP20127"), LOG4CXX_STR("cp20127")))
571
243
  {
572
243
    return std::make_shared<USASCIICharsetEncoder>();
573
243
  }
574
647
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-8859-1"), LOG4CXX_STR("iso-8859-1")) ||
575
411
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-LATIN-1"), LOG4CXX_STR("iso-latin-1")) ||
576
411
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP1252"), LOG4CXX_STR("cp1252")))
577
236
  {
578
236
    return std::make_shared<ISOLatinCharsetEncoder>();
579
236
  }
580
411
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16BE"), LOG4CXX_STR("utf-16be"))
581
213
    || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16"), LOG4CXX_STR("utf-16"))
582
213
    || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP1200"), LOG4CXX_STR("cp1200")))
583
198
  {
584
198
    return std::make_shared<UTF16BECharsetEncoder>();
585
198
  }
586
213
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16LE"), LOG4CXX_STR("utf-16le")))
587
213
  {
588
213
    return std::make_shared<UTF16LECharsetEncoder>();
589
213
  }
590
0
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("LOCALE"), LOG4CXX_STR("locale")))
591
0
  {
592
0
    return std::make_shared<LocaleCharsetEncoder>();
593
0
  }
594
595
0
#if APR_HAS_XLATE
596
0
  return std::make_shared<APRCharsetEncoder>(charset);
597
#else
598
  throw IllegalArgumentException(charset);
599
#endif
600
1.02k
}
log4cxx::helpers::CharsetEncoder::getEncoder(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
Line
Count
Source
559
1.16k
{
560
1.16k
  if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-8"), LOG4CXX_STR("utf-8"))
561
887
    || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP65001"), LOG4CXX_STR("cp65001")))
562
275
  {
563
275
    return std::make_shared<UTF8CharsetEncoder>();
564
275
  }
565
887
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("C"), LOG4CXX_STR("c")) ||
566
887
    charset == LOG4CXX_STR("646") ||
567
887
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("US-ASCII"), LOG4CXX_STR("us-ascii")) ||
568
636
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO646-US"), LOG4CXX_STR("iso646-US")) ||
569
636
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ANSI_X3.4-1968"), LOG4CXX_STR("ansi_x3.4-1968")) ||
570
636
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP20127"), LOG4CXX_STR("cp20127")))
571
251
  {
572
251
    return std::make_shared<USASCIICharsetEncoder>();
573
251
  }
574
636
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-8859-1"), LOG4CXX_STR("iso-8859-1")) ||
575
403
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("ISO-LATIN-1"), LOG4CXX_STR("iso-latin-1")) ||
576
403
    StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP1252"), LOG4CXX_STR("cp1252")))
577
233
  {
578
233
    return std::make_shared<ISOLatinCharsetEncoder>();
579
233
  }
580
403
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16BE"), LOG4CXX_STR("utf-16be"))
581
190
    || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16"), LOG4CXX_STR("utf-16"))
582
190
    || StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("CP1200"), LOG4CXX_STR("cp1200")))
583
213
  {
584
213
    return std::make_shared<UTF16BECharsetEncoder>();
585
213
  }
586
190
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("UTF-16LE"), LOG4CXX_STR("utf-16le")))
587
190
  {
588
190
    return std::make_shared<UTF16LECharsetEncoder>();
589
190
  }
590
0
  else if (StringHelper::equalsIgnoreCase(charset, LOG4CXX_STR("LOCALE"), LOG4CXX_STR("locale")))
591
0
  {
592
0
    return std::make_shared<LocaleCharsetEncoder>();
593
0
  }
594
595
0
#if APR_HAS_XLATE
596
0
  return std::make_shared<APRCharsetEncoder>(charset);
597
#else
598
  throw IllegalArgumentException(charset);
599
#endif
600
1.16k
}
601
602
603
void CharsetEncoder::reset()
604
8.97k
{
605
8.97k
}
606
607
void CharsetEncoder::flush(ByteBuffer& /* out */ )
608
11.1k
{
609
11.1k
}
610
611
612
void CharsetEncoder::encode(CharsetEncoderPtr& enc,
613
  const LogString& src,
614
  LogString::const_iterator& iter,
615
  ByteBuffer& dst)
616
105k
{
617
105k
  log4cxx_status_t stat = enc->encode(src, iter, dst);
618
619
105k
  if (stat != APR_SUCCESS && iter != src.end())
620
0
  {
621
#if LOG4CXX_LOGCHAR_IS_WCHAR || LOG4CXX_LOGCHAR_IS_UNICHAR
622
    iter++;
623
#elif LOG4CXX_LOGCHAR_IS_UTF8
624
625
    //  advance past this character and all continuation characters
626
    do
627
0
    {
628
0
      ++iter;
629
0
    }
630
0
    while (iter != src.end() &&
631
0
         (*iter & 0xC0) == 0x80);
632
633
#else
634
#error logchar is unrecognized
635
#endif
636
0
    dst.put(Transcoder::LOSSCHAR);
637
0
  }
638
105k
}
Unexecuted instantiation: log4cxx::helpers::CharsetEncoder::encode(std::__1::shared_ptr<log4cxx::helpers::CharsetEncoder>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::__wrap_iter<char const*>&, log4cxx::helpers::ByteBuffer&)
log4cxx::helpers::CharsetEncoder::encode(std::__1::shared_ptr<log4cxx::helpers::CharsetEncoder>&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::__wrap_iter<wchar_t const*>&, log4cxx::helpers::ByteBuffer&)
Line
Count
Source
616
105k
{
617
105k
  log4cxx_status_t stat = enc->encode(src, iter, dst);
618
619
105k
  if (stat != APR_SUCCESS && iter != src.end())
620
0
  {
621
0
#if LOG4CXX_LOGCHAR_IS_WCHAR || LOG4CXX_LOGCHAR_IS_UNICHAR
622
0
    iter++;
623
#elif LOG4CXX_LOGCHAR_IS_UTF8
624
625
    //  advance past this character and all continuation characters
626
    do
627
    {
628
      ++iter;
629
    }
630
    while (iter != src.end() &&
631
         (*iter & 0xC0) == 0x80);
632
633
#else
634
#error logchar is unrecognized
635
#endif
636
0
    dst.put(Transcoder::LOSSCHAR);
637
0
  }
638
105k
}
639
640
bool CharsetEncoder::isTriviallyCopyable(const LogString& src, const CharsetEncoderPtr& enc)
641
13.5k
{
642
13.5k
  bool result;
643
13.5k
#if !LOG4CXX_CHARSET_EBCDIC
644
13.5k
  if (dynamic_cast<LocaleCharsetEncoder*>(enc.get()))
645
0
  {
646
0
    result = src.end() == std::find_if(src.begin(), src.end()
647
0
      , [](const logchar& ch) -> bool { return 0x80 <= (unsigned int)ch; });
Unexecuted instantiation: charsetencoder.cpp:log4cxx::helpers::CharsetEncoder::isTriviallyCopyable(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::shared_ptr<log4cxx::helpers::CharsetEncoder> const&)::$_0::operator()(char const&) const
Unexecuted instantiation: charsetencoder.cpp:log4cxx::helpers::CharsetEncoder::isTriviallyCopyable(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::shared_ptr<log4cxx::helpers::CharsetEncoder> const&)::$_0::operator()(wchar_t const&) const
648
0
  }
649
13.5k
  else
650
13.5k
#endif
651
13.5k
    result = !!dynamic_cast<TrivialCharsetEncoder*>(enc.get());
652
13.5k
  return result;
653
13.5k
}
log4cxx::helpers::CharsetEncoder::isTriviallyCopyable(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::shared_ptr<log4cxx::helpers::CharsetEncoder> const&)
Line
Count
Source
641
4.61k
{
642
4.61k
  bool result;
643
4.61k
#if !LOG4CXX_CHARSET_EBCDIC
644
4.61k
  if (dynamic_cast<LocaleCharsetEncoder*>(enc.get()))
645
0
  {
646
0
    result = src.end() == std::find_if(src.begin(), src.end()
647
0
      , [](const logchar& ch) -> bool { return 0x80 <= (unsigned int)ch; });
648
0
  }
649
4.61k
  else
650
4.61k
#endif
651
4.61k
    result = !!dynamic_cast<TrivialCharsetEncoder*>(enc.get());
652
4.61k
  return result;
653
4.61k
}
log4cxx::helpers::CharsetEncoder::isTriviallyCopyable(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::shared_ptr<log4cxx::helpers::CharsetEncoder> const&)
Line
Count
Source
641
8.97k
{
642
8.97k
  bool result;
643
8.97k
#if !LOG4CXX_CHARSET_EBCDIC
644
8.97k
  if (dynamic_cast<LocaleCharsetEncoder*>(enc.get()))
645
0
  {
646
0
    result = src.end() == std::find_if(src.begin(), src.end()
647
0
      , [](const logchar& ch) -> bool { return 0x80 <= (unsigned int)ch; });
648
0
  }
649
8.97k
  else
650
8.97k
#endif
651
8.97k
    result = !!dynamic_cast<TrivialCharsetEncoder*>(enc.get());
652
8.97k
  return result;
653
8.97k
}