Coverage Report

Created: 2026-05-30 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/stringhelper.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
#define __STDC_CONSTANT_MACROS
19
#include <log4cxx/logstring.h>
20
#include <log4cxx/helpers/stringhelper.h>
21
#include <log4cxx/helpers/transcoder.h>
22
#include <algorithm>
23
#include <vector>
24
#include <iterator>
25
#include <algorithm>
26
#include <cctype>
27
28
using namespace LOG4CXX_NS;
29
using namespace LOG4CXX_NS::helpers;
30
31
bool StringHelper::equalsIgnoreCase(const LogString& s1, const logchar* upper, const logchar* lower)
32
0
{
33
0
  for (const auto& item : s1)
34
0
  {
35
0
    if (0 == item || // OSS-Fuzz makes strings with embedded NUL characters
36
0
      (item != *upper && item != *lower))
37
0
    {
38
0
      return false;
39
0
    }
40
0
    ++upper;
41
0
    ++lower;
42
0
  }
43
44
0
  return 0 == *upper;
45
0
}
46
47
bool StringHelper::equalsIgnoreCase(const LogString& s1, const LogString& upper, const LogString& lower)
48
0
{
49
0
  LogString::const_iterator u = upper.begin();
50
0
  LogString::const_iterator l = lower.begin();
51
0
  LogString::const_iterator iter = s1.begin();
52
53
0
  for (;
54
0
    iter != s1.end() && u != upper.end() && l != lower.end();
55
0
    iter++, u++, l++)
56
0
  {
57
0
    if (*iter != *u && *iter != *l)
58
0
    {
59
0
      return false;
60
0
    }
61
0
  }
62
63
0
  return u == upper.end() && iter == s1.end();
64
0
}
65
66
67
68
LogString StringHelper::toLowerCase(const LogString& s)
69
114
{
70
  // Fold ASCII A-Z only. Passing a value not representable as unsigned char
71
  // (or EOF) to std::tolower(int) is undefined behaviour; with signed char,
72
  // any byte > 0x7F sign-extends to a negative int. The previous implementation
73
  // also produced locale-dependent output for the same input, which is wrong
74
  // for the callers (class names, color names, column names — all ASCII).
75
114
  LogString d;
76
114
  d.reserve(s.size());
77
114
  for (auto ch : s)
78
1.89k
  {
79
1.89k
    if (ch >= static_cast<logchar>('A') && ch <= static_cast<logchar>('Z'))
80
333
      d.push_back(static_cast<logchar>(ch + ('a' - 'A')));
81
1.56k
    else
82
1.56k
      d.push_back(ch);
83
1.89k
  }
84
114
  return d;
85
114
}
86
87
LogString StringHelper::trim(const LogString& s)
88
0
{
89
0
  LogString::size_type pos = s.find_first_not_of(' ');
90
91
0
  if (pos == std::string::npos)
92
0
  {
93
0
    return LogString();
94
0
  }
95
96
0
  LogString::size_type n = s.find_last_not_of(' ') - pos + 1;
97
0
  return s.substr(pos, n);
98
0
}
99
100
bool StringHelper::startsWith(const LogString& s, const LogString& prefix)
101
0
{
102
0
  if (s.length() < prefix.length())
103
0
  {
104
0
    return false;
105
0
  }
106
107
0
  return s.compare(0, prefix.length(), prefix) == 0;
108
0
}
109
110
bool StringHelper::endsWith(const LogString& s, const LogString& suffix)
111
0
{
112
0
  if (suffix.length() <= s.length())
113
0
  {
114
0
    return s.compare(s.length() - suffix.length(), suffix.length(), suffix) == 0;
115
0
  }
116
117
0
  return false;
118
0
}
119
120
121
int StringHelper::toInt(const LogString& s)
122
0
{
123
#if LOG4CXX_LOGCHAR_IS_UNICHAR
124
  std::string as;
125
  Transcoder::encode(s, as);
126
  return std::stoi(as);
127
#else
128
0
  return std::stoi(s);
129
0
#endif
130
0
}
131
132
int64_t StringHelper::toInt64(const LogString& s)
133
0
{
134
#if LOG4CXX_LOGCHAR_IS_UNICHAR
135
  std::string as;
136
  Transcoder::encode(s, as);
137
  return std::stoll(as);
138
#else
139
0
  return std::stoll(s);
140
0
#endif
141
0
}
142
143
void StringHelper::toString(int n, LogString& dst)
144
0
{
145
0
#if LOG4CXX_LOGCHAR_IS_WCHAR
146
0
  dst.append(std::to_wstring(n));
147
#elif LOG4CXX_LOGCHAR_IS_UTF8
148
  dst.append(std::to_string(n));
149
#else
150
  Transcoder::decode(std::to_string(n), dst);
151
#endif
152
0
}
153
154
void StringHelper::toString(bool val, LogString& dst)
155
0
{
156
0
  if (val)
157
0
  {
158
0
    dst.append(LOG4CXX_STR("true"));
159
0
  }
160
0
  else
161
0
  {
162
0
    dst.append(LOG4CXX_STR("false"));
163
0
  }
164
0
}
165
166
167
void StringHelper::toString(int64_t n, LogString& dst)
168
0
{
169
0
#if LOG4CXX_LOGCHAR_IS_WCHAR
170
0
  dst.append(std::to_wstring(n));
171
#elif LOG4CXX_LOGCHAR_IS_UTF8
172
  dst.append(std::to_string(n));
173
#else
174
  Transcoder::decode(std::to_string(n), dst);
175
#endif
176
0
}
177
178
179
void StringHelper::toString(size_t n, LogString& dst)
180
0
{
181
0
#if LOG4CXX_LOGCHAR_IS_WCHAR
182
0
  dst.append(std::to_wstring(n));
183
#elif LOG4CXX_LOGCHAR_IS_UTF8
184
  dst.append(std::to_string(n));
185
#else
186
  Transcoder::decode(std::to_string(n), dst);
187
#endif
188
0
}
189
190
LogString StringHelper::format(const LogString& pattern, const std::vector<LogString>& params)
191
0
{
192
193
0
  LogString result;
194
0
  LogString::size_type i = 0;
195
196
0
  while (i < pattern.length())
197
0
  {
198
0
    if (i + 2 < pattern.length() &&
199
0
      pattern[i] == 0x7B /* '{' */ && pattern[i + 1] >= 0x30 /* '0' */ &&
200
0
      pattern[i + 1] <= 0x39 /* '9' */ && pattern[i + 2] == 0x7D /* '}' */)
201
0
    {
202
0
      LogString::size_type arg = pattern[i + 1] - 0x30 /* '0' */;
203
0
      if (arg < params.size())
204
0
      {
205
0
        result = result + params[arg];
206
0
        i += 3;
207
0
        continue;
208
0
      }
209
0
    }
210
0
    result = result + pattern[i];
211
0
    i++;
212
0
  }
213
214
0
  return result;
215
0
}
216
217
#if LOG4CXX_ABI_VERSION <= 15
218
0
void StringHelper::toString(int n, Pool& pool, LogString& dst) { toString(n, dst); }
219
0
void StringHelper::toString(int64_t n, Pool& pool, LogString& dst) { toString(n, dst); }
220
0
void StringHelper::toString(size_t n, Pool& pool, LogString& dst) { toString(n, dst); }
221
#endif