added tty + mior changes

This commit is contained in:
Michele Caini 2016-07-14 00:29:31 +02:00
parent 71c1eff6b1
commit 0c5413156b
6 changed files with 117 additions and 8 deletions

View File

@ -11,4 +11,5 @@
#include "uvw/stream.hpp"
#include "uvw/tcp.hpp"
#include "uvw/timer.hpp"
#include "uvw/tty.hpp"
#include "uvw/util.hpp"

View File

@ -21,6 +21,7 @@ template<> struct HandleType<uv_prepare_t> { };
template<> struct HandleType<uv_signal_t> { };
template<> struct HandleType<uv_tcp_t> { };
template<> struct HandleType<uv_timer_t> { };
template<> struct HandleType<uv_tty_t> { };
template<typename T>
@ -87,9 +88,10 @@ protected:
}
template<typename F, typename... Args>
void invoke(F &&f, Args&&... args) {
auto invoke(F &&f, Args&&... args) {
auto err = std::forward<F>(f)(std::forward<Args>(args)...);
if(err) { Emitter<T>::publish(ErrorEvent{err}); }
return err;
}
public:

View File

@ -31,7 +31,7 @@ class Tcp final: public Stream<Tcp> {
sockaddr_storage ssto;
int len = sizeof(ssto);
char name[sizeof(ssto)];
Addr addr{ "", 0 };
std::pair<std::string, unsigned int> addr{ "", 0 };
int err = std::forward<F>(f)(get<uv_tcp_t>(), reinterpret_cast<sockaddr *>(&ssto), &len);
@ -44,7 +44,11 @@ class Tcp final: public Stream<Tcp> {
}
}
return addr;
/**
* See Boost/Mutant idiom:
* https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Boost_mutant
*/
return reinterpret_cast<Addr&>(addr);
}
public:
@ -78,7 +82,7 @@ public:
template<typename I, typename..., typename Traits = details::IpTraits<I>>
void bind(Addr addr, bool ipv6only = false) noexcept {
bind<I>(addr.first, addr.second, ipv6only);
bind<I>(addr.ip, addr.port, ipv6only);
}
template<typename I, typename..., typename Traits = details::IpTraits<I>>
@ -100,7 +104,7 @@ public:
template<typename I, typename..., typename Traits = details::IpTraits<I>>
void connect(Addr addr) noexcept {
connect<I>(addr.first, addr.second);
connect<I>(addr.ip, addr.port);
}
void accept(Tcp &tcp) noexcept {

97
src/uvw/tty.hpp Normal file
View File

@ -0,0 +1,97 @@
#pragma once
#include <utility>
#include <cstddef>
#include <memory>
#include <uv.h>
#include "event.hpp"
#include "stream.hpp"
#include "util.hpp"
namespace uvw {
namespace details {
template<std::size_t FD>
struct FileDescriptor;
template<> struct FileDescriptor<0> { };
template<> struct FileDescriptor<1> { };
template<> struct FileDescriptor<2> { };
}
class TTY final: public Stream<TTY> {
template<std::size_t FD>
explicit TTY(std::shared_ptr<Loop> ref,
details::FileDescriptor<FD>,
bool readable)
: Stream{HandleType<uv_tty_t>{}, std::move(ref)},
fd{FD},
rw{readable ? 1 : 0}
{ }
public:
static constexpr auto STDIN = details::FileDescriptor<0>{};
static constexpr auto STDOUT = details::FileDescriptor<1>{};
static constexpr auto STDERR = details::FileDescriptor<2>{};
enum class Mode: unsigned short int { NORMAL, RAW, IO };
template<typename... Args>
static std::shared_ptr<TTY> create(Args&&... args) {
return std::shared_ptr<TTY>{new TTY{std::forward<Args>(args)...}};
}
bool init() { return initialize<uv_tty_t>(&uv_tty_init, fd, rw); }
void mode(TTY::Mode m) {
// uv_tty_set_mode is inline, cannot be used with invoke directly
auto wrap = [](auto *handle, auto m) {
return uv_tty_set_mode(handle, m);
};
switch(m) {
case TTY::Mode::NORMAL:
invoke(std::move(wrap), get<uv_tty_t>(), UV_TTY_MODE_NORMAL);
break;
case TTY::Mode::RAW:
invoke(std::move(wrap), get<uv_tty_t>(), UV_TTY_MODE_RAW);
break;
case TTY::Mode::IO:
invoke(std::move(wrap), get<uv_tty_t>(), UV_TTY_MODE_IO);
break;
}
}
void reset() { invoke(&uv_tty_reset_mode); }
WinSize getWinSize() {
std::pair<int, int> size{0, 0};
int width;
int height;
if(0 == invoke(&uv_tty_get_winsize, get<uv_tty_t>(), &width, &height)) {
size.first = width;
size.second = height;
}
/**
* See Boost/Mutant idiom:
* https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Boost_mutant
*/
return reinterpret_cast<WinSize&>(size);
}
private:
uv_file fd;
int rw;
};
}

View File

@ -67,7 +67,12 @@ private:
};
using Addr = std::pair<std::string, unsigned int>;
/**
* See Boost/Mutant idiom:
* https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Boost_mutant
*/
struct Addr { std::string ip; unsigned int port; };
struct WinSize { int width; int height; };
}

View File

@ -31,10 +31,10 @@ void listen(uvw::Loop &loop) {
srv.accept(*client);
uvw::Addr local = srv.address<uvw::Tcp::IPv4>();
std::cout << "local: " << local.first << " " << local.second << std::endl;
std::cout << "local: " << local.ip << " " << local.port << std::endl;
uvw::Addr remote = client->remote<uvw::Tcp::IPv4>();
std::cout << "remote: " << remote.first << " " << remote.second << std::endl;
std::cout << "remote: " << remote.ip << " " << remote.port << std::endl;
client->on<uvw::DataEvent>([](const uvw::DataEvent &event, uvw::Tcp &) {
std::cout.write(event.data(), event.length()) << std::endl;