async_mqtt 9.0.1
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_UTIL_VARIABLE_BYTES_HPP)
8#define ASYNC_MQTT_UTIL_VARIABLE_BYTES_HPP
9
10#include <cstdint>
11#include <optional>
12
13#include <async_mqtt/util/static_vector.hpp>
14#include <async_mqtt/util/detail/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 detail::is_input_iterator<It>::value &&
35 detail::is_input_iterator<End>::value,
36 std::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 if (mul == 128 * 128 * 128 * 128) {
43 ++it;
44 return std::nullopt;
45 }
46 val += (*it & 0b01111111) * mul;
47 mul *= 128;
48 if (!(*it & 0b10000000)) {
49 ++it;
50 return std::uint32_t(val);
51 }
52 }
53 return std::nullopt;
54}
55
56} // namespace async_mqtt
57
58#endif // ASYNC_MQTT_UTIL_VARIABLE_BYTES_HPP