• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
direct_mapping_visitorboost::sinks::aux::direct_mapping_visitor59         explicit direct_mapping_visitor(mapped_type& extracted) :
60             m_Extracted(extracted)
61         {
62         }
63         template< typename T >
operator ()boost::sinks::aux::direct_mapping_visitor64         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 
direct_mapping_visitorboost::sinks::aux::direct_mapping_visitor79         explicit direct_mapping_visitor(mapped_type& extracted) :
80             m_Extracted(extracted)
81         {
82         }
83         template< typename T >
operator ()boost::sinks::aux::direct_mapping_visitor84         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      */
basic_direct_mapping(attribute_name const & name,mapped_type const & default_value)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      */
operator ()(record_view const & rec) const143     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
reference_proxy(mapping_type & mapping,attribute_value_type const & key)191         reference_proxy(mapping_type& mapping, attribute_value_type const& key) : m_Mapping(mapping), m_Key(key) {}
192         //! Insertion
operator =(mapped_type const & val) const193         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 
visitorboost::sinks::basic_custom_mapping::visitor207         visitor(mapping_type const& mapping, mapped_type& extracted) :
208             m_Mapping(mapping),
209             m_Extracted(extracted)
210         {
211         }
212         template< typename T >
operator ()boost::sinks::basic_custom_mapping::visitor213         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      */
basic_custom_mapping(attribute_name const & name,mapped_type const & default_value)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      */
operator ()(record_view const & rec) const257     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
operator [](attribute_value_type const & key)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_
291