Coverage Report

Created: 2025-07-12 06:12

/src/logging-log4cxx/src/main/cpp/nameabbreviator.cpp
Line
Count
Source (jump to first uncovered line)
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/pattern/nameabbreviator.h>
19
#include <log4cxx/helpers/exception.h>
20
#include <log4cxx/helpers/stringhelper.h>
21
#include <log4cxx/helpers/loglog.h>
22
#include <vector>
23
#include <limits.h>
24
#include <stdexcept>
25
26
using namespace LOG4CXX_NS;
27
using namespace LOG4CXX_NS::pattern;
28
using namespace LOG4CXX_NS::helpers;
29
30
IMPLEMENT_LOG4CXX_OBJECT(NameAbbreviator)
31
32
NameAbbreviator::NameAbbreviator()
33
8.08k
{
34
8.08k
}
35
36
NameAbbreviator::~NameAbbreviator()
37
8.08k
{
38
8.08k
}
39
40
namespace LOG4CXX_NS
41
{
42
namespace pattern
43
{
44
/**
45
 * Abbreviator that simply appends full name to buffer.
46
 */
47
class NOPAbbreviator : public NameAbbreviator
48
{
49
  public:
50
    DECLARE_ABSTRACT_LOG4CXX_OBJECT(NOPAbbreviator)
51
0
    BEGIN_LOG4CXX_CAST_MAP()
52
0
    LOG4CXX_CAST_ENTRY(NOPAbbreviator)
53
0
    LOG4CXX_CAST_ENTRY_CHAIN(NameAbbreviator)
54
0
    END_LOG4CXX_CAST_MAP()
55
56
    /**
57
     * Constructor.
58
     */
59
    NOPAbbreviator()
60
4
    {
61
4
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66
    void abbreviate(LogString::size_type /* nameStart */, LogString& /* buf */) const override
67
48
    {
68
48
    }
log4cxx::pattern::NOPAbbreviator::abbreviate(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) const
Line
Count
Source
67
22
    {
68
22
    }
log4cxx::pattern::NOPAbbreviator::abbreviate(unsigned long, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&) const
Line
Count
Source
67
26
    {
68
26
    }
69
};
70
71
72
/**
73
 * Abbreviator that drops starting path elements.
74
 */
75
class MaxElementAbbreviator : public NameAbbreviator
76
{
77
    /**
78
     * Maximum number of path elements to output.
79
     */
80
    const int count;
81
82
  public:
83
    DECLARE_ABSTRACT_LOG4CXX_OBJECT(MaxElementAbbreviator)
84
0
    BEGIN_LOG4CXX_CAST_MAP()
85
0
    LOG4CXX_CAST_ENTRY(MaxElementAbbreviator)
86
0
    LOG4CXX_CAST_ENTRY_CHAIN(NameAbbreviator)
87
0
    END_LOG4CXX_CAST_MAP()
88
    /**
89
     * Create new instance.
90
     * @param count maximum number of path elements to output.
91
     */
92
3.73k
    MaxElementAbbreviator(const int count1) : count(count1)
93
3.73k
    {
94
3.73k
    }
95
96
    /**
97
     * Abbreviate name.
98
     * @param buf buffer to append abbreviation.
99
     * @param nameStart start of name to abbreviate.
100
     */
101
    void abbreviate(LogString::size_type nameStart, LogString& buf) const override
102
5.70k
    {
103
      // We substract 1 from 'len' when assigning to 'end' to avoid out of
104
      // bounds exception in return r.substring(end+1, len). This can happen if
105
      // precision is 1 and the logger name ends with a dot.
106
5.70k
      LogString::size_type end = buf.length() - 1;
107
108
13.4k
      for (LogString::size_type i = count; i > 0; i--)
109
7.95k
      {
110
7.95k
        end = buf.rfind(0x2E /* '.' */, end - 1);
111
112
7.95k
        if ((end == LogString::npos) || (end < nameStart))
113
249
        {
114
249
          return;
115
249
        }
116
7.95k
      }
117
118
5.45k
      buf.erase(buf.begin() + nameStart, buf.begin() + (end + 1));
119
5.45k
    }
log4cxx::pattern::MaxElementAbbreviator::abbreviate(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) const
Line
Count
Source
102
5.47k
    {
103
      // We substract 1 from 'len' when assigning to 'end' to avoid out of
104
      // bounds exception in return r.substring(end+1, len). This can happen if
105
      // precision is 1 and the logger name ends with a dot.
106
5.47k
      LogString::size_type end = buf.length() - 1;
107
108
12.0k
      for (LogString::size_type i = count; i > 0; i--)
109
6.65k
      {
110
6.65k
        end = buf.rfind(0x2E /* '.' */, end - 1);
111
112
6.65k
        if ((end == LogString::npos) || (end < nameStart))
113
122
        {
114
122
          return;
115
122
        }
116
6.65k
      }
117
118
5.35k
      buf.erase(buf.begin() + nameStart, buf.begin() + (end + 1));
119
5.35k
    }
log4cxx::pattern::MaxElementAbbreviator::abbreviate(unsigned long, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&) const
Line
Count
Source
102
228
    {
103
      // We substract 1 from 'len' when assigning to 'end' to avoid out of
104
      // bounds exception in return r.substring(end+1, len). This can happen if
105
      // precision is 1 and the logger name ends with a dot.
106
228
      LogString::size_type end = buf.length() - 1;
107
108
1.39k
      for (LogString::size_type i = count; i > 0; i--)
109
1.29k
      {
110
1.29k
        end = buf.rfind(0x2E /* '.' */, end - 1);
111
112
1.29k
        if ((end == LogString::npos) || (end < nameStart))
113
127
        {
114
127
          return;
115
127
        }
116
1.29k
      }
117
118
101
      buf.erase(buf.begin() + nameStart, buf.begin() + (end + 1));
119
101
    }
120
};
121
122
/**
123
 * Fragment of an pattern abbreviator.
124
 *
125
 */
126
class PatternAbbreviatorFragment
127
{
128
    /**
129
     * Count of initial characters of element to output.
130
     */
131
    LogString::size_type charCount;
132
133
    /**
134
     *  Character used to represent dropped characters.
135
     * '\0' indicates no representation of dropped characters.
136
     */
137
    logchar ellipsis;
138
139
  public:
140
    /**
141
     * Creates a PatternAbbreviatorFragment.
142
     * @param charCount number of initial characters to preserve.
143
     * @param ellipsis character to represent elimination of characters,
144
     *    '\0' if no ellipsis is desired.
145
     */
146
    PatternAbbreviatorFragment(
147
      const int charCount1, const logchar ellipsis1)
148
155k
      : charCount(charCount1), ellipsis(ellipsis1)
149
155k
    {
150
155k
    }
log4cxx::pattern::PatternAbbreviatorFragment::PatternAbbreviatorFragment(int, char)
Line
Count
Source
148
86.2k
      : charCount(charCount1), ellipsis(ellipsis1)
149
86.2k
    {
150
86.2k
    }
log4cxx::pattern::PatternAbbreviatorFragment::PatternAbbreviatorFragment(int, wchar_t)
Line
Count
Source
148
69.6k
      : charCount(charCount1), ellipsis(ellipsis1)
149
69.6k
    {
150
69.6k
    }
151
    PatternAbbreviatorFragment() : charCount(0), ellipsis(0)
152
0
    {
153
0
    }
154
155
    PatternAbbreviatorFragment(const PatternAbbreviatorFragment& src)
156
520k
      : charCount(src.charCount), ellipsis(src.ellipsis)
157
520k
    {
158
520k
    }
159
160
    PatternAbbreviatorFragment& operator=(const PatternAbbreviatorFragment& src)
161
0
    {
162
0
      charCount = src.charCount;
163
0
      ellipsis = src.ellipsis;
164
0
      return *this;
165
0
    }
166
167
    /**
168
     * Abbreviate element of name.
169
     * @param buf buffer to receive element.
170
     * @param startPos starting index of name element.
171
     * @return starting index of next element.
172
     */
173
    LogString::size_type abbreviate(LogString& buf, LogString::size_type startPos) const
174
109k
    {
175
109k
      LogString::size_type nextDot = buf.find(0x2E /* '.' */, startPos);
176
177
109k
      if (nextDot != LogString::npos)
178
109k
      {
179
109k
        if ((nextDot - startPos) > charCount)
180
82.6k
        {
181
82.6k
          buf.erase(buf.begin() + (startPos + charCount), buf.begin() + nextDot);
182
82.6k
          nextDot = startPos + charCount;
183
184
82.6k
          if (ellipsis != 0x00)
185
81.4k
          {
186
81.4k
            buf.insert(nextDot, 1, ellipsis);
187
81.4k
            nextDot++;
188
81.4k
          }
189
82.6k
        }
190
191
109k
        nextDot++;
192
109k
      }
193
194
109k
      return nextDot;
195
109k
    }
log4cxx::pattern::PatternAbbreviatorFragment::abbreviate(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long) const
Line
Count
Source
174
84.0k
    {
175
84.0k
      LogString::size_type nextDot = buf.find(0x2E /* '.' */, startPos);
176
177
84.0k
      if (nextDot != LogString::npos)
178
83.9k
      {
179
83.9k
        if ((nextDot - startPos) > charCount)
180
80.9k
        {
181
80.9k
          buf.erase(buf.begin() + (startPos + charCount), buf.begin() + nextDot);
182
80.9k
          nextDot = startPos + charCount;
183
184
80.9k
          if (ellipsis != 0x00)
185
80.7k
          {
186
80.7k
            buf.insert(nextDot, 1, ellipsis);
187
80.7k
            nextDot++;
188
80.7k
          }
189
80.9k
        }
190
191
83.9k
        nextDot++;
192
83.9k
      }
193
194
84.0k
      return nextDot;
195
84.0k
    }
log4cxx::pattern::PatternAbbreviatorFragment::abbreviate(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, unsigned long) const
Line
Count
Source
174
25.4k
    {
175
25.4k
      LogString::size_type nextDot = buf.find(0x2E /* '.' */, startPos);
176
177
25.4k
      if (nextDot != LogString::npos)
178
25.4k
      {
179
25.4k
        if ((nextDot - startPos) > charCount)
180
1.67k
        {
181
1.67k
          buf.erase(buf.begin() + (startPos + charCount), buf.begin() + nextDot);
182
1.67k
          nextDot = startPos + charCount;
183
184
1.67k
          if (ellipsis != 0x00)
185
777
          {
186
777
            buf.insert(nextDot, 1, ellipsis);
187
777
            nextDot++;
188
777
          }
189
1.67k
        }
190
191
25.4k
        nextDot++;
192
25.4k
      }
193
194
25.4k
      return nextDot;
195
25.4k
    }
196
};
197
198
/**
199
 * Pattern abbreviator.
200
 *
201
 *
202
 */
203
class PatternAbbreviator : public NameAbbreviator
204
{
205
    /**
206
     * Element abbreviation patterns.
207
     */
208
    std::vector<PatternAbbreviatorFragment> fragments;
209
210
  public:
211
    DECLARE_ABSTRACT_LOG4CXX_OBJECT(PatternAbbreviator)
212
0
    BEGIN_LOG4CXX_CAST_MAP()
213
0
    LOG4CXX_CAST_ENTRY(PatternAbbreviator)
214
0
    LOG4CXX_CAST_ENTRY_CHAIN(NameAbbreviator)
215
0
    END_LOG4CXX_CAST_MAP()
216
    /**
217
     * Create PatternAbbreviator.
218
     *
219
     * @param fragments element abbreviation patterns.
220
     */
221
    PatternAbbreviator(const std::vector<PatternAbbreviatorFragment>& fragments1) :
222
4.34k
      fragments(fragments1)
223
4.34k
    {
224
4.34k
      if (fragments1.size() == 0)
225
0
      {
226
0
        throw IllegalArgumentException(LOG4CXX_STR("fragments parameter must contain at least one element"));
227
0
      }
228
4.34k
    }
229
230
    /**
231
     * Abbreviate name.
232
     * @param buf buffer that abbreviated name is appended.
233
     * @param nameStart start of name.
234
     */
235
    void abbreviate(LogString::size_type nameStart, LogString& buf) const override
236
644
    {
237
      //
238
      //  all non-terminal patterns are executed once
239
      //
240
644
      LogString::size_type pos = nameStart;
241
242
4.99k
      for (LogString::size_type i = 0; (i < (fragments.size() - 1)) && (pos < buf.length());
243
4.34k
        i++)
244
4.34k
      {
245
4.34k
        pos = fragments[i].abbreviate(buf, pos);
246
4.34k
      }
247
248
      //
249
      //   last pattern in executed repeatedly
250
      //
251
644
      PatternAbbreviatorFragment terminalFragment =
252
644
        fragments[fragments.size() - 1];
253
254
105k
      while (pos < buf.length())
255
105k
      {
256
105k
        pos = terminalFragment.abbreviate(buf, pos);
257
105k
      }
258
644
    }
log4cxx::pattern::PatternAbbreviator::abbreviate(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) const
Line
Count
Source
236
322
    {
237
      //
238
      //  all non-terminal patterns are executed once
239
      //
240
322
      LogString::size_type pos = nameStart;
241
242
1.48k
      for (LogString::size_type i = 0; (i < (fragments.size() - 1)) && (pos < buf.length());
243
1.16k
        i++)
244
1.16k
      {
245
1.16k
        pos = fragments[i].abbreviate(buf, pos);
246
1.16k
      }
247
248
      //
249
      //   last pattern in executed repeatedly
250
      //
251
322
      PatternAbbreviatorFragment terminalFragment =
252
322
        fragments[fragments.size() - 1];
253
254
83.1k
      while (pos < buf.length())
255
82.8k
      {
256
82.8k
        pos = terminalFragment.abbreviate(buf, pos);
257
82.8k
      }
258
322
    }
log4cxx::pattern::PatternAbbreviator::abbreviate(unsigned long, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&) const
Line
Count
Source
236
322
    {
237
      //
238
      //  all non-terminal patterns are executed once
239
      //
240
322
      LogString::size_type pos = nameStart;
241
242
3.50k
      for (LogString::size_type i = 0; (i < (fragments.size() - 1)) && (pos < buf.length());
243
3.18k
        i++)
244
3.18k
      {
245
3.18k
        pos = fragments[i].abbreviate(buf, pos);
246
3.18k
      }
247
248
      //
249
      //   last pattern in executed repeatedly
250
      //
251
322
      PatternAbbreviatorFragment terminalFragment =
252
322
        fragments[fragments.size() - 1];
253
254
22.6k
      while (pos < buf.length())
255
22.3k
      {
256
22.3k
        pos = terminalFragment.abbreviate(buf, pos);
257
22.3k
      }
258
322
    }
259
};
260
}
261
}
262
263
IMPLEMENT_LOG4CXX_OBJECT(NOPAbbreviator)
264
IMPLEMENT_LOG4CXX_OBJECT(MaxElementAbbreviator)
265
IMPLEMENT_LOG4CXX_OBJECT(PatternAbbreviator)
266
267
268
269
NameAbbreviatorPtr NameAbbreviator::getAbbreviator(const LogString& pattern)
270
15.7k
{
271
15.7k
  if (pattern.length() > 0)
272
8.59k
  {
273
    //  if pattern is just spaces and numbers then
274
    //     use MaxElementAbbreviator
275
8.59k
    LogString trimmed(StringHelper::trim(pattern));
276
277
8.59k
    if (trimmed.length() == 0)
278
510
    {
279
510
      return getDefaultAbbreviator();
280
510
    }
281
282
8.08k
    LogString::size_type i = 0;
283
284
8.08k
    while (
285
127k
      (i < trimmed.length()) && (trimmed[i] >= 0x30 /* '0' */)
286
127k
      && (trimmed[i] <= 0x39 /* '9' */))
287
118k
    {
288
118k
      i++;
289
118k
    }
290
291
    //
292
    //  if all blanks and digits
293
    //
294
8.08k
    if (i == trimmed.length())
295
3.73k
    {
296
3.73k
      int len = 256;
297
3.73k
      try
298
3.73k
      {
299
3.73k
        len = StringHelper::toInt(trimmed);
300
3.73k
      }
301
3.73k
      catch (const std::out_of_range& ex)
302
3.73k
      {
303
547
        LogLog::warn(LOG4CXX_STR("Invalid name abreviator pattern: ") + pattern, ex);
304
547
      }
305
306
3.73k
      if(len > 256){
307
699
        len = 256;
308
3.03k
      }else if( len < 0 ){
309
0
        len = 0;
310
0
      }
311
312
3.73k
      return std::make_shared<MaxElementAbbreviator>(len);
313
3.73k
    }
314
315
4.34k
    std::vector<PatternAbbreviatorFragment> fragments;
316
4.34k
    logchar ellipsis;
317
4.34k
    int charCount;
318
4.34k
    LogString::size_type pos = 0;
319
320
156k
    while (pos < trimmed.length())
321
155k
    {
322
155k
      LogString::size_type ellipsisPos = pos;
323
324
155k
      if (trimmed[pos] == 0x2A /* '*' */)
325
3.07k
      {
326
3.07k
        charCount = INT_MAX;
327
3.07k
        ellipsisPos++;
328
3.07k
      }
329
152k
      else
330
152k
      {
331
152k
        if ((trimmed[pos] >= 0x30 /* '0' */)
332
152k
          && (trimmed[pos] <= 0x39 /* '9' */))
333
2.69k
        {
334
2.69k
          charCount = trimmed[pos] - 0x30 /* '0' */;
335
2.69k
          ellipsisPos++;
336
2.69k
        }
337
150k
        else
338
150k
        {
339
150k
          charCount = 0;
340
150k
        }
341
152k
      }
342
343
155k
      ellipsis = 0;
344
345
155k
      if (ellipsisPos < trimmed.length())
346
155k
      {
347
155k
        ellipsis = trimmed[ellipsisPos];
348
349
155k
        if (ellipsis == 0x2E /* '.' */)
350
145k
        {
351
145k
          ellipsis = 0;
352
145k
        }
353
155k
      }
354
355
155k
      fragments.push_back(PatternAbbreviatorFragment(charCount, ellipsis));
356
155k
      pos = trimmed.find(0x2E /* '.' */, pos);
357
358
155k
      if (pos == LogString::npos)
359
3.53k
      {
360
3.53k
        break;
361
3.53k
      }
362
363
152k
      pos++;
364
152k
    }
365
366
4.34k
    return std::make_shared<PatternAbbreviator>(fragments);
367
8.08k
  }
368
369
  //
370
  //  no matching abbreviation, return defaultAbbreviator
371
  //
372
7.16k
  return getDefaultAbbreviator();
373
15.7k
}
log4cxx::pattern::NameAbbreviator::getAbbreviator(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
270
4.36k
{
271
4.36k
  if (pattern.length() > 0)
272
3.86k
  {
273
    //  if pattern is just spaces and numbers then
274
    //     use MaxElementAbbreviator
275
3.86k
    LogString trimmed(StringHelper::trim(pattern));
276
277
3.86k
    if (trimmed.length() == 0)
278
298
    {
279
298
      return getDefaultAbbreviator();
280
298
    }
281
282
3.56k
    LogString::size_type i = 0;
283
284
3.56k
    while (
285
53.4k
      (i < trimmed.length()) && (trimmed[i] >= 0x30 /* '0' */)
286
53.4k
      && (trimmed[i] <= 0x39 /* '9' */))
287
49.8k
    {
288
49.8k
      i++;
289
49.8k
    }
290
291
    //
292
    //  if all blanks and digits
293
    //
294
3.56k
    if (i == trimmed.length())
295
1.50k
    {
296
1.50k
      int len = 256;
297
1.50k
      try
298
1.50k
      {
299
1.50k
        len = StringHelper::toInt(trimmed);
300
1.50k
      }
301
1.50k
      catch (const std::out_of_range& ex)
302
1.50k
      {
303
283
        LogLog::warn(LOG4CXX_STR("Invalid name abreviator pattern: ") + pattern, ex);
304
283
      }
305
306
1.50k
      if(len > 256){
307
255
        len = 256;
308
1.25k
      }else if( len < 0 ){
309
0
        len = 0;
310
0
      }
311
312
1.50k
      return std::make_shared<MaxElementAbbreviator>(len);
313
1.50k
    }
314
315
2.05k
    std::vector<PatternAbbreviatorFragment> fragments;
316
2.05k
    logchar ellipsis;
317
2.05k
    int charCount;
318
2.05k
    LogString::size_type pos = 0;
319
320
86.6k
    while (pos < trimmed.length())
321
86.2k
    {
322
86.2k
      LogString::size_type ellipsisPos = pos;
323
324
86.2k
      if (trimmed[pos] == 0x2A /* '*' */)
325
1.28k
      {
326
1.28k
        charCount = INT_MAX;
327
1.28k
        ellipsisPos++;
328
1.28k
      }
329
84.9k
      else
330
84.9k
      {
331
84.9k
        if ((trimmed[pos] >= 0x30 /* '0' */)
332
84.9k
          && (trimmed[pos] <= 0x39 /* '9' */))
333
1.46k
        {
334
1.46k
          charCount = trimmed[pos] - 0x30 /* '0' */;
335
1.46k
          ellipsisPos++;
336
1.46k
        }
337
83.5k
        else
338
83.5k
        {
339
83.5k
          charCount = 0;
340
83.5k
        }
341
84.9k
      }
342
343
86.2k
      ellipsis = 0;
344
345
86.2k
      if (ellipsisPos < trimmed.length())
346
85.9k
      {
347
85.9k
        ellipsis = trimmed[ellipsisPos];
348
349
85.9k
        if (ellipsis == 0x2E /* '.' */)
350
80.0k
        {
351
80.0k
          ellipsis = 0;
352
80.0k
        }
353
85.9k
      }
354
355
86.2k
      fragments.push_back(PatternAbbreviatorFragment(charCount, ellipsis));
356
86.2k
      pos = trimmed.find(0x2E /* '.' */, pos);
357
358
86.2k
      if (pos == LogString::npos)
359
1.65k
      {
360
1.65k
        break;
361
1.65k
      }
362
363
84.6k
      pos++;
364
84.6k
    }
365
366
2.05k
    return std::make_shared<PatternAbbreviator>(fragments);
367
3.56k
  }
368
369
  //
370
  //  no matching abbreviation, return defaultAbbreviator
371
  //
372
504
  return getDefaultAbbreviator();
373
4.36k
}
log4cxx::pattern::NameAbbreviator::getAbbreviator(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
Line
Count
Source
270
11.3k
{
271
11.3k
  if (pattern.length() > 0)
272
4.73k
  {
273
    //  if pattern is just spaces and numbers then
274
    //     use MaxElementAbbreviator
275
4.73k
    LogString trimmed(StringHelper::trim(pattern));
276
277
4.73k
    if (trimmed.length() == 0)
278
212
    {
279
212
      return getDefaultAbbreviator();
280
212
    }
281
282
4.51k
    LogString::size_type i = 0;
283
284
4.51k
    while (
285
73.6k
      (i < trimmed.length()) && (trimmed[i] >= 0x30 /* '0' */)
286
73.6k
      && (trimmed[i] <= 0x39 /* '9' */))
287
69.1k
    {
288
69.1k
      i++;
289
69.1k
    }
290
291
    //
292
    //  if all blanks and digits
293
    //
294
4.51k
    if (i == trimmed.length())
295
2.22k
    {
296
2.22k
      int len = 256;
297
2.22k
      try
298
2.22k
      {
299
2.22k
        len = StringHelper::toInt(trimmed);
300
2.22k
      }
301
2.22k
      catch (const std::out_of_range& ex)
302
2.22k
      {
303
264
        LogLog::warn(LOG4CXX_STR("Invalid name abreviator pattern: ") + pattern, ex);
304
264
      }
305
306
2.22k
      if(len > 256){
307
444
        len = 256;
308
1.78k
      }else if( len < 0 ){
309
0
        len = 0;
310
0
      }
311
312
2.22k
      return std::make_shared<MaxElementAbbreviator>(len);
313
2.22k
    }
314
315
2.29k
    std::vector<PatternAbbreviatorFragment> fragments;
316
2.29k
    logchar ellipsis;
317
2.29k
    int charCount;
318
2.29k
    LogString::size_type pos = 0;
319
320
70.0k
    while (pos < trimmed.length())
321
69.6k
    {
322
69.6k
      LogString::size_type ellipsisPos = pos;
323
324
69.6k
      if (trimmed[pos] == 0x2A /* '*' */)
325
1.78k
      {
326
1.78k
        charCount = INT_MAX;
327
1.78k
        ellipsisPos++;
328
1.78k
      }
329
67.8k
      else
330
67.8k
      {
331
67.8k
        if ((trimmed[pos] >= 0x30 /* '0' */)
332
67.8k
          && (trimmed[pos] <= 0x39 /* '9' */))
333
1.23k
        {
334
1.23k
          charCount = trimmed[pos] - 0x30 /* '0' */;
335
1.23k
          ellipsisPos++;
336
1.23k
        }
337
66.6k
        else
338
66.6k
        {
339
66.6k
          charCount = 0;
340
66.6k
        }
341
67.8k
      }
342
343
69.6k
      ellipsis = 0;
344
345
69.6k
      if (ellipsisPos < trimmed.length())
346
69.1k
      {
347
69.1k
        ellipsis = trimmed[ellipsisPos];
348
349
69.1k
        if (ellipsis == 0x2E /* '.' */)
350
65.1k
        {
351
65.1k
          ellipsis = 0;
352
65.1k
        }
353
69.1k
      }
354
355
69.6k
      fragments.push_back(PatternAbbreviatorFragment(charCount, ellipsis));
356
69.6k
      pos = trimmed.find(0x2E /* '.' */, pos);
357
358
69.6k
      if (pos == LogString::npos)
359
1.87k
      {
360
1.87k
        break;
361
1.87k
      }
362
363
67.7k
      pos++;
364
67.7k
    }
365
366
2.29k
    return std::make_shared<PatternAbbreviator>(fragments);
367
4.51k
  }
368
369
  //
370
  //  no matching abbreviation, return defaultAbbreviator
371
  //
372
6.66k
  return getDefaultAbbreviator();
373
11.3k
}
374
375
/**
376
 * Gets default abbreviator.
377
 *
378
 * @return default abbreviator.
379
 */
380
NameAbbreviatorPtr NameAbbreviator::getDefaultAbbreviator()
381
7.68k
{
382
7.68k
  static WideLife<NameAbbreviatorPtr> def = std::make_shared<NOPAbbreviator>();
383
7.68k
  return def;
384
7.68k
}
385