message_generator.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //
  2. // Copyright (c) 2022 Seth Heeren (sgheeren 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_HTTP_IMPL_MESSAGE_GENERATOR_HPP
  10. #define BOOST_BEAST_HTTP_IMPL_MESSAGE_GENERATOR_HPP
  11. #include <boost/beast/http/message_generator.hpp>
  12. #include <boost/smart_ptr/make_unique.hpp>
  13. #include <boost/beast/core/buffers_generator.hpp>
  14. namespace boost {
  15. namespace beast {
  16. namespace http {
  17. template <bool isRequest, class Body, class Fields>
  18. message_generator::message_generator(
  19. http::message<isRequest, Body, Fields>&& m)
  20. : impl_(boost::make_unique<
  21. generator_impl<isRequest, Body, Fields>>(
  22. std::move(m)))
  23. {
  24. }
  25. template <bool isRequest, class Body, class Fields>
  26. struct message_generator::generator_impl
  27. : message_generator::impl_base
  28. {
  29. explicit generator_impl(
  30. http::message<isRequest, Body, Fields>&& m)
  31. : m_(std::move(m))
  32. , sr_(m_)
  33. {
  34. }
  35. bool
  36. is_done() override
  37. {
  38. return sr_.is_done();
  39. }
  40. const_buffers_type
  41. prepare(error_code& ec) override
  42. {
  43. sr_.next(ec, visit{*this});
  44. return current_;
  45. }
  46. void
  47. consume(std::size_t n) override
  48. {
  49. sr_.consume((std::min)(n, beast::buffer_bytes(current_)));
  50. }
  51. bool
  52. keep_alive() const noexcept override
  53. {
  54. return m_.keep_alive();
  55. }
  56. private:
  57. static constexpr unsigned max_fixed_bufs = 12;
  58. http::message<isRequest, Body, Fields> m_;
  59. http::serializer<isRequest, Body, Fields> sr_;
  60. std::array<net::const_buffer, max_fixed_bufs> bs_;
  61. const_buffers_type current_ = bs_; // subspan
  62. struct visit
  63. {
  64. generator_impl& self_;
  65. template<class ConstBufferSequence>
  66. void
  67. operator()(error_code&, ConstBufferSequence const& buffers)
  68. {
  69. auto& s = self_.bs_;
  70. auto& cur = self_.current_;
  71. auto it = net::buffer_sequence_begin(buffers);
  72. std::size_t n =
  73. std::distance(it, net::buffer_sequence_end(buffers));
  74. n = (std::min)(s.size(), n);
  75. cur = { s.data(), n };
  76. std::copy_n(it, n, cur.begin());
  77. }
  78. };
  79. };
  80. } // namespace http
  81. } // namespace beast
  82. } // namespace boost
  83. #endif