dump.hpp 6.9 KB

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