7#if !defined(ASYNC_MQTT_PACKET_PROPERTY_HPP)
8#define ASYNC_MQTT_PACKET_PROPERTY_HPP
18#include <boost/asio/buffer.hpp>
19#include <boost/numeric/conversion/cast.hpp>
20#include <boost/container/static_vector.hpp>
21#include <boost/operators.hpp>
23#include <async_mqtt/util/optional.hpp>
24#include <async_mqtt/util/move.hpp>
25#include <async_mqtt/util/static_vector.hpp>
26#include <async_mqtt/util/endian_convert.hpp>
27#include <async_mqtt/util/json_like_out.hpp>
28#include <async_mqtt/util/utf8validate.hpp>
30#include <async_mqtt/exception.hpp>
32#include <async_mqtt/packet/property_id.hpp>
33#include <async_mqtt/variable_bytes.hpp>
34#include <async_mqtt/buffer.hpp>
40namespace as = boost::asio;
55enum class ostream_format {
69template <std::
size_t N>
77 template <
typename It,
typename End>
79 :id_{
id}, buf_(
b,
e) {}
84 buf_.insert(buf_.end(), (buf.begin(), std::next(buf.begin(),
N)));
92 std::vector<as::const_buffer>
v;
94 v.emplace_back(as::buffer(&id_, 1));
95 v.emplace_back(as::buffer(buf_.data(), buf_.size()));
103 property::id
id()
const {
112 return 1 + buf_.size();
124 return std::tie(
lhs.id_,
lhs.buf_) < std::tie(
rhs.id_,
rhs.buf_);
128 return std::tie(
lhs.id_,
lhs.buf_) == std::tie(
rhs.id_,
rhs.buf_);
131 static constexpr ostream_format
const of_ = ostream_format::direct;
142 buf_{force_move(buf)},
145 if (buf_.size() > 0xffff) {
148 "property::binary_property length is invalid"
151 endian_store(boost::numeric_cast<std::uint16_t>(buf_.size()), length_.data());
159 std::vector<as::const_buffer>
v;
161 v.emplace_back(as::buffer(&id_, 1));
162 v.emplace_back(as::buffer(length_.data(), length_.size()));
163 v.emplace_back(as::buffer(buf_.data(), buf_.size()));
171 property::id
id()
const {
180 return 1 + length_.size() + buf_.size();
200 return std::tie(
lhs.id_,
lhs.buf_) < std::tie(
rhs.id_,
rhs.buf_);
203 friend bool operator==(binary_property
const&
lhs, binary_property
const&
rhs) {
204 return std::tie(
lhs.id_,
lhs.buf_) == std::tie(
rhs.id_,
rhs.buf_);
207 static constexpr ostream_format
const of_ = ostream_format::json_like;
219 if (!utf8string_check(this->
val())) {
222 "string property invalid utf8"
236 value_ = val_to_variable_bytes(boost::numeric_cast<std::uint32_t>(
value));
244 std::vector<as::const_buffer>
v;
246 v.emplace_back(as::buffer(&id_, 1));
247 v.emplace_back(as::buffer(value_.data(), value_.size()));
255 property::id
id()
const {
264 return 1 + value_.size();
280 auto it{value_.begin()};
281 auto val_opt{variable_bytes_to_val(
it, value_.end())};
292 friend bool operator==(variable_property
const&
lhs, variable_property
const&
rhs) {
298 static constexpr ostream_format
const of_ = ostream_format::direct;
316 : detail::n_bytes_property<1>{
317 id::payload_format_indicator,
320 if (
fmt == payload_format::binary)
return char(0);
327 template <
typename It,
typename End>
328 payload_format_indicator(
It b,
End e)
329 : detail::n_bytes_property<1>{id::payload_format_indicator,
b,
e} {}
338 if (buf_.front() == 0)
return payload_format::binary;
339 return payload_format::string;
343 static constexpr detail::ostream_format
const of_ = detail::ostream_format::binary_string;
357 : detail::n_bytes_property<4>{id::message_expiry_interval, endian_static_vector(
val)} {}
359 template <
typename It,
typename End>
360 message_expiry_interval(
It b,
End e)
361 : detail::n_bytes_property<4>{id::message_expiry_interval,
b,
e} {}
367 std::uint32_t
val()
const {
434 : detail::n_bytes_property<4>{id::session_expiry_interval, endian_static_vector(
val)} {
437 template <
typename It>
438 session_expiry_interval(
It b,
It e)
439 : detail::n_bytes_property<4>{id::session_expiry_interval,
b,
e} {}
445 std::uint32_t
val()
const {
473 : detail::n_bytes_property<2>{id::server_keep_alive, endian_static_vector(
val)} {}
475 template <
typename It,
typename End>
477 : detail::n_bytes_property<2>{id::server_keep_alive,
b,
e} {}
483 std::uint16_t
val()
const {
524 : detail::n_bytes_property<1>{
525 id::request_problem_information,
534 template <
typename It,
typename End>
535 request_problem_information(
It b,
End e)
536 : detail::n_bytes_property<1>{id::request_problem_information,
b,
e} {}
543 return buf_.front() == 1;
557 : detail::n_bytes_property<4>{id::will_delay_interval, endian_static_vector(
val)} {}
559 template <
typename It,
typename End>
560 will_delay_interval(
It b,
End e)
561 : detail::n_bytes_property<4>{id::will_delay_interval,
b,
e} {}
567 std::uint32_t
val()
const {
582 : detail::n_bytes_property<1>{
583 id::request_response_information,
593 template <
typename It,
typename End>
594 request_response_information(
It b,
End e)
595 : detail::n_bytes_property<1>(
id::request_response_information,
b,
e) {}
602 return buf_.front() == 1;
655 : detail::n_bytes_property<2>{id::receive_maximum, endian_static_vector(
val)} {
659 "property::receive_maximum value is invalid"
664 template <
typename It,
typename End>
665 receive_maximum(It b, End e)
666 : detail::n_bytes_property<2>{id::receive_maximum, b, e} {
670 "property::receive_maximum value is invalid"
679 std::uint16_t
val()
const {
695 : detail::n_bytes_property<2>{id::topic_alias_maximum, endian_static_vector(
val)} {}
697 template <
typename It,
typename End>
698 topic_alias_maximum(
It b,
End e)
699 : detail::n_bytes_property<2>{id::topic_alias_maximum,
b,
e} {}
705 std::uint16_t
val()
const {
721 : detail::n_bytes_property<2>{id::topic_alias, endian_static_vector(
val)} {}
723 template <
typename It,
typename End>
725 : detail::n_bytes_property<2>(
id::topic_alias,
b,
e) {}
731 std::uint16_t
val()
const {
746 : detail::n_bytes_property<1>{id::maximum_qos, {
static_cast<char>(
value)}} {
747 if (
value != qos::at_most_once &&
748 value != qos::at_least_once) {
751 "property::maximum_qos value is invalid"
756 template <
typename It,
typename End>
757 maximum_qos(It b, End e)
758 : detail::n_bytes_property<1>{id::maximum_qos, b, e} {}
764 std::uint8_t
val()
const {
765 return static_cast<std::uint8_t
>(buf_.front());
768 static constexpr const detail::ostream_format of_ = detail::ostream_format::int_cast;
781 : detail::n_bytes_property<1>{
782 id::retain_available,
792 template <
typename It,
typename End>
794 : detail::n_bytes_property<1>{id::retain_available,
b,
e} {}
801 return buf_.front() == 1;
816 : key_{force_move(
key)}, val_{force_move(
val)} {
817 if (key_.size() > 0xffff) {
820 "property::user_property key length is invalid"
823 if (val_.size() > 0xffff) {
826 "property::user_property val length is invalid"
836 std::vector<as::const_buffer>
v;
838 v.emplace_back(as::buffer(&id_, 1));
839 v.emplace_back(as::buffer(key_.len.data(), key_.len.size()));
840 v.emplace_back(as::buffer(key_.buf));
841 v.emplace_back(as::buffer(val_.len.data(), val_.len.size()));
842 v.emplace_back(as::buffer(val_.buf));
850 property::id
id()
const {
893 return std::tie(
lhs.id_,
lhs.key_.buf,
lhs.val_.buf) < std::tie(
rhs.id_,
rhs.key_.buf,
rhs.val_.buf);
896 friend bool operator==(user_property
const&
lhs, user_property
const&
rhs) {
897 return std::tie(
lhs.id_,
lhs.key_.buf,
lhs.val_.buf) == std::tie(
rhs.id_,
rhs.key_.buf,
rhs.val_.buf);
900 static constexpr detail::ostream_format
const of_ = detail::ostream_format::key_val;
904 explicit len_str(buffer b)
905 : buf{force_move(b)},
906 len{endian_static_vector(boost::numeric_cast<std::uint16_t>(buf.size()))}
909 auto r = utf8string::validate_contents(buf);
910 if (r != utf8string::validation::well_formed)
throw utf8string_contents_error(r);
914 std::size_t size()
const {
915 return len.size() + buf.size();
918 static_vector<char, 2> len;
922 property::id id_ = id::user_property;
937 : detail::n_bytes_property<4>{id::maximum_packet_size, endian_static_vector(
val)} {
941 "property::maximum_packet_size value is invalid"
946 template <
typename It,
typename End>
947 maximum_packet_size(It b, End e)
948 : detail::n_bytes_property<4>{id::maximum_packet_size, b, e} {
952 "property::maximum_packet_size value is invalid"
961 std::uint32_t
val()
const {
977 : detail::n_bytes_property<1>{
978 id::wildcard_subscription_available,
988 template <
typename It,
typename End>
989 wildcard_subscription_available(
It b,
End e)
990 : detail::n_bytes_property<1>{id::wildcard_subscription_available,
b,
e} {}
997 return buf_.front() == 1;
1012 : detail::n_bytes_property<1>{
1013 id::subscription_identifier_available,
1023 template <
typename It,
typename End>
1024 subscription_identifier_available(
It b,
End e)
1025 : detail::n_bytes_property<1>{id::subscription_identifier_available,
b,
e} {}
1032 return buf_.front() == 1;
1047 : detail::n_bytes_property<1>{
1048 id::shared_subscription_available,
1058 template <
typename It,
typename End>
1059 shared_subscription_available(
It b,
End e)
1060 : detail::n_bytes_property<1>{id::shared_subscription_available,
b,
e} {}
1067 return buf_.front() == 1;
1071template <
typename Property>
1072std::enable_if_t< Property::of_ == detail::ostream_format::direct, std::ostream& >
1076 "id:" << p.id() <<
"," <<
1077 "val:" << p.val() <<
1082template <
typename Property>
1083std::enable_if_t< Property::of_ == detail::ostream_format::int_cast, std::ostream& >
1084operator<<(std::ostream& o, Property
const& p) {
1087 "id:" << p.id() <<
"," <<
1088 "val:" <<
static_cast<int>(p.val()) <<
1093template <
typename Property>
1094std::enable_if_t< Property::of_ == detail::ostream_format::key_val, std::ostream& >
1095operator<<(std::ostream& o, Property
const& p) {
1098 "id:" << p.id() <<
"," <<
1099 "key:" << p.key() <<
"," <<
1100 "val:" << p.val() <<
1105template <
typename Property>
1106std::enable_if_t< Property::of_ == detail::ostream_format::binary_string, std::ostream& >
1107operator<<(std::ostream& o, Property
const& p) {
1111 "id:" << p.id() <<
"," <<
1114 if (p.val() == payload_format::binary)
return "binary";
1121template <
typename Property>
1122std::enable_if_t< Property::of_ == detail::ostream_format::json_like, std::ostream& >
1123operator<<(std::ostream& o, Property
const& p) {
1126 "id:" << p.id() <<
"," <<
1127 "val:" << json_like_out(p.val()) <<
Definition packet_variant.hpp:49
buffer that has string_view interface This class provides string_view interface. This class hold stri...
Definition buffer.hpp:30
Definition property.hpp:453
assigned_client_identifier(buffer val)
constructor
Definition property.hpp:459
Definition property.hpp:504
authentication_data(buffer val)
constructor
Definition property.hpp:510
Definition property.hpp:491
authentication_method(buffer val)
constructor
Definition property.hpp:497
Definition property.hpp:375
content_type(buffer val)
constructor
Definition property.hpp:381
Definition property.hpp:401
correlation_data(buffer val)
constructor
Definition property.hpp:407
Definition property.hpp:930
maximum_packet_size(std::uint32_t val)
constructor
Definition property.hpp:936
std::uint32_t val() const
Get value.
Definition property.hpp:961
Definition property.hpp:739
std::uint8_t val() const
Get value.
Definition property.hpp:764
maximum_qos(qos value)
constructor
Definition property.hpp:745
Definition property.hpp:350
message_expiry_interval(std::uint32_t val)
constructor
Definition property.hpp:356
std::uint32_t val() const
Get value.
Definition property.hpp:367
Definition property.hpp:635
reason_string(buffer val)
constructor
Definition property.hpp:641
Definition property.hpp:648
receive_maximum(std::uint16_t val)
constructor
Definition property.hpp:654
std::uint16_t val() const
Get value.
Definition property.hpp:679
Definition property.hpp:388
response_topic(buffer val)
constructor
Definition property.hpp:394
Definition property.hpp:774
bool val() const
Get value.
Definition property.hpp:800
retain_available(bool value)
constructor
Definition property.hpp:780
Definition property.hpp:466
server_keep_alive(std::uint16_t val)
constructor
Definition property.hpp:472
std::uint16_t val() const
Get value.
Definition property.hpp:483
Definition property.hpp:622
server_reference(buffer val)
constructor
Definition property.hpp:628
Definition property.hpp:427
std::uint32_t val() const
Get value.
Definition property.hpp:445
session_expiry_interval(std::uint32_t val)
constructor
Definition property.hpp:433
Definition property.hpp:1040
bool val() const
Get value.
Definition property.hpp:1066
shared_subscription_available(bool value)
constructor
Definition property.hpp:1046
Definition property.hpp:1005
bool val() const
Get value.
Definition property.hpp:1031
subscription_identifier_available(bool value)
constructor
Definition property.hpp:1011
Definition property.hpp:414
subscription_identifier(std::uint32_t subscription_id)
constructor
Definition property.hpp:420
Definition property.hpp:688
topic_alias_maximum(std::uint16_t val)
constructor
Definition property.hpp:694
std::uint16_t val() const
Get value.
Definition property.hpp:705
Definition property.hpp:714
std::uint16_t val() const
Get value.
Definition property.hpp:731
topic_alias(std::uint16_t val)
constructor
Definition property.hpp:720
Definition property.hpp:809
constexpr buffer const & key() const
Get key.
Definition property.hpp:880
std::size_t size() const
Get property size.
Definition property.hpp:858
std::vector< as::const_buffer > const_buffer_sequence() const
Add const buffer sequence into the given buffer.
Definition property.hpp:835
static constexpr std::size_t num_of_const_buffer_sequence()
Get number of element of const_buffer_sequence.
Definition property.hpp:869
constexpr buffer const & val() const
Get value.
Definition property.hpp:888
user_property(buffer key, buffer val)
constructor
Definition property.hpp:815
property::id id() const
Get property::id.
Definition property.hpp:850
Definition property.hpp:970
bool val() const
Get value.
Definition property.hpp:996
wildcard_subscription_available(bool value)
constructor
Definition property.hpp:976
Definition property.hpp:550
will_delay_interval(std::uint32_t val)
constructor
Definition property.hpp:556
std::uint32_t val() const
Get value.
Definition property.hpp:567
payload_format
Definition property.hpp:45
qos
MQTT QoS.
Definition qos.hpp:23
binary_property
Definition property.hpp:139
static constexpr std::size_t num_of_const_buffer_sequence()
Get number of element of const_buffer_sequence.
Definition property.hpp:187
std::vector< as::const_buffer > const_buffer_sequence() const
Add const buffer sequence into the given buffer.
Definition property.hpp:158
property::id id() const
Get property::id.
Definition property.hpp:171
std::size_t size() const
Get property size.
Definition property.hpp:179
constexpr buffer const & val() const
Get value.
Definition property.hpp:195
N bytes_property.
Definition property.hpp:70
property::id id() const
Get property::id.
Definition property.hpp:103
std::size_t size() const
Get property size.
Definition property.hpp:111
std::vector< as::const_buffer > const_buffer_sequence() const
Add const buffer sequence into the given buffer.
Definition property.hpp:91
static constexpr std::size_t num_of_const_buffer_sequence()
Get number of element of const_buffer_sequence.
Definition property.hpp:119
string_property
Definition property.hpp:216
variable property
Definition property.hpp:233
property::id id() const
Get property::id.
Definition property.hpp:255
static constexpr std::size_t num_of_const_buffer_sequence()
Get number of element of const_buffer_sequence.
Definition property.hpp:271
std::size_t size() const
Get property size.
Definition property.hpp:263
std::size_t val() const
Get value.
Definition property.hpp:279
std::vector< as::const_buffer > const_buffer_sequence() const
Add const buffer sequence into the given buffer.
Definition property.hpp:243