37 using packet_id_t =
typename packet_id_type<PacketIdBytes>::type;
48 std::vector<unsuback_reason_code>
params,
51 : fixed_header_{make_fixed_header(control_packet_type::unsuback, 0b0000)},
52 entries_{force_move(
params)},
54 property_length_(async_mqtt::
size(
props)),
55 props_(force_move(
props))
57 using namespace std::literals;
58 endian_store(
packet_id, packet_id_.data());
60 auto pb = val_to_variable_bytes(boost::numeric_cast<std::uint32_t>(property_length_));
62 property_length_buf_.push_back(
e);
65 for (
auto const&
prop : props_) {
67 if (!validate_property(property_location::unsuback,
id)) {
70 "v5::unsuback_packet property "s + id_to_str(
id) +
" is not allowed"
75 remaining_length_ += property_length_buf_.size() + property_length_;
76 remaining_length_buf_ = val_to_variable_bytes(boost::numeric_cast<std::uint32_t>(remaining_length_));
84 "v5::unsuback_packet fixed_header doesn't exist"
87 fixed_header_ =
static_cast<std::uint8_t
>(buf.front());
89 auto cpt_opt = get_control_packet_type_with_check(
static_cast<std::uint8_t
>(fixed_header_));
90 if (!cpt_opt || *cpt_opt != control_packet_type::unsuback) {
93 "v5::unsuback_packet fixed_header is invalid"
98 if (
auto vl_opt = insert_advance_variable_length(buf, remaining_length_buf_)) {
99 remaining_length_ = *vl_opt;
102 throw make_error(errc::bad_message,
"v5::unsuback_packet remaining length is invalid");
104 if (remaining_length_ != buf.size()) {
105 throw make_error(errc::bad_message,
"v5::unsuback_packet remaining length doesn't match buf.size()");
109 if (!copy_advance(buf, packet_id_)) {
112 "v5::unsuback_packet packet_id doesn't exist"
117 auto it = buf.begin();
118 if (
auto pl_opt = variable_bytes_to_val(it, buf.end())) {
119 property_length_ = *pl_opt;
120 std::copy(buf.begin(), it, std::back_inserter(property_length_buf_));
121 buf.remove_prefix(std::size_t(std::distance(buf.begin(), it)));
122 if (buf.size() < property_length_) {
125 "v5::unsuback_packet properties_don't match its length"
128 auto prop_buf = buf.substr(0, property_length_);
129 props_ = make_properties(prop_buf, property_location::unsuback);
130 buf.remove_prefix(property_length_);
135 "v5::unsuback_packet property_length is invalid"
139 if (remaining_length_ == 0) {
140 throw make_error(errc::bad_message,
"v5::unsuback_packet doesn't have entries");
143 while (!buf.empty()) {
148 "v5::unsuback_packet unsuback_reason_code doesn't exist"
151 auto rc =
static_cast<unsuback_reason_code
>(buf.front());
152 entries_.emplace_back(rc);
153 buf.remove_prefix(1);
157 constexpr control_packet_type type()
const {
158 return control_packet_type::unsuback;
167 std::vector<as::const_buffer>
ret;
170 ret.emplace_back(as::buffer(&fixed_header_, 1));
172 ret.emplace_back(as::buffer(remaining_length_buf_.data(), remaining_length_buf_.size()));
174 ret.emplace_back(as::buffer(packet_id_.data(), packet_id_.size()));
176 ret.emplace_back(as::buffer(property_length_buf_.data(), property_length_buf_.size()));
177 auto props_cbs = async_mqtt::const_buffer_sequence(props_);
180 ret.emplace_back(as::buffer(entries_.data(), entries_.size()));
192 remaining_length_buf_.size() +
205 [&] () -> std::size_t {
206 if (property_length_buf_.size() == 0)
return 0;
209 async_mqtt::num_of_const_buffer_sequence(props_);
226 std::vector<unsuback_reason_code>
const&
entries()
const {
239 std::uint8_t fixed_header_;
240 std::vector<unsuback_reason_code> entries_;
242 std::size_t remaining_length_;
245 std::size_t property_length_ = 0;