Coverage Report

Created: 2026-06-15 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/asyncbuffer.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
#include <log4cxx/helpers/asyncbuffer.h>
19
#include <log4cxx/helpers/transcoder.h>
20
#if LOG4CXX_CONCEPTS
21
#include <variant>
22
#endif // LOG4CXX_CONCEPTS
23
24
namespace LOG4CXX_NS
25
{
26
27
namespace helpers
28
{
29
30
struct AsyncBuffer::Private
31
{
32
#if LOG4CXX_CONCEPTS && LOG4CXX_WCHAR_T_API
33
    using value_t = std::variant<MessageBufferAppender, WideMessageBufferAppender>;
34
#else // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts && LOG4CXX_WCHAR_T_API)
35
    using value_t = MessageBufferAppender;
36
#endif // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts && LOG4CXX_WCHAR_T_API)
37
  std::vector<value_t> data;
38
39
  Private(value_t&& f)
40
0
    : data{ std::move(f) }
41
0
  {}
42
43
#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
44
  StringViewType fmt_string;
45
  FmtArgStore    fmt_args;
46
47
  Private(const StringViewType& format_string, FmtArgStore&& args)
48
    : fmt_string{ format_string }
49
    , fmt_args{ std::move(args) }
50
  {}
51
52
#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
53
  WideStringViewType fmt_wstring;
54
  WideFmtArgStore    fmt_wargs;
55
56
  Private(const WideStringViewType& format_string, WideFmtArgStore&& args)
57
    : fmt_wstring{ format_string }
58
    , fmt_wargs{ std::move(args) }
59
  {}
60
#endif // LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
61
#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
62
63
};
64
65
#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
66
void AsyncBuffer::initializeForFmt(const StringViewType& format_string, FmtArgStore&& args)
67
{
68
  if (!m_priv)
69
    m_priv = std::make_unique<Private>(format_string, std::move(args));
70
  else
71
  {
72
    m_priv->fmt_string = format_string;
73
    m_priv->fmt_args = std::move(args);
74
  }
75
}
76
77
#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
78
void AsyncBuffer::initializeForFmt(const WideStringViewType& format_string, WideFmtArgStore&& args)
79
{
80
  if (!m_priv)
81
    m_priv = std::make_unique<Private>(format_string, std::move(args));
82
  else
83
  {
84
    m_priv->fmt_wstring = format_string;
85
    m_priv->fmt_wargs = std::move(args);
86
  }
87
}
88
#endif // LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
89
#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
90
91
#if LOG4CXX_ABI_VERSION <= 15
92
#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
93
void AsyncBuffer::initializeForFmt(StringViewType&& format_string, FmtArgStore&& args)
94
{ initializeForFmt(format_string, std::move(args)); }
95
96
#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
97
void AsyncBuffer::initializeForFmt(WideStringViewType&& format_string, WideFmtArgStore&& args)
98
{ initializeForFmt(format_string, std::move(args)); }
99
#endif // LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
100
#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
101
#endif // LOG4CXX_ABI_VERSION <= 15
102
103
/** An empty buffer.
104
*/
105
AsyncBuffer::AsyncBuffer()
106
3.54k
{}
107
108
/** A new buffer with the content of \c other
109
*/
110
AsyncBuffer::AsyncBuffer(AsyncBuffer&& other)
111
0
  : m_priv(std::move(other.m_priv))
112
0
{
113
0
}
114
115
/** Release resources.
116
*/
117
AsyncBuffer::~AsyncBuffer()
118
3.54k
{
119
3.54k
}
120
121
/**
122
* Has no item been added to this?
123
*/
124
bool AsyncBuffer::empty() const
125
0
{
126
0
  bool result{ true };
127
0
  if (m_priv)
128
0
  {
129
0
    result = m_priv->data.empty();
130
#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
131
    if (result)
132
      result = (0 == m_priv->fmt_string.size());
133
#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
134
    if (result)
135
      result = (0 == m_priv->fmt_wstring.size());
136
#endif // LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
137
#endif
138
0
  }
139
0
  return result;
140
0
}
141
142
/**
143
* Add text version of buffered values to \c msg
144
*/
145
void AsyncBuffer::renderMessage(LogCharMessageBuffer& msg) const
146
0
{
147
0
  if (m_priv)
148
0
  {
149
0
    for (auto& renderer : m_priv->data)
150
#if LOG4CXX_CONCEPTS && LOG4CXX_WCHAR_T_API
151
    {
152
#if LOG4CXX_LOGCHAR_IS_UTF8
153
      if (auto pRenderer = std::get_if<MessageBufferAppender>(&renderer))
154
        (*pRenderer)(msg);
155
      else
156
      {
157
        WideMessageBuffer wideBuf;
158
        std::get<WideMessageBufferAppender>(renderer)(wideBuf);
159
        LOG4CXX_DECODE_WCHAR(lsMsg, wideBuf.extract_str(wideBuf));
160
        msg << lsMsg;
161
      }
162
#else // !LOG4CXX_LOGCHAR_IS_UTF8
163
      if (auto pRenderer = std::get_if<WideMessageBufferAppender>(&renderer))
164
        (*pRenderer)(msg);
165
      else
166
      {
167
        CharMessageBuffer narrowBuf;
168
        std::get<MessageBufferAppender>(renderer)(narrowBuf);
169
        LOG4CXX_DECODE_CHAR(lsMsg, narrowBuf.extract_str(narrowBuf));
170
        msg << lsMsg;
171
      }
172
#endif // !LOG4CXX_LOGCHAR_IS_UTF8
173
    }
174
#else // !LOG4CXX_CONCEPTS
175
0
      renderer(msg);
176
0
#endif // !LOG4CXX_CONCEPTS
177
178
#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
179
#if LOG4CXX_LOGCHAR_IS_UTF8
180
    if (0 < m_priv->fmt_string.size())
181
      msg << fmt::vformat(m_priv->fmt_string, m_priv->fmt_args);
182
#if LOG4CXX_WCHAR_T_API
183
    if (0 < m_priv->fmt_wstring.size())
184
    {
185
      LOG4CXX_DECODE_WCHAR(lsMsg, fmt::vformat(m_priv->fmt_wstring, m_priv->fmt_wargs));
186
      msg << lsMsg;
187
    }
188
#endif // LOG4CXX_WCHAR_T_API
189
#endif // LOG4CXX_LOGCHAR_IS_UTF8
190
191
#if LOG4CXX_LOGCHAR_IS_WCHAR
192
    if (0 < m_priv->fmt_wstring.size())
193
      msg << fmt::vformat(m_priv->fmt_wstring, m_priv->fmt_wargs);
194
    if (0 < m_priv->fmt_string.size())
195
    {
196
      LOG4CXX_DECODE_CHAR(lsMsg, fmt::vformat(m_priv->fmt_string, m_priv->fmt_args));
197
      msg << lsMsg;
198
    }
199
#endif // LOG4CXX_LOGCHAR_IS_WCHAR
200
#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
201
0
  }
202
0
}
203
204
/**
205
* Remove all message appenders
206
*/
207
void AsyncBuffer::clear()
208
0
{
209
0
  if (m_priv)
210
0
  {
211
0
    m_priv->data.clear();
212
#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
213
    m_priv->fmt_string = {};
214
#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
215
    m_priv->fmt_wstring = {};
216
#endif // LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
217
#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
218
0
  }
219
0
}
220
221
#if LOG4CXX_CONCEPTS
222
/**
223
 *   Append \c function to this buffer.
224
 */
225
void AsyncBuffer::append(MessageBufferAppender&& f)
226
{
227
  if (!m_priv)
228
    m_priv = std::make_unique<Private>(std::move(f));
229
  else
230
    m_priv->data.push_back(std::move(f));
231
}
232
233
#if LOG4CXX_WCHAR_T_API
234
/**
235
 *   Append \c function to this buffer.
236
 */
237
void AsyncBuffer::append(WideMessageBufferAppender&& f)
238
{
239
  if (!m_priv)
240
    m_priv = std::make_unique<Private>(std::move(f));
241
  else
242
    m_priv->data.push_back(std::move(f));
243
}
244
#endif // LOG4CXX_WCHAR_T_API
245
#else // !LOG4CXX_CONCEPTS
246
/**
247
 *   Append \c function to this buffer.
248
 */
249
void AsyncBuffer::append(MessageBufferAppender&& f)
250
0
{
251
0
  if (!m_priv)
252
0
    m_priv = std::make_unique<Private>(std::move(f));
253
0
  else
254
0
    m_priv->data.push_back(std::move(f));
255
0
}
256
#endif // !LOG4CXX_CONCEPTS
257
258
} // namespace helpers
259
} // namespace LOG4CXX_NS
260