/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 | 586 | { |
34 | 586 | } |
35 | | |
36 | | NameAbbreviator::~NameAbbreviator() |
37 | 586 | { |
38 | 586 | } |
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 | 1 | { |
61 | 1 | } |
62 | | |
63 | | /** |
64 | | * {@inheritDoc} |
65 | | */ |
66 | | void abbreviate(LogString::size_type /* nameStart */, LogString& /* buf */) const override |
67 | 22 | { |
68 | 22 | } |
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 | 231 | MaxElementAbbreviator(const int count1) : count(count1) |
93 | 231 | { |
94 | 231 | } |
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 | 231 | { |
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 | 231 | LogString::size_type end = buf.length() - 1; |
107 | | |
108 | 1.20k | for (LogString::size_type i = count; i > 0; i--) |
109 | 1.10k | { |
110 | 1.10k | end = buf.rfind(0x2E /* '.' */, end - 1); |
111 | | |
112 | 1.10k | if ((end == LogString::npos) || (end < nameStart)) |
113 | 125 | { |
114 | 125 | return; |
115 | 125 | } |
116 | 1.10k | } |
117 | | |
118 | 106 | buf.erase(buf.begin() + nameStart, buf.begin() + (end + 1)); |
119 | 106 | } |
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 | 7.70k | : charCount(charCount1), ellipsis(ellipsis1) |
149 | 7.70k | { |
150 | 7.70k | } |
151 | | PatternAbbreviatorFragment() : charCount(0), ellipsis(0) |
152 | 0 | { |
153 | 0 | } |
154 | | |
155 | | PatternAbbreviatorFragment(const PatternAbbreviatorFragment& src) |
156 | 25.6k | : charCount(src.charCount), ellipsis(src.ellipsis) |
157 | 25.6k | { |
158 | 25.6k | } |
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 | 75.9k | { |
175 | 75.9k | LogString::size_type nextDot = buf.find(0x2E /* '.' */, startPos); |
176 | | |
177 | 75.9k | if (nextDot != LogString::npos) |
178 | 75.8k | { |
179 | 75.8k | if ((nextDot - startPos) > charCount) |
180 | 72.4k | { |
181 | 72.4k | buf.erase(buf.begin() + (startPos + charCount), buf.begin() + nextDot); |
182 | 72.4k | nextDot = startPos + charCount; |
183 | | |
184 | 72.4k | if (ellipsis != 0x00) |
185 | 71.9k | { |
186 | 71.9k | buf.insert(nextDot, 1, ellipsis); |
187 | 71.9k | nextDot++; |
188 | 71.9k | } |
189 | 72.4k | } |
190 | | |
191 | 75.8k | nextDot++; |
192 | 75.8k | } |
193 | | |
194 | 75.9k | return nextDot; |
195 | 75.9k | } |
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 | 354 | fragments(fragments1) |
223 | 354 | { |
224 | 354 | if (fragments1.size() == 0) |
225 | 0 | { |
226 | 0 | throw IllegalArgumentException(LOG4CXX_STR("fragments parameter must contain at least one element")); |
227 | 0 | } |
228 | 354 | } |
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 | 354 | { |
237 | | // |
238 | | // all non-terminal patterns are executed once |
239 | | // |
240 | 354 | LogString::size_type pos = nameStart; |
241 | | |
242 | 2.04k | for (LogString::size_type i = 0; (i < (fragments.size() - 1)) && (pos < buf.length()); |
243 | 1.69k | i++) |
244 | 1.69k | { |
245 | 1.69k | pos = fragments[i].abbreviate(buf, pos); |
246 | 1.69k | } |
247 | | |
248 | | // |
249 | | // last pattern in executed repeatedly |
250 | | // |
251 | 354 | PatternAbbreviatorFragment terminalFragment = |
252 | 354 | fragments[fragments.size() - 1]; |
253 | | |
254 | 74.5k | while (pos < buf.length()) |
255 | 74.2k | { |
256 | 74.2k | pos = terminalFragment.abbreviate(buf, pos); |
257 | 74.2k | } |
258 | 354 | } |
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 | 607 | { |
271 | 607 | if (pattern.length() > 0) |
272 | 594 | { |
273 | | // if pattern is just spaces and numbers then |
274 | | // use MaxElementAbbreviator |
275 | 594 | LogString trimmed(StringHelper::trim(pattern)); |
276 | | |
277 | 594 | if (trimmed.length() == 0) |
278 | 9 | { |
279 | 9 | return getDefaultAbbreviator(); |
280 | 9 | } |
281 | | |
282 | 585 | LogString::size_type i = 0; |
283 | | |
284 | 585 | while ( |
285 | 2.53k | (i < trimmed.length()) && (trimmed[i] >= 0x30 /* '0' */) |
286 | 2.53k | && (trimmed[i] <= 0x39 /* '9' */)) |
287 | 1.95k | { |
288 | 1.95k | i++; |
289 | 1.95k | } |
290 | | |
291 | | // |
292 | | // if all blanks and digits |
293 | | // |
294 | 585 | if (i == trimmed.length()) |
295 | 231 | { |
296 | 231 | int len = 256; |
297 | 231 | try |
298 | 231 | { |
299 | 231 | len = StringHelper::toInt(trimmed); |
300 | 231 | } |
301 | 231 | catch (const std::out_of_range& ex) |
302 | 231 | { |
303 | 7 | LogLog::warn(LOG4CXX_STR("Invalid name abreviator pattern: ") + pattern, ex); |
304 | 7 | } |
305 | | |
306 | 231 | if(len > 256){ |
307 | 28 | len = 256; |
308 | 203 | }else if( len < 0 ){ |
309 | 0 | len = 0; |
310 | 0 | } |
311 | | |
312 | 231 | return std::make_shared<MaxElementAbbreviator>(len); |
313 | 231 | } |
314 | | |
315 | 354 | std::vector<PatternAbbreviatorFragment> fragments; |
316 | 354 | logchar ellipsis; |
317 | 354 | int charCount; |
318 | 354 | LogString::size_type pos = 0; |
319 | | |
320 | 7.77k | while (pos < trimmed.length()) |
321 | 7.70k | { |
322 | 7.70k | LogString::size_type ellipsisPos = pos; |
323 | | |
324 | 7.70k | if (trimmed[pos] == 0x2A /* '*' */) |
325 | 325 | { |
326 | 325 | charCount = INT_MAX; |
327 | 325 | ellipsisPos++; |
328 | 325 | } |
329 | 7.37k | else |
330 | 7.37k | { |
331 | 7.37k | if ((trimmed[pos] >= 0x30 /* '0' */) |
332 | 7.37k | && (trimmed[pos] <= 0x39 /* '9' */)) |
333 | 297 | { |
334 | 297 | charCount = trimmed[pos] - 0x30 /* '0' */; |
335 | 297 | ellipsisPos++; |
336 | 297 | } |
337 | 7.08k | else |
338 | 7.08k | { |
339 | 7.08k | charCount = 0; |
340 | 7.08k | } |
341 | 7.37k | } |
342 | | |
343 | 7.70k | ellipsis = 0; |
344 | | |
345 | 7.70k | if (ellipsisPos < trimmed.length()) |
346 | 7.65k | { |
347 | 7.65k | ellipsis = trimmed[ellipsisPos]; |
348 | | |
349 | 7.65k | if (ellipsis == 0x2E /* '.' */) |
350 | 6.19k | { |
351 | 6.19k | ellipsis = 0; |
352 | 6.19k | } |
353 | 7.65k | } |
354 | | |
355 | 7.70k | fragments.push_back(PatternAbbreviatorFragment(charCount, ellipsis)); |
356 | 7.70k | pos = trimmed.find(0x2E /* '.' */, pos); |
357 | | |
358 | 7.70k | if (pos == LogString::npos) |
359 | 284 | { |
360 | 284 | break; |
361 | 284 | } |
362 | | |
363 | 7.41k | pos++; |
364 | 7.41k | } |
365 | | |
366 | 354 | return std::make_shared<PatternAbbreviator>(fragments); |
367 | 585 | } |
368 | | |
369 | | // |
370 | | // no matching abbreviation, return defaultAbbreviator |
371 | | // |
372 | 13 | return getDefaultAbbreviator(); |
373 | 607 | } |
374 | | |
375 | | /** |
376 | | * Gets default abbreviator. |
377 | | * |
378 | | * @return default abbreviator. |
379 | | */ |
380 | | NameAbbreviatorPtr NameAbbreviator::getDefaultAbbreviator() |
381 | 22 | { |
382 | 22 | static WideLife<NameAbbreviatorPtr> def = std::make_shared<NOPAbbreviator>(); |
383 | 22 | return def; |
384 | 22 | } |
385 | | |