From 7ae993c5d2c09049c0934c3ef326e3d414d59d8e Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 25 Aug 2016 09:32:24 +0200 Subject: [PATCH 1/5] refactoring --- README.md | 4 +- src/uvw/dns.hpp | 10 ++-- src/uvw/fs.hpp | 2 +- src/uvw/fs_event.hpp | 2 +- src/uvw/fs_poll.hpp | 2 +- src/uvw/handle.hpp | 2 +- src/uvw/misc.hpp | 112 ------------------------------------- src/uvw/pipe.hpp | 2 +- src/uvw/poll.hpp | 2 +- src/uvw/process.hpp | 2 +- src/uvw/tcp.hpp | 16 +++--- src/uvw/tty.hpp | 2 +- src/uvw/udp.hpp | 20 +++---- src/uvw/util.hpp | 129 +++++++++++++++++++++++++++++++++++++++---- 14 files changed, 150 insertions(+), 157 deletions(-) delete mode 100644 src/uvw/misc.hpp diff --git a/README.md b/README.md index 6c759d5e..450eaf6c 100644 --- a/README.md +++ b/README.md @@ -195,8 +195,8 @@ tcp->bind("127.0.0.1", 4242); tcp->listen(); ``` -Note also that `uvw::TcpHandle` already supports _IPv6_ out-of-the-box. The statement above is equivalent to `tcp->bind("127.0.0.1", 4242)`.
-It's suffice to explicitly specify `uvw::net::IPv6` as the underlying protocol to use it. +Note also that `uvw::TcpHandle` already supports _IPv6_ out-of-the-box. The statement above is equivalent to `tcp->bind("127.0.0.1", 4242)`.
+It's suffice to explicitly specify `uvw::IPv6` as the underlying protocol to use it. The API reference is the recommended documentation for further details about resources and their methods. diff --git a/src/uvw/dns.hpp b/src/uvw/dns.hpp index 1b0ef12a..89b2963a 100644 --- a/src/uvw/dns.hpp +++ b/src/uvw/dns.hpp @@ -7,7 +7,7 @@ #include #include "event.hpp" #include "request.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { @@ -214,7 +214,7 @@ public: * @param port A valid port number. * @param flags Optional flags that modify the behavior of `getnameinfo`. */ - template + template void getNameInfo(std::string ip, unsigned int port, int flags = 0) { typename details::IpTraits::Type addr; details::IpTraits::AddrFunc(ip.data(), port, &addr); @@ -226,7 +226,7 @@ public: * @param addr A valid instance of Addr. * @param flags Optional flags that modify the behavior of `getnameinfo`. */ - template + template void getNameInfo(Addr addr, int flags = 0) { getNameInfo(addr.ip, addr.port, flags); } @@ -237,7 +237,7 @@ public: * @param port A valid port number. * @param flags Optional flags that modify the behavior of `getnameinfo`. */ - template + template auto getNameInfoSync(std::string ip, unsigned int port, int flags = 0) { typename details::IpTraits::Type addr; details::IpTraits::AddrFunc(ip.data(), port, &addr); @@ -251,7 +251,7 @@ public: * @param addr A valid instance of Addr. * @param flags Optional flags that modify the behavior of `getnameinfo`. */ - template + template auto getNameInfoSync(Addr addr, int flags = 0) { getNameInfoSync(addr.ip, addr.port, flags); } diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index dd44371a..1611037b 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -8,7 +8,7 @@ #include #include "event.hpp" #include "request.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { diff --git a/src/uvw/fs_event.hpp b/src/uvw/fs_event.hpp index 53febbe0..ead9ed2b 100644 --- a/src/uvw/fs_event.hpp +++ b/src/uvw/fs_event.hpp @@ -7,7 +7,7 @@ #include #include "event.hpp" #include "handle.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { diff --git a/src/uvw/fs_poll.hpp b/src/uvw/fs_poll.hpp index a57eb7d8..bbe59ad9 100644 --- a/src/uvw/fs_poll.hpp +++ b/src/uvw/fs_poll.hpp @@ -7,7 +7,7 @@ #include #include "event.hpp" #include "handle.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index 89f6b3a0..2adb088f 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -6,7 +6,7 @@ #include #include #include "resource.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { diff --git a/src/uvw/misc.hpp b/src/uvw/misc.hpp deleted file mode 100644 index 03c01d7d..00000000 --- a/src/uvw/misc.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - - -#include -#include -#include -#include -#include -#include -#include "util.hpp" - - -namespace uvw { - - -namespace net { - - -struct IPv4 { }; -struct IPv6 { }; - - -} - - -namespace details { - - -template -struct IpTraits; - -template<> -struct IpTraits { - using Type = sockaddr_in; - using AddrFuncType = int(*)(const char *, int, sockaddr_in *); - using NameFuncType = int(*)(const sockaddr_in *, char *, std::size_t); - static constexpr AddrFuncType addrFunc = &uv_ip4_addr; - static constexpr NameFuncType nameFunc = &uv_ip4_name; -}; - -template<> -struct IpTraits { - using Type = sockaddr_in6; - using AddrFuncType = int(*)(const char *, int, sockaddr_in6 *); - using NameFuncType = int(*)(const sockaddr_in6 *, char *, std::size_t); - static constexpr AddrFuncType addrFunc = &uv_ip6_addr; - static constexpr NameFuncType nameFunc = &uv_ip6_name; -}; - - -template -Addr address(const typename IpTraits::Type *aptr, int len) noexcept { - std::pair addr{}; - char name[len]; - - int err = IpTraits::nameFunc(aptr, name, len); - - if(0 == 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); -} - - -template -Addr address(F &&f, const H *handle) noexcept { - sockaddr_storage ssto; - int len = sizeof(ssto); - Addr addr{}; - - int err = std::forward(f)(handle, reinterpret_cast(&ssto), &len); - - if(0 == err) { - typename IpTraits::Type *aptr = reinterpret_cast::Type *>(&ssto); - addr = address(aptr, len); - } - - return addr; -} - - -template -std::string path(F &&f, H *handle) noexcept { - std::size_t size = N; - char buf[size]; - std::string str{}; - auto err = std::forward(f)(handle, buf, &size); - - if(UV_ENOBUFS == err) { - std::unique_ptr data{new char[size]}; - err = std::forward(f)(handle, data.get(), &size); - - if(0 == err) { - str = data.get(); - } - } else { - str.assign(buf, size); - } - - return str; -} - - -} - - -} diff --git a/src/uvw/pipe.hpp b/src/uvw/pipe.hpp index 3000e78e..c3c0b62f 100644 --- a/src/uvw/pipe.hpp +++ b/src/uvw/pipe.hpp @@ -9,7 +9,7 @@ #include "event.hpp" #include "request.hpp" #include "stream.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { diff --git a/src/uvw/poll.hpp b/src/uvw/poll.hpp index 316e9667..8a752d30 100644 --- a/src/uvw/poll.hpp +++ b/src/uvw/poll.hpp @@ -7,7 +7,7 @@ #include #include "event.hpp" #include "handle.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { diff --git a/src/uvw/process.hpp b/src/uvw/process.hpp index 641e7b9c..e8f171dc 100644 --- a/src/uvw/process.hpp +++ b/src/uvw/process.hpp @@ -8,7 +8,7 @@ #include "event.hpp" #include "handle.hpp" #include "stream.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { diff --git a/src/uvw/tcp.hpp b/src/uvw/tcp.hpp index 7fecb042..2e809db7 100644 --- a/src/uvw/tcp.hpp +++ b/src/uvw/tcp.hpp @@ -10,7 +10,7 @@ #include "event.hpp" #include "request.hpp" #include "stream.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { @@ -32,7 +32,7 @@ enum class UVTcpFlags: std::underlying_type_t { * * TCP handles are used to represent both TCP streams and servers.
* By default, _IPv4_ is used as a template parameter. The handle already - * supports _IPv6_ out-of-the-box by using `uvw::net::IPv6`. + * supports _IPv6_ out-of-the-box by using `uvw::IPv6`. */ class TcpHandle final: public StreamHandle { explicit TcpHandle(std::shared_ptr ref) @@ -138,7 +138,7 @@ public: * @param port The port to which to bind. * @param flags Optional additional flags. */ - template + template void bind(std::string ip, unsigned int port, Flags flags = Flags{}) { typename details::IpTraits::Type addr; details::IpTraits::addrFunc(ip.data(), port, &addr); @@ -161,7 +161,7 @@ public: * @param addr A valid instance of Addr. * @param flags Optional additional flags. */ - template + template void bind(Addr addr, Flags flags = Flags{}) { bind(addr.ip, addr.port, flags); } @@ -170,7 +170,7 @@ public: * @brief Gets the current address to which the handle is bound. * @return A valid instance of Addr, an empty one in case of errors. */ - template + template Addr sock() const noexcept { return details::address(&uv_tcp_getsockname, get()); } @@ -179,7 +179,7 @@ public: * @brief Gets the address of the peer connected to the handle. * @return A valid instance of Addr, an empty one in case of errors. */ - template + template Addr peer() const noexcept { return details::address(&uv_tcp_getpeername, get()); } @@ -194,7 +194,7 @@ public: * @param ip The address to which to bind. * @param port The port to which to bind. */ - template + template void connect(std::string ip, unsigned int port) { typename details::IpTraits::Type addr; details::IpTraits::addrFunc(ip.data(), port, &addr); @@ -218,7 +218,7 @@ public: * * @param addr A valid instance of Addr. */ - template + template void connect(Addr addr) { connect(addr.ip, addr.port); } diff --git a/src/uvw/tty.hpp b/src/uvw/tty.hpp index f8d9a8e4..d8fcfc12 100644 --- a/src/uvw/tty.hpp +++ b/src/uvw/tty.hpp @@ -7,7 +7,7 @@ #include #include "event.hpp" #include "stream.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { diff --git a/src/uvw/udp.hpp b/src/uvw/udp.hpp index cdc45c5b..7030666b 100644 --- a/src/uvw/udp.hpp +++ b/src/uvw/udp.hpp @@ -9,7 +9,7 @@ #include "event.hpp" #include "request.hpp" #include "handle.hpp" -#include "misc.hpp" +#include "util.hpp" namespace uvw { @@ -103,7 +103,7 @@ public: * * UDP handles encapsulate UDP communication for both clients and servers.
* By default, _IPv4_ is used as a template parameter. The handle already - * supports _IPv6_ out-of-the-box by using `uvw::net::IPv6`. + * supports _IPv6_ out-of-the-box by using `uvw::IPv6`. */ class UDPHandle final: public Handle { template @@ -201,7 +201,7 @@ public: * @param port The port to which to bind. * @param flags Optional additional flags. */ - template + template void bind(std::string ip, unsigned int port, Flags flags = Flags{}) { typename details::IpTraits::Type addr; details::IpTraits::addrFunc(ip.data(), port, &addr); @@ -223,7 +223,7 @@ public: * @param addr A valid instance of Addr. * @param flags Optional additional flags. */ - template + template void bind(Addr addr, Flags flags = Flags{}) { bind(addr.ip, addr.port, flags); } @@ -232,7 +232,7 @@ public: * @brief Get the local IP and port of the UDP handle. * @return A valid instance of Addr, an empty one in case of errors. */ - template + template Addr sock() const noexcept { return details::address(&uv_udp_getsockname, get()); } @@ -249,7 +249,7 @@ public: * @param interface Interface address. * @param membership Action to be performed. */ - template + template void multicastMembership(std::string multicast, std::string interface, Membership membership) { invoke(&uv_udp_set_membership, get(), multicast.data(), interface.data(), static_cast(membership)); } @@ -277,7 +277,7 @@ public: * @brief Sets the multicast interface to send or receive data on. * @param interface Interface address. */ - template + template void multicastInterface(std::string interface) { invoke(&uv_udp_set_multicast_interface, get(), interface.data()); } @@ -313,7 +313,7 @@ public: * @param data The data to be sent. * @param len The lenght of the submitted data. */ - template + template void send(std::string ip, unsigned int port, std::unique_ptr data, ssize_t len) { typename details::IpTraits::Type addr; details::IpTraits::addrFunc(ip.data(), port, &addr); @@ -342,7 +342,7 @@ public: * @param len The lenght of the submitted data. * @return Number of bytes written. */ - template + template int trySend(std::string ip, unsigned int port, std::unique_ptr data, ssize_t len) { typename details::IpTraits::Type addr; details::IpTraits::addrFunc(ip.data(), port, &addr); @@ -368,7 +368,7 @@ public: * An UDPDataEvent event will be emitted when the handle receives data.
* An ErrorEvent event will be emitted in case of errors. */ - template + template void recv() { invoke(&uv_udp_recv_start, get(), &allocCallback, &recvCallback); } diff --git a/src/uvw/util.hpp b/src/uvw/util.hpp index 4f206480..2a87110f 100644 --- a/src/uvw/util.hpp +++ b/src/uvw/util.hpp @@ -149,18 +149,6 @@ private: }; -/** - * @brief Address representation. - * - * Pair alias (see Boost/Mutant idiom) used to pack together an ip and a - * port.
- * Instead of `first` and `second`, the two parameters are named: - * - * * `ip`, that is of type `std::string` - * * `port`, that is of type `unsigned int` - */ -struct Addr { std::string ip; unsigned int port; }; - /** * @brief Windows size representation. * @@ -248,6 +236,35 @@ HandleType guessHandle(FileHandle file) { } +/** + * @brief The IPv4 tag + * + * To be used as template parameter to switch between IPv4 and IPv6. + */ +struct IPv4 { }; + + +/** + * @brief The IPv6 tag + * + * To be used as template parameter to switch between IPv4 and IPv6. + */ +struct IPv6 { }; + + +/** + * @brief Address representation. + * + * Pair alias (see Boost/Mutant idiom) used to pack together an ip and a + * port.
+ * Instead of `first` and `second`, the two parameters are named: + * + * * `ip`, that is of type `std::string` + * * `port`, that is of type `unsigned int` + */ +struct Addr { std::string ip; unsigned int port; }; + + /** * TODO * @@ -271,4 +288,92 @@ HandleType guessHandle(FileHandle file) { */ +namespace details { + + +template +struct IpTraits; + + +template<> +struct IpTraits { + using Type = sockaddr_in; + using AddrFuncType = int(*)(const char *, int, sockaddr_in *); + using NameFuncType = int(*)(const sockaddr_in *, char *, std::size_t); + static constexpr AddrFuncType addrFunc = &uv_ip4_addr; + static constexpr NameFuncType nameFunc = &uv_ip4_name; +}; + + +template<> +struct IpTraits { + using Type = sockaddr_in6; + using AddrFuncType = int(*)(const char *, int, sockaddr_in6 *); + using NameFuncType = int(*)(const sockaddr_in6 *, char *, std::size_t); + static constexpr AddrFuncType addrFunc = &uv_ip6_addr; + static constexpr NameFuncType nameFunc = &uv_ip6_name; +}; + + +template +Addr address(const typename IpTraits::Type *aptr, int len) noexcept { + std::pair addr{}; + char name[len]; + + int err = IpTraits::nameFunc(aptr, name, len); + + if(0 == 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); +} + + +template +Addr address(F &&f, const H *handle) noexcept { + sockaddr_storage ssto; + int len = sizeof(ssto); + Addr addr{}; + + int err = std::forward(f)(handle, reinterpret_cast(&ssto), &len); + + if(0 == err) { + typename IpTraits::Type *aptr = reinterpret_cast::Type *>(&ssto); + addr = address(aptr, len); + } + + return addr; +} + + +template +std::string path(F &&f, H *handle) noexcept { + std::size_t size = N; + char buf[size]; + std::string str{}; + auto err = std::forward(f)(handle, buf, &size); + + if(UV_ENOBUFS == err) { + std::unique_ptr data{new char[size]}; + err = std::forward(f)(handle, data.get(), &size); + + if(0 == err) { + str = data.get(); + } + } else { + str.assign(buf, size); + } + + return str; +} + + +} + + } From e1e135636c49527e72fb8ebe473a4698e6259b05 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 25 Aug 2016 14:49:35 +0200 Subject: [PATCH 2/5] bug fixing + minor changes --- src/uvw/tty.hpp | 16 +++++----------- src/uvw/udp.hpp | 5 ++--- src/uvw/util.hpp | 31 +++++++++++++++---------------- 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/src/uvw/tty.hpp b/src/uvw/tty.hpp index d8fcfc12..bf7cc3ba 100644 --- a/src/uvw/tty.hpp +++ b/src/uvw/tty.hpp @@ -120,20 +120,14 @@ public: * @return The current Window size or `{0, 0}` in case of errors. */ WinSize getWinSize() { - std::pair size{0, 0}; - int width; - int height; + WinSize size; - if(0 == invoke(&uv_tty_get_winsize, get(), &width, &height)) { - size.first = width; - size.second = height; + if(0 != invoke(&uv_tty_get_winsize, get(), &size.width, &size.height)) { + size.width = 0; + size.height = 0; } - /** - * See Boost/Mutant idiom: - * https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Boost_mutant - */ - return reinterpret_cast(size); + return size; } private: diff --git a/src/uvw/udp.hpp b/src/uvw/udp.hpp index 7030666b..cc039203 100644 --- a/src/uvw/udp.hpp +++ b/src/uvw/udp.hpp @@ -109,7 +109,6 @@ class UDPHandle final: public Handle { template static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) { typename details::IpTraits::Type *aptr = reinterpret_cast::Type *>(addr); - int len = sizeof(*addr); UDPHandle &udp = *(static_cast(handle->data)); // data will be destroyed no matter of what the value of nread is @@ -117,12 +116,12 @@ class UDPHandle final: public Handle { if(nread > 0) { // data available (can be truncated) - udp.publish(UDPDataEvent{details::address(aptr, len), std::move(data), nread, flags & UV_UDP_PARTIAL}); + udp.publish(UDPDataEvent{details::address(aptr), std::move(data), nread, flags & UV_UDP_PARTIAL}); } else if(nread == 0 && addr == nullptr) { // no more data to be read, doing nothing is fine } else if(nread == 0 && addr != nullptr) { // empty udp packet - udp.publish(UDPDataEvent{details::address(aptr, len), std::move(data), nread, false}); + udp.publish(UDPDataEvent{details::address(aptr), std::move(data), nread, false}); } else { // transmission error udp.publish(ErrorEvent(nread)); diff --git a/src/uvw/util.hpp b/src/uvw/util.hpp index 2a87110f..b34eaaab 100644 --- a/src/uvw/util.hpp +++ b/src/uvw/util.hpp @@ -298,39 +298,38 @@ struct IpTraits; template<> struct IpTraits { using Type = sockaddr_in; - using AddrFuncType = int(*)(const char *, int, sockaddr_in *); - using NameFuncType = int(*)(const sockaddr_in *, char *, std::size_t); + using AddrFuncType = int(*)(const char *, int, Type *); + using NameFuncType = int(*)(const Type *, char *, std::size_t); static constexpr AddrFuncType addrFunc = &uv_ip4_addr; static constexpr NameFuncType nameFunc = &uv_ip4_name; + static constexpr auto sinPort(const Type *addr) { return addr->sin_port; } }; template<> struct IpTraits { using Type = sockaddr_in6; - using AddrFuncType = int(*)(const char *, int, sockaddr_in6 *); - using NameFuncType = int(*)(const sockaddr_in6 *, char *, std::size_t); + using AddrFuncType = int(*)(const char *, int, Type *); + using NameFuncType = int(*)(const Type *, char *, std::size_t); static constexpr AddrFuncType addrFunc = &uv_ip6_addr; static constexpr NameFuncType nameFunc = &uv_ip6_name; + static constexpr auto sinPort(const Type *addr) { return addr->sin6_port; } }; -template -Addr address(const typename IpTraits::Type *aptr, int len) noexcept { - std::pair addr{}; - char name[len]; +template +Addr address(const typename details::IpTraits::Type *aptr) noexcept { + Addr addr; + char name[N]; - int err = IpTraits::nameFunc(aptr, name, len); + int err = details::IpTraits::nameFunc(aptr, name, N); if(0 == err) { - addr = { std::string{name}, ntohs(aptr->sin_port) }; + addr.port = ntohs(details::IpTraits::sinPort(aptr)); + addr.ip = std::string{name}; } - /** - * See Boost/Mutant idiom: - * https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Boost_mutant - */ - return reinterpret_cast(addr); + return addr; } @@ -344,7 +343,7 @@ Addr address(F &&f, const H *handle) noexcept { if(0 == err) { typename IpTraits::Type *aptr = reinterpret_cast::Type *>(&ssto); - addr = address(aptr, len); + addr = address(aptr); } return addr; From 97a91569497032ca2e0c7815a66bcd32f6ee284b Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 25 Aug 2016 15:19:00 +0200 Subject: [PATCH 3/5] minor changes --- src/uvw/tty.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uvw/tty.hpp b/src/uvw/tty.hpp index bf7cc3ba..a2820a3f 100644 --- a/src/uvw/tty.hpp +++ b/src/uvw/tty.hpp @@ -117,14 +117,14 @@ public: /** * @brief Gets the current Window size. - * @return The current Window size or `{0, 0}` in case of errors. + * @return The current Window size or `{-1, -1}` in case of errors. */ WinSize getWinSize() { WinSize size; if(0 != invoke(&uv_tty_get_winsize, get(), &size.width, &size.height)) { - size.width = 0; - size.height = 0; + size.width = -1; + size.height = -1; } return size; From 09285bd4056c5a71d2d45fa5f551c0d34d05602a Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 25 Aug 2016 15:19:12 +0200 Subject: [PATCH 4/5] added interfaces utility --- src/uvw/util.hpp | 84 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 20 deletions(-) diff --git a/src/uvw/util.hpp b/src/uvw/util.hpp index b34eaaab..96aac28c 100644 --- a/src/uvw/util.hpp +++ b/src/uvw/util.hpp @@ -2,10 +2,12 @@ #include +#include #include #include #include #include +#include #include @@ -151,15 +153,11 @@ private: /** * @brief Windows size representation. - * - * Pair alias (see Boost/Mutant idiom) used to pack together a width and a - * height.
- * Instead of `first` and `second`, the two parameters are named: - * - * * `width`, that is of type `int` - * * `height`, that is of type `int` */ -struct WinSize { int width; int height; }; +struct WinSize { + int width; /*!< The _width_ of the given window. */ + int height; /*!< The _height_ of the given window. */ +}; using HandleType = details::UVHandleType; @@ -237,7 +235,7 @@ HandleType guessHandle(FileHandle file) { /** - * @brief The IPv4 tag + * @brief The IPv4 tag. * * To be used as template parameter to switch between IPv4 and IPv6. */ @@ -245,7 +243,7 @@ struct IPv4 { }; /** - * @brief The IPv6 tag + * @brief The IPv6 tag. * * To be used as template parameter to switch between IPv4 and IPv6. */ @@ -254,15 +252,11 @@ struct IPv6 { }; /** * @brief Address representation. - * - * Pair alias (see Boost/Mutant idiom) used to pack together an ip and a - * port.
- * Instead of `first` and `second`, the two parameters are named: - * - * * `ip`, that is of type `std::string` - * * `port`, that is of type `unsigned int` */ -struct Addr { std::string ip; unsigned int port; }; +struct Addr { + std::string ip; /*!< Either an IPv4 or an IPv6. */ + unsigned int port; /*!< A valid service identifier. */ +}; /** @@ -273,8 +267,6 @@ struct Addr { std::string ip; unsigned int port; }; * * uv_getrusage * * uv_cpu_info * * uv_free_cpu_info - * * uv_interface_addresses - * * uv_free_interface_addresses * * uv_loadavg * * uv_exepath * * uv_cwd @@ -375,4 +367,56 @@ std::string path(F &&f, H *handle) noexcept { } +/** + * \brief Interface address. + */ +struct Interface { + std::string name; /*!< The name of the interface (as an example _eth0_). */ + std::string physical; /*!< The physical address. */ + bool internal; /*!< True if it is an internal interface (as an example _loopback_), false otherwise. */ + Addr address; /*!< The address of the given interface. */ + Addr netmask; /*!< The netmask of the given interface. */ +}; + + +/** + * @brief Gets a set of descriptors of all the available interfaces. + * + * This function can be used to query the underlying system and get a set of + * descriptors of all the available interfaces, either internal or not. + * + * @return A set of descriptors of all the available interfaces. + */ +std::vector interfaces() noexcept { + std::vector interfaces; + + uv_interface_address_t *ifaces; + int count; + + uv_interface_addresses(&ifaces, &count); + + std::for_each(ifaces, ifaces+count, [&interfaces](const auto &iface) { + Interface interface; + + interface.name = iface.name; + interface.physical = iface.phys_addr; + interface.internal = iface.is_internal; + + if(iface.address.address4.sin_family == AF_INET) { + interface.address = details::address(&iface.address.address4); + interface.netmask = details::address(&iface.netmask.netmask4); + } else if(iface.address.address4.sin_family == AF_INET6) { + interface.address = details::address(&iface.address.address6); + interface.netmask = details::address(&iface.netmask.netmask6); + } + + interfaces.push_back(std::move(interface)); + }); + + uv_free_interface_addresses(ifaces, count); + + return interfaces; +} + + } From 0bffb21fffb21f8a4b3eb41ff2aa768d99f202cc Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 25 Aug 2016 17:33:37 +0200 Subject: [PATCH 5/5] added miscellaneous utilities + odr check --- src/uvw/pipe.hpp | 2 +- src/uvw/util.hpp | 249 +++++++++++++++++++++++--------------------- test/CMakeLists.txt | 20 ++-- test/odr.cpp | 1 + 4 files changed, 140 insertions(+), 132 deletions(-) create mode 100644 test/odr.cpp diff --git a/src/uvw/pipe.hpp b/src/uvw/pipe.hpp index c3c0b62f..15258250 100644 --- a/src/uvw/pipe.hpp +++ b/src/uvw/pipe.hpp @@ -148,7 +148,7 @@ public: */ HandleType receive() noexcept { auto type = uv_pipe_pending_type(get()); - return guessHandle(type); + return Utilities::guessHandle(type); } private: diff --git a/src/uvw/util.hpp b/src/uvw/util.hpp index 96aac28c..97c0e8f0 100644 --- a/src/uvw/util.hpp +++ b/src/uvw/util.hpp @@ -172,68 +172,6 @@ using Uid = uv_uid_t; using Gid = uv_gid_t; -/** - * @brief Gets the type of the stream to be used with the given descriptor. - * - * Returns the type of stream that should be used with a given file - * descriptor.
- * Usually this will be used during initialization to guess the type of the - * stdio streams. - * - * @param file A valid descriptor. - * @return One of the following types: - * - * * `HandleType::UNKNOWN` - * * `HandleType::PIPE` - * * `HandleType::TCP` - * * `HandleType::TTY` - * * `HandleType::UDP` - * * `HandleType::FILE` - */ -HandleType guessHandle(FileHandle file) { - auto type = uv_guess_handle(file); - - switch(type) { - case UV_ASYNC: - return HandleType::ASYNC; - case UV_CHECK: - return HandleType::CHECK; - case UV_FS_EVENT: - return HandleType::FS_EVENT; - case UV_FS_POLL: - return HandleType::FS_POLL; - case UV_HANDLE: - return HandleType::HANDLE; - case UV_IDLE: - return HandleType::IDLE; - case UV_NAMED_PIPE: - return HandleType::PIPE; - case UV_POLL: - return HandleType::POLL; - case UV_PREPARE: - return HandleType::PREPARE; - case UV_PROCESS: - return HandleType::PROCESS; - case UV_STREAM: - return HandleType::STREAM; - case UV_TCP: - return HandleType::TCP; - case UV_TIMER: - return HandleType::TIMER; - case UV_TTY: - return HandleType::TTY; - case UV_UDP: - return HandleType::UDP; - case UV_SIGNAL: - return HandleType::SIGNAL; - case UV_FILE: - return HandleType::FILE; - default: - return HandleType::UNKNOWN; - } -} - - /** * @brief The IPv4 tag. * @@ -260,24 +198,15 @@ struct Addr { /** - * TODO - * - * * uv_replace_allocator - * * uv_uptime - * * uv_getrusage - * * uv_cpu_info - * * uv_free_cpu_info - * * uv_loadavg - * * uv_exepath - * * uv_cwd - * * uv_chdir - * * uv_os_homedir - * * uv_os_tmpdir - * * uv_os_get_passwd - * * uv_os_free_passwd - * * uv_get_total_memory - * * uv_hrtime + * \brief Interface address. */ +struct Interface { + std::string name; /*!< The name of the interface (as an example _eth0_). */ + std::string physical; /*!< The physical address. */ + bool internal; /*!< True if it is an internal interface (as an example _loopback_), false otherwise. */ + Addr address; /*!< The address of the given interface. */ + Addr netmask; /*!< The netmask of the given interface. */ +}; namespace details { @@ -368,55 +297,133 @@ std::string path(F &&f, H *handle) noexcept { /** - * \brief Interface address. + * @brief Miscellaneous utilities. + * + * Miscellaneous functions that don’t really belong to any other class. */ -struct Interface { - std::string name; /*!< The name of the interface (as an example _eth0_). */ - std::string physical; /*!< The physical address. */ - bool internal; /*!< True if it is an internal interface (as an example _loopback_), false otherwise. */ - Addr address; /*!< The address of the given interface. */ - Addr netmask; /*!< The netmask of the given interface. */ +struct Utilities { + /** + * @brief Gets the type of the stream to be used with the given descriptor. + * + * Returns the type of stream that should be used with a given file + * descriptor.
+ * Usually this will be used during initialization to guess the type of the + * stdio streams. + * + * @param file A valid descriptor. + * @return One of the following types: + * + * * `HandleType::UNKNOWN` + * * `HandleType::PIPE` + * * `HandleType::TCP` + * * `HandleType::TTY` + * * `HandleType::UDP` + * * `HandleType::FILE` + */ + static HandleType guessHandle(FileHandle file) { + auto type = uv_guess_handle(file); + + switch(type) { + case UV_ASYNC: + return HandleType::ASYNC; + case UV_CHECK: + return HandleType::CHECK; + case UV_FS_EVENT: + return HandleType::FS_EVENT; + case UV_FS_POLL: + return HandleType::FS_POLL; + case UV_HANDLE: + return HandleType::HANDLE; + case UV_IDLE: + return HandleType::IDLE; + case UV_NAMED_PIPE: + return HandleType::PIPE; + case UV_POLL: + return HandleType::POLL; + case UV_PREPARE: + return HandleType::PREPARE; + case UV_PROCESS: + return HandleType::PROCESS; + case UV_STREAM: + return HandleType::STREAM; + case UV_TCP: + return HandleType::TCP; + case UV_TIMER: + return HandleType::TIMER; + case UV_TTY: + return HandleType::TTY; + case UV_UDP: + return HandleType::UDP; + case UV_SIGNAL: + return HandleType::SIGNAL; + case UV_FILE: + return HandleType::FILE; + default: + return HandleType::UNKNOWN; + } + } + + + /** + * @brief Gets a set of descriptors of all the available interfaces. + * + * This function can be used to query the underlying system and get a set of + * descriptors of all the available interfaces, either internal or not. + * + * @return A set of descriptors of all the available interfaces. + */ + static std::vector interfaces() noexcept { + std::vector interfaces; + + uv_interface_address_t *ifaces; + int count; + + uv_interface_addresses(&ifaces, &count); + + std::for_each(ifaces, ifaces+count, [&interfaces](const auto &iface) { + Interface interface; + + interface.name = iface.name; + interface.physical = iface.phys_addr; + interface.internal = iface.is_internal; + + if(iface.address.address4.sin_family == AF_INET) { + interface.address = details::address(&iface.address.address4); + interface.netmask = details::address(&iface.netmask.netmask4); + } else if(iface.address.address4.sin_family == AF_INET6) { + interface.address = details::address(&iface.address.address6); + interface.netmask = details::address(&iface.netmask.netmask6); + } + + interfaces.push_back(std::move(interface)); + }); + + uv_free_interface_addresses(ifaces, count); + + return interfaces; + } }; /** - * @brief Gets a set of descriptors of all the available interfaces. + * TODO * - * This function can be used to query the underlying system and get a set of - * descriptors of all the available interfaces, either internal or not. - * - * @return A set of descriptors of all the available interfaces. + * * uv_replace_allocator + * * uv_uptime + * * uv_getrusage + * * uv_cpu_info + * * uv_free_cpu_info + * * uv_loadavg + * * uv_exepath + * * uv_cwd + * * uv_chdir + * * uv_os_homedir + * * uv_os_tmpdir + * * uv_os_get_passwd + * * uv_os_free_passwd + * * uv_get_total_memory + * * uv_hrtime */ -std::vector interfaces() noexcept { - std::vector interfaces; - - uv_interface_address_t *ifaces; - int count; - - uv_interface_addresses(&ifaces, &count); - - std::for_each(ifaces, ifaces+count, [&interfaces](const auto &iface) { - Interface interface; - - interface.name = iface.name; - interface.physical = iface.phys_addr; - interface.internal = iface.is_internal; - - if(iface.address.address4.sin_family == AF_INET) { - interface.address = details::address(&iface.address.address4); - interface.netmask = details::address(&iface.netmask.netmask4); - } else if(iface.address.address4.sin_family == AF_INET6) { - interface.address = details::address(&iface.address.address6); - interface.netmask = details::address(&iface.netmask.netmask6); - } - - interfaces.push_back(std::move(interface)); - }); - - uv_free_interface_addresses(ifaces, count); - - return interfaces; -} } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d7a521d9..6a185f4c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -33,7 +33,7 @@ set(TARGET_WORK work) # Test TARGET_MAIN -set(TARGET_MAIN_SOURCES main.cpp) +set(TARGET_MAIN_SOURCES odr.cpp main.cpp) add_executable(${TARGET_MAIN} ${TARGET_MAIN_SOURCES}) target_include_directories(${TARGET_MAIN} PRIVATE ${COMMON_INCLUDE_DIRS}) target_link_libraries(${TARGET_MAIN} PRIVATE ${COMMON_LINK_LIBS}) @@ -41,7 +41,7 @@ add_test(NAME ${TARGET_MAIN} COMMAND ${TARGET_MAIN}) # Test TARGET_ASYNC -set(TARGET_ASYNC_SOURCES uvw/async.cpp) +set(TARGET_ASYNC_SOURCES odr.cpp uvw/async.cpp) add_executable(${TARGET_ASYNC} ${TARGET_ASYNC_SOURCES}) target_include_directories(${TARGET_ASYNC} PRIVATE ${COMMON_INCLUDE_DIRS}) target_link_libraries(${TARGET_ASYNC} PRIVATE ${COMMON_LINK_LIBS}) @@ -49,7 +49,7 @@ add_test(NAME ${TARGET_ASYNC} COMMAND ${TARGET_ASYNC}) # Test TARGET_CHECK -set(TARGET_CHECK_SOURCES uvw/check.cpp) +set(TARGET_CHECK_SOURCES odr.cpp uvw/check.cpp) add_executable(${TARGET_CHECK} ${TARGET_CHECK_SOURCES}) target_include_directories(${TARGET_CHECK} PRIVATE ${COMMON_INCLUDE_DIRS}) target_link_libraries(${TARGET_CHECK} PRIVATE ${COMMON_LINK_LIBS}) @@ -57,7 +57,7 @@ add_test(NAME ${TARGET_CHECK} COMMAND ${TARGET_CHECK}) # Test TARGET_EMITTER -set(TARGET_EMITTER_SOURCES uvw/emitter.cpp) +set(TARGET_EMITTER_SOURCES odr.cpp uvw/emitter.cpp) add_executable(${TARGET_EMITTER} ${TARGET_EMITTER_SOURCES}) target_include_directories(${TARGET_EMITTER} PRIVATE ${COMMON_INCLUDE_DIRS}) target_link_libraries(${TARGET_EMITTER} PRIVATE ${COMMON_LINK_LIBS}) @@ -65,7 +65,7 @@ add_test(NAME ${TARGET_EMITTER} COMMAND ${TARGET_EMITTER}) # Test TARGET_IDLE -set(TARGET_IDLE_SOURCES uvw/idle.cpp) +set(TARGET_IDLE_SOURCES odr.cpp uvw/idle.cpp) add_executable(${TARGET_IDLE} ${TARGET_IDLE_SOURCES}) target_include_directories(${TARGET_IDLE} PRIVATE ${COMMON_INCLUDE_DIRS}) target_link_libraries(${TARGET_IDLE} PRIVATE ${COMMON_LINK_LIBS}) @@ -73,7 +73,7 @@ add_test(NAME ${TARGET_IDLE} COMMAND ${TARGET_IDLE}) # Test TARGET_LOOP -set(TARGET_LOOP_SOURCES uvw/loop.cpp) +set(TARGET_LOOP_SOURCES odr.cpp uvw/loop.cpp) add_executable(${TARGET_LOOP} ${TARGET_LOOP_SOURCES}) target_include_directories(${TARGET_LOOP} PRIVATE ${COMMON_INCLUDE_DIRS}) target_link_libraries(${TARGET_LOOP} PRIVATE ${COMMON_LINK_LIBS}) @@ -81,7 +81,7 @@ add_test(NAME ${TARGET_LOOP} COMMAND ${TARGET_LOOP}) # Test TARGET_PREPARE -set(TARGET_PREPARE_SOURCES uvw/prepare.cpp) +set(TARGET_PREPARE_SOURCES odr.cpp uvw/prepare.cpp) add_executable(${TARGET_PREPARE} ${TARGET_PREPARE_SOURCES}) target_include_directories(${TARGET_PREPARE} PRIVATE ${COMMON_INCLUDE_DIRS}) target_link_libraries(${TARGET_PREPARE} PRIVATE ${COMMON_LINK_LIBS}) @@ -89,7 +89,7 @@ add_test(NAME ${TARGET_PREPARE} COMMAND ${TARGET_PREPARE}) # Test TARGET_SIGNAL -set(TARGET_SIGNAL_SOURCES uvw/signal.cpp) +set(TARGET_SIGNAL_SOURCES odr.cpp uvw/signal.cpp) add_executable(${TARGET_SIGNAL} ${TARGET_SIGNAL_SOURCES}) target_include_directories(${TARGET_SIGNAL} PRIVATE ${COMMON_INCLUDE_DIRS}) target_link_libraries(${TARGET_SIGNAL} PRIVATE ${COMMON_LINK_LIBS}) @@ -97,7 +97,7 @@ add_test(NAME ${TARGET_SIGNAL} COMMAND ${TARGET_SIGNAL}) # Test TARGET_TIMER -set(TARGET_TIMER_SOURCES uvw/timer.cpp) +set(TARGET_TIMER_SOURCES odr.cpp uvw/timer.cpp) add_executable(${TARGET_TIMER} ${TARGET_TIMER_SOURCES}) target_include_directories(${TARGET_TIMER} PRIVATE ${COMMON_INCLUDE_DIRS}) target_link_libraries(${TARGET_TIMER} PRIVATE ${COMMON_LINK_LIBS}) @@ -105,7 +105,7 @@ add_test(NAME ${TARGET_TIMER} COMMAND ${TARGET_TIMER}) # Test TARGET_WORK -set(TARGET_WORK_SOURCES uvw/work.cpp) +set(TARGET_WORK_SOURCES odr.cpp uvw/work.cpp) add_executable(${TARGET_WORK} ${TARGET_WORK_SOURCES}) target_include_directories(${TARGET_WORK} PRIVATE ${COMMON_INCLUDE_DIRS}) target_link_libraries(${TARGET_WORK} PRIVATE ${COMMON_LINK_LIBS}) diff --git a/test/odr.cpp b/test/odr.cpp new file mode 100644 index 00000000..94105c5e --- /dev/null +++ b/test/odr.cpp @@ -0,0 +1 @@ +#include