forked from boostorg/mqtt5
support large publish packets
Reviewers: ivica Reviewed By: ivica Subscribers: korina Differential Revision: https://repo.mireo.local/D26763
This commit is contained in:
@ -28,19 +28,22 @@ void assign_tls_sni(const authority_path& ap, TlsContext& ctx, TlsStream& s);
|
||||
namespace detail {
|
||||
|
||||
template <typename Handler, typename DfltExecutor>
|
||||
decltype(auto) tracking_executor(const Handler& handler, const DfltExecutor& ex) {
|
||||
using tracking_type = std::decay_t<
|
||||
typename asio::prefer_result<
|
||||
asio::associated_executor_t<Handler, DfltExecutor>,
|
||||
asio::execution::outstanding_work_t::tracked_t
|
||||
>::type
|
||||
>;
|
||||
|
||||
template <typename Handler, typename DfltExecutor>
|
||||
tracking_type<Handler, DfltExecutor>
|
||||
tracking_executor(const Handler& handler, const DfltExecutor& ex) {
|
||||
return asio::prefer(
|
||||
asio::get_associated_executor(handler, ex),
|
||||
asio::execution::outstanding_work.tracked
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Handler, typename DfltExecutor>
|
||||
using tracking_type = typename asio::prefer_result<
|
||||
asio::associated_executor_t<Handler, DfltExecutor>,
|
||||
asio::execution::outstanding_work_t::tracked_t
|
||||
>::type;
|
||||
|
||||
template <typename T, typename B>
|
||||
concept has_async_write = requires(T a) {
|
||||
a.async_write(
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
return flag_def<bits, repr> { val };
|
||||
}
|
||||
|
||||
uint16_t byte_size() const { return sizeof(repr); }
|
||||
size_t byte_size() const { return sizeof(repr); }
|
||||
|
||||
template <size_t rhs_bits, typename rhs_repr>
|
||||
auto operator|(const flag_def<rhs_bits, rhs_repr>& rhs) const {
|
||||
@ -103,13 +103,13 @@ class int_val : public encoder {
|
||||
public:
|
||||
int_val(T val) : _val(val) {}
|
||||
|
||||
uint16_t byte_size() const {
|
||||
size_t byte_size() const {
|
||||
if constexpr (is_optional<T>) {
|
||||
if (_val) return uint16_t(val_length(*_val));
|
||||
return uint16_t(0);
|
||||
if (_val) return val_length(*_val);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return uint16_t(val_length(_val));
|
||||
return val_length(_val);
|
||||
}
|
||||
|
||||
std::string& encode(std::string& s) const {
|
||||
@ -185,11 +185,11 @@ public:
|
||||
static_assert(std::is_reference_v<T> || std::is_same_v<T, std::string_view>);
|
||||
}
|
||||
|
||||
uint16_t byte_size() const {
|
||||
size_t byte_size() const {
|
||||
if constexpr (is_optional<T>)
|
||||
return uint16_t(_val ? _with_length * 2 + val_length(*_val) : 0);
|
||||
return _val ? _with_length * 2 + val_length(*_val) : 0;
|
||||
else
|
||||
return uint16_t(_with_length * 2 + val_length(_val));
|
||||
return _with_length * 2 + val_length(_val);
|
||||
}
|
||||
|
||||
std::string& encode(std::string& s) const {
|
||||
@ -215,12 +215,12 @@ private:
|
||||
template <typename U>
|
||||
std::string& encode_val(std::string& s, U&& u) const {
|
||||
using namespace boost::endian;
|
||||
int16_t byte_len = int16_t(val_length(std::forward<U>(u)));
|
||||
auto byte_len = val_length(std::forward<U>(u));
|
||||
if (byte_len == 0 && !_with_length) return s;
|
||||
if (_with_length) {
|
||||
size_t sz = s.size(); s.resize(sz + 2);
|
||||
auto p = reinterpret_cast<uint8_t*>(s.data() + sz);
|
||||
endian_store<int16_t, sizeof(int16_t), order::big>(p, byte_len);
|
||||
endian_store<int16_t, sizeof(int16_t), order::big>(p, int16_t(byte_len));
|
||||
}
|
||||
s.append(std::begin(u), std::begin(u) + byte_len);
|
||||
return s;
|
||||
@ -266,8 +266,8 @@ public:
|
||||
composed_val(T lhs, U rhs) :
|
||||
_lhs(std::forward<T>(lhs)), _rhs(std::forward<U>(rhs)) {}
|
||||
|
||||
uint16_t byte_size() const {
|
||||
return uint16_t(_lhs.byte_size() + _rhs.byte_size());
|
||||
size_t byte_size() const {
|
||||
return _lhs.byte_size() + _rhs.byte_size();
|
||||
}
|
||||
|
||||
std::string& encode(std::string& s) const {
|
||||
|
@ -114,13 +114,40 @@ BOOST_AUTO_TEST_CASE(test_publish) {
|
||||
BOOST_CHECK(packet_id);
|
||||
BOOST_CHECK_EQUAL(*packet_id_, packet_id);
|
||||
BOOST_CHECK_EQUAL(topic_, topic);
|
||||
BOOST_CHECK_EQUAL(payload_, payload_);
|
||||
BOOST_CHECK_EQUAL(payload_, payload);
|
||||
BOOST_CHECK_EQUAL(*pprops[prop::message_expiry_interval], message_expiry);
|
||||
BOOST_CHECK_EQUAL(*pprops[prop::content_type], content_type);
|
||||
BOOST_CHECK_EQUAL(pprops[prop::user_property][0], publish_prop_1);
|
||||
BOOST_CHECK_EQUAL(pprops[prop::user_property][1], publish_prop_2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_large_publish) {
|
||||
// testing variables
|
||||
uint16_t packet_id = 40001;
|
||||
std::string_view topic = "publish_topic";
|
||||
std::string large_payload(1'000'000, 'a');
|
||||
|
||||
auto msg = encoders::encode_publish(
|
||||
packet_id, topic, large_payload,
|
||||
qos_e::at_least_once, retain_e::yes, dup_e::no,
|
||||
publish_props{}
|
||||
);
|
||||
|
||||
byte_citer it = msg.cbegin(), last = msg.cend();
|
||||
auto header = decoders::decode_fixed_header(it, last);
|
||||
BOOST_CHECK_MESSAGE(header, "Parsing PUBLISH fixed header failed.");
|
||||
|
||||
const auto& [control_byte, remain_length] = *header;
|
||||
auto rv = decoders::decode_publish(control_byte, remain_length, it);
|
||||
BOOST_CHECK_MESSAGE(rv, "Parsing PUBLISH failed.");
|
||||
|
||||
const auto& [topic_, packet_id_, flags, pprops, payload_] = *rv;
|
||||
BOOST_CHECK(packet_id);
|
||||
BOOST_CHECK_EQUAL(*packet_id_, packet_id);
|
||||
BOOST_CHECK_EQUAL(topic_, topic);
|
||||
BOOST_CHECK_EQUAL(payload_, large_payload);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_puback) {
|
||||
// testing variables
|
||||
uint16_t packet_id = 9199;
|
||||
|
Reference in New Issue
Block a user