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/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
0
    : pAppenderList{ std::make_shared<const AppenderList>(newList) }
42
0
  {}
43
44
public: // Accessors
45
  AppenderListPtr getAppenders() const
46
0
  {
47
#ifdef __cpp_lib_atomic_shared_ptr
48
    return pAppenderList.load(std::memory_order_acquire);
49
#else // !defined(__cpp_lib_atomic_shared_ptr)
50
0
    std::lock_guard<std::mutex> lock( m_mutex );
51
0
    return pAppenderList;
52
0
#endif // !defined(__cpp_lib_atomic_shared_ptr)
53
0
  }
54
55
public: // Modifiers
56
  void setAppenders(const AppenderList& newList)
57
0
  {
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
0
    std::lock_guard<std::mutex> lock( m_mutex );
62
0
    pAppenderList = std::make_shared<const AppenderList>(newList);
63
0
#endif // !defined(__cpp_lib_atomic_shared_ptr)
64
0
  }
65
};
66
67
AppenderAttachableImpl::AppenderAttachableImpl()
68
0
{
69
0
}
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl()
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl()
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
0
{
78
0
}
79
80
81
void AppenderAttachableImpl::addAppender(const AppenderPtr newAppender)
82
0
{
83
0
  if (!newAppender)
84
0
    return;
85
0
  if (m_priv)
86
0
  {
87
0
    auto allAppenders = m_priv->getAppenders();
88
0
    if (allAppenders->end() == std::find(allAppenders->begin(), allAppenders->end(), newAppender))
89
0
    {
90
0
      auto newAppenders = *allAppenders;
91
0
      newAppenders.push_back(newAppender);
92
0
      m_priv->setAppenders(newAppenders);
93
0
    }
94
0
  }
95
0
  else
96
0
    m_priv = std::make_unique<priv_data>(AppenderList{newAppender});
97
0
}
98
99
int AppenderAttachableImpl::appendLoopOnAppenders(const spi::LoggingEventPtr& event)
100
0
{
101
0
  int result = 0;
102
0
  if (m_priv)
103
0
  {
104
0
    auto allAppenders = m_priv->getAppenders();
105
0
    for (auto& appender : *allAppenders)
106
0
    {
107
0
      appender->doAppend(event);
108
0
      ++result;
109
0
    }
110
0
  }
111
0
  return result;
112
0
}
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
0
{
122
0
  AppenderList result;
123
0
  if (m_priv)
124
0
    result = *m_priv->getAppenders();
125
0
  return result;
126
0
}
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
0
{
159
0
  if (m_priv)
160
0
  {
161
0
    auto allAppenders = m_priv->getAppenders();
162
0
    for (auto& appender : *allAppenders)
163
0
      appender->close();
164
0
    m_priv->setAppenders({});
165
0
  }
166
0
}
167
168
void AppenderAttachableImpl::removeAppender(const AppenderPtr appender)
169
0
{
170
0
  if (m_priv && appender)
171
0
  {
172
0
    auto newAppenders = *m_priv->getAppenders();
173
0
    auto pItem = std::find(newAppenders.begin(), newAppenders.end(), appender);
174
0
    if (newAppenders.end() != pItem)
175
0
    {
176
0
      newAppenders.erase(pItem);
177
0
      m_priv->setAppenders(newAppenders);
178
0
    }
179
0
  }
180
0
}
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