/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 | | |