/* * Copyright Andrey Semashev 2007 - 2014. * 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 filter_parser.hpp * \author Andrey Semashev * \date 31.03.2008 * * The header contains definition of a filter parser function. */ #ifndef BOOST_LOG_UTILITY_SETUP_FILTER_PARSER_HPP_INCLUDED_ #define BOOST_LOG_UTILITY_SETUP_FILTER_PARSER_HPP_INCLUDED_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif namespace boost { BOOST_LOG_OPEN_NAMESPACE /*! * The interface class for all filter factories. */ template< typename CharT > struct filter_factory { //! Character type typedef CharT char_type; //! String type typedef std::basic_string< char_type > string_type; /*! * Default constructor */ BOOST_DEFAULTED_FUNCTION(filter_factory(), {}) /*! * Virtual destructor */ virtual ~filter_factory() {} /*! * The callback for filter for the attribute existence test */ virtual filter on_exists_test(attribute_name const& name) { return filter(expressions::has_attr(name)); } /*! * The callback for equality relation filter */ virtual filter on_equality_relation(attribute_name const& name, string_type const& arg) { BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The equality attribute value relation is not supported", (name)); BOOST_LOG_UNREACHABLE_RETURN(filter()); } /*! * The callback for inequality relation filter */ virtual filter on_inequality_relation(attribute_name const& name, string_type const& arg) { BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The inequality attribute value relation is not supported", (name)); BOOST_LOG_UNREACHABLE_RETURN(filter()); } /*! * The callback for less relation filter */ virtual filter on_less_relation(attribute_name const& name, string_type const& arg) { BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The less attribute value relation is not supported", (name)); BOOST_LOG_UNREACHABLE_RETURN(filter()); } /*! * The callback for greater relation filter */ virtual filter on_greater_relation(attribute_name const& name, string_type const& arg) { BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The greater attribute value relation is not supported", (name)); BOOST_LOG_UNREACHABLE_RETURN(filter()); } /*! * The callback for less or equal relation filter */ virtual filter on_less_or_equal_relation(attribute_name const& name, string_type const& arg) { BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The less-or-equal attribute value relation is not supported", (name)); BOOST_LOG_UNREACHABLE_RETURN(filter()); } /*! * The callback for greater or equal relation filter */ virtual filter on_greater_or_equal_relation(attribute_name const& name, string_type const& arg) { BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The greater-or-equal attribute value relation is not supported", (name)); BOOST_LOG_UNREACHABLE_RETURN(filter()); } /*! * The callback for custom relation filter */ virtual filter on_custom_relation(attribute_name const& name, string_type const& rel, string_type const& arg) { BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The custom attribute value relation \"" + boost::log::aux::to_narrow(arg) + "\" is not supported", (name)); BOOST_LOG_UNREACHABLE_RETURN(filter()); } BOOST_DELETED_FUNCTION(filter_factory(filter_factory const&)) BOOST_DELETED_FUNCTION(filter_factory& operator= (filter_factory const&)) }; /*! * The base class for filter factories. The class defines default implementations for most * filter expressions. In order to be able to construct filters, the attribute value type must * support reading from a stream. Also, the default filters will rely on relational operators for * the type, so these operators must also be defined. */ template< typename CharT, typename AttributeValueT > class basic_filter_factory : public filter_factory< CharT > { //! Base type typedef filter_factory< CharT > base_type; public: //! The type(s) of the attribute value expected typedef AttributeValueT value_type; // Type imports typedef typename base_type::string_type string_type; /*! * The callback for filter for the attribute existence test */ virtual filter on_exists_test(attribute_name const& name) { return filter(expressions::has_attr< value_type >(name)); } /*! * The callback for equality relation filter */ virtual filter on_equality_relation(attribute_name const& name, string_type const& arg) { return filter(expressions::attr< value_type >(name) == parse_argument(arg)); } /*! * The callback for inequality relation filter */ virtual filter on_inequality_relation(attribute_name const& name, string_type const& arg) { return filter(expressions::attr< value_type >(name) != parse_argument(arg)); } /*! * The callback for less relation filter */ virtual filter on_less_relation(attribute_name const& name, string_type const& arg) { return filter(expressions::attr< value_type >(name) < parse_argument(arg)); } /*! * The callback for greater relation filter */ virtual filter on_greater_relation(attribute_name const& name, string_type const& arg) { return filter(expressions::attr< value_type >(name) > parse_argument(arg)); } /*! * The callback for less or equal relation filter */ virtual filter on_less_or_equal_relation(attribute_name const& name, string_type const& arg) { return filter(expressions::attr< value_type >(name) <= parse_argument(arg)); } /*! * The callback for greater or equal relation filter */ virtual filter on_greater_or_equal_relation(attribute_name const& name, string_type const& arg) { return filter(expressions::attr< value_type >(name) >= parse_argument(arg)); } /*! * The callback for custom relation filter */ virtual filter on_custom_relation(attribute_name const& name, string_type const& rel, string_type const& arg) { BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The custom attribute value relation \"" + boost::log::aux::to_narrow(arg) + "\" is not supported", (name)); BOOST_LOG_UNREACHABLE_RETURN(filter()); } /*! * The function parses the argument value for a binary relation */ virtual value_type parse_argument(string_type const& arg) { return boost::lexical_cast< value_type >(arg); } }; /*! * The function registers a filter factory object for the specified attribute name. The factory will be * used to construct a filter during parsing the filter string. * * \pre name != NULL && factory != NULL, name points to a zero-terminated string * \param name Attribute name to associate the factory with * \param factory The filter factory */ template< typename CharT > BOOST_LOG_SETUP_API void register_filter_factory( attribute_name const& name, shared_ptr< filter_factory< CharT > > const& factory); /*! * The function registers a filter factory object for the specified attribute name. The factory will be * used to construct a filter during parsing the filter string. * * \pre name != NULL && factory != NULL, name points to a zero-terminated string * \param name Attribute name to associate the factory with * \param factory The filter factory */ template< typename FactoryT > inline typename enable_if< is_base_and_derived< filter_factory< typename FactoryT::char_type >, FactoryT > >::type register_filter_factory(attribute_name const& name, shared_ptr< FactoryT > const& factory) { typedef filter_factory< typename FactoryT::char_type > factory_base; register_filter_factory(name, boost::static_pointer_cast< factory_base >(factory)); } /*! * The function registers a simple filter factory object for the specified attribute name. The factory will * support attribute values of type \c AttributeValueT, which must support all relation operations, such as * equality comparison and less/greater ordering, and also extraction from stream. * * \pre name != NULL, name points to a zero-terminated string * \param name Attribute name to associate the factory with */ template< typename AttributeValueT, typename CharT > inline void register_simple_filter_factory(attribute_name const& name) { shared_ptr< filter_factory< CharT > > factory = boost::make_shared< basic_filter_factory< CharT, AttributeValueT > >(); register_filter_factory(name, factory); } /*! * The function registers a simple filter factory object for the specified attribute name. The factory will * support attribute values of type \c AttributeValueT, which must support all relation operations, such as * equality comparison and less/greater ordering, and also extraction from stream. * * \pre name != NULL, name points to a zero-terminated string * \param name Attribute name to associate the factory with */ template< typename AttributeValueT > inline void register_simple_filter_factory(attribute_name const& name) { register_simple_filter_factory< AttributeValueT, char >(name); } /*! * The function registers a simple filter factory object for the specified attribute keyword. The factory will * support attribute values described by the keyword. The values must support all relation operations, such as * equality comparison and less/greater ordering, and also extraction from stream. * * \pre name != NULL, name points to a zero-terminated string * \param keyword Attribute keyword to associate the factory with */ template< typename CharT, typename DescriptorT, template< typename > class ActorT > inline void register_simple_filter_factory(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword) { register_simple_filter_factory< typename DescriptorT::value_type, CharT >(keyword.get_name()); } /*! * The function parses a filter from the sequence of characters * * \pre begin <= end, both pointers must not be \c NULL * \param begin Pointer to the first character of the sequence * \param end Pointer to the after-the-last character of the sequence * \return A function object that can be used as a filter. * * \b Throws: An std::exception-based exception, if a filter cannot be recognized in the character sequence. */ template< typename CharT > BOOST_LOG_SETUP_API filter parse_filter(const CharT* begin, const CharT* end); /*! * The function parses a filter from the string * * \param str A string that contains filter description * \return A function object that can be used as a filter. * * \b Throws: An std::exception-based exception, if a filter cannot be recognized in the character sequence. */ template< typename CharT, typename TraitsT, typename AllocatorT > inline filter parse_filter(std::basic_string< CharT, TraitsT, AllocatorT > const& str) { const CharT* p = str.c_str(); return parse_filter(p, p + str.size()); } /*! * The function parses a filter from the string * * \pre str != NULL, str points to a zero-terminated string. * \param str A string that contains filter description. * \return A function object that can be used as a filter. * * \b Throws: An std::exception-based exception, if a filter cannot be recognized in the character sequence. */ template< typename CharT > inline filter parse_filter(const CharT* str) { return parse_filter(str, str + std::char_traits< CharT >::length(str)); } BOOST_LOG_CLOSE_NAMESPACE // namespace log } // namespace boost #include #endif // BOOST_LOG_UTILITY_SETUP_FILTER_PARSER_HPP_INCLUDED_