Move clamp to core

This commit is contained in:
Vinnie Falco
2016-10-24 20:02:38 -04:00
parent a878165e36
commit a2ea4f38c1
9 changed files with 71 additions and 50 deletions

View 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

View File

@@ -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
{ {

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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
; ;

View File

@@ -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

View File

@@ -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

View File

@@ -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
) )