]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/log/src/setup/default_formatter_factory.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / log / src / setup / default_formatter_factory.cpp
1 /*
2 * Copyright Andrey Semashev 2007 - 2015.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
6 */
7 /*!
8 * \file default_formatter_factory.cpp
9 * \author Andrey Semashev
10 * \date 14.07.2013
11 *
12 * \brief This header is the Boost.Log library implementation, see the library documentation
13 * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
14 */
15
16 #if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
17
18 #include <boost/log/detail/setup_config.hpp>
19 #include <cstddef>
20 #include <ctime>
21 #include <boost/mpl/vector.hpp>
22 #include <boost/mpl/vector/vector40.hpp>
23 #include <boost/preprocessor/cat.hpp>
24 #include <boost/preprocessor/seq/enum.hpp>
25 #include <boost/preprocessor/seq/size.hpp>
26 #include <boost/date_time/special_defs.hpp>
27 #include <boost/date_time/gregorian/gregorian_types.hpp>
28 #include <boost/date_time/local_time/local_time_types.hpp>
29 #include <boost/date_time/posix_time/posix_time_types.hpp>
30 #include <boost/log/attributes/attribute_name.hpp>
31 #include <boost/log/attributes/value_visitation.hpp>
32 #include <boost/log/utility/type_dispatch/standard_types.hpp>
33 #include <boost/log/utility/type_dispatch/date_time_types.hpp>
34 #include <boost/log/utility/string_literal.hpp>
35 #include <boost/log/utility/formatting_ostream.hpp>
36 #include <boost/log/detail/code_conversion.hpp>
37 #include <boost/log/detail/snprintf.hpp>
38 #include <boost/log/detail/process_id.hpp>
39 #if !defined(BOOST_LOG_NO_THREADS)
40 #include <boost/log/detail/thread_id.hpp>
41 #endif
42 #include <boost/log/attributes/named_scope.hpp>
43 #include "default_formatter_factory.hpp"
44 #include <boost/log/detail/header.hpp>
45
46 namespace boost {
47
48 BOOST_LOG_OPEN_NAMESPACE
49
50 namespace aux {
51
52 #if !defined(BOOST_LOG_NO_THREADS)
53 #define BOOST_LOG_AUX_THREAD_ID_TYPE() (boost::log::aux::thread::id)
54 #else
55 #define BOOST_LOG_AUX_THREAD_ID_TYPE()
56 #endif
57
58 #define BOOST_LOG_AUX_LOG_ATTRIBUTE_VALUE_TYPES()\
59 (boost::log::attributes::named_scope_list)(boost::log::aux::process::id)BOOST_LOG_AUX_THREAD_ID_TYPE()
60
61 // The list of the attribute value types supported by the default formatter. Note that we have to exclude std::time_t
62 // as it is an integral type, as well as double from the native time duration types - these are part of arithmetic types already.
63 #define BOOST_LOG_AUX_LOG_DEFAULT_VALUE_TYPES()\
64 BOOST_LOG_DEFAULT_ATTRIBUTE_VALUE_TYPES()\
65 (std::tm)\
66 BOOST_LOG_BOOST_DATE_TYPES()\
67 BOOST_LOG_BOOST_TIME_DURATION_TYPES()\
68 BOOST_LOG_BOOST_TIME_PERIOD_TYPES()\
69 BOOST_LOG_AUX_LOG_ATTRIBUTE_VALUE_TYPES()
70
71 BOOST_LOG_ANONYMOUS_NAMESPACE {
72
73 //! The default formatter generated by the default formatter factory
74 template< typename CharT >
75 class default_formatter
76 {
77 public:
78 typedef void result_type;
79
80 private:
81 //! Attribute value visitor
82 struct visitor
83 {
84 typedef void result_type;
85
86 explicit visitor(basic_formatting_ostream< CharT >& strm) : m_strm(strm)
87 {
88 }
89
90 template< typename T >
91 void operator() (T const& value) const
92 {
93 m_strm << value;
94 }
95
96 void operator() (std::tm const& value) const
97 {
98 char buf[32];
99 std::size_t len = std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &value);
100 m_strm.write(buf, len);
101 }
102
103 void operator() (boost::posix_time::ptime const& value) const
104 {
105 if (!value.is_special())
106 {
107 std::tm t = boost::posix_time::to_tm(value);
108 char buf[32];
109 std::size_t len = std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &t);
110 std::size_t size = sizeof(buf) - len;
111 int res = boost::log::aux::snprintf(buf + len, size, ".%.6u", static_cast< unsigned int >(value.time_of_day().total_microseconds() % 1000000));
112 if (res < 0)
113 buf[len] = '\0';
114 else if (static_cast< std::size_t >(res) >= size)
115 len += size - 1;
116 else
117 len += res;
118
119 m_strm.write(buf, len);
120 }
121 else
122 {
123 format_special_date_time(value);
124 }
125 }
126
127 void operator() (boost::local_time::local_date_time const& value) const
128 {
129 if (!value.is_special())
130 {
131 this->operator()(value.local_time());
132 m_strm << ' ' << value.zone_as_posix_string();
133 }
134 else
135 {
136 format_special_date_time(value);
137 }
138 }
139
140 void operator() (boost::gregorian::date const& value) const
141 {
142 if (!value.is_special())
143 {
144 std::tm t = boost::gregorian::to_tm(value);
145 char buf[32];
146 std::size_t len = std::strftime(buf, sizeof(buf), "%Y-%m-%d", &t);
147 m_strm.write(buf, len);
148 }
149 else
150 {
151 format_special_date_time(value.as_special());
152 }
153 }
154
155 void operator() (boost::posix_time::time_duration const& value) const
156 {
157 if (!value.is_special())
158 {
159 boost::posix_time::time_duration val = value;
160 if (val.is_negative())
161 {
162 m_strm << '-';
163 val = -val;
164 }
165 unsigned long long total_useconds = value.total_microseconds();
166 unsigned long long hours = total_useconds / (3600ull * 1000000ull);
167 unsigned int minutes = static_cast< unsigned int >(total_useconds / (60ull * 1000000ull) % 60ull);
168 unsigned int seconds = static_cast< unsigned int >(total_useconds / 1000000ull % 60ull);
169 unsigned int useconds = static_cast< unsigned int >(total_useconds % 1000000ull);
170 char buf[64];
171 int len = boost::log::aux::snprintf(buf, sizeof(buf), "%.2llu:%.2u:%.2u.%.6u", hours, minutes, seconds, useconds);
172 if (len > 0)
173 {
174 unsigned int size = static_cast< unsigned int >(len) >= sizeof(buf) ? static_cast< unsigned int >(sizeof(buf)) : static_cast< unsigned int >(len);
175 m_strm.write(buf, size);
176 }
177 }
178 else
179 {
180 format_special_date_time(value);
181 }
182 }
183
184 void operator() (boost::gregorian::date_duration const& value) const
185 {
186 if (!value.is_special())
187 {
188 m_strm << value.get_rep().as_number();
189 }
190 else
191 {
192 format_special_date_time(value.get_rep().as_special());
193 }
194 }
195
196 template< typename PointRepT, typename DurationRepT >
197 void operator() (boost::date_time::period< PointRepT, DurationRepT > const& value) const
198 {
199 m_strm << '[';
200 this->operator()(value.begin());
201 m_strm << '/';
202 this->operator()(value.last());
203 m_strm << ']';
204 }
205
206 private:
207 template< typename T >
208 void format_special_date_time(T const& value) const
209 {
210 if (value.is_not_a_date_time())
211 m_strm << "not-a-date-time";
212 else if (value.is_pos_infinity())
213 m_strm << "+infinity";
214 else if (value.is_neg_infinity())
215 m_strm << "-infinity";
216 }
217
218 void format_special_date_time(boost::date_time::special_values value) const
219 {
220 switch (value)
221 {
222 case boost::date_time::not_a_date_time:
223 m_strm << "not-a-date-time";
224 break;
225 case boost::date_time::pos_infin:
226 m_strm << "+infinity";
227 break;
228 case boost::date_time::neg_infin:
229 m_strm << "-infinity";
230 break;
231 default:
232 break;
233 }
234 }
235
236 private:
237 basic_formatting_ostream< CharT >& m_strm;
238 };
239
240 public:
241 explicit default_formatter(attribute_name name) : m_attribute_name(name)
242 {
243 }
244
245 result_type operator() (record_view const& rec, basic_formatting_ostream< CharT >& strm) const
246 {
247 typedef BOOST_PP_CAT(mpl::vector, BOOST_PP_SEQ_SIZE(BOOST_LOG_AUX_LOG_DEFAULT_VALUE_TYPES()))<
248 BOOST_PP_SEQ_ENUM(BOOST_LOG_AUX_LOG_DEFAULT_VALUE_TYPES())
249 > value_types;
250
251 boost::log::visit< value_types >(m_attribute_name, rec, visitor(strm));
252 }
253
254 private:
255 const attribute_name m_attribute_name;
256 };
257
258 } // namespace
259
260 //! The callback for equality relation filter
261 template< typename CharT >
262 typename default_formatter_factory< CharT >::formatter_type
263 default_formatter_factory< CharT >::create_formatter(attribute_name const& name, args_map const& args)
264 {
265 // No user-defined factory, shall use the most generic formatter we can ever imagine at this point
266 return formatter_type(default_formatter< CharT >(name));
267 }
268
269 // Explicitly instantiate factory implementation
270 #ifdef BOOST_LOG_USE_CHAR
271 template class default_formatter_factory< char >;
272 #endif
273 #ifdef BOOST_LOG_USE_WCHAR_T
274 template class default_formatter_factory< wchar_t >;
275 #endif
276
277 } // namespace aux
278
279 BOOST_LOG_CLOSE_NAMESPACE // namespace log
280
281 } // namespace boost
282
283 #include <boost/log/detail/footer.hpp>
284
285 #endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)