added tty + mior changes
This commit is contained in:
parent
71c1eff6b1
commit
0c5413156b
@ -11,4 +11,5 @@
|
||||
#include "uvw/stream.hpp"
|
||||
#include "uvw/tcp.hpp"
|
||||
#include "uvw/timer.hpp"
|
||||
#include "uvw/tty.hpp"
|
||||
#include "uvw/util.hpp"
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
97
src/uvw/tty.hpp
Normal 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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@ -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; };
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user