46 using packet_id_t =
typename packet_id_type<PacketIdBytes>::type;
101 "v5::pubrec_packet fixed_header doesn't exist"
104 fixed_header_ =
static_cast<std::uint8_t
>(buf.front());
105 buf.remove_prefix(1);
108 if (
auto vl_opt = insert_advance_variable_length(buf, remaining_length_buf_)) {
109 remaining_length_ = *
vl_opt;
112 throw make_error(errc::bad_message,
"v5::pubrec_packet remaining length is invalid");
116 if (!insert_advance(buf, packet_id_)) {
119 "v5::pubrec_packet packet_id doesn't exist"
123 if (remaining_length_ == PacketIdBytes) {
125 throw make_error(errc::bad_message,
"v5::pubrec_packet remaining length is invalid");
131 reason_code_.emplace(
static_cast<pubrec_reason_code
>(buf.front()));
132 buf.remove_prefix(1);
133 switch (*reason_code_) {
134 case pubrec_reason_code::success:
135 case pubrec_reason_code::no_matching_subscribers:
136 case pubrec_reason_code::unspecified_error:
137 case pubrec_reason_code::implementation_specific_error:
138 case pubrec_reason_code::not_authorized:
139 case pubrec_reason_code::topic_name_invalid:
140 case pubrec_reason_code::packet_identifier_in_use:
141 case pubrec_reason_code::quota_exceeded:
142 case pubrec_reason_code::payload_format_invalid:
147 "v5::pubrec_packet connect reason_code is invalid"
152 if (remaining_length_ == 3) {
154 throw make_error(errc::bad_message,
"v5::pubrec_packet remaining length is invalid");
160 auto it = buf.begin();
161 if (
auto pl_opt = variable_bytes_to_val(it, buf.end())) {
162 property_length_ = *pl_opt;
163 std::copy(buf.begin(), it, std::back_inserter(property_length_buf_));
164 buf.remove_prefix(std::size_t(std::distance(buf.begin(), it)));
165 if (buf.size() < property_length_) {
168 "v5::pubrec_packet properties_don't match its length"
171 auto prop_buf = buf.
substr(0, property_length_);
172 props_ = make_properties(prop_buf, property_location::pubrec);
173 buf.remove_prefix(property_length_);
178 "v5::pubrec_packet property_length is invalid"
185 "v5::pubrec_packet properties don't match its length"
190 constexpr control_packet_type type()
const {
191 return control_packet_type::pubrec;
200 std::vector<as::const_buffer>
ret;
202 ret.emplace_back(as::buffer(&fixed_header_, 1));
203 ret.emplace_back(as::buffer(remaining_length_buf_.data(), remaining_length_buf_.size()));
205 ret.emplace_back(as::buffer(packet_id_.data(), packet_id_.size()));
208 ret.emplace_back(as::buffer(&*reason_code_, 1));
210 if (property_length_buf_.size() != 0) {
211 ret.emplace_back(as::buffer(property_length_buf_.data(), property_length_buf_.size()));
212 auto props_cbs = async_mqtt::const_buffer_sequence(props_);
227 remaining_length_buf_.size() +
240 [&] () -> std::size_t {
244 [&] () -> std::size_t {
245 if (property_length_buf_.size() == 0)
return 0;
248 async_mqtt::num_of_const_buffer_sequence(props_);
267 pubrec_reason_code
code()
const {
268 if (reason_code_)
return *reason_code_;
269 return pubrec_reason_code::success;
284 "pid:" <<
v.packet_id();
285 if (
v.reason_code_) {
286 o <<
",rc:" << *
v.reason_code_;
288 if (!
v.props().empty()) {
289 o <<
",ps:" <<
v.props();
298 optional<pubrec_reason_code> reason_code,
302 make_fixed_header(control_packet_type::pubrec, 0b0000)
307 packet_id_(packet_id_.capacity()),
308 reason_code_{reason_code},
309 property_length_(async_mqtt::
size(
props)),
310 props_(force_move(
props))
312 using namespace std::literals;
313 endian_store(
packet_id, packet_id_.data());
315 auto guard = unique_scope_guard(
317 auto rb = val_to_variable_bytes(boost::numeric_cast<std::uint32_t>(remaining_length_));
319 remaining_length_buf_.push_back(e);
324 if (!reason_code_)
return;
325 remaining_length_ += 1;
327 if (property_length_ == 0)
return;
329 auto pb = val_to_variable_bytes(boost::numeric_cast<std::uint32_t>(property_length_));
331 property_length_buf_.push_back(e);
334 for (
auto const& prop : props_) {
336 if (!validate_property(property_location::pubrec,
id)) {
339 "v5::pubrec_packet property "s + id_to_str(
id) +
" is not allowed"
344 remaining_length_ += property_length_buf_.size() + property_length_;
348 std::uint8_t fixed_header_;
349 std::size_t remaining_length_;
350 static_vector<char, 4> remaining_length_buf_;
351 static_vector<char, PacketIdBytes> packet_id_;
353 optional<pubrec_reason_code> reason_code_;
355 std::size_t property_length_ = 0;
356 static_vector<char, 4> property_length_buf_;