variable_length.hpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright Takatoshi Kondo 2018
  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. #if !defined(MQTT_VARIABLE_LENGTH_HPP)
  7. #define MQTT_VARIABLE_LENGTH_HPP
  8. #include <string>
  9. #include <mqtt/namespace.hpp>
  10. #include <mqtt/exception.hpp>
  11. namespace MQTT_NS {
  12. inline std::string
  13. variable_bytes(std::size_t size) {
  14. std::string bytes;
  15. if (size > 0xfffffff) return bytes;
  16. while (size > 127) {
  17. bytes.push_back(static_cast<char>((size & 0b01111111) | 0b10000000));
  18. size >>= 7;
  19. }
  20. bytes.push_back(size & 0b01111111);
  21. return bytes;
  22. }
  23. template <typename Container>
  24. inline void
  25. variable_push(Container& c, std::size_t size) {
  26. if (size > 0xfffffff) return;
  27. while (size > 127) {
  28. c.push_back(static_cast<typename Container::value_type>((size & 0b01111111) | 0b10000000));
  29. size >>= 7;
  30. }
  31. c.push_back(size & 0b01111111);
  32. }
  33. template <typename T>
  34. constexpr std::tuple<std::size_t, std::size_t>
  35. variable_length(T const& bytes) {
  36. std::size_t len = 0;
  37. std::size_t mul = 1;
  38. std::size_t consumed = 0;
  39. for (auto b : bytes) {
  40. len += (b & 0b01111111) * mul;
  41. mul *= 128;
  42. ++consumed;
  43. if (mul > 128 * 128 * 128 * 128) return {0, 0};
  44. if (!(b & 0b10000000)) break;
  45. }
  46. return {len, consumed};
  47. }
  48. template <typename Iterator>
  49. constexpr std::tuple<std::size_t, std::size_t>
  50. variable_length(Iterator b, Iterator e) {
  51. std::size_t len = 0;
  52. std::size_t mul = 1;
  53. std::size_t consumed = 0;
  54. for (; b != e; ++b) {
  55. len += (*b & 0b01111111) * mul;
  56. mul *= 128;
  57. ++consumed;
  58. if (mul > 128 * 128 * 128 * 128) return {0, 0};
  59. if (!(*b & 0b10000000)) break;
  60. }
  61. return {len, consumed};
  62. }
  63. } // namespace MQTT_NS
  64. #endif // MQTT_VARIABLE_LENGTH_HPP