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