make_printable replaces buffers rename (API Change):

* The function buffers is deprecated, use the new
  function make_printable as the replacement.

Actions Required:

* Replace call sites to use make_printable instead of buffers,
  and also include make_printable.hpp instead of ostream.hpp.
This commit is contained in:
Vinnie Falco
2018-12-16 14:36:17 -08:00
parent 991bae8486
commit 0006ab3b2b
16 changed files with 230 additions and 92 deletions

View File

@ -21,7 +21,8 @@ Version 200
API Changes: API Changes:
* buffers_adaptor is renamed (was buffers_adapter) * buffers_adaptor replaces buffers_adapter (rename)
* make_printable replaces buffers (rename)
Actions Required: Actions Required:
@ -29,6 +30,9 @@ Actions Required:
replace buffers_adapter with buffers_adaptor. Or, define replace buffers_adapter with buffers_adaptor. Or, define
BOOST_BEAST_ALLOW_DEPRECATED BOOST_BEAST_ALLOW_DEPRECATED
* Replace call sites to use make_printable instead of buffers,
and also include make_printable.hpp instead of ostream.hpp.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Version 199: Version 199:

View File

@ -146,7 +146,7 @@ output streams.
[table Buffer Output Streams [table Buffer Output Streams
[[Name][Description]] [[Name][Description]]
[[ [[
[link beast.ref.boost__beast__buffers `buffers`] [link beast.ref.boost__beast__make_printable `make_printable`]
][ ][
This function wraps a __ConstBufferSequence__ so it may be This function wraps a __ConstBufferSequence__ so it may be
used with `operator<<` and `std::ostream`. used with `operator<<` and `std::ostream`.

View File

@ -214,7 +214,7 @@
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__bind_handler">bind_handler</link></member> <member><link linkend="beast.ref.boost__beast__bind_handler">bind_handler</link></member>
<member><link linkend="beast.ref.boost__beast__bind_front_handler">bind_front_handler</link></member> <member><link linkend="beast.ref.boost__beast__bind_front_handler">bind_front_handler</link></member>
<member><link linkend="beast.ref.boost__beast__buffers">buffers</link></member> <member><link linkend="beast.ref.boost__beast__make_printable">make_printable</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_cat">buffers_cat</link></member> <member><link linkend="beast.ref.boost__beast__buffers_cat">buffers_cat</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_front">buffers_front</link></member> <member><link linkend="beast.ref.boost__beast__buffers_front">buffers_front</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_prefix">buffers_prefix</link></member> <member><link linkend="beast.ref.boost__beast__buffers_prefix">buffers_prefix</link></member>

View File

@ -193,8 +193,8 @@ public:
// If we get here then the connection is closed gracefully // If we get here then the connection is closed gracefully
// The buffers() function helps print a ConstBufferSequence // The make_printable() function helps print a ConstBufferSequence
std::cout << beast::buffers(buffer_.data()) << std::endl; std::cout << beast::make_printable(buffer_.data()) << std::endl;
} }
}; };

View File

@ -173,8 +173,8 @@ public:
// If we get here then the connection is closed gracefully // If we get here then the connection is closed gracefully
// The buffers() function helps print a ConstBufferSequence // The make_printable() function helps print a ConstBufferSequence
std::cout << beast::buffers(buffer_.data()) << std::endl; std::cout << beast::make_printable(buffer_.data()) << std::endl;
} }
}; };

View File

@ -85,10 +85,10 @@ do_session(
return fail(ec, "write"); return fail(ec, "write");
// This buffer will hold the incoming message // This buffer will hold the incoming message
beast::multi_buffer b; beast::multi_buffer buffer;
// Read a message into our buffer // Read a message into our buffer
ws.async_read(b, yield[ec]); ws.async_read(buffer, yield[ec]);
if(ec) if(ec)
return fail(ec, "read"); return fail(ec, "read");
@ -99,8 +99,8 @@ do_session(
// If we get here then the connection is closed gracefully // If we get here then the connection is closed gracefully
// The buffers() function helps print a ConstBufferSequence // The make_printable() function helps print a ConstBufferSequence
std::cout << beast::buffers(b.data()) << std::endl; std::cout << beast::make_printable(buffer.data()) << std::endl;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -74,10 +74,10 @@ do_session(
return fail(ec, "write"); return fail(ec, "write");
// This buffer will hold the incoming message // This buffer will hold the incoming message
beast::multi_buffer b; beast::multi_buffer buffer;
// Read a message into our buffer // Read a message into our buffer
ws.async_read(b, yield[ec]); ws.async_read(buffer, yield[ec]);
if(ec) if(ec)
return fail(ec, "read"); return fail(ec, "read");
@ -88,8 +88,8 @@ do_session(
// If we get here then the connection is closed gracefully // If we get here then the connection is closed gracefully
// The buffers() function helps print a ConstBufferSequence // The make_printable() function helps print a ConstBufferSequence
std::cout << beast::buffers(b.data()) << std::endl; std::cout << beast::make_printable(buffer.data()) << std::endl;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -79,18 +79,18 @@ int main(int argc, char** argv)
ws.write(net::buffer(std::string(text))); ws.write(net::buffer(std::string(text)));
// This buffer will hold the incoming message // This buffer will hold the incoming message
beast::multi_buffer b; beast::multi_buffer buffer;
// Read a message into our buffer // Read a message into our buffer
ws.read(b); ws.read(buffer);
// Close the WebSocket connection // Close the WebSocket connection
ws.close(websocket::close_code::normal); ws.close(websocket::close_code::normal);
// If we get here then the connection is closed gracefully // If we get here then the connection is closed gracefully
// The buffers() function helps print a ConstBufferSequence // The make_printable() function helps print a ConstBufferSequence
std::cout << beast::buffers(b.data()) << std::endl; std::cout << beast::make_printable(buffer.data()) << std::endl;
} }
catch(std::exception const& e) catch(std::exception const& e)
{ {

View File

@ -77,8 +77,8 @@ int main(int argc, char** argv)
// If we get here then the connection is closed gracefully // If we get here then the connection is closed gracefully
// The buffers() function helps print a ConstBufferSequence // The make_printable() function helps print a ConstBufferSequence
std::cout << beast::buffers(buffer.data()) << std::endl; std::cout << beast::make_printable(buffer.data()) << std::endl;
} }
catch(std::exception const& e) catch(std::exception const& e)
{ {

View File

@ -30,6 +30,7 @@
#include <boost/beast/core/flat_buffer.hpp> #include <boost/beast/core/flat_buffer.hpp>
#include <boost/beast/core/flat_static_buffer.hpp> #include <boost/beast/core/flat_static_buffer.hpp>
#include <boost/beast/core/handler_ptr.hpp> #include <boost/beast/core/handler_ptr.hpp>
#include <boost/beast/core/make_printable.hpp>
#include <boost/beast/core/multi_buffer.hpp> #include <boost/beast/core/multi_buffer.hpp>
#include <boost/beast/core/ostream.hpp> #include <boost/beast/core/ostream.hpp>
#include <boost/beast/core/read_size.hpp> #include <boost/beast/core/read_size.hpp>

View File

@ -16,7 +16,7 @@
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <boost/asio/buffer.hpp> #include <boost/asio/buffer.hpp>
#include <memory> #include <memory>
#include <iosfwd> #include <ostream>
#include <streambuf> #include <streambuf>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
@ -25,38 +25,6 @@ namespace boost {
namespace beast { namespace beast {
namespace detail { namespace detail {
template<class Buffers>
class buffers_helper
{
Buffers b_;
public:
explicit
buffers_helper(Buffers const& b)
: b_(b)
{
}
template<class B>
friend
std::ostream&
operator<<(std::ostream& os,
buffers_helper<B> const& v);
};
template<class Buffers>
std::ostream&
operator<<(std::ostream& os,
buffers_helper<Buffers> const& v)
{
for(auto b : buffers_range(std::ref(v.b_)))
os.write(static_cast<char const*>(
b.data()), b.size());
return os;
}
//------------------------------------------------------------------------------
struct basic_streambuf_movable_helper : struct basic_streambuf_movable_helper :
std::basic_streambuf<char, std::char_traits<char>> std::basic_streambuf<char, std::char_traits<char>>
{ {
@ -67,12 +35,12 @@ struct basic_streambuf_movable_helper :
using basic_streambuf_movable = using basic_streambuf_movable =
std::is_move_constructible<basic_streambuf_movable_helper>; std::is_move_constructible<basic_streambuf_movable_helper>;
//------------------------------------------------------------------------------
template<class DynamicBuffer, template<class DynamicBuffer,
class CharT, class Traits, bool isMovable> class CharT, class Traits, bool isMovable>
class ostream_buffer; class ostream_buffer;
//------------------------------------------------------------------------------
template<class DynamicBuffer, class CharT, class Traits> template<class DynamicBuffer, class CharT, class Traits>
class ostream_buffer class ostream_buffer
<DynamicBuffer, CharT, Traits, true> <DynamicBuffer, CharT, Traits, true>
@ -136,6 +104,8 @@ public:
} }
}; };
//------------------------------------------------------------------------------
// This nonsense is all to work around a glitch in libstdc++ // This nonsense is all to work around a glitch in libstdc++
// where std::basic_streambuf copy constructor is private: // where std::basic_streambuf copy constructor is private:
// https://github.com/gcc-mirror/gcc/blob/gcc-4_8-branch/libstdc%2B%2B-v3/include/std/streambuf#L799 // https://github.com/gcc-mirror/gcc/blob/gcc-4_8-branch/libstdc%2B%2B-v3/include/std/streambuf#L799

View File

@ -0,0 +1,107 @@
//
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_MAKE_PRINTABLE_HPP
#define BOOST_BEAST_MAKE_PRINTABLE_HPP
#include <boost/beast/core/detail/config.hpp>
#include <boost/asio/buffer.hpp>
#include <ostream>
namespace boost {
namespace beast {
namespace detail {
template<class Buffers>
class make_printable_adaptor
{
Buffers b_;
public:
explicit
make_printable_adaptor(Buffers const& b)
: b_(b)
{
}
template<class B>
friend
std::ostream&
operator<<(std::ostream& os,
make_printable_adaptor<B> const& v);
};
template<class Buffers>
std::ostream&
operator<<(std::ostream& os,
make_printable_adaptor<Buffers> const& v)
{
for(
auto it = net::buffer_sequence_begin(v.b_),
end = net::buffer_sequence_end(v.b_);
it != end;
++it)
{
net::const_buffer cb = *it;
os.write(static_cast<char const*>(
cb.data()), cb.size());
}
return os;
}
} // detail
/** Helper to permit a buffer sequence to be printed to a std::ostream
This function is used to wrap a buffer sequence to allow it to
be interpreted as characters and written to a `std::ostream` such
as `std::cout`. No character translation is performed; unprintable
and null characters will be transferred as-is to the output stream.
@par Example
This function prints the size and contents of a buffer sequence
to standard output:
@code
template <class ConstBufferSequence>
void
print (ConstBufferSequence const& buffers)
{
using net::buffer_size;
std::cout <<
"Buffer size: " << buffer_size(buffers) << " bytes\n"
"Buffer data: '" << make_printable(buffers) << "'\n";
}
@endcode
@param buffers An object meeting the requirements of
<em>ConstBufferSequence</em> to be streamed. The implementation
will make a copy of this object. Ownership of the underlying
memory is not transferred, the application is still responsible
for managing its lifetime.
*/
template<class ConstBufferSequence>
#if BOOST_BEAST_DOXYGEN
__implementation_defined__
#else
detail::make_printable_adaptor<ConstBufferSequence>
#endif
make_printable(ConstBufferSequence const& buffers)
{
static_assert(net::is_const_buffer_sequence<
ConstBufferSequence>::value,
"ConstBufferSequence requirements not met");
return detail::make_printable_adaptor<
ConstBufferSequence>{buffers};
}
} // beast
} // boost
#endif

View File

@ -17,45 +17,13 @@
#include <streambuf> #include <streambuf>
#include <utility> #include <utility>
#ifdef BOOST_BEAST_ALLOW_DEPRECATED
#include <boost/beast/core/make_printable.hpp>
#endif
namespace boost { namespace boost {
namespace beast { namespace beast {
/** Return an object representing a @b ConstBufferSequence.
This function wraps a reference to a buffer sequence and permits
the following operation:
@li `operator<<` to `std::ostream`. No character translation is
performed; unprintable and null characters will be transferred
as-is to the output stream.
@par Example
@code
multi_buffer b;
...
std::cout << buffers(b.data()) << std::endl;
@endcode
@param b An object meeting the requirements of @b ConstBufferSequence
to be streamed. The implementation will make a copy of this object.
Ownership of the underlying memory is not transferred, the application
is still responsible for managing its lifetime.
*/
template<class ConstBufferSequence>
#if BOOST_BEAST_DOXYGEN
__implementation_defined__
#else
detail::buffers_helper<ConstBufferSequence>
#endif
buffers(ConstBufferSequence const& b)
{
static_assert(net::is_const_buffer_sequence<
ConstBufferSequence>::value,
"ConstBufferSequence requirements not met");
return detail::buffers_helper<
ConstBufferSequence>{b};
}
/** Return an output stream that formats values into a @b DynamicBuffer. /** Return an output stream that formats values into a @b DynamicBuffer.
This function wraps the caller provided @b DynamicBuffer into This function wraps the caller provided @b DynamicBuffer into
@ -98,6 +66,25 @@ ostream(DynamicBuffer& buffer)
detail::basic_streambuf_movable::value>{buffer}; detail::basic_streambuf_movable::value>{buffer};
} }
//------------------------------------------------------------------------------
#ifdef BOOST_BEAST_ALLOW_DEPRECATED
template<class T>
detail::make_printable_adaptor<T>
buffers(T const& t)
{
return make_printable(t);
}
#else
template<class T>
void buffers(T const&)
{
static_assert(sizeof(T) == 0,
"The function buffers() is deprecated, use make_printable() instead, "
"or define BOOST_BEAST_ALLOW_DEPRECATED to silence this error.");
}
#endif
} // beast } // beast
} // boost } // boost

View File

@ -36,6 +36,7 @@ add_executable (tests-beast-core
flat_buffer.cpp flat_buffer.cpp
flat_static_buffer.cpp flat_static_buffer.cpp
handler_ptr.cpp handler_ptr.cpp
make_printable.cpp
multi_buffer.cpp multi_buffer.cpp
ostream.cpp ostream.cpp
read_size.cpp read_size.cpp

View File

@ -26,6 +26,7 @@ local SOURCES =
flat_buffer.cpp flat_buffer.cpp
flat_static_buffer.cpp flat_static_buffer.cpp
handler_ptr.cpp handler_ptr.cpp
make_printable.cpp
multi_buffer.cpp multi_buffer.cpp
ostream.cpp ostream.cpp
read_size.cpp read_size.cpp

View File

@ -0,0 +1,67 @@
//
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include <boost/beast/core/make_printable.hpp>
#include <boost/beast/_experimental/unit_test/suite.hpp>
#include <iostream>
#include <sstream>
#include "buffer_test.hpp"
namespace boost {
namespace beast {
class make_printable_test : public beast::unit_test::suite
{
public:
template <class ConstBufferSequence>
void
print (ConstBufferSequence const& buffers)
{
using net::buffer_size;
std::cout <<
"Buffer size: " << buffer_size(buffers) << " bytes\n"
"Buffer data: '" << make_printable(buffers) << "'\n";
}
void
testJavadoc()
{
BEAST_EXPECT(&make_printable_test::print<buffers_triple>);
}
void
testMakePrintable()
{
using net::buffer;
char buf[13];
buffers_triple b(buf, sizeof(buf));
string_view src = "Hello, world!";
BEAST_EXPECT(src.size() == sizeof(buf));
net::buffer_copy(b,
net::const_buffer(src.data(), src.size()));
std::ostringstream ss;
ss << make_printable(b);
BEAST_EXPECT(ss.str() == src);
}
void
run() override
{
testJavadoc();
testMakePrintable();
}
};
BEAST_DEFINE_TESTSUITE(beast,core,make_printable);
} // beast
} // boost