]>
Commit | Line | Data |
---|---|---|
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 dump.hpp | |
9 | * \author Andrey Semashev | |
10 | * \date 03.05.2013 | |
11 | * | |
12 | * This header contains the \c dump output manipulator. | |
13 | */ | |
14 | ||
15 | #ifndef BOOST_LOG_UTILITY_MANIPULATORS_DUMP_HPP_INCLUDED_ | |
16 | #define BOOST_LOG_UTILITY_MANIPULATORS_DUMP_HPP_INCLUDED_ | |
17 | ||
18 | #include <cstddef> | |
19 | #include <iosfwd> | |
20 | #include <boost/log/detail/config.hpp> | |
21 | #include <boost/log/detail/header.hpp> | |
22 | ||
23 | #ifdef BOOST_HAS_PRAGMA_ONCE | |
24 | #pragma once | |
25 | #endif | |
26 | ||
27 | namespace boost { | |
28 | ||
29 | BOOST_LOG_OPEN_NAMESPACE | |
30 | ||
31 | namespace aux { | |
32 | ||
33 | typedef void dump_data_char_t(const void* data, std::size_t size, std::basic_ostream< char >& strm); | |
34 | extern BOOST_LOG_API dump_data_char_t* dump_data_char; | |
35 | BOOST_FORCEINLINE void dump_data(const void* data, std::size_t size, std::basic_ostream< char >& strm) | |
36 | { | |
37 | (dump_data_char)(data, size, strm); | |
38 | } | |
39 | ||
40 | typedef void dump_data_wchar_t(const void* data, std::size_t size, std::basic_ostream< wchar_t >& strm); | |
41 | extern BOOST_LOG_API dump_data_wchar_t* dump_data_wchar; | |
42 | BOOST_FORCEINLINE void dump_data(const void* data, std::size_t size, std::basic_ostream< wchar_t >& strm) | |
43 | { | |
44 | (dump_data_wchar)(data, size, strm); | |
45 | } | |
46 | ||
47 | #if !defined(BOOST_NO_CXX11_CHAR16_T) | |
48 | typedef void dump_data_char16_t(const void* data, std::size_t size, std::basic_ostream< char16_t >& strm); | |
49 | extern BOOST_LOG_API dump_data_char16_t* dump_data_char16; | |
50 | BOOST_FORCEINLINE void dump_data(const void* data, std::size_t size, std::basic_ostream< char16_t >& strm) | |
51 | { | |
52 | (dump_data_char16)(data, size, strm); | |
53 | } | |
54 | #endif | |
55 | ||
56 | #if !defined(BOOST_NO_CXX11_CHAR32_T) | |
57 | typedef void dump_data_char32_t(const void* data, std::size_t size, std::basic_ostream< char32_t >& strm); | |
58 | extern BOOST_LOG_API dump_data_char32_t* dump_data_char32; | |
59 | BOOST_FORCEINLINE void dump_data(const void* data, std::size_t size, std::basic_ostream< char32_t >& strm) | |
60 | { | |
61 | (dump_data_char32)(data, size, strm); | |
62 | } | |
63 | #endif | |
64 | ||
65 | template< std::size_t SizeV, typename R > | |
66 | struct enable_dump_size_based | |
67 | { | |
68 | }; | |
69 | ||
70 | template< typename R > | |
71 | struct enable_dump_size_based< 1u, R > | |
72 | { | |
73 | typedef R type; | |
74 | }; | |
75 | ||
76 | template< typename T, typename R > | |
77 | struct enable_dump : | |
78 | public enable_dump_size_based< sizeof(T), R > | |
79 | { | |
80 | }; | |
81 | ||
82 | template< typename R > | |
83 | struct enable_dump< void, R > | |
84 | { | |
85 | typedef R type; | |
86 | }; | |
87 | ||
88 | template< typename R > | |
89 | struct enable_dump< const void, R > | |
90 | { | |
91 | typedef R type; | |
92 | }; | |
93 | ||
94 | template< typename R > | |
95 | struct enable_dump< volatile void, R > | |
96 | { | |
97 | typedef R type; | |
98 | }; | |
99 | ||
100 | template< typename R > | |
101 | struct enable_dump< const volatile void, R > | |
102 | { | |
103 | typedef R type; | |
104 | }; | |
105 | ||
106 | } // namespace aux | |
107 | ||
108 | /*! | |
109 | * \brief Manipulator for printing binary representation of the data | |
110 | */ | |
111 | class dump_manip | |
112 | { | |
113 | private: | |
114 | //! Beginning of the data | |
115 | const void* m_data; | |
116 | //! Size of the data, in bytes | |
117 | std::size_t m_size; | |
118 | ||
119 | public: | |
120 | dump_manip(const void* data, std::size_t size) BOOST_NOEXCEPT : m_data(data), m_size(size) {} | |
121 | dump_manip(dump_manip const& that) BOOST_NOEXCEPT : m_data(that.m_data), m_size(that.m_size) {} | |
122 | ||
123 | const void* get_data() const BOOST_NOEXCEPT { return m_data; } | |
124 | std::size_t get_size() const BOOST_NOEXCEPT { return m_size; } | |
125 | }; | |
126 | ||
127 | //! The operator outputs binary data to a stream | |
128 | template< typename CharT, typename TraitsT > | |
129 | inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, dump_manip const& manip) | |
130 | { | |
131 | if (strm.good()) | |
132 | aux::dump_data(manip.get_data(), manip.get_size(), strm); | |
133 | ||
134 | return strm; | |
135 | } | |
136 | ||
137 | /*! | |
138 | * \brief Manipulator for printing binary representation of the data with a size limit | |
139 | */ | |
140 | class bounded_dump_manip : | |
141 | public dump_manip | |
142 | { | |
143 | private: | |
144 | //! Maximum size to output, in bytes | |
145 | std::size_t m_max_size; | |
146 | ||
147 | public: | |
148 | bounded_dump_manip(const void* data, std::size_t size, std::size_t max_size) BOOST_NOEXCEPT : dump_manip(data, size), m_max_size(max_size) {} | |
149 | bounded_dump_manip(bounded_dump_manip const& that) BOOST_NOEXCEPT : dump_manip(static_cast< dump_manip const& >(that)), m_max_size(that.m_max_size) {} | |
150 | ||
151 | std::size_t get_max_size() const BOOST_NOEXCEPT { return m_max_size; } | |
152 | }; | |
153 | ||
154 | //! The operator outputs binary data to a stream | |
155 | template< typename CharT, typename TraitsT > | |
156 | inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, bounded_dump_manip const& manip) | |
157 | { | |
158 | if (strm.good()) | |
159 | { | |
160 | const std::size_t size = manip.get_size(), max_size = manip.get_max_size(); | |
161 | if (max_size >= size) | |
162 | { | |
163 | aux::dump_data(manip.get_data(), size, strm); | |
164 | } | |
165 | else | |
166 | { | |
167 | aux::dump_data(manip.get_data(), max_size, strm); | |
168 | strm << " and " << (size - max_size) << " bytes more"; | |
169 | } | |
170 | } | |
171 | ||
172 | return strm; | |
173 | } | |
174 | ||
175 | /*! | |
176 | * \brief Creates a stream manipulator that will output contents of a memory region in hexadecimal form | |
177 | * \param data The pointer to the beginning of the region | |
178 | * \param size The size of the region, in bytes | |
179 | * \return The manipulator that is to be put to a stream | |
180 | */ | |
181 | template< typename T > | |
182 | inline typename aux::enable_dump< T, dump_manip >::type dump(T* data, std::size_t size) BOOST_NOEXCEPT | |
183 | { | |
184 | return dump_manip((const void*)data, size); | |
185 | } | |
186 | ||
187 | /*! | |
188 | * \brief Creates a stream manipulator that will dump elements of an array in hexadecimal form | |
189 | * \param data The pointer to the beginning of the array | |
190 | * \param count The size of the region, in number of \c T elements | |
191 | * \return The manipulator that is to be put to a stream | |
192 | */ | |
193 | template< typename T > | |
194 | inline dump_manip dump_elements(T* data, std::size_t count) BOOST_NOEXCEPT | |
195 | { | |
196 | return dump_manip((const void*)data, count * sizeof(T)); | |
197 | } | |
198 | ||
199 | /*! | |
200 | * \brief Creates a stream manipulator that will output contents of a memory region in hexadecimal form | |
201 | * \param data The pointer to the beginning of the region | |
202 | * \param size The size of the region, in bytes | |
203 | * \param max_size The maximum number of bytes of the region to output | |
204 | * \return The manipulator that is to be put to a stream | |
205 | */ | |
206 | template< typename T > | |
207 | inline typename aux::enable_dump< T, bounded_dump_manip >::type dump(T* data, std::size_t size, std::size_t max_size) BOOST_NOEXCEPT | |
208 | { | |
209 | return bounded_dump_manip((const void*)data, size, max_size); | |
210 | } | |
211 | ||
212 | /*! | |
213 | * \brief Creates a stream manipulator that will dump elements of an array in hexadecimal form | |
214 | * \param data The pointer to the beginning of the array | |
215 | * \param count The size of the region, in number of \c T elements | |
216 | * \param max_count The maximum number of elements to output | |
217 | * \return The manipulator that is to be put to a stream | |
218 | */ | |
219 | template< typename T > | |
220 | inline bounded_dump_manip dump_elements(T* data, std::size_t count, std::size_t max_count) BOOST_NOEXCEPT | |
221 | { | |
222 | return bounded_dump_manip((const void*)data, count * sizeof(T), max_count * sizeof(T)); | |
223 | } | |
224 | ||
225 | BOOST_LOG_CLOSE_NAMESPACE // namespace log | |
226 | ||
227 | } // namespace boost | |
228 | ||
229 | #include <boost/log/detail/footer.hpp> | |
230 | ||
231 | #endif // BOOST_LOG_UTILITY_MANIPULATORS_DUMP_HPP_INCLUDED_ |