Coverage Report

Created: 2026-06-08 06:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/appenderattachableimpl.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/helpers/appenderattachableimpl.h>
18
#include <algorithm>
19
#include <mutex>
20
21
using namespace LOG4CXX_NS;
22
using namespace LOG4CXX_NS::helpers;
23
24
IMPLEMENT_LOG4CXX_OBJECT(AppenderAttachableImpl)
25
26
using AppenderListPtr = std::shared_ptr<const AppenderList>;
27
28
/** A vector of appender pointers. */
29
struct AppenderAttachableImpl::priv_data
30
{
31
private: // Attributes
32
#ifdef __cpp_lib_atomic_shared_ptr
33
  std::atomic<AppenderListPtr> pAppenderList;
34
#else // !defined(__cpp_lib_atomic_shared_ptr)
35
  AppenderListPtr    pAppenderList;
36
  mutable std::mutex m_mutex;
37
#endif // !defined(__cpp_lib_atomic_shared_ptr)
38
39
public: // ...structors
40
  priv_data(const AppenderList& newList = {})
41
1
    : pAppenderList{ std::make_shared<const AppenderList>(newList) }
42
1
  {}
43
44
public: // Accessors
45
  AppenderListPtr getAppenders() const
46
6.91k
  {
47
#ifdef __cpp_lib_atomic_shared_ptr
48
    return pAppenderList.load(std::memory_order_acquire);
49
#else // !defined(__cpp_lib_atomic_shared_ptr)
50
6.91k
    std::lock_guard<std::mutex> lock( m_mutex );
51
6.91k
    return pAppenderList;
52
6.91k
#endif // !defined(__cpp_lib_atomic_shared_ptr)
53
6.91k
  }
54
55
public: // Modifiers
56
  void setAppenders(const AppenderList& newList)
57
1.38k
  {
58
#ifdef __cpp_lib_atomic_shared_ptr
59
    pAppenderList.store(std::make_shared<AppenderList>(newList), std::memory_order_release);
60
#else // !defined(__cpp_lib_atomic_shared_ptr)
61
1.38k
    std::lock_guard<std::mutex> lock( m_mutex );
62
1.38k
    pAppenderList = std::make_shared<const AppenderList>(newList);
63
1.38k
#endif // !defined(__cpp_lib_atomic_shared_ptr)
64
1.38k
  }
65
};
66
67
AppenderAttachableImpl::AppenderAttachableImpl()
68
2
{
69
2
}
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl()
log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl()
Line
Count
Source
68
2
{
69
2
}
70
71
#if LOG4CXX_ABI_VERSION <= 15
72
AppenderAttachableImpl::AppenderAttachableImpl(Pool& pool)
73
0
{
74
0
}
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl(log4cxx::helpers::Pool&)
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl(log4cxx::helpers::Pool&)
75
#endif
76
AppenderAttachableImpl::~AppenderAttachableImpl()
77
2
{
78
2
}
79
80
81
void AppenderAttachableImpl::addAppender(const AppenderPtr newAppender)
82
461
{
83
461
  if (!newAppender)
84
0
    return;
85
461
  if (m_priv)
86
460
  {
87
460
    auto allAppenders = m_priv->getAppenders();
88
460
    if (allAppenders->end() == std::find(allAppenders->begin(), allAppenders->end(), newAppender))
89
460
    {
90
460
      auto newAppenders = *allAppenders;
91
460
      newAppenders.push_back(newAppender);
92
460
      m_priv->setAppenders(newAppenders);
93
460
    }
94
460
  }
95
1
  else
96
1
    m_priv = std::make_unique<priv_data>(AppenderList{newAppender});
97
461
}
98
99
int AppenderAttachableImpl::appendLoopOnAppenders(const spi::LoggingEventPtr& event)
100
9.22k
{
101
9.22k
  int result = 0;
102
9.22k
  if (m_priv)
103
4.61k
  {
104
4.61k
    auto allAppenders = m_priv->getAppenders();
105
4.61k
    for (auto& appender : *allAppenders)
106
4.61k
    {
107
4.61k
      appender->doAppend(event);
108
4.61k
      ++result;
109
4.61k
    }
110
4.61k
  }
111
9.22k
  return result;
112
9.22k
}
113
#if LOG4CXX_ABI_VERSION <= 15
114
int AppenderAttachableImpl::appendLoopOnAppenders(const spi::LoggingEventPtr& event, helpers::Pool& p)
115
0
{
116
0
  return appendLoopOnAppenders(event);
117
0
}
118
#endif
119
120
AppenderList AppenderAttachableImpl::getAllAppenders() const
121
1.84k
{
122
1.84k
  AppenderList result;
123
1.84k
  if (m_priv)
124
923
    result = *m_priv->getAppenders();
125
1.84k
  return result;
126
1.84k
}
127
128
AppenderPtr AppenderAttachableImpl::getAppender(const LogString& name) const
129
0
{
130
0
  AppenderPtr result;
131
0
  if (m_priv)
132
0
  {
133
0
    auto allAppenders = m_priv->getAppenders();
134
0
    for (auto& appender : *allAppenders)
135
0
    {
136
0
      if (name == appender->getName())
137
0
      {
138
0
        result = appender;
139
0
        break;
140
0
      }
141
0
    }
142
0
  }
143
0
  return result;
144
0
}
145
146
bool AppenderAttachableImpl::isAttached(const AppenderPtr appender) const
147
0
{
148
0
  bool result = false;
149
0
  if (m_priv && appender)
150
0
  {
151
0
    auto allAppenders = m_priv->getAppenders();
152
0
    result = allAppenders->end() != std::find(allAppenders->begin(), allAppenders->end(), appender);
153
0
  }
154
0
  return result;
155
0
}
156
157
void AppenderAttachableImpl::removeAllAppenders()
158
924
{
159
924
  if (m_priv)
160
462
  {
161
462
    auto allAppenders = m_priv->getAppenders();
162
462
    for (auto& appender : *allAppenders)
163
0
      appender->close();
164
462
    m_priv->setAppenders({});
165
462
  }
166
924
}
167
168
void AppenderAttachableImpl::removeAppender(const AppenderPtr appender)
169
461
{
170
461
  if (m_priv && appender)
171
461
  {
172
461
    auto newAppenders = *m_priv->getAppenders();
173
461
    auto pItem = std::find(newAppenders.begin(), newAppenders.end(), appender);
174
461
    if (newAppenders.end() != pItem)
175
461
    {
176
461
      newAppenders.erase(pItem);
177
461
      m_priv->setAppenders(newAppenders);
178
461
    }
179
461
  }
180
461
}
181
182
void AppenderAttachableImpl::removeAppender(const LogString& name)
183
0
{
184
0
  if (m_priv)
185
0
  {
186
0
    auto newAppenders = *m_priv->getAppenders();
187
0
    auto pItem = std::find_if(newAppenders.begin(), newAppenders.end()
188
0
      , [&name](const AppenderPtr& appender) -> bool
189
0
      {
190
0
        return name == appender->getName();
191
0
      });
192
0
    if (newAppenders.end() != pItem)
193
0
    {
194
0
      newAppenders.erase(pItem);
195
0
      m_priv->setAppenders(newAppenders);
196
0
    }
197
0
  }
198
0
}
199
200
bool AppenderAttachableImpl::replaceAppender(const AppenderPtr& oldAppender, const AppenderPtr& newAppender)
201
0
{
202
0
  bool found = false;
203
0
  if (m_priv && oldAppender && newAppender)
204
0
  {
205
0
    auto name = oldAppender->getName();
206
0
    auto newAppenders = *m_priv->getAppenders();
207
0
    auto pItem = std::find_if(newAppenders.begin(), newAppenders.end()
208
0
      , [&name](const AppenderPtr& appender) -> bool
209
0
      {
210
0
        return name == appender->getName();
211
0
      });
212
0
    if (newAppenders.end() != pItem)
213
0
    {
214
0
      *pItem = newAppender;
215
0
      m_priv->setAppenders(newAppenders);
216
0
      found = true;
217
0
    }
218
0
  }
219
0
  return found;
220
0
}
221
222
void AppenderAttachableImpl::replaceAppenders(const AppenderList& newList)
223
0
{
224
0
  if (m_priv)
225
0
  {
226
0
    auto allAppenders = m_priv->getAppenders();
227
0
    for (auto& a : *allAppenders)
228
0
      a->close();
229
0
    m_priv->setAppenders(newList);
230
0
  }
231
0
  else
232
0
    m_priv = std::make_unique<priv_data>(newList);
233
0
}
234
235