1 //
2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9 
10 #ifndef BOOST_BEAST_MAKE_PRINTABLE_HPP
11 #define BOOST_BEAST_MAKE_PRINTABLE_HPP
12 
13 #include <boost/beast/core/detail/config.hpp>
14 #include <boost/beast/core/buffer_traits.hpp>
15 #include <boost/asio/buffer.hpp>
16 #include <ostream>
17 
18 namespace boost {
19 namespace beast {
20 
21 namespace detail {
22 
23 template<class Buffers>
24 class make_printable_adaptor
25 {
26     Buffers b_;
27 
28 public:
29     explicit
make_printable_adaptor(Buffers const & b)30     make_printable_adaptor(Buffers const& b)
31         : b_(b)
32     {
33     }
34 
35     template<class B>
36     friend
37     std::ostream&
38     operator<<(std::ostream& os,
39         make_printable_adaptor<B> const& v);
40 };
41 
42 template<class Buffers>
43 std::ostream&
operator <<(std::ostream & os,make_printable_adaptor<Buffers> const & v)44 operator<<(std::ostream& os,
45     make_printable_adaptor<Buffers> const& v)
46 {
47     for(
48         auto it = net::buffer_sequence_begin(v.b_),
49         end = net::buffer_sequence_end(v.b_);
50         it != end;
51         ++it)
52     {
53         net::const_buffer cb = *it;
54         os.write(static_cast<char const*>(
55             cb.data()), cb.size());
56     }
57     return os;
58 }
59 
60 } // detail
61 
62 /** Helper to permit a buffer sequence to be printed to a std::ostream
63 
64     This function is used to wrap a buffer sequence to allow it to
65     be interpreted as characters and written to a `std::ostream` such
66     as `std::cout`. No character translation is performed; unprintable
67     and null characters will be transferred as-is to the output stream.
68 
69     @par Example
70     This function prints the size and contents of a buffer sequence
71     to standard output:
72     @code
73     template <class ConstBufferSequence>
74     void
75     print (ConstBufferSequence const& buffers)
76     {
77         std::cout <<
78             "Buffer size: " << buffer_bytes(buffers) << " bytes\n"
79             "Buffer data: '" << make_printable(buffers) << "'\n";
80     }
81     @endcode
82 
83     @param buffers An object meeting the requirements of
84     <em>ConstBufferSequence</em> to be streamed. The implementation
85     will make a copy of this object. Ownership of the underlying
86     memory is not transferred, the application is still responsible
87     for managing its lifetime.
88 */
89 template<class ConstBufferSequence>
90 #if BOOST_BEAST_DOXYGEN
91 __implementation_defined__
92 #else
93 detail::make_printable_adaptor<ConstBufferSequence>
94 #endif
make_printable(ConstBufferSequence const & buffers)95 make_printable(ConstBufferSequence const& buffers)
96 {
97     static_assert(net::is_const_buffer_sequence<
98         ConstBufferSequence>::value,
99             "ConstBufferSequence type requirements not met");
100     return detail::make_printable_adaptor<
101         ConstBufferSequence>{buffers};
102 }
103 
104 } // beast
105 } // boost
106 
107 #endif
108