forked from boostorg/beast
Move clamp to core
This commit is contained in:
40
include/beast/core/detail/clamp.hpp
Normal file
40
include/beast/core/detail/clamp.hpp
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2013-2016 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)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef BEAST_CORE_DETAIL_CLAMP_HPP
|
||||||
|
#define BEAST_CORE_DETAIL_CLAMP_HPP
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class UInt>
|
||||||
|
static
|
||||||
|
std::size_t
|
||||||
|
clamp(UInt x)
|
||||||
|
{
|
||||||
|
if(x >= std::numeric_limits<std::size_t>::max())
|
||||||
|
return std::numeric_limits<std::size_t>::max();
|
||||||
|
return static_cast<std::size_t>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class UInt>
|
||||||
|
static
|
||||||
|
std::size_t
|
||||||
|
clamp(UInt x, std::size_t limit)
|
||||||
|
{
|
||||||
|
if(x >= limit)
|
||||||
|
return limit;
|
||||||
|
return static_cast<std::size_t>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // detail
|
||||||
|
} // beast
|
||||||
|
|
||||||
|
#endif
|
@@ -9,6 +9,7 @@
|
|||||||
#define BEAST_WEBSOCKET_DETAIL_STREAM_BASE_HPP
|
#define BEAST_WEBSOCKET_DETAIL_STREAM_BASE_HPP
|
||||||
|
|
||||||
#include <beast/websocket/error.hpp>
|
#include <beast/websocket/error.hpp>
|
||||||
|
#include <beast/websocket/option.hpp>
|
||||||
#include <beast/websocket/rfc6455.hpp>
|
#include <beast/websocket/rfc6455.hpp>
|
||||||
#include <beast/websocket/detail/decorator.hpp>
|
#include <beast/websocket/detail/decorator.hpp>
|
||||||
#include <beast/websocket/detail/frame.hpp>
|
#include <beast/websocket/detail/frame.hpp>
|
||||||
@@ -21,36 +22,12 @@
|
|||||||
#include <boost/asio/error.hpp>
|
#include <boost/asio/error.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
|
||||||
#include <limits>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
namespace websocket {
|
namespace websocket {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class UInt>
|
|
||||||
static
|
|
||||||
std::size_t
|
|
||||||
clamp(UInt x)
|
|
||||||
{
|
|
||||||
if(x >= std::numeric_limits<std::size_t>::max())
|
|
||||||
return std::numeric_limits<std::size_t>::max();
|
|
||||||
return static_cast<std::size_t>(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class UInt>
|
|
||||||
static
|
|
||||||
std::size_t
|
|
||||||
clamp(UInt x, std::size_t limit)
|
|
||||||
{
|
|
||||||
if(x >= limit)
|
|
||||||
return limit;
|
|
||||||
return static_cast<std::size_t>(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
using pong_cb = std::function<void(ping_data const&)>;
|
|
||||||
|
|
||||||
/// Identifies the role of a WebSockets stream.
|
/// Identifies the role of a WebSockets stream.
|
||||||
enum class role_type
|
enum class role_type
|
||||||
{
|
{
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <beast/core/prepare_buffers.hpp>
|
#include <beast/core/prepare_buffers.hpp>
|
||||||
#include <beast/core/static_streambuf.hpp>
|
#include <beast/core/static_streambuf.hpp>
|
||||||
#include <beast/core/stream_concepts.hpp>
|
#include <beast/core/stream_concepts.hpp>
|
||||||
|
#include <beast/core/detail/clamp.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -148,6 +149,7 @@ void
|
|||||||
stream<NextLayer>::read_frame_op<DynamicBuffer, Handler>::
|
stream<NextLayer>::read_frame_op<DynamicBuffer, Handler>::
|
||||||
operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
||||||
{
|
{
|
||||||
|
using beast::detail::clamp;
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
do_start = 0,
|
do_start = 0,
|
||||||
@@ -191,8 +193,7 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
|||||||
|
|
||||||
case do_read_payload:
|
case do_read_payload:
|
||||||
d.state = do_read_payload + 1;
|
d.state = do_read_payload + 1;
|
||||||
d.dmb = d.db.prepare(
|
d.dmb = d.db.prepare(clamp(d.ws.rd_need_));
|
||||||
detail::clamp(d.ws.rd_need_));
|
|
||||||
// receive payload data
|
// receive payload data
|
||||||
d.ws.stream_.async_read_some(
|
d.ws.stream_.async_read_some(
|
||||||
*d.dmb, std::move(*this));
|
*d.dmb, std::move(*this));
|
||||||
@@ -590,6 +591,7 @@ read_frame(frame_info& fi, DynamicBuffer& dynabuf, error_code& ec)
|
|||||||
"SyncStream requirements not met");
|
"SyncStream requirements not met");
|
||||||
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"DynamicBuffer requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
|
using beast::detail::clamp;
|
||||||
close_code::value code{};
|
close_code::value code{};
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
@@ -668,8 +670,7 @@ read_frame(frame_info& fi, DynamicBuffer& dynabuf, error_code& ec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// read payload
|
// read payload
|
||||||
auto smb = dynabuf.prepare(
|
auto smb = dynabuf.prepare(clamp(rd_need_));
|
||||||
detail::clamp(rd_need_));
|
|
||||||
auto const bytes_transferred =
|
auto const bytes_transferred =
|
||||||
stream_.read_some(smb, ec);
|
stream_.read_some(smb, ec);
|
||||||
failed_ = ec != 0;
|
failed_ = ec != 0;
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include <beast/core/prepare_buffers.hpp>
|
#include <beast/core/prepare_buffers.hpp>
|
||||||
#include <beast/core/static_streambuf.hpp>
|
#include <beast/core/static_streambuf.hpp>
|
||||||
#include <beast/core/stream_concepts.hpp>
|
#include <beast/core/stream_concepts.hpp>
|
||||||
|
#include <beast/core/detail/clamp.hpp>
|
||||||
#include <beast/websocket/detail/frame.hpp>
|
#include <beast/websocket/detail/frame.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -122,6 +123,7 @@ class stream<NextLayer>::write_frame_op
|
|||||||
, cont(boost_asio_handler_cont_helpers::
|
, cont(boost_asio_handler_cont_helpers::
|
||||||
is_continuation(h))
|
is_continuation(h))
|
||||||
{
|
{
|
||||||
|
using beast::detail::clamp;
|
||||||
fh.op = ws.wr_.cont ?
|
fh.op = ws.wr_.cont ?
|
||||||
opcode::cont : ws.wr_opcode_;
|
opcode::cont : ws.wr_opcode_;
|
||||||
ws.wr_.cont = ! fin;
|
ws.wr_.cont = ! fin;
|
||||||
@@ -135,8 +137,7 @@ class stream<NextLayer>::write_frame_op
|
|||||||
{
|
{
|
||||||
fh.key = ws.maskgen_();
|
fh.key = ws.maskgen_();
|
||||||
detail::prepare_key(key, fh.key);
|
detail::prepare_key(key, fh.key);
|
||||||
tmp_size = detail::clamp(
|
tmp_size = clamp(fh.len, ws.wr_buf_size_);
|
||||||
fh.len, ws.wr_buf_size_);
|
|
||||||
tmp = boost_asio_handler_alloc_helpers::
|
tmp = boost_asio_handler_alloc_helpers::
|
||||||
allocate(tmp_size, h);
|
allocate(tmp_size, h);
|
||||||
remain = fh.len;
|
remain = fh.len;
|
||||||
@@ -232,6 +233,7 @@ stream<NextLayer>::
|
|||||||
write_frame_op<Buffers, Handler>::
|
write_frame_op<Buffers, Handler>::
|
||||||
operator()(error_code ec, bool again)
|
operator()(error_code ec, bool again)
|
||||||
{
|
{
|
||||||
|
using beast::detail::clamp;
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
using boost::asio::mutable_buffers_1;
|
using boost::asio::mutable_buffers_1;
|
||||||
auto& d = *d_;
|
auto& d = *d_;
|
||||||
@@ -275,8 +277,7 @@ operator()(error_code ec, bool again)
|
|||||||
std::move(*this));
|
std::move(*this));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto const n =
|
auto const n = clamp(d.remain, d.tmp_size);
|
||||||
detail::clamp(d.remain, d.tmp_size);
|
|
||||||
mutable_buffers_1 mb{d.tmp, n};
|
mutable_buffers_1 mb{d.tmp, n};
|
||||||
buffer_copy(mb, d.cb);
|
buffer_copy(mb, d.cb);
|
||||||
d.cb.consume(n);
|
d.cb.consume(n);
|
||||||
@@ -295,8 +296,7 @@ operator()(error_code ec, bool again)
|
|||||||
// sent masked payload
|
// sent masked payload
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
auto const n =
|
auto const n = clamp(d.remain, d.tmp_size);
|
||||||
detail::clamp(d.remain, d.tmp_size);
|
|
||||||
mutable_buffers_1 mb{d.tmp,
|
mutable_buffers_1 mb{d.tmp,
|
||||||
static_cast<std::size_t>(n)};
|
static_cast<std::size_t>(n)};
|
||||||
buffer_copy(mb, d.cb);
|
buffer_copy(mb, d.cb);
|
||||||
@@ -396,6 +396,7 @@ write_frame(bool fin,
|
|||||||
static_assert(beast::is_ConstBufferSequence<
|
static_assert(beast::is_ConstBufferSequence<
|
||||||
ConstBufferSequence>::value,
|
ConstBufferSequence>::value,
|
||||||
"ConstBufferSequence requirements not met");
|
"ConstBufferSequence requirements not met");
|
||||||
|
using beast::detail::clamp;
|
||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
using boost::asio::buffer_size;
|
using boost::asio::buffer_size;
|
||||||
@@ -434,8 +435,7 @@ write_frame(bool fin,
|
|||||||
ConstBufferSequence> cb(buffers);
|
ConstBufferSequence> cb(buffers);
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
auto const n =
|
auto const n = clamp(remain, wr_.size);
|
||||||
detail::clamp(remain, wr_.size);
|
|
||||||
fh.len = n;
|
fh.len = n;
|
||||||
remain -= n;
|
remain -= n;
|
||||||
fh.fin = fin ? remain == 0 : false;
|
fh.fin = fin ? remain == 0 : false;
|
||||||
@@ -466,7 +466,7 @@ write_frame(bool fin,
|
|||||||
consuming_buffers<
|
consuming_buffers<
|
||||||
ConstBufferSequence> cb(buffers);
|
ConstBufferSequence> cb(buffers);
|
||||||
{
|
{
|
||||||
auto const n = detail::clamp(remain, wr_.size);
|
auto const n = clamp(remain, wr_.size);
|
||||||
auto const mb = buffer(wr_.buf.get(), n);
|
auto const mb = buffer(wr_.buf.get(), n);
|
||||||
buffer_copy(mb, cb);
|
buffer_copy(mb, cb);
|
||||||
cb.consume(n);
|
cb.consume(n);
|
||||||
@@ -480,7 +480,7 @@ write_frame(bool fin,
|
|||||||
}
|
}
|
||||||
while(remain > 0)
|
while(remain > 0)
|
||||||
{
|
{
|
||||||
auto const n = detail::clamp(remain, wr_.size);
|
auto const n = clamp(remain, wr_.size);
|
||||||
auto const mb = buffer(wr_.buf.get(), n);
|
auto const mb = buffer(wr_.buf.get(), n);
|
||||||
buffer_copy(mb, cb);
|
buffer_copy(mb, cb);
|
||||||
cb.consume(n);
|
cb.consume(n);
|
||||||
@@ -503,8 +503,7 @@ write_frame(bool fin,
|
|||||||
fh.key = maskgen_();
|
fh.key = maskgen_();
|
||||||
detail::prepared_key_type key;
|
detail::prepared_key_type key;
|
||||||
detail::prepare_key(key, fh.key);
|
detail::prepare_key(key, fh.key);
|
||||||
auto const n =
|
auto const n = clamp(remain, wr_.size);
|
||||||
detail::clamp(remain, wr_.size);
|
|
||||||
auto const mb = buffer(wr_.buf.get(), n);
|
auto const mb = buffer(wr_.buf.get(), n);
|
||||||
buffer_copy(mb, cb);
|
buffer_copy(mb, cb);
|
||||||
detail::mask_inplace(mb, key);
|
detail::mask_inplace(mb, key);
|
||||||
|
@@ -9,9 +9,10 @@
|
|||||||
#define BEAST_WEBSOCKET_OPTION_HPP
|
#define BEAST_WEBSOCKET_OPTION_HPP
|
||||||
|
|
||||||
#include <beast/websocket/rfc6455.hpp>
|
#include <beast/websocket/rfc6455.hpp>
|
||||||
#include <beast/websocket/detail/stream_base.hpp>
|
#include <beast/websocket/detail/decorator.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -191,6 +192,12 @@ struct message_type
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
using pong_cb = std::function<void(ping_data const&)>;
|
||||||
|
|
||||||
|
} // detail
|
||||||
|
|
||||||
/** Pong callback option.
|
/** Pong callback option.
|
||||||
|
|
||||||
Sets the callback to be invoked whenever a pong is received
|
Sets the callback to be invoked whenever a pong is received
|
||||||
|
@@ -20,6 +20,7 @@ unit-test core-tests :
|
|||||||
core/buffer_cat.cpp
|
core/buffer_cat.cpp
|
||||||
core/buffer_concepts.cpp
|
core/buffer_concepts.cpp
|
||||||
core/buffers_adapter.cpp
|
core/buffers_adapter.cpp
|
||||||
|
core/clamp.cpp
|
||||||
core/consuming_buffers.cpp
|
core/consuming_buffers.cpp
|
||||||
core/dynabuf_readstream.cpp
|
core/dynabuf_readstream.cpp
|
||||||
core/error.cpp
|
core/error.cpp
|
||||||
@@ -78,7 +79,6 @@ unit-test websocket-tests :
|
|||||||
websocket/teardown.cpp
|
websocket/teardown.cpp
|
||||||
websocket/frame.cpp
|
websocket/frame.cpp
|
||||||
websocket/mask.cpp
|
websocket/mask.cpp
|
||||||
websocket/stream_base.cpp
|
|
||||||
websocket/utf8_checker.cpp
|
websocket/utf8_checker.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@ add_executable (core-tests
|
|||||||
buffer_cat.cpp
|
buffer_cat.cpp
|
||||||
buffer_concepts.cpp
|
buffer_concepts.cpp
|
||||||
buffers_adapter.cpp
|
buffers_adapter.cpp
|
||||||
|
clamp.cpp
|
||||||
consuming_buffers.cpp
|
consuming_buffers.cpp
|
||||||
dynabuf_readstream.cpp
|
dynabuf_readstream.cpp
|
||||||
error.cpp
|
error.cpp
|
||||||
|
@@ -6,22 +6,20 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Test that header file is self-contained.
|
// Test that header file is self-contained.
|
||||||
#include <beast/websocket/detail/stream_base.hpp>
|
#include <beast/core/detail/clamp.hpp>
|
||||||
|
|
||||||
#include <beast/unit_test/suite.hpp>
|
#include <beast/unit_test/suite.hpp>
|
||||||
#include <initializer_list>
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
namespace websocket {
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
class stream_base_test : public beast::unit_test::suite
|
class clamp_test : public beast::unit_test::suite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void testClamp()
|
void testClamp()
|
||||||
{
|
{
|
||||||
BEAST_EXPECT(detail::clamp(
|
BEAST_EXPECT(clamp(
|
||||||
std::numeric_limits<std::uint64_t>::max()) ==
|
std::numeric_limits<std::uint64_t>::max()) ==
|
||||||
std::numeric_limits<std::size_t>::max());
|
std::numeric_limits<std::size_t>::max());
|
||||||
}
|
}
|
||||||
@@ -32,9 +30,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(stream_base,websocket,beast);
|
BEAST_DEFINE_TESTSUITE(clamp,core,beast);
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
} // websocket
|
|
||||||
} // beast
|
} // beast
|
||||||
|
|
@@ -17,7 +17,6 @@ add_executable (websocket-tests
|
|||||||
teardown.cpp
|
teardown.cpp
|
||||||
frame.cpp
|
frame.cpp
|
||||||
mask.cpp
|
mask.cpp
|
||||||
stream_base.cpp
|
|
||||||
utf8_checker.cpp
|
utf8_checker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user