2 #ifndef UVCC_REQUEST_UDP__HPP 3 #define UVCC_REQUEST_UDP__HPP 5 #include "uvcc/utility.hpp" 6 #include "uvcc/request-base.hpp" 7 #include "uvcc/handle-udp.hpp" 8 #include "uvcc/buffer.hpp" 9 #include "uvcc/netstruct.hpp" 14 #include <type_traits> 27 friend class request::instance< udp_send >;
32 using uv_t = ::uv_udp_send_t;
33 using on_request_t = std::function<
void(
udp_send _request,
buffer _buffer) >;
41 struct properties :
request::properties
43 buffer::uv_t *uv_buf =
nullptr;
44 ::sockaddr_storage peer = { 0,};
54 explicit udp_send(uv_t *_uv_req) :
request(
reinterpret_cast<
request::uv_t* >(_uv_req)) {}
58 ~udp_send() =
default;
61 uv_req = instance::create();
62 static_cast< uv_t* >(uv_req)->type = UV_UDP_SEND;
68 udp_send(
udp_send&&)
noexcept =
default;
72 template<
typename =
void >
static void udp_send_cb(::uv_udp_send_t*,
int);
75 on_request_t& on_request()
const noexcept {
return instance::from(uv_req)->request_cb_storage.value(); }
78 udp handle()
const noexcept {
return udp(
static_cast< uv_t* >(uv_req)->handle); }
85 _sockaddr =
reinterpret_cast< _T_& >(instance::from(uv_req)->properties().peer);
86 switch (
reinterpret_cast< ::sockaddr >(_sockaddr).sa_family)
88 case AF_INET:
return sizeof(_T_) >=
sizeof(::sockaddr_in);
89 case AF_INET6:
return sizeof(_T_) >=
sizeof(::sockaddr_in6);
90 default:
return sizeof(_T_) ==
sizeof(::sockaddr_storage);
104 auto instance_ptr = instance::from(uv_req);
106 udp::instance::from(_udp.uv_handle)->ref();
107 buffer::instance::from(_buf.uv_buf)->ref();
110 auto &properties = instance_ptr->properties();
112 properties.uv_buf = _buf.uv_buf;
113 init(properties.peer,
reinterpret_cast<
const ::sockaddr& >(_sockaddr));
117 auto uv_ret = ::uv_udp_send(
118 static_cast< uv_t* >(uv_req),
static_cast< udp::uv_t* >(_udp),
119 static_cast<
const buffer::uv_t* >(_buf), _buf.count(),
120 reinterpret_cast<
const ::sockaddr* >(&_sockaddr),
126 udp::instance::from(_udp.uv_handle)->unref();
127 buffer::instance::from(_buf.uv_buf)->unref();
128 instance_ptr->unref();
143 return uv_status(::uv_udp_try_send(
144 static_cast< udp::uv_t* >(_udp),
145 static_cast<
const buffer::uv_t* >(_buf), _buf.count(),
146 reinterpret_cast<
const ::sockaddr* >(&_sockaddr)
151 explicit operator
const uv_t*()
const noexcept {
return static_cast<
const uv_t* >(uv_req); }
152 explicit operator uv_t*()
noexcept {
return static_cast< uv_t* >(uv_req); }
156 void udp_send::udp_send_cb(::uv_udp_send_t *_uv_req,
int _status)
158 auto instance_ptr = instance::from(_uv_req);
159 instance_ptr->uv_error = _status;
161 ref_guard<
udp::instance > unref_handle(*udp::instance::from(_uv_req->handle), adopt_ref);
162 ref_guard< instance > unref_req(*instance_ptr, adopt_ref);
164 auto &udp_send_cb = instance_ptr->request_cb_storage.value();
166 udp_send_cb(udp_send(_uv_req), buffer(instance_ptr->properties().uv_buf, adopt_ref));
168 buffer::instance::from(instance_ptr->properties().uv_buf)->unref();
Namespace for all uvcc definitions.
operator bool() const noexcept
Equivalent to (base() != nullptr).
The base class for the libuv requests.
udp handle() const noexcept
The UDP handle where this send request has been taking place.
int try_send(udp &_udp, const buffer &_buf, const _T_ &_sockaddr)
int run(udp &_udp, const buffer &_buf, const _T_ &_sockaddr)
Run the request.
A scoped reference counting guard.
bool getpeername(_T_ &_sockaddr) const noexcept
Get the address of the remote peer which this request has sent data to.