1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
/*
* Copyright Andrey Semashev 2007 - 2015.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file formatter_parser.hpp
* \author Andrey Semashev
* \date 07.04.2008
*
* The header contains definition of a formatter parser function, along with facilities to
* add support for custom formatters.
*/
#ifndef BOOST_LOG_UTILITY_SETUP_FORMATTER_PARSER_HPP_INCLUDED_
#define BOOST_LOG_UTILITY_SETUP_FORMATTER_PARSER_HPP_INCLUDED_
#include <iosfwd>
#include <map>
#include <string>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/log/detail/setup_config.hpp>
#include <boost/log/attributes/attribute_name.hpp>
#include <boost/log/core/record.hpp>
#include <boost/log/expressions/formatter.hpp>
#include <boost/log/expressions/attr.hpp>
#include <boost/log/expressions/formatters/stream.hpp>
#include <boost/log/detail/header.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
BOOST_LOG_OPEN_NAMESPACE
/*!
* Formatter factory base interface.
*/
template< typename CharT >
struct formatter_factory
{
//! Character type
typedef CharT char_type;
//! String type
typedef std::basic_string< char_type > string_type;
//! The formatter function object
typedef basic_formatter< char_type > formatter_type;
/*!
* Type of the map of formatter factory arguments [argument name -> argument value].
* This type of maps will be passed to formatter factories on attempt to create a formatter.
*/
typedef std::map< string_type, string_type > args_map;
/*!
* Default constructor
*/
BOOST_DEFAULTED_FUNCTION(formatter_factory(), {})
/*!
* Virtual destructor
*/
virtual ~formatter_factory() {}
/*!
* The function creates a formatter for the specified attribute.
*
* \param name Attribute name
* \param args Formatter arguments
*/
virtual formatter_type create_formatter(attribute_name const& name, args_map const& args) = 0;
BOOST_DELETED_FUNCTION(formatter_factory(formatter_factory const&))
BOOST_DELETED_FUNCTION(formatter_factory& operator= (formatter_factory const&))
};
/*!
* Base class for formatter factories. This class provides default implementation of formatter expressions for
* types supporting stream output. The factory does not take into account any additional parameters that may be specified.
*/
template< typename CharT, typename AttributeValueT >
class basic_formatter_factory :
public formatter_factory< CharT >
{
private:
typedef formatter_factory< CharT > base_type;
public:
//! Attribute value type
typedef AttributeValueT value_type;
// Type imports from the base class
typedef typename base_type::formatter_type formatter_type;
typedef typename base_type::args_map args_map;
/*!
* The function creates a formatter for the specified attribute.
*
* \param name Attribute name
* \param args Formatter arguments
*/
formatter_type create_formatter(attribute_name const& name, args_map const& args)
{
return formatter_type(expressions::stream << expressions::attr< value_type >(name));
}
};
/*!
* \brief The function registers a user-defined formatter factory
*
* The function registers a user-defined formatter factory. The registered factory function will be
* called when the formatter parser detects the specified attribute name in the formatter string.
*
* \pre <tt>!!attr_name && !!factory</tt>.
*
* \param attr_name Attribute name
* \param factory Pointer to the formatter factory
*/
template< typename CharT >
BOOST_LOG_SETUP_API void register_formatter_factory(
attribute_name const& attr_name, shared_ptr< formatter_factory< CharT > > const& factory);
/*!
* \brief The function registers a user-defined formatter factory
*
* The function registers a user-defined formatter factory. The registered factory function will be
* called when the formatter parser detects the specified attribute name in the formatter string.
*
* \pre <tt>!!attr_name && !!factory</tt>.
*
* \param attr_name Attribute name
* \param factory Pointer to the formatter factory
*/
template< typename FactoryT >
inline typename boost::enable_if_c<
is_base_and_derived< formatter_factory< typename FactoryT::char_type >, FactoryT >::value
>::type register_formatter_factory(attribute_name const& attr_name, shared_ptr< FactoryT > const& factory)
{
typedef formatter_factory< typename FactoryT::char_type > factory_base;
register_formatter_factory(attr_name, boost::static_pointer_cast< factory_base >(factory));
}
/*!
* \brief The function registers a simple formatter factory
*
* The function registers a simple formatter factory. The registered factory will generate formatters
* that will be equivalent to the <tt>log::expressions::attr</tt> formatter (i.e. that will use the
* native \c operator<< to format the attribute value). The factory does not use any arguments from the format string,
* if specified.
*
* \pre <tt>!!attr_name</tt>.
*
* \param attr_name Attribute name
*/
template< typename AttributeValueT, typename CharT >
inline void register_simple_formatter_factory(attribute_name const& attr_name)
{
shared_ptr< formatter_factory< CharT > > factory =
boost::make_shared< basic_formatter_factory< CharT, AttributeValueT > >();
register_formatter_factory(attr_name, factory);
}
/*!
* The function parses a formatter from the sequence of characters
*
* \pre <tt>begin <= end</tt>, both pointers must not be NULL
* \param begin Pointer to the first character of the sequence
* \param end Pointer to the after-the-last character of the sequence
* \return The parsed formatter.
*
* \b Throws: An <tt>std::exception</tt>-based exception, if a formatter cannot be recognized in the character sequence.
*/
template< typename CharT >
BOOST_LOG_SETUP_API basic_formatter< CharT > parse_formatter(const CharT* begin, const CharT* end);
/*!
* The function parses a formatter from the string
*
* \param str A string that contains format description
* \return The parsed formatter.
*
* \b Throws: An <tt>std::exception</tt>-based exception, if a formatter cannot be recognized in the character sequence.
*/
template< typename CharT, typename TraitsT, typename AllocatorT >
inline basic_formatter< CharT > parse_formatter(std::basic_string< CharT, TraitsT, AllocatorT > const& str)
{
const CharT* p = str.c_str();
return parse_formatter(p, p + str.size());
}
/*!
* The function parses a formatter from the string
*
* \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string
* \param str A string that contains format description.
* \return The parsed formatter.
*
* \b Throws: An <tt>std::exception</tt>-based exception, if a formatter cannot be recognized in the character sequence.
*/
template< typename CharT >
inline basic_formatter< CharT > parse_formatter(const CharT* str)
{
return parse_formatter(str, str + std::char_traits< CharT >::length(str));
}
BOOST_LOG_CLOSE_NAMESPACE // namespace log
} // namespace boost
#include <boost/log/detail/footer.hpp>
#endif // BOOST_LOG_UTILITY_SETUP_FORMATTER_PARSER_HPP_INCLUDED_
|