summaryrefslogtreecommitdiff
path: root/boost/beast/websocket/detail
diff options
context:
space:
mode:
Diffstat (limited to 'boost/beast/websocket/detail')
-rw-r--r--boost/beast/websocket/detail/error.hpp78
-rw-r--r--boost/beast/websocket/detail/frame.hpp25
-rw-r--r--boost/beast/websocket/detail/mask.hpp177
-rw-r--r--boost/beast/websocket/detail/pausation.hpp203
-rw-r--r--boost/beast/websocket/detail/pmd_extension.hpp80
-rw-r--r--boost/beast/websocket/detail/stream_base.hpp221
-rw-r--r--boost/beast/websocket/detail/type_traits.hpp4
-rw-r--r--boost/beast/websocket/detail/utf8_checker.hpp6
8 files changed, 417 insertions, 377 deletions
diff --git a/boost/beast/websocket/detail/error.hpp b/boost/beast/websocket/detail/error.hpp
new file mode 100644
index 0000000000..57b837bd4c
--- /dev/null
+++ b/boost/beast/websocket/detail/error.hpp
@@ -0,0 +1,78 @@
+//
+// 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_WEBSOCKET_DETAIL_ERROR_IPP
+#define BOOST_BEAST_WEBSOCKET_DETAIL_ERROR_IPP
+
+#include <boost/beast/core/error.hpp>
+#include <boost/beast/core/string.hpp>
+
+namespace boost {
+
+namespace beast {
+namespace websocket {
+enum class error;
+enum class condition;
+} // websocket
+} // beast
+
+namespace system {
+template<>
+struct is_error_code_enum<beast::websocket::error>
+{
+ static bool const value = true;
+};
+template<>
+struct is_error_condition_enum<beast::websocket::condition>
+{
+ static bool const value = true;
+};
+} // system
+
+namespace beast {
+namespace websocket {
+namespace detail {
+
+class error_codes : public error_category
+{
+public:
+ const char*
+ name() const noexcept override;
+
+ std::string
+ message(int ev) const override;
+
+ error_condition
+ default_error_condition(int ev) const noexcept override;
+};
+
+class error_conditions : public error_category
+{
+public:
+ const char*
+ name() const noexcept override;
+
+ std::string
+ message(int cv) const override;
+};
+
+} // detail
+
+error_code
+make_error_code(error e);
+
+error_condition
+make_error_condition(condition c);
+
+} // websocket
+} // beast
+
+} // boost
+
+#endif
diff --git a/boost/beast/websocket/detail/frame.hpp b/boost/beast/websocket/detail/frame.hpp
index 95080aeefc..c3bd1690a9 100644
--- a/boost/beast/websocket/detail/frame.hpp
+++ b/boost/beast/websocket/detail/frame.hpp
@@ -10,6 +10,7 @@
#ifndef BOOST_BEAST_WEBSOCKET_DETAIL_FRAME_HPP
#define BOOST_BEAST_WEBSOCKET_DETAIL_FRAME_HPP
+#include <boost/beast/websocket/error.hpp>
#include <boost/beast/websocket/rfc6455.hpp>
#include <boost/beast/websocket/detail/utf8_checker.hpp>
#include <boost/beast/core/buffers_suffix.hpp>
@@ -75,7 +76,7 @@ native_to_little_uint32(std::uint32_t v, void* buf)
p[3] = (v >> 24) & 0xff;
}
-/** WebSocket frame header opcodes. */
+// frame header opcodes
enum class opcode : std::uint8_t
{
cont = 0,
@@ -110,8 +111,7 @@ struct frame_header
};
// holds the largest possible frame header
-using fh_buffer =
- flat_static_buffer<14>;
+using fh_buffer = flat_static_buffer<14>;
// holds the largest possible control frame
using frame_buffer =
@@ -245,8 +245,10 @@ read_ping(ping_data& data, Buffers const& bs)
//
template<class Buffers>
void
-read_close(close_reason& cr,
- Buffers const& bs, close_code& code)
+read_close(
+ close_reason& cr,
+ Buffers const& bs,
+ error_code& ec)
{
using boost::asio::buffer;
using boost::asio::buffer_copy;
@@ -257,12 +259,13 @@ read_close(close_reason& cr,
if(n == 0)
{
cr = close_reason{};
- code = close_code::none;
+ ec.assign(0, ec.category());
return;
}
if(n == 1)
{
- code = close_code::protocol_error;
+ // invalid payload size == 1
+ ec = error::bad_close_size;
return;
}
buffers_suffix<Buffers> cb(bs);
@@ -274,7 +277,8 @@ read_close(close_reason& cr,
n -= 2;
if(! is_valid_close_code(cr.code))
{
- code = close_code::protocol_error;
+ // invalid close code
+ ec = error::bad_close_code;
return;
}
}
@@ -285,7 +289,8 @@ read_close(close_reason& cr,
if(! check_utf8(
cr.reason.data(), cr.reason.size()))
{
- code = close_code::protocol_error;
+ // not valid utf-8
+ ec = error::bad_close_payload;
return;
}
}
@@ -293,7 +298,7 @@ read_close(close_reason& cr,
{
cr.reason = "";
}
- code = close_code::none;
+ ec.assign(0, ec.category());
}
} // detail
diff --git a/boost/beast/websocket/detail/mask.hpp b/boost/beast/websocket/detail/mask.hpp
index 92ea0a4238..8958d793b8 100644
--- a/boost/beast/websocket/detail/mask.hpp
+++ b/boost/beast/websocket/detail/mask.hpp
@@ -11,6 +11,7 @@
#define BOOST_BEAST_WEBSOCKET_DETAIL_MASK_HPP
#include <boost/beast/core/detail/config.hpp>
+#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <array>
#include <climits>
@@ -83,179 +84,59 @@ using maskgen = maskgen_t<std::minstd_rand>;
//------------------------------------------------------------------------------
-using prepared_key =
- std::conditional<sizeof(void*) == 8,
- std::uint64_t, std::uint32_t>::type;
+using prepared_key = std::array<unsigned char, 4>;
inline
void
-prepare_key(std::uint32_t& prepared, std::uint32_t key)
+prepare_key(prepared_key& prepared, std::uint32_t key)
{
- prepared = key;
+ prepared[0] = (key >> 0) & 0xff;
+ prepared[1] = (key >> 8) & 0xff;
+ prepared[2] = (key >> 16) & 0xff;
+ prepared[3] = (key >> 24) & 0xff;
}
-inline
+template<std::size_t N>
void
-prepare_key(std::uint64_t& prepared, std::uint32_t key)
-{
- prepared =
- (static_cast<std::uint64_t>(key) << 32) | key;
-}
-
-template<class T>
-inline
-typename std::enable_if<std::is_integral<T>::value, T>::type
-ror(T t, unsigned n = 1)
+rol(std::array<unsigned char, N>& v, std::size_t n)
{
- auto constexpr bits =
- static_cast<unsigned>(
- sizeof(T) * CHAR_BIT);
- n &= bits-1;
- return static_cast<T>((t << (bits - n)) | (
- static_cast<typename std::make_unsigned<T>::type>(t) >> n));
+ auto v0 = v;
+ for(std::size_t i = 0; i < v.size(); ++i )
+ v[i] = v0[(i + n) % v.size()];
}
-// 32-bit optimized
-//
-template<class = void>
-void
-mask_inplace_fast(
- boost::asio::mutable_buffer const& b,
- std::uint32_t& key)
-{
- auto n = b.size();
- auto p = reinterpret_cast<std::uint8_t*>(b.data());
- if(n >= sizeof(key))
- {
- // Bring p to 4-byte alignment
- auto const i = reinterpret_cast<
- std::uintptr_t>(p) & (sizeof(key)-1);
- switch(i)
- {
- case 1: p[2] ^= static_cast<std::uint8_t>(key >> 16); BOOST_BEAST_FALLTHROUGH;
- case 2: p[1] ^= static_cast<std::uint8_t>(key >> 8); BOOST_BEAST_FALLTHROUGH;
- case 3: p[0] ^= static_cast<std::uint8_t>(key);
- {
- auto const d = static_cast<unsigned>(sizeof(key) - i);
- key = ror(key, 8*d);
- n -= d;
- p += d;
- BOOST_BEAST_FALLTHROUGH;
- }
- default:
- break;
- }
- }
-
- // Mask 4 bytes at a time
- for(auto i = n / sizeof(key); i; --i)
- {
- *reinterpret_cast<
- std::uint32_t*>(p) ^= key;
- p += sizeof(key);
- }
-
- // Leftovers
- n &= sizeof(key)-1;
- switch(n)
- {
- case 3: p[2] ^= static_cast<std::uint8_t>(key >> 16); BOOST_BEAST_FALLTHROUGH;
- case 2: p[1] ^= static_cast<std::uint8_t>(key >> 8); BOOST_BEAST_FALLTHROUGH;
- case 1: p[0] ^= static_cast<std::uint8_t>(key);
- key = ror(key, static_cast<unsigned>(8*n));
- BOOST_BEAST_FALLTHROUGH;
- default:
- break;
- }
-}
-
-// 64-bit optimized
+// Apply mask in place
//
-template<class = void>
+inline
void
-mask_inplace_fast(
- boost::asio::mutable_buffer const& b,
- std::uint64_t& key)
+mask_inplace(boost::asio::mutable_buffer& b, prepared_key& key)
{
auto n = b.size();
- auto p = reinterpret_cast<std::uint8_t*>(b.data());
- if(n >= sizeof(key))
+ auto mask = key; // avoid aliasing
+ auto p = reinterpret_cast<unsigned char*>(b.data());
+ while(n >= 4)
{
- // Bring p to 8-byte alignment
- auto const i = reinterpret_cast<
- std::uintptr_t>(p) & (sizeof(key)-1);
- switch(i)
- {
- case 1: p[6] ^= static_cast<std::uint8_t>(key >> 48);
- case 2: p[5] ^= static_cast<std::uint8_t>(key >> 40);
- case 3: p[4] ^= static_cast<std::uint8_t>(key >> 32);
- case 4: p[3] ^= static_cast<std::uint8_t>(key >> 24);
- case 5: p[2] ^= static_cast<std::uint8_t>(key >> 16);
- case 6: p[1] ^= static_cast<std::uint8_t>(key >> 8);
- case 7: p[0] ^= static_cast<std::uint8_t>(key);
- {
- auto const d = static_cast<
- unsigned>(sizeof(key) - i);
- key = ror(key, 8*d);
- n -= d;
- p += d;
- }
- default:
- break;
- }
+ for(int i = 0; i < 4; ++i)
+ p[i] ^= mask[i];
+ p += 4;
+ n -= 4;
}
-
- // Mask 8 bytes at a time
- for(auto i = n / sizeof(key); i; --i)
+ if(n > 0)
{
- *reinterpret_cast<
- std::uint64_t*>(p) ^= key;
- p += sizeof(key);
+ for(std::size_t i = 0; i < n; ++i)
+ p[i] ^= mask[i];
+ rol(key, n);
}
-
- // Leftovers
- n &= sizeof(key)-1;
- switch(n)
- {
- case 7: p[6] ^= static_cast<std::uint8_t>(key >> 48);
- case 6: p[5] ^= static_cast<std::uint8_t>(key >> 40);
- case 5: p[4] ^= static_cast<std::uint8_t>(key >> 32);
- case 4: p[3] ^= static_cast<std::uint8_t>(key >> 24);
- case 3: p[2] ^= static_cast<std::uint8_t>(key >> 16);
- case 2: p[1] ^= static_cast<std::uint8_t>(key >> 8);
- case 1: p[0] ^= static_cast<std::uint8_t>(key);
- key = ror(key, static_cast<unsigned>(8*n));
- default:
- break;
- }
-}
-
-inline
-void
-mask_inplace(
- boost::asio::mutable_buffer const& b,
- std::uint32_t& key)
-{
- mask_inplace_fast(b, key);
-}
-
-inline
-void
-mask_inplace(
- boost::asio::mutable_buffer const& b,
- std::uint64_t& key)
-{
- mask_inplace_fast(b, key);
}
// Apply mask in place
//
template<class MutableBuffers, class KeyType>
void
-mask_inplace(
- MutableBuffers const& bs, KeyType& key)
+mask_inplace(MutableBuffers const& bs, KeyType& key)
{
- for(boost::asio::mutable_buffer b : bs)
+ for(boost::asio::mutable_buffer b :
+ beast::detail::buffers_range(bs))
mask_inplace(b, key);
}
diff --git a/boost/beast/websocket/detail/pausation.hpp b/boost/beast/websocket/detail/pausation.hpp
index f51ee10327..e3870b038a 100644
--- a/boost/beast/websocket/detail/pausation.hpp
+++ b/boost/beast/websocket/detail/pausation.hpp
@@ -10,13 +10,10 @@
#ifndef BOOST_BEAST_WEBSOCKET_DETAIL_PAUSATION_HPP
#define BOOST_BEAST_WEBSOCKET_DETAIL_PAUSATION_HPP
-#include <boost/beast/core/handler_ptr.hpp>
+#include <boost/beast/core/detail/allocator.hpp>
#include <boost/asio/associated_allocator.hpp>
-#include <boost/asio/coroutine.hpp>
#include <boost/assert.hpp>
-#include <array>
#include <memory>
-#include <new>
#include <utility>
namespace boost {
@@ -30,124 +27,59 @@ namespace detail {
//
class pausation
{
- struct base
+ struct handler
{
- base() = default;
- base(base &&) = delete;
- base(base const&) = delete;
- virtual ~base() = default;
- virtual void operator()() = 0;
+ handler() = default;
+ handler(handler &&) = delete;
+ handler(handler const&) = delete;
+ virtual ~handler() = default;
+ virtual void destroy() = 0;
+ virtual void invoke() = 0;
};
- template<class F>
- struct holder : base
+ template<class Handler>
+ class impl : public handler
{
- F f;
-
- holder(holder&&) = default;
-
- template<class U>
- explicit
- holder(U&& u)
- : f(std::forward<U>(u))
- {
- }
-
- void
- operator()() override
- {
- F f_(std::move(f));
- this->~holder();
- // invocation of f_() can
- // assign a new object to *this.
- f_();
- }
- };
-
- struct exemplar : boost::asio::coroutine
- {
- struct H
- {
- void operator()();
- };
-
- struct T
- {
- using handler_type = H;
- };
-
- handler_ptr<T, H> hp;
-
- void operator()();
- };
-
- template<class Op>
- class saved_op
- {
- Op* op_ = nullptr;
+ Handler h_;
public:
- ~saved_op()
- {
- if(op_)
- {
- Op op(std::move(*op_));
- op_->~Op();
- typename std::allocator_traits<
- boost::asio::associated_allocator_t<Op>>::
- template rebind_alloc<Op> alloc{
- boost::asio::get_associated_allocator(op)};
- std::allocator_traits<
- decltype(alloc)>::deallocate(alloc, op_, 1);
- }
- }
-
- saved_op(saved_op&& other)
- : op_(other.op_)
+ template<class DeducedHandler>
+ impl(DeducedHandler&& h)
+ : h_(std::forward<DeducedHandler>(h))
{
- other.op_ = nullptr;
}
- saved_op& operator=(saved_op&& other)
- {
- BOOST_ASSERT(! op_);
- op_ = other.op_;
- other.op_ = 0;
- return *this;
- }
-
- explicit
- saved_op(Op&& op)
+ void
+ destroy() override
{
- typename std::allocator_traits<
- boost::asio::associated_allocator_t<Op>>::
- template rebind_alloc<Op> alloc{
- boost::asio::get_associated_allocator(op)};
- auto const p = std::allocator_traits<
- decltype(alloc)>::allocate(alloc, 1);
- op_ = new(p) Op{std::move(op)};
+ Handler h(std::move(h_));
+ typename beast::detail::allocator_traits<
+ boost::asio::associated_allocator_t<
+ Handler>>::template rebind_alloc<impl> alloc{
+ boost::asio::get_associated_allocator(h)};
+ beast::detail::allocator_traits<
+ decltype(alloc)>::destroy(alloc, this);
+ beast::detail::allocator_traits<
+ decltype(alloc)>::deallocate(alloc, this, 1);
}
void
- operator()()
+ invoke() override
{
- BOOST_ASSERT(op_);
- Op op{std::move(*op_)};
- typename std::allocator_traits<
- boost::asio::associated_allocator_t<Op>>::
- template rebind_alloc<Op> alloc{
- boost::asio::get_associated_allocator(op)};
- std::allocator_traits<
- decltype(alloc)>::deallocate(alloc, op_, 1);
- op_ = nullptr;
- op();
+ Handler h(std::move(h_));
+ typename beast::detail::allocator_traits<
+ boost::asio::associated_allocator_t<
+ Handler>>::template rebind_alloc<impl> alloc{
+ boost::asio::get_associated_allocator(h)};
+ beast::detail::allocator_traits<
+ decltype(alloc)>::destroy(alloc, this);
+ beast::detail::allocator_traits<
+ decltype(alloc)>::deallocate(alloc, this, 1);
+ h();
}
};
- using buf_type = char[sizeof(holder<exemplar>)];
-
- base* base_ = nullptr;
- alignas(holder<exemplar>) buf_type buf_;
+ handler* h_ = nullptr;
public:
pausation() = default;
@@ -156,69 +88,70 @@ public:
~pausation()
{
- if(base_)
- base_->~base();
+ if(h_)
+ h_->destroy();
}
pausation(pausation&& other)
{
boost::ignore_unused(other);
- BOOST_ASSERT(! other.base_);
+ BOOST_ASSERT(! other.h_);
}
pausation&
operator=(pausation&& other)
{
boost::ignore_unused(other);
- BOOST_ASSERT(! base_);
- BOOST_ASSERT(! other.base_);
+ BOOST_ASSERT(! h_);
+ BOOST_ASSERT(! other.h_);
return *this;
}
- template<class F>
- void
- emplace(F&& f);
-
- template<class F>
+ template<class CompletionHandler>
void
- save(F&& f);
+ emplace(CompletionHandler&& handler);
explicit
operator bool() const
{
- return base_ != nullptr;
+ return h_ != nullptr;
}
bool
maybe_invoke()
{
- if(base_)
+ if(h_)
{
- auto const basep = base_;
- base_ = nullptr;
- (*basep)();
+ auto const h = h_;
+ h_ = nullptr;
+ h->invoke();
return true;
}
return false;
}
};
-template<class F>
+template<class CompletionHandler>
void
-pausation::emplace(F&& f)
+pausation::emplace(CompletionHandler&& handler)
{
- using type = holder<typename std::decay<F>::type>;
- static_assert(sizeof(buf_type) >= sizeof(type),
- "buffer too small");
- BOOST_ASSERT(! base_);
- base_ = ::new(buf_) type{std::forward<F>(f)};
-}
-
-template<class F>
-void
-pausation::save(F&& f)
-{
- emplace(saved_op<F>{std::move(f)});
+ BOOST_ASSERT(! h_);
+ typename beast::detail::allocator_traits<
+ boost::asio::associated_allocator_t<
+ CompletionHandler>>::template rebind_alloc<
+ impl<CompletionHandler>> alloc{
+ boost::asio::get_associated_allocator(handler)};
+ using A = decltype(alloc);
+ auto const d =
+ [&alloc](impl<CompletionHandler>* p)
+ {
+ beast::detail::allocator_traits<A>::deallocate(alloc, p, 1);
+ };
+ std::unique_ptr<impl<CompletionHandler>, decltype(d)> p{
+ beast::detail::allocator_traits<A>::allocate(alloc, 1), d};
+ beast::detail::allocator_traits<A>::construct(
+ alloc, p.get(), std::forward<CompletionHandler>(handler));
+ h_ = p.release();
}
} // detail
diff --git a/boost/beast/websocket/detail/pmd_extension.hpp b/boost/beast/websocket/detail/pmd_extension.hpp
index a28b844cd7..ce4f2425cf 100644
--- a/boost/beast/websocket/detail/pmd_extension.hpp
+++ b/boost/beast/websocket/detail/pmd_extension.hpp
@@ -19,6 +19,7 @@
#include <boost/beast/http/rfc7230.hpp>
#include <boost/asio/buffer.hpp>
#include <utility>
+#include <type_traits>
namespace boost {
namespace beast {
@@ -355,85 +356,6 @@ pmd_normalize(pmd_offer& offer)
}
}
-//--------------------------------------------------------------------
-
-// Compress a buffer sequence
-// Returns: `true` if more calls are needed
-//
-template<class DeflateStream, class ConstBufferSequence>
-bool
-deflate(
- DeflateStream& zo,
- boost::asio::mutable_buffer& out,
- buffers_suffix<ConstBufferSequence>& cb,
- bool fin,
- std::size_t& total_in,
- error_code& ec)
-{
- using boost::asio::buffer;
- BOOST_ASSERT(out.size() >= 6);
- zlib::z_params zs;
- zs.avail_in = 0;
- zs.next_in = nullptr;
- zs.avail_out = out.size();
- zs.next_out = out.data();
- for(auto in : beast::detail::buffers_range(cb))
- {
- zs.avail_in = in.size();
- if(zs.avail_in == 0)
- continue;
- zs.next_in = in.data();
- zo.write(zs, zlib::Flush::none, ec);
- if(ec)
- {
- if(ec != zlib::error::need_buffers)
- return false;
- BOOST_ASSERT(zs.avail_out == 0);
- BOOST_ASSERT(zs.total_out == out.size());
- ec.assign(0, ec.category());
- break;
- }
- if(zs.avail_out == 0)
- {
- BOOST_ASSERT(zs.total_out == out.size());
- break;
- }
- BOOST_ASSERT(zs.avail_in == 0);
- }
- total_in = zs.total_in;
- cb.consume(zs.total_in);
- if(zs.avail_out > 0 && fin)
- {
- auto const remain = boost::asio::buffer_size(cb);
- if(remain == 0)
- {
- // Inspired by Mark Adler
- // https://github.com/madler/zlib/issues/149
- //
- // VFALCO We could do this flush twice depending
- // on how much space is in the output.
- zo.write(zs, zlib::Flush::block, ec);
- BOOST_ASSERT(! ec || ec == zlib::error::need_buffers);
- if(ec == zlib::error::need_buffers)
- ec.assign(0, ec.category());
- if(ec)
- return false;
- if(zs.avail_out >= 6)
- {
- zo.write(zs, zlib::Flush::full, ec);
- BOOST_ASSERT(! ec);
- // remove flush marker
- zs.total_out -= 4;
- out = buffer(out.data(), zs.total_out);
- return false;
- }
- }
- }
- ec.assign(0, ec.category());
- out = buffer(out.data(), zs.total_out);
- return true;
-}
-
} // detail
} // websocket
} // beast
diff --git a/boost/beast/websocket/detail/stream_base.hpp b/boost/beast/websocket/detail/stream_base.hpp
new file mode 100644
index 0000000000..2e93cce3d4
--- /dev/null
+++ b/boost/beast/websocket/detail/stream_base.hpp
@@ -0,0 +1,221 @@
+//
+// 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_WEBSOCKET_STREAM_BASE_HPP
+#define BOOST_BEAST_WEBSOCKET_STREAM_BASE_HPP
+
+#include <boost/beast/websocket/option.hpp>
+#include <boost/beast/websocket/detail/pmd_extension.hpp>
+#include <boost/beast/zlib/deflate_stream.hpp>
+#include <boost/beast/zlib/inflate_stream.hpp>
+#include <boost/beast/core/buffers_suffix.hpp>
+#include <boost/beast/core/error.hpp>
+#include <boost/asio/buffer.hpp>
+#include <cstdint>
+#include <memory>
+
+namespace boost {
+namespace beast {
+namespace websocket {
+namespace detail {
+
+// used to order reads and writes
+class soft_mutex
+{
+ int id_ = 0;
+
+public:
+ soft_mutex() = default;
+ soft_mutex(soft_mutex const&) = delete;
+ soft_mutex& operator=(soft_mutex const&) = delete;
+
+ soft_mutex(soft_mutex&& other) noexcept
+ : id_(other.id_)
+ {
+ other.id_ = 0;
+ }
+
+ soft_mutex& operator=(soft_mutex&& other) noexcept
+ {
+ id_ = other.id_;
+ other.id_ = 0;
+ return *this;
+ }
+
+ // VFALCO I'm not too happy that this function is needed
+ void reset()
+ {
+ id_ = 0;
+ }
+
+ bool is_locked() const
+ {
+ return id_ != 0;
+ }
+
+ template<class T>
+ bool is_locked(T const*) const
+ {
+ return id_ == T::id;
+ }
+
+ template<class T>
+ void lock(T const*)
+ {
+ BOOST_ASSERT(id_ == 0);
+ id_ = T::id;
+ }
+
+ template<class T>
+ void unlock(T const*)
+ {
+ BOOST_ASSERT(id_ == T::id);
+ id_ = 0;
+ }
+
+ template<class T>
+ bool try_lock(T const*)
+ {
+ // If this assert goes off it means you are attempting to
+ // simultaneously initiate more than one of same asynchronous
+ // operation, which is not allowed. For example, you must wait
+ // for an async_read to complete before performing another
+ // async_read.
+ //
+ BOOST_ASSERT(id_ != T::id);
+ if(id_ != 0)
+ return false;
+ id_ = T::id;
+ return true;
+ }
+
+ template<class T>
+ bool try_unlock(T const*)
+ {
+ if(id_ != T::id)
+ return false;
+ id_ = 0;
+ return true;
+ }
+};
+
+template<bool deflateSupported>
+struct stream_base
+{
+ // State information for the permessage-deflate extension
+ struct pmd_type
+ {
+ // `true` if current read message is compressed
+ bool rd_set = false;
+
+ zlib::deflate_stream zo;
+ zlib::inflate_stream zi;
+ };
+
+ std::unique_ptr<pmd_type> pmd_; // pmd settings or nullptr
+ permessage_deflate pmd_opts_; // local pmd options
+ detail::pmd_offer pmd_config_; // offer (client) or negotiation (server)
+
+ // return `true` if current message is deflated
+ bool
+ rd_deflated() const
+ {
+ return pmd_ && pmd_->rd_set;
+ }
+
+ // set whether current message is deflated
+ // returns `false` on protocol violation
+ bool
+ rd_deflated(bool rsv1)
+ {
+ if(pmd_)
+ {
+ pmd_->rd_set = rsv1;
+ return true;
+ }
+ return ! rsv1; // pmd not negotiated
+ }
+
+ template<class ConstBufferSequence>
+ bool
+ deflate(
+ boost::asio::mutable_buffer& out,
+ buffers_suffix<ConstBufferSequence>& cb,
+ bool fin,
+ std::size_t& total_in,
+ error_code& ec);
+
+ void
+ do_context_takeover_write(role_type role);
+
+ void
+ inflate(
+ zlib::z_params& zs,
+ zlib::Flush flush,
+ error_code& ec);
+
+ void
+ do_context_takeover_read(role_type role);
+};
+
+template<>
+struct stream_base<false>
+{
+ // These stubs are for avoiding linking in the zlib
+ // code when permessage-deflate is not enabled.
+
+ bool
+ rd_deflated() const
+ {
+ return false;
+ }
+
+ bool
+ rd_deflated(bool rsv1)
+ {
+ return ! rsv1;
+ }
+
+ template<class ConstBufferSequence>
+ bool
+ deflate(
+ boost::asio::mutable_buffer&,
+ buffers_suffix<ConstBufferSequence>&,
+ bool,
+ std::size_t&,
+ error_code&)
+ {
+ return false;
+ }
+
+ void
+ do_context_takeover_write(role_type)
+ {
+ }
+
+ void
+ inflate(
+ zlib::z_params&,
+ zlib::Flush,
+ error_code&)
+ {
+ }
+
+ void
+ do_context_takeover_read(role_type)
+ {
+ }
+};
+
+} // detail
+} // websocket
+} // beast
+} // boost
+
+#endif
diff --git a/boost/beast/websocket/detail/type_traits.hpp b/boost/beast/websocket/detail/type_traits.hpp
index 6c2806146c..6913174fd0 100644
--- a/boost/beast/websocket/detail/type_traits.hpp
+++ b/boost/beast/websocket/detail/type_traits.hpp
@@ -19,12 +19,12 @@ namespace websocket {
namespace detail {
template<class F>
-using is_RequestDecorator =
+using is_request_decorator =
typename beast::detail::is_invocable<F,
void(request_type&)>::type;
template<class F>
-using is_ResponseDecorator =
+using is_response_decorator =
typename beast::detail::is_invocable<F,
void(response_type&)>::type;
diff --git a/boost/beast/websocket/detail/utf8_checker.hpp b/boost/beast/websocket/detail/utf8_checker.hpp
index e86310f051..61c241bc19 100644
--- a/boost/beast/websocket/detail/utf8_checker.hpp
+++ b/boost/beast/websocket/detail/utf8_checker.hpp
@@ -151,13 +151,13 @@ write(std::uint8_t const* in, std::size_t size)
{
default:
BOOST_ASSERT(false);
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case 1:
cp_[1] = 0x81;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case 2:
cp_[2] = 0x81;
- BOOST_BEAST_FALLTHROUGH;
+ BOOST_FALLTHROUGH;
case 3:
cp_[3] = 0x81;
break;