123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #ifndef __ASIO2_TCP_RECV_OP_HPP__
- #define __ASIO2_TCP_RECV_OP_HPP__
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- #pragma once
- #endif
- #include <memory>
- #include <future>
- #include <utility>
- #include <string_view>
- #include <asio2/base/error.hpp>
- #include <asio2/base/detail/ecs.hpp>
- namespace asio2::detail
- {
- template<class derived_t, class args_t>
- class tcp_recv_op
- {
- protected:
- template<class, class = std::void_t<>>
- struct has_member_dgram : std::false_type {};
- template<class T>
- struct has_member_dgram<T, std::void_t<decltype(T::dgram_)>> : std::true_type {};
- public:
-
- tcp_recv_op() noexcept {}
-
- ~tcp_recv_op() = default;
- protected:
- template<typename C>
- void _tcp_post_recv(std::shared_ptr<derived_t> this_ptr, std::shared_ptr<ecs_t<C>> ecs)
- {
- using condition_lowest_type = typename ecs_t<C>::condition_lowest_type;
- derived_t& derive = static_cast<derived_t&>(*this);
- ASIO2_ASSERT(derive.io_->running_in_this_thread());
- if (!derive.is_started())
- {
- if (derive.state_ == state_t::started)
- {
- derive._do_disconnect(asio2::get_last_error(), std::move(this_ptr));
- }
- return;
- }
- #if defined(_DEBUG) || defined(DEBUG)
- ASIO2_ASSERT(derive.post_recv_counter_.load() == 0);
- derive.post_recv_counter_++;
- #endif
- ASIO2_ASSERT(derive.reading_ == false);
- derive.reading_ = true;
- ecs_t<C>& e = *ecs;
- if constexpr (
- std::is_same_v<condition_lowest_type, asio::detail::transfer_all_t> ||
- std::is_same_v<condition_lowest_type, asio::detail::transfer_at_least_t> ||
- std::is_same_v<condition_lowest_type, asio::detail::transfer_exactly_t> ||
- std::is_same_v<condition_lowest_type, asio2::detail::hook_buffer_t>)
- {
- asio::async_read(derive.stream(), derive.buffer().base(), e.get_condition().lowest(),
- make_allocator(derive.rallocator(),
- [&derive, this_ptr = std::move(this_ptr), ecs = std::move(ecs)]
- (const error_code& ec, std::size_t bytes_recvd) mutable
- {
- #if defined(_DEBUG) || defined(DEBUG)
- derive.post_recv_counter_--;
- #endif
- derive.reading_ = false;
- derive._handle_recv(ec, bytes_recvd, std::move(this_ptr), std::move(ecs));
- }));
- }
- else
- {
- asio::async_read_until(derive.stream(), derive.buffer().base(), e.get_condition().lowest(),
- make_allocator(derive.rallocator(),
- [&derive, this_ptr = std::move(this_ptr), ecs = std::move(ecs)]
- (const error_code& ec, std::size_t bytes_recvd) mutable
- {
- #if defined(_DEBUG) || defined(DEBUG)
- derive.post_recv_counter_--;
- #endif
- derive.reading_ = false;
- derive._handle_recv(ec, bytes_recvd, std::move(this_ptr), std::move(ecs));
- }));
- }
- }
- template<typename C>
- void _tcp_dgram_fire_recv(
- const error_code& ec, std::size_t bytes_recvd,
- std::shared_ptr<derived_t>& this_ptr, std::shared_ptr<ecs_t<C>>& ecs)
- {
- detail::ignore_unused(ec);
- derived_t& derive = static_cast<derived_t&>(*this);
- const std::uint8_t* buffer = static_cast<const std::uint8_t*>(derive.buffer().data().data());
- if (std::uint8_t(buffer[0]) < std::uint8_t(254))
- {
- derive._fire_recv(this_ptr, ecs, std::string_view(reinterpret_cast<
- std::string_view::const_pointer>(buffer + 1), bytes_recvd - 1));
- }
- else if (std::uint8_t(buffer[0]) == std::uint8_t(254))
- {
- derive._fire_recv(this_ptr, ecs, std::string_view(reinterpret_cast<
- std::string_view::const_pointer>(buffer + 1 + 2), bytes_recvd - 1 - 2));
- }
- else
- {
- ASIO2_ASSERT(std::uint8_t(buffer[0]) == std::uint8_t(255));
- derive._fire_recv(this_ptr, ecs, std::string_view(reinterpret_cast<
- std::string_view::const_pointer>(buffer + 1 + 8), bytes_recvd - 1 - 8));
- }
- }
- template<typename C>
- void _tcp_handle_recv(
- const error_code& ec, std::size_t bytes_recvd,
- std::shared_ptr<derived_t> this_ptr, std::shared_ptr<ecs_t<C>> ecs)
- {
- using condition_lowest_type = typename ecs_t<C>::condition_lowest_type;
- derived_t& derive = static_cast<derived_t&>(*this);
- ASIO2_ASSERT(derive.io_->running_in_this_thread());
- set_last_error(ec);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if (!derive.is_started())
- {
- if (derive.state_ == state_t::started)
- {
- ASIO2_LOG_INFOR("_tcp_handle_recv with closed socket: {} {}", ec.value(), ec.message());
- derive._do_disconnect(ec, this_ptr);
- }
- derive._stop_readend_timer(std::move(this_ptr));
- return;
- }
- if (!ec)
- {
-
- derive.update_alive_time();
- if constexpr (std::is_same_v<condition_lowest_type, use_dgram_t>)
- {
- if constexpr (has_member_dgram<derived_t>::value)
- {
- if (bytes_recvd == 0)
- {
- derive._do_disconnect(asio::error::no_data, this_ptr);
- derive._stop_readend_timer(std::move(this_ptr));
- return;
- }
- }
- else
- {
- ASIO2_ASSERT(false);
- }
- derive._tcp_dgram_fire_recv(ec, bytes_recvd, this_ptr, ecs);
- }
- else
- {
- if constexpr (!std::is_same_v<condition_lowest_type, asio2::detail::hook_buffer_t>)
- {
- derive._fire_recv(this_ptr, ecs, std::string_view(reinterpret_cast<
- std::string_view::const_pointer>(derive.buffer().data().data()), bytes_recvd));
- }
- else
- {
- derive._fire_recv(this_ptr, ecs, std::string_view(reinterpret_cast<
- std::string_view::const_pointer>(derive.buffer().data().data()),
- derive.buffer().size()));
- }
- }
- if constexpr (!std::is_same_v<condition_lowest_type, asio2::detail::hook_buffer_t>)
- {
- derive.buffer().consume(bytes_recvd);
- }
- else
- {
- std::ignore = true;
- }
- derive._post_recv(std::move(this_ptr), std::move(ecs));
- }
- else
- {
- ASIO2_LOG_DEBUG("_tcp_handle_recv with error: {} {}", ec.value(), ec.message());
- if (ec == asio::error::eof)
- {
-
-
-
-
-
-
- ASIO2_ASSERT(bytes_recvd == 0);
- if (bytes_recvd)
- {
-
- ASIO2_LOG_INFOR("_tcp_handle_recv with eof: {}", bytes_recvd);
- }
- }
- derive._do_disconnect(ec, this_ptr);
- derive._stop_readend_timer(std::move(this_ptr));
- }
-
-
-
-
- }
- protected:
- };
- }
- #endif
|