]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 attribute_mapping.hpp | |
9 | * \author Andrey Semashev | |
10 | * \date 07.11.2008 | |
11 | * | |
12 | * The header contains facilities that are used in different sinks to map attribute values | |
13 | * used throughout the application to values used with the specific native logging API. | |
14 | * These tools are mostly needed to map application severity levels on native levels, | |
15 | * required by OS-specific sink backends. | |
16 | */ | |
17 | ||
18 | #ifndef BOOST_LOG_SINKS_ATTRIBUTE_MAPPING_HPP_INCLUDED_ | |
19 | #define BOOST_LOG_SINKS_ATTRIBUTE_MAPPING_HPP_INCLUDED_ | |
20 | ||
21 | #include <map> | |
22 | #include <boost/log/detail/config.hpp> | |
23 | #include <boost/log/detail/tagged_integer.hpp> | |
24 | #include <boost/log/core/record_view.hpp> | |
25 | #include <boost/log/attributes/attribute_name.hpp> | |
26 | #include <boost/log/attributes/attribute_value_set.hpp> | |
27 | #include <boost/log/attributes/value_visitation.hpp> | |
28 | #include <boost/log/detail/header.hpp> | |
29 | ||
30 | #ifdef BOOST_HAS_PRAGMA_ONCE | |
31 | #pragma once | |
32 | #endif | |
33 | ||
34 | namespace boost { | |
35 | ||
36 | BOOST_LOG_OPEN_NAMESPACE | |
37 | ||
38 | namespace sinks { | |
39 | ||
40 | //! Base class for attribute mapping function objects | |
41 | template< typename MappedT > | |
42 | struct basic_mapping | |
43 | { | |
44 | //! Mapped value type | |
45 | typedef MappedT mapped_type; | |
46 | //! Result type | |
47 | typedef mapped_type result_type; | |
48 | }; | |
49 | ||
50 | namespace aux { | |
51 | ||
52 | //! Attribute value visitor | |
53 | template< typename MappedT > | |
54 | struct direct_mapping_visitor | |
55 | { | |
56 | typedef void result_type; | |
57 | typedef MappedT mapped_type; | |
58 | ||
59 | explicit direct_mapping_visitor(mapped_type& extracted) : | |
60 | m_Extracted(extracted) | |
61 | { | |
62 | } | |
63 | template< typename T > | |
64 | void operator() (T const& val) const | |
65 | { | |
66 | m_Extracted = mapped_type(val); | |
67 | } | |
68 | ||
69 | private: | |
70 | mapped_type& m_Extracted; | |
71 | }; | |
72 | // Specialization for the tagged integer | |
73 | template< typename IntT, typename TagT > | |
74 | struct direct_mapping_visitor< boost::log::aux::tagged_integer< IntT, TagT > > | |
75 | { | |
76 | typedef void result_type; | |
77 | typedef boost::log::aux::tagged_integer< IntT, TagT > mapped_type; | |
78 | ||
79 | explicit direct_mapping_visitor(mapped_type& extracted) : | |
80 | m_Extracted(extracted) | |
81 | { | |
82 | } | |
83 | template< typename T > | |
84 | void operator() (T const& val) const | |
85 | { | |
86 | mapped_type v = { static_cast< IntT >(val) }; | |
87 | m_Extracted = v; | |
88 | } | |
89 | ||
90 | private: | |
91 | mapped_type& m_Extracted; | |
92 | }; | |
93 | ||
94 | } // namespace aux | |
95 | ||
96 | /*! | |
97 | * \brief Straightforward mapping | |
98 | * | |
99 | * This type of mapping assumes that attribute with a particular name always | |
100 | * provides values that map directly onto the native values. The mapping | |
101 | * simply returns the extracted attribute value converted to the native value. | |
102 | */ | |
103 | template< typename MappedT, typename AttributeValueT = int > | |
104 | class basic_direct_mapping : | |
105 | public basic_mapping< MappedT > | |
106 | { | |
107 | //! Base type | |
108 | typedef basic_direct_mapping< MappedT > base_type; | |
109 | ||
110 | public: | |
111 | //! Attribute contained value type | |
112 | typedef AttributeValueT attribute_value_type; | |
113 | //! Mapped value type | |
114 | typedef typename base_type::mapped_type mapped_type; | |
115 | ||
116 | private: | |
117 | //! Attribute name | |
118 | const attribute_name m_Name; | |
119 | //! Visitor invoker for the attribute value | |
120 | value_visitor_invoker< attribute_value_type > m_Invoker; | |
121 | //! Default native value | |
122 | mapped_type m_DefaultValue; | |
123 | ||
124 | public: | |
125 | /*! | |
126 | * Constructor | |
127 | * | |
128 | * \param name Attribute name | |
129 | * \param default_value The default native value that is returned if the attribute value is not found | |
130 | */ | |
131 | explicit basic_direct_mapping(attribute_name const& name, mapped_type const& default_value) : | |
132 | m_Name(name), | |
133 | m_DefaultValue(default_value) | |
134 | { | |
135 | } | |
136 | ||
137 | /*! | |
138 | * Extraction operator | |
139 | * | |
140 | * \param rec A log record to extract value from | |
141 | * \return An extracted attribute value | |
142 | */ | |
143 | mapped_type operator() (record_view const& rec) const | |
144 | { | |
145 | mapped_type res = m_DefaultValue; | |
146 | aux::direct_mapping_visitor< mapped_type > vis(res); | |
147 | m_Invoker(m_Name, rec.attribute_values(), vis); | |
148 | return res; | |
149 | } | |
150 | }; | |
151 | ||
152 | /*! | |
153 | * \brief Customizable mapping | |
154 | * | |
155 | * The class allows to setup a custom mapping between an attribute and native values. | |
156 | * The mapping should be initialized similarly to the standard \c map container, by using | |
157 | * indexing operator and assignment. | |
158 | * | |
159 | * \note Unlike many other components of the library, exact type of the attribute value | |
160 | * must be specified in the template parameter \c AttributeValueT. Type sequences | |
161 | * are not supported. | |
162 | */ | |
163 | template< typename MappedT, typename AttributeValueT = int > | |
164 | class basic_custom_mapping : | |
165 | public basic_mapping< MappedT > | |
166 | { | |
167 | //! Base type | |
168 | typedef basic_mapping< MappedT > base_type; | |
169 | ||
170 | public: | |
171 | //! Attribute contained value type | |
172 | typedef AttributeValueT attribute_value_type; | |
173 | //! Mapped value type | |
174 | typedef typename base_type::mapped_type mapped_type; | |
175 | ||
176 | private: | |
177 | //! \cond | |
178 | ||
179 | //! Mapping type | |
180 | typedef std::map< attribute_value_type, mapped_type > mapping_type; | |
181 | //! Smart reference class for implementing insertion into the map | |
182 | class reference_proxy; | |
183 | friend class reference_proxy; | |
184 | class reference_proxy | |
185 | { | |
186 | mapping_type& m_Mapping; | |
187 | attribute_value_type m_Key; | |
188 | ||
189 | public: | |
190 | //! Constructor | |
191 | reference_proxy(mapping_type& mapping, attribute_value_type const& key) : m_Mapping(mapping), m_Key(key) {} | |
192 | //! Insertion | |
193 | reference_proxy const& operator= (mapped_type const& val) const | |
194 | { | |
195 | m_Mapping[m_Key] = val; | |
196 | return *this; | |
197 | } | |
198 | }; | |
199 | ||
200 | //! Attribute value visitor | |
201 | struct visitor; | |
202 | friend struct visitor; | |
203 | struct visitor | |
204 | { | |
205 | typedef void result_type; | |
206 | ||
207 | visitor(mapping_type const& mapping, mapped_type& extracted) : | |
208 | m_Mapping(mapping), | |
209 | m_Extracted(extracted) | |
210 | { | |
211 | } | |
212 | template< typename T > | |
213 | void operator() (T const& val) const | |
214 | { | |
215 | typename mapping_type::const_iterator it = m_Mapping.find(val); | |
216 | if (it != m_Mapping.end()) | |
217 | m_Extracted = it->second; | |
218 | } | |
219 | ||
220 | private: | |
221 | mapping_type const& m_Mapping; | |
222 | mapped_type& m_Extracted; | |
223 | }; | |
224 | ||
225 | //! \endcond | |
226 | ||
227 | private: | |
228 | //! Attribute name | |
229 | const attribute_name m_Name; | |
230 | //! Visitor invoker for the attribute value | |
231 | value_visitor_invoker< attribute_value_type > m_Invoker; | |
232 | //! Default native value | |
233 | mapped_type m_DefaultValue; | |
234 | //! Conversion mapping | |
235 | mapping_type m_Mapping; | |
236 | ||
237 | public: | |
238 | /*! | |
239 | * Constructor | |
240 | * | |
241 | * \param name Attribute name | |
242 | * \param default_value The default native value that is returned if the conversion cannot be performed | |
243 | */ | |
244 | explicit basic_custom_mapping(attribute_name const& name, mapped_type const& default_value) : | |
245 | m_Name(name), | |
246 | m_DefaultValue(default_value) | |
247 | { | |
248 | } | |
249 | /*! | |
250 | * Extraction operator. Extracts the attribute value and attempts to map it onto | |
251 | * the native value. | |
252 | * | |
253 | * \param rec A log record to extract value from | |
254 | * \return A mapped value, if mapping was successful, or the default value if | |
255 | * mapping did not succeed. | |
256 | */ | |
257 | mapped_type operator() (record_view const& rec) const | |
258 | { | |
259 | mapped_type res = m_DefaultValue; | |
260 | visitor vis(m_Mapping, res); | |
261 | m_Invoker(m_Name, rec.attribute_values(), vis); | |
262 | return res; | |
263 | } | |
264 | /*! | |
265 | * Insertion operator | |
266 | * | |
267 | * \param key Attribute value to be mapped | |
268 | * \return An object of unspecified type that allows to insert a new mapping through assignment. | |
269 | * The \a key argument becomes the key attribute value, and the assigned value becomes the | |
270 | * mapped native value. | |
271 | */ | |
272 | #ifndef BOOST_LOG_DOXYGEN_PASS | |
273 | reference_proxy operator[] (attribute_value_type const& key) | |
274 | #else | |
275 | implementation_defined operator[] (attribute_value_type const& key) | |
276 | #endif | |
277 | { | |
278 | return reference_proxy(m_Mapping, key); | |
279 | } | |
280 | }; | |
281 | ||
282 | } // namespace sinks | |
283 | ||
284 | BOOST_LOG_CLOSE_NAMESPACE // namespace log | |
285 | ||
286 | } // namespace boost | |
287 | ||
288 | #include <boost/log/detail/footer.hpp> | |
289 | ||
290 | #endif // BOOST_LOG_SINKS_ATTRIBUTE_MAPPING_HPP_INCLUDED_ |