async_mqtt 5.0.0
Loading...
Searching...
No Matches
variable_bytes.hpp
1// Copyright Takatoshi Kondo 2022
2//
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7#if !defined(ASYNC_MQTT_VARIABLE_BYTES_HPP)
8#define ASYNC_MQTT_VARIABLE_BYTES_HPP
9
10#include <cstdint>
11
12#include <async_mqtt/util/static_vector.hpp>
13#include <async_mqtt/util/optional.hpp>
14#include <async_mqtt/util/is_iterator.hpp>
15
16namespace async_mqtt {
17
18inline static_vector<char, 4>
19val_to_variable_bytes(std::uint32_t val) {
20 static_vector<char, 4> bytes;
21 if (val > 0xfffffff) return bytes;
22 while (val > 127) {
23 bytes.push_back(static_cast<char>((val & 0b01111111) | 0b10000000));
24 val >>= 7;
25 }
26 bytes.push_back(val & 0b01111111);
27 return bytes;
28}
29
30
31template <typename It, typename End>
32constexpr
33std::enable_if_t<
34 is_input_iterator<It>::value &&
35 is_input_iterator<End>::value,
36 optional<std::uint32_t>
37>
38variable_bytes_to_val(It& it, End e) {
39 std::size_t val = 0;
40 std::size_t mul = 1;
41 for (; it != e; ++it) {
42 val += (*it & 0b01111111) * mul;
43 mul *= 128;
44 if (mul > 128 * 128 * 128 * 128) {
45 ++it;
46 return nullopt;
47 }
48 if (!(*it & 0b10000000)) {
49 ++it;
50 break;
51 }
52 }
53 return std::uint32_t(val);
54}
55
56} // namespace async_mqtt
57
58#endif // ASYNC_MQTT_VARIABLE_BYTES_HPP