message_generator.hpp 2.3 KB

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