varint.hpp 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. //
  2. // Copyright (c) 2017 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_DETAIL_VARINT_HPP
  10. #define BOOST_BEAST_DETAIL_VARINT_HPP
  11. #include <boost/static_assert.hpp>
  12. #include <cstdlib>
  13. #include <iterator>
  14. #include <type_traits>
  15. namespace boost {
  16. namespace beast {
  17. namespace detail {
  18. // https://developers.google.com/protocol-buffers/docs/encoding#varints
  19. inline
  20. std::size_t
  21. varint_size(std::size_t value)
  22. {
  23. std::size_t n = 1;
  24. while(value > 127)
  25. {
  26. ++n;
  27. value /= 128;
  28. }
  29. return n;
  30. }
  31. template<class FwdIt>
  32. std::size_t
  33. varint_read(FwdIt& first)
  34. {
  35. using value_type = typename
  36. std::iterator_traits<FwdIt>::value_type;
  37. BOOST_STATIC_ASSERT(
  38. std::is_integral<value_type>::value &&
  39. sizeof(value_type) == 1);
  40. std::size_t value = 0;
  41. std::size_t factor = 1;
  42. while((*first & 0x80) != 0)
  43. {
  44. value += (*first++ & 0x7f) * factor;
  45. factor *= 128;
  46. }
  47. value += *first++ * factor;
  48. return value;
  49. }
  50. template<class FwdIt>
  51. void
  52. varint_write(FwdIt& first, std::size_t value)
  53. {
  54. using value_type = typename
  55. std::iterator_traits<FwdIt>::value_type;
  56. BOOST_STATIC_ASSERT(
  57. std::is_integral<value_type>::value &&
  58. sizeof(value_type) == 1);
  59. while(value > 127)
  60. {
  61. *first++ = static_cast<value_type>(
  62. 0x80 | value);
  63. value /= 128;
  64. }
  65. *first++ = static_cast<value_type>(value);
  66. }
  67. } // detail
  68. } // beast
  69. } // boost
  70. #endif