]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/log/expressions/formatters/c_decorator.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / log / expressions / formatters / c_decorator.hpp
CommitLineData
7c673cae
FG
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 formatters/c_decorator.hpp
9 * \author Andrey Semashev
10 * \date 18.11.2012
11 *
12 * The header contains implementation of C-style character decorators.
13 */
14
15#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
16#define BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
17
18#include <limits>
19#include <boost/range/iterator_range_core.hpp>
20#include <boost/log/detail/config.hpp>
21#include <boost/log/detail/snprintf.hpp>
22#include <boost/log/expressions/formatters/char_decorator.hpp>
23#include <boost/log/detail/header.hpp>
24
25#ifdef BOOST_HAS_PRAGMA_ONCE
26#pragma once
27#endif
28
29namespace boost {
30
31BOOST_LOG_OPEN_NAMESPACE
32
33namespace expressions {
34
35namespace aux {
36
37template< typename >
38struct c_decorator_traits;
39
40#ifdef BOOST_LOG_USE_CHAR
41template< >
42struct c_decorator_traits< char >
43{
44 static boost::iterator_range< const char* const* > get_patterns()
45 {
46 static const char* const patterns[] =
47 {
48 "\\", "\a", "\b", "\f", "\n", "\r", "\t", "\v", "'", "\"", "?"
49 };
50 return boost::make_iterator_range(patterns);
51 }
52 static boost::iterator_range< const char* const* > get_replacements()
53 {
54 static const char* const replacements[] =
55 {
56 "\\\\", "\\a", "\\b", "\\f", "\\n", "\\r", "\\t", "\\v", "\\'", "\\\"", "\\?"
57 };
58 return boost::make_iterator_range(replacements);
59 }
60 template< unsigned int N >
61 static std::size_t print_escaped(char (&buf)[N], char c)
62 {
63 int n = boost::log::aux::snprintf(buf, N, "\\x%.2X", static_cast< unsigned int >(static_cast< uint8_t >(c)));
64 if (n < 0)
65 {
66 n = 0;
67 buf[0] = '\0';
68 }
69 return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
70 }
71};
72#endif // BOOST_LOG_USE_CHAR
73
74#ifdef BOOST_LOG_USE_WCHAR_T
75template< >
76struct c_decorator_traits< wchar_t >
77{
78 static boost::iterator_range< const wchar_t* const* > get_patterns()
79 {
80 static const wchar_t* const patterns[] =
81 {
82 L"\\", L"\a", L"\b", L"\f", L"\n", L"\r", L"\t", L"\v", L"'", L"\"", L"?"
83 };
84 return boost::make_iterator_range(patterns);
85 }
86 static boost::iterator_range< const wchar_t* const* > get_replacements()
87 {
88 static const wchar_t* const replacements[] =
89 {
90 L"\\\\", L"\\a", L"\\b", L"\\f", L"\\n", L"\\r", L"\\t", L"\\v", L"\\'", L"\\\"", L"\\?"
91 };
92 return boost::make_iterator_range(replacements);
93 }
94 template< unsigned int N >
95 static std::size_t print_escaped(wchar_t (&buf)[N], wchar_t c)
96 {
97 const wchar_t* format;
98 unsigned int val;
99 if (sizeof(wchar_t) == 1)
100 {
101 format = L"\\x%.2X";
102 val = static_cast< uint8_t >(c);
103 }
104 else if (sizeof(wchar_t) == 2)
105 {
106 format = L"\\x%.4X";
107 val = static_cast< uint16_t >(c);
108 }
109 else
110 {
111 format = L"\\x%.8X";
112 val = static_cast< uint32_t >(c);
113 }
114
115 int n = boost::log::aux::swprintf(buf, N, format, val);
116 if (n < 0)
117 {
118 n = 0;
119 buf[0] = L'\0';
120 }
121 return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
122 }
123};
124#endif // BOOST_LOG_USE_WCHAR_T
125
126template< typename CharT >
127struct c_decorator_gen
128{
129 typedef CharT char_type;
130
131 template< typename SubactorT >
132 BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
133 {
134 typedef c_decorator_traits< char_type > traits_type;
135 typedef pattern_replacer< char_type > replacer_type;
136 typedef char_decorator_actor< SubactorT, replacer_type > result_type;
137 typedef typename result_type::terminal_type terminal_type;
138 typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(traits_type::get_patterns(), traits_type::get_replacements())) }};
139 return result_type(act);
140 }
141};
142
143} // namespace aux
144
145/*!
146 * C-style decorator generator object. The decorator replaces characters with specific meaning in C
147 * language with the corresponding escape sequences. The generator provides <tt>operator[]</tt> that
148 * can be used to construct the actual decorator. For example:
149 *
150 * <code>
151 * c_decor[ stream << attr< std::string >("MyAttr") ]
152 * </code>
153 *
154 * For wide-character formatting there is the similar \c wc_decor decorator generator object.
155 */
156#ifdef BOOST_LOG_USE_CHAR
20effc67 157BOOST_INLINE_VARIABLE const aux::c_decorator_gen< char > c_decor = {};
7c673cae
FG
158#endif
159#ifdef BOOST_LOG_USE_WCHAR_T
20effc67 160BOOST_INLINE_VARIABLE const aux::c_decorator_gen< wchar_t > wc_decor = {};
7c673cae
FG
161#endif
162
163/*!
164 * The function creates a C-style decorator generator for arbitrary character type.
165 */
166template< typename CharT >
167BOOST_FORCEINLINE aux::c_decorator_gen< CharT > make_c_decor()
168{
169 return aux::c_decorator_gen< CharT >();
170}
171
172/*!
173 * A character decorator implementation that escapes all non-prontable and non-ASCII characters
174 * in the output with C-style escape sequences.
175 */
176template< typename CharT >
177class c_ascii_pattern_replacer :
178 public pattern_replacer< CharT >
179{
180private:
181 //! Base type
182 typedef pattern_replacer< CharT > base_type;
183
184public:
185 //! Result type
186 typedef typename base_type::result_type result_type;
187 //! Character type
188 typedef typename base_type::char_type char_type;
189 //! String type
190 typedef typename base_type::string_type string_type;
191
192private:
193 //! Traits type
194 typedef aux::c_decorator_traits< char_type > traits_type;
195
196public:
197 //! Default constructor
198 c_ascii_pattern_replacer() : base_type(traits_type::get_patterns(), traits_type::get_replacements())
199 {
200 }
201
202 //! Applies string replacements starting from the specified position
203 result_type operator() (string_type& str, typename string_type::size_type start_pos = 0) const
204 {
205 base_type::operator() (str, start_pos);
206
207 typedef typename string_type::iterator string_iterator;
208 for (string_iterator it = str.begin() + start_pos, end = str.end(); it != end; ++it)
209 {
210 char_type c = *it;
211 if (c < 0x20 || c > 0x7e)
212 {
213 char_type buf[(std::numeric_limits< char_type >::digits + 3) / 4 + 3];
214 std::size_t n = traits_type::print_escaped(buf, c);
215 std::size_t pos = it - str.begin();
216 str.replace(pos, 1, buf, n);
217 it = str.begin() + n - 1;
218 end = str.end();
219 }
220 }
221 }
222};
223
224namespace aux {
225
226template< typename CharT >
227struct c_ascii_decorator_gen
228{
229 typedef CharT char_type;
230
231 template< typename SubactorT >
232 BOOST_FORCEINLINE char_decorator_actor< SubactorT, c_ascii_pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
233 {
234 typedef c_ascii_pattern_replacer< char_type > replacer_type;
235 typedef char_decorator_actor< SubactorT, replacer_type > result_type;
236 typedef typename result_type::terminal_type terminal_type;
237 typename result_type::base_type act = {{ terminal_type(subactor, replacer_type()) }};
238 return result_type(act);
239 }
240};
241
242} // namespace aux
243
244/*!
245 * C-style decorator generator object. Acts similarly to \c c_decor, except that \c c_ascii_decor also
246 * converts all non-ASCII and non-printable ASCII characters, except for space character, into
247 * C-style hexadecimal escape sequences. The generator provides <tt>operator[]</tt> that
248 * can be used to construct the actual decorator. For example:
249 *
250 * <code>
251 * c_ascii_decor[ stream << attr< std::string >("MyAttr") ]
252 * </code>
253 *
254 * For wide-character formatting there is the similar \c wc_ascii_decor decorator generator object.
255 */
256#ifdef BOOST_LOG_USE_CHAR
20effc67 257BOOST_INLINE_VARIABLE const aux::c_ascii_decorator_gen< char > c_ascii_decor = {};
7c673cae
FG
258#endif
259#ifdef BOOST_LOG_USE_WCHAR_T
20effc67 260BOOST_INLINE_VARIABLE const aux::c_ascii_decorator_gen< wchar_t > wc_ascii_decor = {};
7c673cae
FG
261#endif
262
263/*!
264 * The function creates a C-style decorator generator for arbitrary character type.
265 */
266template< typename CharT >
267BOOST_FORCEINLINE aux::c_ascii_decorator_gen< CharT > make_c_ascii_decor()
268{
269 return aux::c_ascii_decorator_gen< CharT >();
270}
271
272} // namespace expressions
273
274BOOST_LOG_CLOSE_NAMESPACE // namespace log
275
276} // namespace boost
277
278#include <boost/log/detail/footer.hpp>
279
280#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_