Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:22

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2015.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   formatters/c_decorator.hpp
0009  * \author Andrey Semashev
0010  * \date   18.11.2012
0011  *
0012  * The header contains implementation of C-style character decorators.
0013  */
0014 
0015 #ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
0016 #define BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
0017 
0018 #include <limits>
0019 #include <boost/core/snprintf.hpp>
0020 #include <boost/range/iterator_range_core.hpp>
0021 #include <boost/log/detail/config.hpp>
0022 #include <boost/log/expressions/formatters/char_decorator.hpp>
0023 #include <boost/log/detail/header.hpp>
0024 
0025 #ifdef BOOST_HAS_PRAGMA_ONCE
0026 #pragma once
0027 #endif
0028 
0029 namespace boost {
0030 
0031 BOOST_LOG_OPEN_NAMESPACE
0032 
0033 namespace expressions {
0034 
0035 namespace aux {
0036 
0037 template< typename >
0038 struct c_decorator_traits;
0039 
0040 #ifdef BOOST_LOG_USE_CHAR
0041 template< >
0042 struct c_decorator_traits< char >
0043 {
0044     static boost::iterator_range< const char* const* > get_patterns()
0045     {
0046         static const char* const patterns[] =
0047         {
0048             "\\", "\a", "\b", "\f", "\n", "\r", "\t", "\v", "'", "\"", "?"
0049         };
0050         return boost::make_iterator_range(patterns);
0051     }
0052     static boost::iterator_range< const char* const* > get_replacements()
0053     {
0054         static const char* const replacements[] =
0055         {
0056             "\\\\", "\\a", "\\b", "\\f", "\\n", "\\r", "\\t", "\\v", "\\'", "\\\"", "\\?"
0057         };
0058         return boost::make_iterator_range(replacements);
0059     }
0060     template< unsigned int N >
0061     static std::size_t print_escaped(char (&buf)[N], char c)
0062     {
0063         int n = boost::core::snprintf(buf, N, "\\x%.2X", static_cast< unsigned int >(static_cast< uint8_t >(c)));
0064         if (BOOST_UNLIKELY(n < 0))
0065         {
0066             n = 0;
0067             buf[0] = '\0';
0068         }
0069         return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
0070     }
0071 };
0072 #endif // BOOST_LOG_USE_CHAR
0073 
0074 #ifdef BOOST_LOG_USE_WCHAR_T
0075 template< >
0076 struct c_decorator_traits< wchar_t >
0077 {
0078     static boost::iterator_range< const wchar_t* const* > get_patterns()
0079     {
0080         static const wchar_t* const patterns[] =
0081         {
0082             L"\\", L"\a", L"\b", L"\f", L"\n", L"\r", L"\t", L"\v", L"'", L"\"", L"?"
0083         };
0084         return boost::make_iterator_range(patterns);
0085     }
0086     static boost::iterator_range< const wchar_t* const* > get_replacements()
0087     {
0088         static const wchar_t* const replacements[] =
0089         {
0090             L"\\\\", L"\\a", L"\\b", L"\\f", L"\\n", L"\\r", L"\\t", L"\\v", L"\\'", L"\\\"", L"\\?"
0091         };
0092         return boost::make_iterator_range(replacements);
0093     }
0094     template< unsigned int N >
0095     static std::size_t print_escaped(wchar_t (&buf)[N], wchar_t c)
0096     {
0097         const wchar_t* format;
0098         unsigned int val;
0099         if (sizeof(wchar_t) == 1)
0100         {
0101             format = L"\\x%.2X";
0102             val = static_cast< uint8_t >(c);
0103         }
0104         else if (sizeof(wchar_t) == 2)
0105         {
0106             format = L"\\x%.4X";
0107             val = static_cast< uint16_t >(c);
0108         }
0109         else
0110         {
0111             format = L"\\x%.8X";
0112             val = static_cast< uint32_t >(c);
0113         }
0114 
0115         int n = boost::core::swprintf(buf, N, format, val);
0116         if (BOOST_UNLIKELY(n < 0))
0117         {
0118             n = 0;
0119             buf[0] = L'\0';
0120         }
0121         return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
0122     }
0123 };
0124 #endif // BOOST_LOG_USE_WCHAR_T
0125 
0126 template< typename CharT >
0127 struct c_decorator_gen
0128 {
0129     typedef CharT char_type;
0130 
0131     template< typename SubactorT >
0132     BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
0133     {
0134         typedef c_decorator_traits< char_type > traits_type;
0135         typedef pattern_replacer< char_type > replacer_type;
0136         typedef char_decorator_actor< SubactorT, replacer_type > result_type;
0137         typedef typename result_type::terminal_type terminal_type;
0138         typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(traits_type::get_patterns(), traits_type::get_replacements())) }};
0139         return result_type(act);
0140     }
0141 };
0142 
0143 } // namespace aux
0144 
0145 /*!
0146  * C-style decorator generator object. The decorator replaces characters with specific meaning in C
0147  * language with the corresponding escape sequences. The generator provides <tt>operator[]</tt> that
0148  * can be used to construct the actual decorator. For example:
0149  *
0150  * <code>
0151  * c_decor[ stream << attr< std::string >("MyAttr") ]
0152  * </code>
0153  *
0154  * For wide-character formatting there is the similar \c wc_decor decorator generator object.
0155  */
0156 #ifdef BOOST_LOG_USE_CHAR
0157 BOOST_INLINE_VARIABLE const aux::c_decorator_gen< char > c_decor = {};
0158 #endif
0159 #ifdef BOOST_LOG_USE_WCHAR_T
0160 BOOST_INLINE_VARIABLE const aux::c_decorator_gen< wchar_t > wc_decor = {};
0161 #endif
0162 
0163 /*!
0164  * The function creates a C-style decorator generator for arbitrary character type.
0165  */
0166 template< typename CharT >
0167 BOOST_FORCEINLINE aux::c_decorator_gen< CharT > make_c_decor()
0168 {
0169     return aux::c_decorator_gen< CharT >();
0170 }
0171 
0172 /*!
0173  * A character decorator implementation that escapes all non-prontable and non-ASCII characters
0174  * in the output with C-style escape sequences.
0175  */
0176 template< typename CharT >
0177 class c_ascii_pattern_replacer :
0178     public pattern_replacer< CharT >
0179 {
0180 private:
0181     //! Base type
0182     typedef pattern_replacer< CharT > base_type;
0183 
0184 public:
0185     //! Result type
0186     typedef typename base_type::result_type result_type;
0187     //! Character type
0188     typedef typename base_type::char_type char_type;
0189     //! String type
0190     typedef typename base_type::string_type string_type;
0191 
0192 private:
0193     //! Traits type
0194     typedef aux::c_decorator_traits< char_type > traits_type;
0195 
0196 public:
0197     //! Default constructor
0198     c_ascii_pattern_replacer() : base_type(traits_type::get_patterns(), traits_type::get_replacements())
0199     {
0200     }
0201 
0202     //! Applies string replacements starting from the specified position
0203     result_type operator() (string_type& str, typename string_type::size_type start_pos = 0) const
0204     {
0205         base_type::operator() (str, start_pos);
0206 
0207         typedef typename string_type::iterator string_iterator;
0208         for (string_iterator it = str.begin() + start_pos, end = str.end(); it != end; ++it)
0209         {
0210             char_type c = *it;
0211             if (c < 0x20 || c > 0x7e)
0212             {
0213                 char_type buf[(std::numeric_limits< char_type >::digits + 3) / 4 + 3];
0214                 std::size_t n = traits_type::print_escaped(buf, c);
0215                 std::size_t pos = it - str.begin();
0216                 str.replace(pos, 1, buf, n);
0217                 it = str.begin() + n - 1;
0218                 end = str.end();
0219             }
0220         }
0221     }
0222 };
0223 
0224 namespace aux {
0225 
0226 template< typename CharT >
0227 struct c_ascii_decorator_gen
0228 {
0229     typedef CharT char_type;
0230 
0231     template< typename SubactorT >
0232     BOOST_FORCEINLINE char_decorator_actor< SubactorT, c_ascii_pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
0233     {
0234         typedef c_ascii_pattern_replacer< char_type > replacer_type;
0235         typedef char_decorator_actor< SubactorT, replacer_type > result_type;
0236         typedef typename result_type::terminal_type terminal_type;
0237         typename result_type::base_type act = {{ terminal_type(subactor, replacer_type()) }};
0238         return result_type(act);
0239     }
0240 };
0241 
0242 } // namespace aux
0243 
0244 /*!
0245  * C-style decorator generator object. Acts similarly to \c c_decor, except that \c c_ascii_decor also
0246  * converts all non-ASCII and non-printable ASCII characters, except for space character, into
0247  * C-style hexadecimal escape sequences. The generator provides <tt>operator[]</tt> that
0248  * can be used to construct the actual decorator. For example:
0249  *
0250  * <code>
0251  * c_ascii_decor[ stream << attr< std::string >("MyAttr") ]
0252  * </code>
0253  *
0254  * For wide-character formatting there is the similar \c wc_ascii_decor decorator generator object.
0255  */
0256 #ifdef BOOST_LOG_USE_CHAR
0257 BOOST_INLINE_VARIABLE const aux::c_ascii_decorator_gen< char > c_ascii_decor = {};
0258 #endif
0259 #ifdef BOOST_LOG_USE_WCHAR_T
0260 BOOST_INLINE_VARIABLE const aux::c_ascii_decorator_gen< wchar_t > wc_ascii_decor = {};
0261 #endif
0262 
0263 /*!
0264  * The function creates a C-style decorator generator for arbitrary character type.
0265  */
0266 template< typename CharT >
0267 BOOST_FORCEINLINE aux::c_ascii_decorator_gen< CharT > make_c_ascii_decor()
0268 {
0269     return aux::c_ascii_decorator_gen< CharT >();
0270 }
0271 
0272 } // namespace expressions
0273 
0274 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0275 
0276 } // namespace boost
0277 
0278 #include <boost/log/detail/footer.hpp>
0279 
0280 #endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_