7 #if !defined(MQTT_MESSAGE_HPP)
8 #define MQTT_MESSAGE_HPP
16 #include <boost/asio/buffer.hpp>
17 #include <boost/container/static_vector.hpp>
18 #include <boost/numeric/conversion/cast.hpp>
48 namespace detail_v3_1_1 {
65 return {
as::buffer(message_.data(), message_.size()) };
73 return message_.size();
91 return std::string(message_.data(),
size());
94 boost::container::static_vector<char, 2> message_;
98 template <std::
size_t PacketIdBytes>
99 class basic_header_packet_id_message;
103 template <std::
size_t PacketIdBytes>
115 template <
typename Iterator>
120 std::copy(b, e, std::back_inserter(message_));
137 return message_.size();
155 return std::string(message_.data(),
size());
158 boost::container::static_vector<char, 2 + PacketIdBytes>
const&
message()
const {
163 boost::container::static_vector<char, 2 + PacketIdBytes> message_;
168 template <std::
size_t PacketIdBytes>
178 template <std::
size_t PacketIdBytes>
188 template <std::
size_t PacketIdBytes>
197 :
base(buf.begin(), buf.end())
213 template <std::
size_t PacketIdBytes>
222 template <std::
size_t PacketIdBytes>
255 static_cast<char>(session_present ? 1 : 0),
256 static_cast<char>(return_code)
274 return message_.size();
292 return std::string(message_.data(),
size());
296 boost::container::static_vector<char, 4> message_;
304 std::uint16_t keep_alive_sec,
308 optional<buffer> user_name,
309 optional<buffer> password
323 protocol_name_and_level_ { 0x00, 0x04,
'M',
'Q',
'T',
'T', 0x04 },
334 add_uint16_t_to_buf(user_name_length_buf_, boost::numeric_cast<std::uint16_t>(user_name_.size()));
336 remaining_length_ += 2 + user_name_.size();
341 add_uint16_t_to_buf(password_length_buf_, boost::numeric_cast<std::uint16_t>(password_.size()));
343 remaining_length_ += 2 + password_.size();
351 will_topic_name_ =
force_move(w.value().topic());
353 will_topic_name_length_buf_,
354 boost::numeric_cast<std::uint16_t>(will_topic_name_.size())
357 will_message_ =
force_move(w.value().message());
359 will_message_length_buf_,
360 boost::numeric_cast<std::uint16_t>(will_message_.size()));
362 remaining_length_ += 2 + will_topic_name_.size() + 2 + will_message_.size();
367 remaining_length_buf_.push_back(e);
377 std::vector<as::const_buffer> ret;
380 ret.emplace_back(
as::buffer(&fixed_header_, 1));
381 ret.emplace_back(
as::buffer(remaining_length_buf_.data(), remaining_length_buf_.size()));
382 ret.emplace_back(
as::buffer(protocol_name_and_level_.data(), protocol_name_and_level_.size()));
383 ret.emplace_back(
as::buffer(&connect_flags_, 1));
384 ret.emplace_back(
as::buffer(keep_alive_buf_.data(), keep_alive_buf_.size()));
386 ret.emplace_back(
as::buffer(client_id_length_buf_.data(), client_id_length_buf_.size()));
390 ret.emplace_back(
as::buffer(will_topic_name_length_buf_.data(), will_topic_name_length_buf_.size()));
391 ret.emplace_back(
as::buffer(will_topic_name_));
392 ret.emplace_back(
as::buffer(will_message_length_buf_.data(), will_message_length_buf_.size()));
397 ret.emplace_back(
as::buffer(user_name_length_buf_.data(), user_name_length_buf_.size()));
402 ret.emplace_back(
as::buffer(password_length_buf_.data(), password_length_buf_.size()));
416 remaining_length_buf_.size() +
451 ret.push_back(
static_cast<char>(fixed_header_));
452 ret.append(remaining_length_buf_.data(), remaining_length_buf_.size());
453 ret.append(protocol_name_and_level_.data(), protocol_name_and_level_.size());
454 ret.push_back(connect_flags_);
455 ret.append(keep_alive_buf_.data(), keep_alive_buf_.size());
457 ret.append(client_id_length_buf_.data(), client_id_length_buf_.size());
458 ret.append(client_id_.data(), client_id_.size());
461 ret.append(will_topic_name_length_buf_.data(), will_topic_name_length_buf_.size());
462 ret.append(will_topic_name_.data(), will_topic_name_.size());
463 ret.append(will_message_length_buf_.data(), will_message_length_buf_.size());
464 ret.append(will_message_.data(), will_message_.size());
468 ret.append(user_name_length_buf_.data(), user_name_length_buf_.size());
469 ret.append(user_name_.data(), user_name_.size());
473 ret.append(password_length_buf_.data(), password_length_buf_.size());
474 ret.append(password_.data(), password_.size());
481 std::uint8_t fixed_header_;
484 std::size_t remaining_length_;
485 boost::container::static_vector<char, 4> remaining_length_buf_;
487 boost::container::static_vector<char, 7> protocol_name_and_level_;
489 boost::container::static_vector<char, 2> client_id_length_buf_;
492 boost::container::static_vector<char, 2> will_topic_name_length_buf_;
494 boost::container::static_vector<char, 2> will_message_length_buf_;
497 boost::container::static_vector<char, 2> user_name_length_buf_;
499 boost::container::static_vector<char, 2> password_length_buf_;
501 boost::container::static_vector<char, 2> keep_alive_buf_;
504 template <std::
size_t PacketIdBytes>
508 typename ConstBufferSequence,
509 typename std::enable_if<
510 as::is_const_buffer_sequence<ConstBufferSequence>::value,
516 as::const_buffer topic_name,
517 ConstBufferSequence payloads,
521 topic_name_(topic_name),
533 auto num_of_payloads =
static_cast<std::size_t
>(std::distance(b, e));
534 payloads_.reserve(num_of_payloads);
535 for (; b != e; ++b) {
537 remaining_length_ +=
payload.size();
545 remaining_length_buf_.push_back(e);
549 packet_id_.reserve(PacketIdBytes);
557 fixed_header_ =
static_cast<std::uint8_t
>(buf.front());
559 buf.remove_prefix(1);
563 remaining_length_ = std::get<0>(len_consumed);
564 auto consumed = std::get<1>(len_consumed);
568 std::next(buf.begin(),
static_cast<string_view::difference_type
>(consumed)),
569 std::back_inserter(remaining_length_buf_));
570 buf.remove_prefix(consumed);
573 std::copy(buf.begin(), std::next(buf.begin(), 2), std::back_inserter(topic_name_length_buf_));
574 auto topic_name_length =
make_uint16_t(topic_name_length_buf_.begin(), topic_name_length_buf_.end());
575 buf.remove_prefix(2);
581 buf.remove_prefix(topic_name_length);
589 std::copy(buf.begin(), std::next(buf.begin(), PacketIdBytes), std::back_inserter(packet_id_));
590 buf.remove_prefix(PacketIdBytes);
608 std::vector<as::const_buffer> ret;
610 ret.emplace_back(
as::buffer(&fixed_header_, 1));
611 ret.emplace_back(
as::buffer(remaining_length_buf_.data(), remaining_length_buf_.size()));
612 ret.emplace_back(
as::buffer(topic_name_length_buf_.data(), topic_name_length_buf_.size()));
614 if (!packet_id_.empty()) {
615 ret.emplace_back(
as::buffer(packet_id_.data(), packet_id_.size()));
617 std::copy(payloads_.begin(), payloads_.end(), std::back_inserter(ret));
628 remaining_length_buf_.size() +
641 (packet_id_.empty() ? 0 : 1) +
656 ret.push_back(
static_cast<char>(fixed_header_));
657 ret.append(remaining_length_buf_.data(), remaining_length_buf_.size());
659 ret.append(topic_name_length_buf_.data(), topic_name_length_buf_.size());
662 ret.append(packet_id_.data(), packet_id_.size());
663 for (
auto const&
payload : payloads_) {
723 std::vector<string_view> ret;
724 ret.reserve(payloads_.size());
725 for (
auto const&
payload : payloads_) {
736 auto size = std::accumulate(
740 [](std::size_t s, as::const_buffer
const&
payload) {
741 return s += payload.size();
748 auto ptr = spa.get();
750 for (
auto const&
payload : payloads_) {
769 std::uint8_t fixed_header_;
770 as::const_buffer topic_name_;
771 boost::container::static_vector<char, 2> topic_name_length_buf_;
772 boost::container::static_vector<char, PacketIdBytes> packet_id_;
773 std::vector<as::const_buffer> payloads_;
774 std::size_t remaining_length_;
775 boost::container::static_vector<char, 4> remaining_length_buf_;
781 template <std::
size_t PacketIdBytes>
786 : topic_name_(topic_name),
787 topic_name_length_buf_ {
num_to_2bytes(boost::numeric_cast<std::uint16_t>(topic_name_.size())) },
791 as::const_buffer topic_name_;
792 boost::container::static_vector<char, 2> topic_name_length_buf_;
798 std::vector<std::tuple<as::const_buffer, subscribe_options>> params,
802 remaining_length_(PacketIdBytes)
807 for (
auto&& e : params) {
808 as::const_buffer topic_name = std::get<0>(e);
812 entries_.reserve(params.size());
813 for (
auto&& e : params) {
814 as::const_buffer topic_name = std::get<0>(e);
815 size_t size = topic_name.size();
817 entries_.emplace_back(topic_name, std::get<1>(e));
825 remaining_length_buf_.push_back(e);
835 std::vector<as::const_buffer> ret;
838 ret.emplace_back(
as::buffer(&fixed_header_, 1));
840 ret.emplace_back(
as::buffer(remaining_length_buf_.data(), remaining_length_buf_.size()));
842 ret.emplace_back(
as::buffer(packet_id_.data(), packet_id_.size()));
844 for (
auto const& e : entries_) {
845 ret.emplace_back(
as::buffer(e.topic_name_length_buf_.data(), e.topic_name_length_buf_.size()));
860 remaining_length_buf_.size() +
887 ret.push_back(
static_cast<char>(fixed_header_));
888 ret.append(remaining_length_buf_.data(), remaining_length_buf_.size());
890 ret.append(packet_id_.data(), packet_id_.size());
892 for (
auto const& e : entries_) {
893 ret.append(e.topic_name_length_buf_.data(), e.topic_name_length_buf_.size());
895 ret.push_back(
static_cast<char>(e.qos_));
902 std::uint8_t fixed_header_;
903 std::vector<entry> entries_;
904 boost::container::static_vector<char, PacketIdBytes> packet_id_;
905 std::size_t remaining_length_;
906 boost::container::static_vector<char, 4> remaining_length_buf_;
911 template <std::
size_t PacketIdBytes>
915 std::vector<suback_return_code> params,
919 remaining_length_(params.
size() + PacketIdBytes)
924 remaining_length_buf_.push_back(e);
927 entries_.reserve(params.size());
928 for (
auto e : params) {
929 entries_.push_back(
static_cast<char>(e));
939 std::vector<as::const_buffer> ret;
942 ret.emplace_back(
as::buffer(&fixed_header_, 1));
943 ret.emplace_back(
as::buffer(remaining_length_buf_.data(), remaining_length_buf_.size()));
944 ret.emplace_back(
as::buffer(packet_id_.data(), packet_id_.size()));
957 remaining_length_buf_.size() +
980 ret.push_back(
static_cast<char>(fixed_header_));
981 ret.append(remaining_length_buf_.data(), remaining_length_buf_.size());
983 ret.append(packet_id_.data(), packet_id_.size());
984 ret.append(entries_);
990 std::uint8_t fixed_header_;
991 std::string entries_;
992 boost::container::static_vector<char, PacketIdBytes> packet_id_;
993 std::size_t remaining_length_;
994 boost::container::static_vector<char, 4> remaining_length_buf_;
999 template <std::
size_t PacketIdBytes>
1003 entry(as::const_buffer topic_name)
1005 topic_name_length_buf_ {
num_to_2bytes(boost::numeric_cast<std::uint16_t>(topic_name_.size())) }
1008 as::const_buffer topic_name_;
1009 boost::container::static_vector<char, 2> topic_name_length_buf_;
1014 std::vector<as::const_buffer> params,
1018 remaining_length_(PacketIdBytes)
1023 for (
auto&& e : params) {
1027 entries_.reserve(params.size());
1028 for (
auto&& e : params) {
1029 entries_.emplace_back(e);
1030 remaining_length_ +=
1036 remaining_length_buf_.push_back(e);
1046 std::vector<as::const_buffer> ret;
1049 ret.emplace_back(
as::buffer(&fixed_header_, 1));
1050 ret.emplace_back(
as::buffer(remaining_length_buf_.data(), remaining_length_buf_.size()));
1052 ret.emplace_back(
as::buffer(packet_id_.data(), packet_id_.size()));
1054 for (
auto const& e : entries_) {
1055 ret.emplace_back(
as::buffer(e.topic_name_length_buf_.data(), e.topic_name_length_buf_.size()));
1069 remaining_length_buf_.size() +
1082 entries_.size() * 2;
1093 ret.reserve(
size());
1095 ret.push_back(
static_cast<char>(fixed_header_));
1097 ret.append(remaining_length_buf_.data(), remaining_length_buf_.size());
1099 ret.append(packet_id_.data(), packet_id_.size());
1101 for (
auto const& e : entries_) {
1102 ret.append(e.topic_name_length_buf_.data(), e.topic_name_length_buf_.size());
1110 std::uint8_t fixed_header_;
1111 std::vector<entry> entries_;
1112 boost::container::static_vector<char, PacketIdBytes> packet_id_;
1113 std::size_t remaining_length_;
1114 boost::container::static_vector<char, 4> remaining_length_buf_;
buffer that has string_view interface This class provides string_view interface. This class hold stri...
Definition: buffer.hpp:30
buffer substr(std::size_t offset, std::size_t length=string_view::npos) const &
get substring The returned buffer ragnge is the same as std::string_view::substr()....
Definition: buffer.hpp:68
Definition: message.hpp:505
constexpr publish_options get_options() const
Get publish_options.
Definition: message.hpp:682
std::size_t size() const
Get whole size of sequence.
Definition: message.hpp:625
buffer payload_as_buffer() const
Get payload as single buffer.
Definition: message.hpp:735
std::vector< string_view > payload() const
Get payload.
Definition: message.hpp:722
constexpr void set_dup(bool dup)
Set dup flag.
Definition: message.hpp:764
constexpr bool is_dup() const
Check dup flag.
Definition: message.hpp:706
constexpr qos get_qos() const
Get qos.
Definition: message.hpp:690
basic_publish_message(typename packet_id_type< PacketIdBytes >::type packet_id, as::const_buffer topic_name, ConstBufferSequence payloads, publish_options pubopts)
Definition: message.hpp:514
std::string continuous_buffer() const
Create one continuous buffer. All sequence of buffers are concatinated. It is useful to store to file...
Definition: message.hpp:651
constexpr string_view topic() const
Get topic name.
Definition: message.hpp:714
basic_publish_message(buffer buf)
Definition: message.hpp:555
packet_id_type< PacketIdBytes >::type packet_id() const
Get packet id.
Definition: message.hpp:674
std::vector< as::const_buffer > const_buffer_sequence() const
Create const buffer sequence it is for boost asio APIs.
Definition: message.hpp:607
std::size_t num_of_const_buffer_sequence() const
Get number of element of const_buffer_sequence.
Definition: message.hpp:636
constexpr bool is_retain() const
Check retain flag.
Definition: message.hpp:698
Definition: message.hpp:912
std::string continuous_buffer() const
Create one continuours buffer. All sequence of buffers are concatinated. It is useful to store to fil...
Definition: message.hpp:975
basic_suback_message(std::vector< suback_return_code > params, typename packet_id_type< PacketIdBytes >::type packet_id)
Definition: message.hpp:914
std::vector< as::const_buffer > const_buffer_sequence() const
Create const buffer sequence it is for boost asio APIs.
Definition: message.hpp:938
static constexpr std::size_t num_of_const_buffer_sequence()
Get number of element of const_buffer_sequence.
Definition: message.hpp:965
std::size_t size() const
Get whole size of sequence.
Definition: message.hpp:954
Definition: message.hpp:782
std::vector< as::const_buffer > const_buffer_sequence() const
Create const buffer sequence it is for boost asio APIs.
Definition: message.hpp:834
basic_subscribe_message(std::vector< std::tuple< as::const_buffer, subscribe_options >> params, typename packet_id_type< PacketIdBytes >::type packet_id)
Definition: message.hpp:797
std::size_t size() const
Get whole size of sequence.
Definition: message.hpp:857
std::size_t num_of_const_buffer_sequence() const
Get number of element of const_buffer_sequence.
Definition: message.hpp:868
std::string continuous_buffer() const
Create one continuours buffer. All sequence of buffers are concatinated. It is useful to store to fil...
Definition: message.hpp:882
Definition: message.hpp:1000
std::string continuous_buffer() const
Create one continuours buffer. All sequence of buffers are concatinated. It is useful to store to fil...
Definition: message.hpp:1091
std::vector< as::const_buffer > const_buffer_sequence() const
Create const buffer sequence it is for boost asio APIs.
Definition: message.hpp:1045
std::size_t size() const
Get whole size of sequence.
Definition: message.hpp:1066
std::size_t num_of_const_buffer_sequence() const
Get number of element of const_buffer_sequence.
Definition: message.hpp:1077
basic_unsubscribe_message(std::vector< as::const_buffer > params, typename packet_id_type< PacketIdBytes >::type packet_id)
Definition: message.hpp:1013
Definition: message.hpp:249
std::size_t size() const
Get whole size of sequence.
Definition: message.hpp:273
std::string continuous_buffer() const
Create one continuours buffer. All sequence of buffers are concatinated. It is useful to store to fil...
Definition: message.hpp:291
std::vector< as::const_buffer > const_buffer_sequence() const
Create const buffer sequence it is for boost asio APIs.
Definition: message.hpp:265
connack_message(bool session_present, connect_return_code return_code)
Definition: message.hpp:251
static constexpr std::size_t num_of_const_buffer_sequence()
Get number of element of const_buffer_sequence.
Definition: message.hpp:281
Definition: message.hpp:301
std::string continuous_buffer() const
Create one continuours buffer. All sequence of buffers are concatinated. It is useful to store to fil...
Definition: message.hpp:446
std::size_t size() const
Get whole size of sequence.
Definition: message.hpp:413
std::vector< as::const_buffer > const_buffer_sequence() const
Create const buffer sequence it is for boost asio APIs.
Definition: message.hpp:376
connect_message(std::uint16_t keep_alive_sec, buffer client_id, bool clean_session, optional< will > w, optional< buffer > user_name, optional< buffer > password)
Definition: message.hpp:303
static constexpr std::size_t num_of_const_buffer_sequence()
Get number of element of const_buffer_sequence.
Definition: message.hpp:424
constexpr bool has_password_flag(char v)
Definition: connect_flags.hpp:43
constexpr char const will_retain
Definition: connect_flags.hpp:21
constexpr char const user_name_flag
Definition: connect_flags.hpp:23
constexpr char const will_flag
Definition: connect_flags.hpp:20
constexpr bool has_user_name_flag(char v)
Definition: connect_flags.hpp:47
constexpr void set_will_qos(char &v, qos qos_value)
Definition: connect_flags.hpp:51
constexpr bool has_will_flag(char v)
Definition: connect_flags.hpp:33
constexpr char const clean_session
Definition: connect_flags.hpp:18
constexpr char const password_flag
Definition: connect_flags.hpp:22
constexpr bool is_dup(std::uint8_t v)
Definition: publish.hpp:22
constexpr qos get_qos(std::uint8_t v)
Definition: publish.hpp:26
constexpr void set_dup(std::uint8_t &fixed_header, bool dup)
Definition: publish.hpp:34
constexpr bool is_retain(std::uint8_t v)
Definition: publish.hpp:30
std::string remaining_bytes(std::size_t size)
Definition: remaining_length.hpp:17
boost::string_ref string_view
Definition: string_view.hpp:64
void utf8string_check(string_view str)
Definition: string_check.hpp:20
constexpr std::tuple< std::size_t, std::size_t > remaining_length(string_view bytes)
Definition: remaining_length.hpp:24
control_packet_type
Definition: control_packet_type.hpp:18
constexpr std::remove_reference_t< T > && force_move(T &&t)
Definition: move.hpp:20
boost::container::static_vector< char, 2 > num_to_2bytes(std::uint16_t val)
Definition: two_byte_util.hpp:20
void add_uint16_t_to_buf(T &buf, std::uint16_t num)
Definition: two_byte_util.hpp:28
dup
Definition: publish.hpp:48
char const * get_pointer(as::const_buffer const &cb)
Definition: const_buffer_util.hpp:17
connect_return_code
Definition: connect_return_code.hpp:17
buffer const * buffer_sequence_end(buffer const &buf)
Definition: buffer.hpp:155
buffer const * buffer_sequence_begin(buffer const &buf)
Definition: buffer.hpp:151
qos
Definition: subscribe_options.hpp:34
constexpr std::uint16_t make_uint16_t(It b, It e)
Definition: two_byte_util.hpp:34
constexpr std::uint8_t make_fixed_header(control_packet_type type, std::uint8_t flags)
Definition: fixed_header.hpp:15
std::size_t get_size(as::const_buffer const &cb)
Definition: const_buffer_util.hpp:21
Definition: buffer.hpp:242
const_buffer buffer(MQTT_NS::buffer const &data)
create boost::asio::const_buffer from the MQTT_NS::buffer boost::asio::const_buffer is a kind of view...
Definition: buffer.hpp:253
Definition: buffer.hpp:241
shared_ptr_array make_shared_ptr_array(std::size_t size)
shared_ptr_array creating function. You can choose the target type.
Definition: two_or_four_byte_util.hpp:52
Definition: two_or_four_byte_util.hpp:33
Definition: exception.hpp:21
Definition: publish.hpp:53
constexpr qos get_qos() const
Definition: publish.hpp:84
Definition: exception.hpp:33
Definition: subscribe_options.hpp:40
constexpr qos get_qos() const
Definition: subscribe_options.hpp:73
Definition: message.hpp:169
basic_puback_message(typename packet_id_type< PacketIdBytes >::type packet_id)
Definition: message.hpp:171
Definition: message.hpp:214
basic_pubcomp_message(typename packet_id_type< PacketIdBytes >::type packet_id)
Definition: message.hpp:215
Definition: message.hpp:179
basic_pubrec_message(typename packet_id_type< PacketIdBytes >::type packet_id)
Definition: message.hpp:181
Definition: message.hpp:189
basic_pubrel_message(string_view buf)
Definition: message.hpp:196
basic_pubrel_message(typename packet_id_type< PacketIdBytes >::type packet_id)
Definition: message.hpp:191
packet_id_type< PacketIdBytes >::type packet_id() const
Get packet id.
Definition: message.hpp:205
Definition: message.hpp:223
basic_unsuback_message(typename packet_id_type< PacketIdBytes >::type packet_id)
Definition: message.hpp:224
Definition: message.hpp:243
disconnect_message()
Definition: message.hpp:244
Definition: message.hpp:231
pingreq_message()
Definition: message.hpp:232
Definition: message.hpp:237
pingresp_message()
Definition: message.hpp:238
Definition: exception.hpp:65