238 lines
6.9 KiB
C++
238 lines
6.9 KiB
C++
//
|
|
// 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
|
|
//
|
|
|
|
#ifndef BOOST_BEAST_BUFFERS_PREFIX_HPP
|
|
#define BOOST_BEAST_BUFFERS_PREFIX_HPP
|
|
|
|
#include <boost/beast/core/detail/config.hpp>
|
|
#include <boost/beast/core/type_traits.hpp>
|
|
#include <boost/beast/core/detail/in_place_init.hpp>
|
|
#include <boost/asio/buffer.hpp>
|
|
#include <cstdint>
|
|
#include <type_traits>
|
|
|
|
namespace boost {
|
|
namespace beast {
|
|
|
|
/** A buffer sequence adapter that shortens the sequence size.
|
|
|
|
The class adapts a buffer sequence to efficiently represent
|
|
a shorter subset of the original list of buffers starting
|
|
with the first byte of the original sequence.
|
|
|
|
@tparam BufferSequence The buffer sequence to adapt.
|
|
*/
|
|
template<class BufferSequence>
|
|
class buffers_prefix_view
|
|
{
|
|
using buffers_type = typename
|
|
std::decay<BufferSequence>::type;
|
|
|
|
using iter_type = typename
|
|
detail::buffer_sequence_iterator<buffers_type>::type;
|
|
|
|
BufferSequence bs_;
|
|
std::size_t size_;
|
|
iter_type end_;
|
|
|
|
template<class Deduced>
|
|
buffers_prefix_view(
|
|
Deduced&& other, std::size_t dist)
|
|
: bs_(std::forward<Deduced>(other).bs_)
|
|
, size_(other.size_)
|
|
, end_(std::next(bs_.begin(), dist))
|
|
{
|
|
}
|
|
|
|
void
|
|
setup(std::size_t size);
|
|
|
|
public:
|
|
/// The type for each element in the list of buffers.
|
|
using value_type = typename std::conditional<
|
|
std::is_convertible<typename
|
|
std::iterator_traits<iter_type>::value_type,
|
|
boost::asio::mutable_buffer>::value,
|
|
boost::asio::mutable_buffer,
|
|
boost::asio::const_buffer>::type;
|
|
|
|
#if BOOST_BEAST_DOXYGEN
|
|
/// A bidirectional iterator type that may be used to read elements.
|
|
using const_iterator = implementation_defined;
|
|
|
|
#else
|
|
class const_iterator;
|
|
|
|
#endif
|
|
|
|
/// Move constructor.
|
|
buffers_prefix_view(buffers_prefix_view&&);
|
|
|
|
/// Copy constructor.
|
|
buffers_prefix_view(buffers_prefix_view const&);
|
|
|
|
/// Move assignment.
|
|
buffers_prefix_view& operator=(buffers_prefix_view&&);
|
|
|
|
/// Copy assignment.
|
|
buffers_prefix_view& operator=(buffers_prefix_view const&);
|
|
|
|
/** Construct a buffer sequence prefix.
|
|
|
|
@param size The maximum number of bytes in the prefix.
|
|
If this is larger than the size of passed, buffers,
|
|
the resulting sequence will represent the entire
|
|
input sequence.
|
|
|
|
@param buffers The buffer sequence to adapt. A copy of
|
|
the sequence will be made, but ownership of the underlying
|
|
memory is not transferred.
|
|
*/
|
|
buffers_prefix_view(
|
|
std::size_t size,
|
|
BufferSequence const& buffers);
|
|
|
|
/** Construct a buffer sequence prefix in-place.
|
|
|
|
@param size The maximum number of bytes in the prefix.
|
|
If this is larger than the size of passed, buffers,
|
|
the resulting sequence will represent the entire
|
|
input sequence.
|
|
|
|
@param args Arguments forwarded to the contained buffers constructor.
|
|
*/
|
|
template<class... Args>
|
|
buffers_prefix_view(
|
|
std::size_t size,
|
|
boost::in_place_init_t,
|
|
Args&&... args);
|
|
|
|
/// Get a bidirectional iterator to the first element.
|
|
const_iterator
|
|
begin() const;
|
|
|
|
/// Get a bidirectional iterator to one past the last element.
|
|
const_iterator
|
|
end() const;
|
|
};
|
|
|
|
/** Returns a prefix of a constant buffer.
|
|
|
|
The returned buffer points to the same memory as the
|
|
passed buffer, but with a size that is equal to or less
|
|
than the size of the original buffer.
|
|
|
|
@param size The size of the returned buffer.
|
|
|
|
@param buffer The buffer to shorten. The underlying
|
|
memory is not modified.
|
|
|
|
@return A new buffer that points to the first `size`
|
|
bytes of the original buffer.
|
|
*/
|
|
inline
|
|
boost::asio::const_buffer
|
|
buffers_prefix(std::size_t size,
|
|
boost::asio::const_buffer buffer)
|
|
{
|
|
return {buffer.data(),
|
|
(std::min)(size, buffer.size())};
|
|
}
|
|
|
|
/** Returns a prefix of a mutable buffer.
|
|
|
|
The returned buffer points to the same memory as the
|
|
passed buffer, but with a size that is equal to or less
|
|
than the size of the original buffer.
|
|
|
|
@param size The size of the returned buffer.
|
|
|
|
@param buffer The buffer to shorten. The underlying
|
|
memory is not modified.
|
|
|
|
@return A new buffer that points to the first `size` bytes
|
|
of the original buffer.
|
|
*/
|
|
inline
|
|
boost::asio::mutable_buffer
|
|
buffers_prefix(std::size_t size,
|
|
boost::asio::mutable_buffer buffer)
|
|
{
|
|
return {buffer.data(),
|
|
(std::min)(size, buffer.size())};
|
|
}
|
|
|
|
/** Returns a prefix of a buffer sequence.
|
|
|
|
This function returns a new buffer sequence which when iterated,
|
|
presents a shorter subset of the original list of buffers starting
|
|
with the first byte of the original sequence.
|
|
|
|
@param size The maximum number of bytes in the wrapped
|
|
sequence. If this is larger than the size of passed,
|
|
buffers, the resulting sequence will represent the
|
|
entire input sequence.
|
|
|
|
@param buffers An instance of @b ConstBufferSequence or
|
|
@b MutableBufferSequence to adapt. A copy of the sequence
|
|
will be made, but ownership of the underlying memory is
|
|
not transferred.
|
|
*/
|
|
template<class BufferSequence>
|
|
#if BOOST_BEAST_DOXYGEN
|
|
buffers_prefix_view<BufferSequence>
|
|
#else
|
|
inline
|
|
typename std::enable_if<
|
|
! std::is_same<BufferSequence,
|
|
boost::asio::const_buffer>::value &&
|
|
! std::is_same<BufferSequence,
|
|
boost::asio::mutable_buffer>::value,
|
|
buffers_prefix_view<BufferSequence>>::type
|
|
#endif
|
|
buffers_prefix(std::size_t size, BufferSequence const& buffers)
|
|
{
|
|
static_assert(
|
|
boost::asio::is_const_buffer_sequence<BufferSequence>::value ||
|
|
boost::asio::is_mutable_buffer_sequence<BufferSequence>::value,
|
|
"BufferSequence requirements not met");
|
|
return buffers_prefix_view<BufferSequence>(size, buffers);
|
|
}
|
|
|
|
/** Returns the first buffer in a buffer sequence
|
|
|
|
This returns the first buffer in the buffer sequence.
|
|
If the buffer sequence is an empty range, the returned
|
|
buffer will have a zero buffer size.
|
|
|
|
@param buffers The buffer sequence. If the sequence is
|
|
mutable, the returned buffer sequence will also be mutable.
|
|
Otherwise, the returned buffer sequence will be constant.
|
|
*/
|
|
template<class BufferSequence>
|
|
typename std::conditional<
|
|
boost::asio::is_mutable_buffer_sequence<BufferSequence>::value,
|
|
boost::asio::mutable_buffer,
|
|
boost::asio::const_buffer>::type
|
|
buffers_front(BufferSequence const& buffers)
|
|
{
|
|
auto const first =
|
|
boost::asio::buffer_sequence_begin(buffers);
|
|
if(first == boost::asio::buffer_sequence_end(buffers))
|
|
return {};
|
|
return *first;
|
|
}
|
|
|
|
} // beast
|
|
} // boost
|
|
|
|
#include <boost/beast/core/impl/buffers_prefix.ipp>
|
|
|
|
#endif
|