refactoring of Stream/Tcp

This commit is contained in:
Michele Caini 2016-07-19 15:12:28 +02:00
parent 67e9238001
commit 5b321fd09a
2 changed files with 36 additions and 38 deletions

View File

@ -89,6 +89,31 @@ protected:
: Handle<T>{std::move(rt), std::move(ref)}
{ }
template<typename I, typename U, typename F, typename..., typename Traits = details::IpTraits<I>>
Addr address(F &&f) {
sockaddr_storage ssto;
int len = sizeof(ssto);
char name[sizeof(ssto)];
std::pair<std::string, unsigned int> addr{ "", 0 };
int err = std::forward<F>(f)(this->template get<U>(), reinterpret_cast<sockaddr *>(&ssto), &len);
if(!err) {
typename Traits::Type *aptr = reinterpret_cast<typename Traits::Type *>(&ssto);
err = Traits::NameFunc(aptr, name, len);
if(!err) {
addr = { std::string{name}, ntohs(aptr->sin_port) };
}
}
/**
* See Boost/Mutant idiom:
* https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Boost_mutant
*/
return reinterpret_cast<Addr&>(addr);
}
public:
void shutdown() {
std::weak_ptr<T> weak = this->shared_from_this();

View File

@ -1,6 +1,7 @@
#pragma once
#include <type_traits>
#include <utility>
#include <memory>
#include <string>
@ -43,37 +44,16 @@ class Tcp final: public Stream<Tcp> {
: Stream{HandleType<uv_tcp_t>{}, std::move(ref)}
{ }
template<typename I, typename F, typename..., typename Traits = details::IpTraits<I>>
Addr address(F &&f) {
sockaddr_storage ssto;
int len = sizeof(ssto);
char name[sizeof(ssto)];
std::pair<std::string, unsigned int> addr{ "", 0 };
int err = std::forward<F>(f)(get<uv_tcp_t>(), reinterpret_cast<sockaddr *>(&ssto), &len);
if(!err) {
typename Traits::Type *aptr = reinterpret_cast<typename Traits::Type *>(&ssto);
err = Traits::NameFunc(aptr, name, len);
if(!err) {
addr = { std::string{name}, ntohs(aptr->sin_port) };
}
}
/**
* See Boost/Mutant idiom:
* https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Boost_mutant
*/
return reinterpret_cast<Addr&>(addr);
}
public:
using Time = std::chrono::seconds;
using IPv4 = details::IPv4;
using IPv6 = details::IPv6;
enum class Bind: std::underlying_type_t<uv_tcp_flags> {
IPV6ONLY = UV_TCP_IPV6ONLY
};
template<typename... Args>
static std::shared_ptr<Tcp> create(Args&&... args) {
return std::shared_ptr<Tcp>{new Tcp{std::forward<Args>(args)...}};
@ -90,27 +70,22 @@ public:
}
template<typename I, typename..., typename Traits = details::IpTraits<I>>
void bind(std::string ip, unsigned int port, bool ipv6only = false) {
void bind(std::string ip, unsigned int port, Flags<Bind> flags = Flags<Bind>{}) {
typename Traits::Type addr;
Traits::AddrFunc(ip.c_str(), port, &addr);
unsigned int flags = ipv6only ? UV_TCP_IPV6ONLY : 0;
invoke(&uv_tcp_bind, get<uv_tcp_t>(), reinterpret_cast<const sockaddr *>(&addr), flags);
}
template<typename I, typename..., typename Traits = details::IpTraits<I>>
void bind(Addr addr, bool ipv6only = false) {
bind<I>(addr.ip, addr.port, ipv6only);
void bind(Addr addr, Flags<Bind> flags = Flags<Bind>{}) {
bind<I>(addr.ip, addr.port, flags);
}
template<typename I, typename..., typename Traits = details::IpTraits<I>>
Addr address() {
return address<I>(uv_tcp_getsockname);
}
Addr address() { return Stream::address<I, uv_tcp_t>(uv_tcp_getsockname); }
template<typename I, typename..., typename Traits = details::IpTraits<I>>
Addr remote() {
return address<I>(uv_tcp_getpeername);
}
Addr remote() { return Stream::address<I, uv_tcp_t>(uv_tcp_getpeername); }
template<typename I, typename..., typename Traits = details::IpTraits<I>>
void connect(std::string ip, unsigned int port) {
@ -131,9 +106,7 @@ public:
}
template<typename I, typename..., typename Traits = details::IpTraits<I>>
void connect(Addr addr) {
connect<I>(addr.ip, addr.port);
}
void connect(Addr addr) { connect<I>(addr.ip, addr.port); }
void accept(Tcp &tcp) {
invoke(&uv_accept, get<uv_stream_t>(), tcp.get<uv_stream_t>());