-
-
Save stormouse/af4bcc376e00b405934568350ae06130 to your computer and use it in GitHub Desktop.
proxy-a-bit-less-messy-imo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct EventHandler | |
{ | |
virtual void handle(event_t ev) = 0; | |
virtual EventHandler* next() const = 0; | |
virtual void propagate(event_t ev) { | |
EventHandler* n = next(); | |
if (n != nullptr) | |
n->handle(ev); | |
} | |
}; | |
struct Channel : public EventHandler | |
{ | |
int read() { /* unimportant */ } | |
int write() { /* unimportant */ } | |
void transferTo(const Channel& dstChannel) { | |
readBuffer()->copyTo(*dstChannel.writeBuffer()); | |
readBuffer()->clear(); | |
} | |
bool is_read_ready() const { return _fdState & READ_READY; } | |
bool is_read_active() const { return !readBuffer()->empty(); } | |
bool is_write_ready() const { return _fdState & WRITE_READY; } | |
bool is_write_active() const { return !writeBuffer()->empty(); } | |
virtual void handle(event_t ev) override { | |
if (IOEvent::is_read_ready(ev)) { | |
_fdState = _fdState | IOState::READ_READY; | |
} else { | |
_fdState = _fdState & ~IOState::READ_READY; | |
} | |
if (IOEvent::is_write_ready(ev)) { | |
_fdState = _fdState | IOState::WRITE_READY; | |
} else { | |
_fdState = _fdState & (~IOState::WRITE_READY); | |
} | |
propagate(ev); | |
} | |
virtual ~Channel() { | |
// close fd | |
} | |
private: | |
Buffer* readBuffer() { return _readBuf; } | |
Buffer* writeBuffer() { return _writeBuf; } | |
Buffer* _readBuf; | |
Buffer* _writeBuf; | |
IOState _fdState; | |
}; | |
struct Pipe : public EventHandler { | |
std::unique_ptr<Channel> a; | |
std::unique_ptr<Channel> b; | |
Pipe(std::unique_ptr<Channel> a, std::unique_ptr<Channel> b) | |
: a(std::move(a)), b(std::move(b)) {} | |
virtual void handle(event_t ev) override { | |
if (IOEvent::is_failure(ev)) { | |
// TODO: destroy pipe | |
return; | |
} | |
if (a->is_read_ready()) { | |
a->read(); | |
} | |
if (b->is_read_ready()) { | |
b->read(); | |
} | |
if (a->is_read_active() && b->is_write_ready()) { | |
a->transferTo(b); | |
b->write(); | |
} | |
if (b->is_read_active() && a->is_write_ready()) { | |
b->transferTo(a); | |
a->write(); | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment