read_size.hpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //
  2. // Copyright (c) 2016-2019 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_IMPL_READ_SIZE_HPP
  10. #define BOOST_BEAST_IMPL_READ_SIZE_HPP
  11. #include <boost/asio/buffer.hpp>
  12. #include <boost/assert.hpp>
  13. #include <stdexcept>
  14. #include <type_traits>
  15. namespace boost {
  16. namespace beast {
  17. namespace detail {
  18. template<class T, class = void>
  19. struct has_read_size_helper : std::false_type {};
  20. template<class T>
  21. struct has_read_size_helper<T, decltype(
  22. read_size_helper(std::declval<T&>(), 512),
  23. (void)0)> : std::true_type
  24. {
  25. };
  26. template<class DynamicBuffer>
  27. std::size_t
  28. read_size(DynamicBuffer& buffer,
  29. std::size_t max_size, std::true_type)
  30. {
  31. return read_size_helper(buffer, max_size);
  32. }
  33. template<class DynamicBuffer>
  34. std::size_t
  35. read_size(DynamicBuffer& buffer,
  36. std::size_t max_size, std::false_type)
  37. {
  38. static_assert(
  39. net::is_dynamic_buffer<DynamicBuffer>::value,
  40. "DynamicBuffer type requirements not met");
  41. auto const size = buffer.size();
  42. auto const limit = buffer.max_size() - size;
  43. BOOST_ASSERT(size <= buffer.max_size());
  44. return std::min<std::size_t>(
  45. std::max<std::size_t>(512, buffer.capacity() - size),
  46. std::min<std::size_t>(max_size, limit));
  47. }
  48. } // detail
  49. template<class DynamicBuffer>
  50. std::size_t
  51. read_size(
  52. DynamicBuffer& buffer, std::size_t max_size)
  53. {
  54. return detail::read_size(buffer, max_size,
  55. detail::has_read_size_helper<DynamicBuffer>{});
  56. }
  57. template<class DynamicBuffer>
  58. std::size_t
  59. read_size_or_throw(
  60. DynamicBuffer& buffer, std::size_t max_size)
  61. {
  62. auto const n = read_size(buffer, max_size);
  63. if(n == 0)
  64. BOOST_THROW_EXCEPTION(std::length_error{
  65. "buffer overflow"});
  66. return n;
  67. }
  68. } // beast
  69. } // boost
  70. #endif