File indexing completed on 2025-01-18 09:39:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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
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
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 }
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
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
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
0174
0175
0176 template< typename CharT >
0177 class c_ascii_pattern_replacer :
0178 public pattern_replacer< CharT >
0179 {
0180 private:
0181
0182 typedef pattern_replacer< CharT > base_type;
0183
0184 public:
0185
0186 typedef typename base_type::result_type result_type;
0187
0188 typedef typename base_type::char_type char_type;
0189
0190 typedef typename base_type::string_type string_type;
0191
0192 private:
0193
0194 typedef aux::c_decorator_traits< char_type > traits_type;
0195
0196 public:
0197
0198 c_ascii_pattern_replacer() : base_type(traits_type::get_patterns(), traits_type::get_replacements())
0199 {
0200 }
0201
0202
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 }
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
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
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 }
0273
0274 BOOST_LOG_CLOSE_NAMESPACE
0275
0276 }
0277
0278 #include <boost/log/detail/footer.hpp>
0279
0280 #endif