This commit is contained in:
Michele Caini 2016-08-03 17:29:54 +02:00
parent d484c5a92b
commit 1abfe6a2f6
4 changed files with 218 additions and 8 deletions

View File

@ -415,7 +415,7 @@ EXTRACT_ALL = NO
# be included in the documentation.
# The default value is: NO.
EXTRACT_PRIVATE = YES
EXTRACT_PRIVATE = NO
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
# scope will be included in the documentation.

View File

@ -21,6 +21,12 @@ template<typename R, typename... A> struct IsFunc<R(A...)>: std::true_type { };
}
/**
* @brief The SharedLib class.
*
* `uvw` provides cross platform utilities for loading shared libraries and
* retrieving symbols from them, by means of the API offered by libuv.
*/
class SharedLib final {
explicit SharedLib(std::shared_ptr<Loop> ref, std::string filename) noexcept
: pLoop{std::move(ref)},
@ -30,6 +36,15 @@ class SharedLib final {
}
public:
/**
* @brief Creates a new shared library object.
* @param args
*
* * A pointer to the loop from which the handle generated.
* * The filename of the library in UTF8.
*
* @return A pointer to the newly created handle.
*/
template<typename... Args>
static std::shared_ptr<SharedLib> create(Args&&... args) noexcept {
return std::shared_ptr<SharedLib>{new SharedLib{std::forward<Args>(args)...}};
@ -45,8 +60,21 @@ public:
SharedLib& operator=(const SharedLib &) = delete;
SharedLib& operator=(SharedLib &&) = delete;
/**
* @brief Checks if the library has been correctly opened.
* @return True if the library is opened, false otherwise.
*/
explicit operator bool() const noexcept { return !opened; }
/**
* @brief Retrieves a data pointer from a dynamic library.
*
* `F` shall be a valid function type (as an example, `void(int)`).<br/>
* It is legal for a symbol to map to `nullptr`.
*
* @param name The symbol to be retrieved.
* @return A valid function pointer in case of success, `nullptr` otherwise.
*/
template<typename F>
F * sym(std::string name) {
static_assert(details::IsFunc<F>::value, "!");
@ -56,10 +84,18 @@ public:
return func;
}
/**
* @brief Returns the last error message, if any.
* @return The last error message, if any.
*/
const char * error() const noexcept {
return uv_dlerror(&lib);
}
/**
* @brief Gets the loop from which the object was originated.
* @return A reference to a loop instance.
*/
Loop& loop() const noexcept { return *pLoop; }
private:

View File

@ -29,29 +29,73 @@ enum class UVHandleType: std::underlying_type_t<uv_handle_type> {
}
/**
* @brief The PipeHandle handle.
*
* Pipe handles provide an abstraction over local domain sockets on Unix and
* named pipes on Windows.
*/
class PipeHandle final: public StreamHandle<PipeHandle, uv_pipe_t> {
using StreamHandle::StreamHandle;
explicit PipeHandle(std::shared_ptr<Loop> ref, bool pass = false)
: StreamHandle{std::move(ref)}, ipc{pass}
{ }
public:
using Pending = details::UVHandleType;
/**
* @brief Creates a new poll handle.
* @param args
*
* * A pointer to the loop from which the handle generated.
* * An optional boolean value (_ipc_) that indicates if this pipe will be
* used for handle passing between processes.
*
* @return A pointer to the newly created handle.
*/
template<typename... Args>
static std::shared_ptr<PipeHandle> create(Args&&... args) {
return std::shared_ptr<PipeHandle>{new PipeHandle{std::forward<Args>(args)...}};
}
bool init(bool ipc = false) {
/**
* @brief Initializes the handle.
* @return True in case of success, false otherwise.
*/
bool init() {
return initialize<uv_pipe_t>(&uv_pipe_init, ipc);
}
/**
* @brief Opens an existing file descriptor or handle as a pipe.
*
* The passed file descriptor or handle is not checked for its type, but
* its required that it represents a valid pipe.
*
* @param file A valid file handle (either a file descriptor or a handle).
*/
void open(FileHandle file) {
invoke(&uv_pipe_open, get<uv_pipe_t>(), file);
}
/**
* @brief bind Binds the pipe to a file path (Unix) or a name (Windows).
*
* Paths on Unix get truncated typically between 92 and 108 bytes.
*
* @param name A valid file path.
*/
void bind(std::string name) {
invoke(&uv_pipe_bind, get<uv_pipe_t>(), name.data());
}
/**
* @brief Connects to the Unix domain socket or the named pipe.
*
* Paths on Unix get truncated typically between 92 and 108 bytes.
*
* @param name A valid domain socket or named pipe.
*/
void connect(std::string name) {
auto listener = [ptr = shared_from_this()](const auto &event, details::ConnectReq &) {
ptr->publish(event);
@ -63,22 +107,56 @@ public:
connect->connect(&uv_pipe_connect, get<uv_pipe_t>(), name.data());
}
/**
* @brief Gets the name of the Unix domain socket or the named pipe.
* @return The name of the Unix domain socket or the named pipe.
*/
std::string sock() const noexcept {
return details::path(&uv_pipe_getsockname, get<uv_pipe_t>());
}
/**
* @brief Gets the name of the Unix domain socket or the named pipe to which
* the handle is connected.
* @return The name of the Unix domain socket or the named pipe to which
* the handle is connected.
*/
std::string peer() const noexcept {
return details::path(&uv_pipe_getpeername, get<uv_pipe_t>());
}
/**
* @brief Sets the number of pending pipe this instance can handle.
*
* This method can be used to set the number of pending pipe this instance
* handles when the pipe server is waiting for connections.<br/>
* Note that this setting applies to Windows only.
*
* @param count The number of accepted pending pipe.
*/
void pending(int count) noexcept {
uv_pipe_pending_instances(get<uv_pipe_t>(), count);
}
/**
* @brief Gets the number of pending pipe this instance can handle.
* @return The number of pending pipe this instance can handle.
*/
int pending() noexcept {
return uv_pipe_pending_count(get<uv_pipe_t>());
}
/**
* @brief Used to receive handles over IPC pipes.
*
* Steps to be done:
*
* * Call `pending()`, if its greater than zero then proceed.
* * Initialize a handle of the given type, returned by `receive()`.
* * Call `accept(pipe, handle)`.
*
* @return
*/
Pending receive() noexcept {
auto type = uv_pipe_pending_type(get<uv_pipe_t>());
@ -93,6 +171,9 @@ public:
return Pending::UNKNOWN;
}
}
private:
bool ipc;
};

View File

@ -12,6 +12,16 @@
namespace uvw {
/**
* @brief Utility class to handle flags.
*
* This class can be used to handle flags of a same enumeration type.<br/>
* It is meant to be used as an argument for functions and member methods and
* as part of events.<br/>
* `Flags<E>` objects can be easily _or-ed_ and _and-ed_ with other instances of
* the same type or with instances of the type `E` (that is, the actual flag
* type), thus converted to the underlying type when needed.
*/
template<typename E>
class Flags final {
using InnerType = std::underlying_type_t<E>;
@ -21,8 +31,22 @@ class Flags final {
public:
using Type = InnerType;
/**
* @brief Constructs a Flags object from a value of the enum `E`.
* @param flag An value of the enum `E`.
*/
constexpr Flags(E flag) noexcept: flags{toInnerType(flag)} { }
/**
* @brief Constructs a Flags object from an instance of the underlying type
* of the enum `E`.
* @param f An instance of the underlying type of the enum `E`.
*/
constexpr Flags(Type f): flags{f} { }
/**
* @brief Constructs an uninitialized Flags object.
*/
constexpr Flags(): flags{} { }
constexpr Flags(const Flags &f) noexcept: flags{f.flags} { }
@ -40,13 +64,44 @@ public:
return *this;
}
/**
* @brief Or operator.
* @param f A valid instance of Flags.
* @return This instance _or-ed_ with `f`.
*/
constexpr Flags operator|(const Flags &f) const noexcept { return Flags(flags | f.flags); }
/**
* @brief Or operator.
* @param flag A value of the enum `E`.
* @return This instance _or-ed_ with `flag`.
*/
constexpr Flags operator|(E flag) const noexcept { return Flags(flags | toInnerType(flag)); }
/**
* @brief And operator.
* @param f A valid instance of Flags.
* @return This instance _and-ed_ with `f`.
*/
constexpr Flags operator&(const Flags &f) const noexcept { return Flags(flags & f.flags); }
/**
* @brief And operator.
* @param flag A value of the enum `E`.
* @return This instance _and-ed_ with `flag`.
*/
constexpr Flags operator&(E flag) const noexcept { return Flags(flags & toInnerType(flag)); }
/**
* @brief Checks if this instance is initialized.
* @return False if it's uninitialized, true otherwise.
*/
explicit constexpr operator bool() const noexcept { return !(flags == InnerType{}); }
/**
* @brief Casts the instance to the underlying type of `E`.
* @return An integral representation of the contained flags.
*/
constexpr operator Type() const noexcept { return flags; }
private:
@ -54,10 +109,32 @@ private:
};
/**
* @brief Wrapper for underlying library's types.
*
* In particular, It is used for:
*
* * FileHandle (that is an alias for `UVTypeWrapper<uv_file>`)
* * OSSocketHandle (that is an alias for `UVTypeWrapper<uv_os_sock_t>`)
* * OSFileDescriptor (that is an alias for `UVTypeWrapper<uv_os_fd_t>`)
*
* It can be bound to each value of type `T` and it will be implicitly converted
* to the underlying type when needed.
*/
template<typename T>
struct UVTypeWrapper {
using Type = T;
/**
* @brief Constructs a new instance of the wrapper.
* @param val The value to be stored.
*/
constexpr UVTypeWrapper(Type val): value{val} { }
/**
* @brief Cast operator to the underlying type.
* @return The stored value.
*/
constexpr operator Type() const noexcept { return value; }
private:
const Type value;
@ -69,12 +146,28 @@ using OSSocketHandle = UVTypeWrapper<uv_os_sock_t>;
using OSFileDescriptor = UVTypeWrapper<uv_os_fd_t>;
static constexpr auto STDIN = FileHandle{0};
static constexpr auto STDOUT = FileHandle{1};
static constexpr auto STDERR = FileHandle{2};
/**
* @brief Address representation.
*
* Pair alias (see Boost/Mutant idiom) used to pack together an ip and a
* port.<br/>
* 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.
*
* Pair alias (see Boost/Mutant idiom) used to pack together a width and a
* height.<br/>
* 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; };