mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
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:
@ -21,7 +21,8 @@ Version 200
|
||||
|
||||
API Changes:
|
||||
|
||||
* buffers_adaptor is renamed (was buffers_adapter)
|
||||
* buffers_adaptor replaces buffers_adapter (rename)
|
||||
* make_printable replaces buffers (rename)
|
||||
|
||||
Actions Required:
|
||||
|
||||
@ -29,6 +30,9 @@ Actions Required:
|
||||
replace buffers_adapter with buffers_adaptor. Or, define
|
||||
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:
|
||||
|
@ -146,7 +146,7 @@ output streams.
|
||||
[table Buffer Output Streams
|
||||
[[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
|
||||
used with `operator<<` and `std::ostream`.
|
||||
|
@ -214,7 +214,7 @@
|
||||
<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_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_front">buffers_front</link></member>
|
||||
<member><link linkend="beast.ref.boost__beast__buffers_prefix">buffers_prefix</link></member>
|
||||
|
@ -193,8 +193,8 @@ public:
|
||||
|
||||
// If we get here then the connection is closed gracefully
|
||||
|
||||
// The buffers() function helps print a ConstBufferSequence
|
||||
std::cout << beast::buffers(buffer_.data()) << std::endl;
|
||||
// The make_printable() function helps print a ConstBufferSequence
|
||||
std::cout << beast::make_printable(buffer_.data()) << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -173,8 +173,8 @@ public:
|
||||
|
||||
// If we get here then the connection is closed gracefully
|
||||
|
||||
// The buffers() function helps print a ConstBufferSequence
|
||||
std::cout << beast::buffers(buffer_.data()) << std::endl;
|
||||
// The make_printable() function helps print a ConstBufferSequence
|
||||
std::cout << beast::make_printable(buffer_.data()) << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -85,10 +85,10 @@ do_session(
|
||||
return fail(ec, "write");
|
||||
|
||||
// This buffer will hold the incoming message
|
||||
beast::multi_buffer b;
|
||||
beast::multi_buffer buffer;
|
||||
|
||||
// Read a message into our buffer
|
||||
ws.async_read(b, yield[ec]);
|
||||
ws.async_read(buffer, yield[ec]);
|
||||
if(ec)
|
||||
return fail(ec, "read");
|
||||
|
||||
@ -99,8 +99,8 @@ do_session(
|
||||
|
||||
// If we get here then the connection is closed gracefully
|
||||
|
||||
// The buffers() function helps print a ConstBufferSequence
|
||||
std::cout << beast::buffers(b.data()) << std::endl;
|
||||
// The make_printable() function helps print a ConstBufferSequence
|
||||
std::cout << beast::make_printable(buffer.data()) << std::endl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -74,10 +74,10 @@ do_session(
|
||||
return fail(ec, "write");
|
||||
|
||||
// This buffer will hold the incoming message
|
||||
beast::multi_buffer b;
|
||||
beast::multi_buffer buffer;
|
||||
|
||||
// Read a message into our buffer
|
||||
ws.async_read(b, yield[ec]);
|
||||
ws.async_read(buffer, yield[ec]);
|
||||
if(ec)
|
||||
return fail(ec, "read");
|
||||
|
||||
@ -88,8 +88,8 @@ do_session(
|
||||
|
||||
// If we get here then the connection is closed gracefully
|
||||
|
||||
// The buffers() function helps print a ConstBufferSequence
|
||||
std::cout << beast::buffers(b.data()) << std::endl;
|
||||
// The make_printable() function helps print a ConstBufferSequence
|
||||
std::cout << beast::make_printable(buffer.data()) << std::endl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -79,18 +79,18 @@ int main(int argc, char** argv)
|
||||
ws.write(net::buffer(std::string(text)));
|
||||
|
||||
// This buffer will hold the incoming message
|
||||
beast::multi_buffer b;
|
||||
beast::multi_buffer buffer;
|
||||
|
||||
// Read a message into our buffer
|
||||
ws.read(b);
|
||||
ws.read(buffer);
|
||||
|
||||
// Close the WebSocket connection
|
||||
ws.close(websocket::close_code::normal);
|
||||
|
||||
// If we get here then the connection is closed gracefully
|
||||
|
||||
// The buffers() function helps print a ConstBufferSequence
|
||||
std::cout << beast::buffers(b.data()) << std::endl;
|
||||
// The make_printable() function helps print a ConstBufferSequence
|
||||
std::cout << beast::make_printable(buffer.data()) << std::endl;
|
||||
}
|
||||
catch(std::exception const& e)
|
||||
{
|
||||
|
@ -77,8 +77,8 @@ int main(int argc, char** argv)
|
||||
|
||||
// If we get here then the connection is closed gracefully
|
||||
|
||||
// The buffers() function helps print a ConstBufferSequence
|
||||
std::cout << beast::buffers(buffer.data()) << std::endl;
|
||||
// The make_printable() function helps print a ConstBufferSequence
|
||||
std::cout << beast::make_printable(buffer.data()) << std::endl;
|
||||
}
|
||||
catch(std::exception const& e)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <boost/beast/core/flat_buffer.hpp>
|
||||
#include <boost/beast/core/flat_static_buffer.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/ostream.hpp>
|
||||
#include <boost/beast/core/read_size.hpp>
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <memory>
|
||||
#include <iosfwd>
|
||||
#include <ostream>
|
||||
#include <streambuf>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@ -25,38 +25,6 @@ namespace boost {
|
||||
namespace beast {
|
||||
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 :
|
||||
std::basic_streambuf<char, std::char_traits<char>>
|
||||
{
|
||||
@ -67,12 +35,12 @@ struct basic_streambuf_movable_helper :
|
||||
using basic_streambuf_movable =
|
||||
std::is_move_constructible<basic_streambuf_movable_helper>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class DynamicBuffer,
|
||||
class CharT, class Traits, bool isMovable>
|
||||
class ostream_buffer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class DynamicBuffer, class CharT, class Traits>
|
||||
class ostream_buffer
|
||||
<DynamicBuffer, CharT, Traits, true>
|
||||
@ -136,6 +104,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// This nonsense is all to work around a glitch in libstdc++
|
||||
// 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
|
||||
|
107
include/boost/beast/core/make_printable.hpp
Normal file
107
include/boost/beast/core/make_printable.hpp
Normal 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
|
@ -17,45 +17,13 @@
|
||||
#include <streambuf>
|
||||
#include <utility>
|
||||
|
||||
#ifdef BOOST_BEAST_ALLOW_DEPRECATED
|
||||
#include <boost/beast/core/make_printable.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
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.
|
||||
|
||||
This function wraps the caller provided @b DynamicBuffer into
|
||||
@ -98,6 +66,25 @@ ostream(DynamicBuffer& 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
|
||||
} // boost
|
||||
|
||||
|
@ -36,6 +36,7 @@ add_executable (tests-beast-core
|
||||
flat_buffer.cpp
|
||||
flat_static_buffer.cpp
|
||||
handler_ptr.cpp
|
||||
make_printable.cpp
|
||||
multi_buffer.cpp
|
||||
ostream.cpp
|
||||
read_size.cpp
|
||||
|
@ -26,6 +26,7 @@ local SOURCES =
|
||||
flat_buffer.cpp
|
||||
flat_static_buffer.cpp
|
||||
handler_ptr.cpp
|
||||
make_printable.cpp
|
||||
multi_buffer.cpp
|
||||
ostream.cpp
|
||||
read_size.cpp
|
||||
|
67
test/beast/core/make_printable.cpp
Normal file
67
test/beast/core/make_printable.cpp
Normal 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
|
Reference in New Issue
Block a user