From 8693eef8febde4df90b7fbd1fb9ac813b132fa50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Tom=C3=A1s?= Date: Mon, 20 Jul 2020 01:50:14 -0300 Subject: Wrap external functionality into classes --- src/client/cursor.cpp | 13 --------- src/client/jetc.cpp | 59 +++++----------------------------------- src/client/window.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/common/file.cpp | 30 +++++++++++++++++++++ src/common/ipc.cpp | 2 ++ src/common/socket.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/server/buffer.cpp | 14 +++++----- src/server/client.cpp | 8 +++--- src/server/jet.cpp | 71 +++++++++++------------------------------------- src/server/point.cpp | 2 +- 10 files changed, 210 insertions(+), 136 deletions(-) delete mode 100644 src/client/cursor.cpp create mode 100644 src/common/file.cpp create mode 100644 src/common/socket.cpp diff --git a/src/client/cursor.cpp b/src/client/cursor.cpp deleted file mode 100644 index 4e76151..0000000 --- a/src/client/cursor.cpp +++ /dev/null @@ -1,13 +0,0 @@ -struct Cursor { - int x; - int y; - Window *w; - - void move_left() { - if (x > 0) x--; - } - - void move_right() { - if (x < w->width - 1 && w->pos(x + 1, y) != 0) x++; - } -}; diff --git a/src/client/jetc.cpp b/src/client/jetc.cpp index 8d31d72..2dd6074 100644 --- a/src/client/jetc.cpp +++ b/src/client/jetc.cpp @@ -1,57 +1,22 @@ #include #include -#include - -#include -#include -#include -#include -#include #include +#include #include -#include #define NORMAL_MODE 0 #define INSERT_MODE 1 -#define PORT 6969 int main(int argc, char *argv[]) { - initscr(); - cbreak(); - noecho(); - intrflush(stdscr, FALSE); - keypad(stdscr, TRUE); - Window window; - getmaxyx(stdscr, window.height, window.width); - window.init(); - - int s = socket(AF_INET, SOCK_STREAM, 0); - sockaddr_in addr = { AF_INET, htons(PORT), htonl(INADDR_LOOPBACK) }; - connect(s, (sockaddr *) &addr, sizeof(sockaddr_in)); int mode = NORMAL_MODE; - Cursor cursor = { 0, 0, &window }; int quit = 0; while (!quit) { - clear(); + window.redraw(); - int8_t msg[5]; - msg[0] = OP_SHOW; - encode2(window.width, msg, 1); - encode2(window.height, msg, 3); - write(s, msg, 5); - read(s, window.view, window.width * window.height); - for (int i = 0; i < window.width * window.height; i++) { - printw("%c", window.view[i]); - } - move(cursor.y, cursor.x); - - int8_t mov[2]; - int8_t del[1]; - int8_t ins[2]; int input = getch(); if (mode == NORMAL_MODE) { switch (input) { @@ -62,16 +27,10 @@ int main(int argc, char *argv[]) { mode = INSERT_MODE; break; case 'h': - mov[0] = OP_MOVE1; - mov[1] = -1; - write(s, mov, 2); - cursor.move_left(); + window.move_left(); break; case 'l': - mov[0] = OP_MOVE1; - mov[1] = 1; - write(s, mov, 2); - cursor.move_right(); + window.move_right(); break; } } else { @@ -80,19 +39,13 @@ int main(int argc, char *argv[]) { mode = NORMAL_MODE; break; case KEY_BACKSPACE: - del[0] = OP_DELETE; - write(s, del, 1); + window.delete_element(); break; default: - ins[0] = OP_INSERT; - ins[1] = input; - write(s, ins, 2); + window.insert_element(input); } } } - close(s); - - endwin(); return 0; } diff --git a/src/client/window.cpp b/src/client/window.cpp index e718e63..9e389fe 100644 --- a/src/client/window.cpp +++ b/src/client/window.cpp @@ -1,16 +1,85 @@ -struct Window { +#include + +class Window { + Socket io; char *view; int width; int height; + int cursor_x; + int cursor_y; + + public: + + Window() : cursor_x(0), cursor_y(0) { + initscr(); + cbreak(); + noecho(); + intrflush(stdscr, FALSE); + keypad(stdscr, TRUE); + + getmaxyx(stdscr, height, width); - void init() { view = new char[width * height]; for (int i = 0; i < width * height; i++) { view[i] = 0; } + + io.connect(); + } + + ~Window() { + endwin(); + } + + void redraw() { + clear(); + + int8_t msg[5]; + msg[0] = OP_SHOW; + encode2(width, msg, 1); + encode2(height, msg, 3); + io.send(msg, 5); + io.recv(view, width * height); + for (int i = 0; i < width * height; i++) { + printw("%c", view[i]); + } + move(cursor_y, cursor_x); } char pos(size_t x, size_t y) { return view[x + y * width]; } + + void move_left() { + int8_t mov[2]; + if (cursor_x > 0) { + mov[0] = OP_MOVE1; + mov[1] = -1; + io.send(mov, 2); + cursor_x--; + } + } + + void move_right() { + int8_t mov[2]; + if (cursor_x < width - 1 && pos(cursor_x + 1, cursor_y) != 0) { + mov[0] = OP_MOVE1; + mov[1] = 1; + io.send(mov, 2); + cursor_x++; + } + } + + void delete_element() { + int8_t del[1]; + del[0] = OP_DELETE; + io.send(del, 1); + } + + void insert_element(int input) { + int8_t ins[2]; + ins[0] = OP_INSERT; + ins[1] = input; + io.send(ins, 2); + } }; diff --git a/src/common/file.cpp b/src/common/file.cpp new file mode 100644 index 0000000..a9d8c2b --- /dev/null +++ b/src/common/file.cpp @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +class File { + int descriptor; + + public: + + File(const char *filepath, int flags) { + descriptor = open(filepath, flags); + } + + File(const char *filepath, int flags, mode_t mode) { + descriptor = open(filepath, flags, mode); + } + + size_t send(void *msg, size_t length) { + return write(descriptor, msg, length); + } + + size_t recv(void *msg, size_t length) { + return read(descriptor, msg, length); + } + + ~File() { + close(descriptor); + } +}; diff --git a/src/common/ipc.cpp b/src/common/ipc.cpp index 7d46307..d5a42e4 100644 --- a/src/common/ipc.cpp +++ b/src/common/ipc.cpp @@ -1,3 +1,5 @@ +#include + enum Operation { OP_NULL = 0, OP_MOVE1, diff --git a/src/common/socket.cpp b/src/common/socket.cpp new file mode 100644 index 0000000..7eb4b46 --- /dev/null +++ b/src/common/socket.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include + +#define MAX_EVENTS 10 + +#define PORT 6969 + +class Socket { + int descriptor; + + public: + + Socket() { + descriptor = socket(AF_INET, SOCK_STREAM, 0); + } + + Socket(int descriptor) : descriptor(descriptor) {} + + typedef void (*EventAction) (int); + + void listen(EventAction on_new_connection, EventAction on_existing_connection) { + sockaddr_in addr = { AF_INET, htons(PORT), htonl(INADDR_LOOPBACK)}; + int opt = 1; + setsockopt(descriptor, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)); + bind(descriptor, (sockaddr *) &addr, sizeof(sockaddr_in)); + ::listen(descriptor, MAX_EVENTS); + + int epollfd = epoll_create1(0); + + epoll_event ev; + ev.events = EPOLLIN; + ev.data.fd = descriptor; + epoll_ctl(epollfd, EPOLL_CTL_ADD, descriptor, &ev); + + epoll_event events[MAX_EVENTS]; + + while (true) { + int nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1); + + for (int i = 0; i < nfds; i++) { + if (events[i].data.fd == descriptor) { + int clientfd = accept(descriptor, 0, 0); + ev.events = EPOLLIN | EPOLLET; + ev.data.fd = clientfd; + epoll_ctl(epollfd, EPOLL_CTL_ADD, clientfd, &ev); + on_new_connection(clientfd); + } else { + on_existing_connection(events[i].data.fd); + } + } + } + + } + + void connect() { + sockaddr_in addr = { AF_INET, htons(PORT), htonl(INADDR_LOOPBACK) }; + ::connect(descriptor, (sockaddr *) &addr, sizeof(sockaddr_in)); + } + + size_t send(void *msg, size_t length) { + return write(descriptor, msg, length); + } + + size_t recv(void *msg, size_t length) { + return read(descriptor, msg, length); + } + + ~Socket() { + close(descriptor); + } +}; diff --git a/src/server/buffer.cpp b/src/server/buffer.cpp index 7b4c92d..62c7ea9 100644 --- a/src/server/buffer.cpp +++ b/src/server/buffer.cpp @@ -14,9 +14,9 @@ struct Buffer { void read_file(const char *pathname) { free_storage(); - int file = open(pathname, O_RDONLY); + File file(pathname, O_RDONLY); storage = new Page(); - int bytes_read = read(file, storage->elements, PAGE_SIZE); + int bytes_read = file.recv(storage->elements, PAGE_SIZE); Page *iter = storage; while (bytes_read > 0) { iter->gap_start = bytes_read; @@ -24,22 +24,20 @@ struct Buffer { iter->next = new Page(); iter->next->prev = iter; iter = iter->next; - bytes_read = read(file, iter->elements, PAGE_SIZE); + bytes_read = file.recv(iter->elements, PAGE_SIZE); } if (iter->element_count == 0) { delete iter; } - close(file); } void write_file(const char *pathname) { - int file = open(pathname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + File file(pathname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); Page *iter = storage; while (iter) { - write(file, iter->elements, iter->gap_start); - write(file, iter->elements + iter->gap_end, PAGE_SIZE - iter->gap_end); + file.send(iter->elements, iter->gap_start); + file.send(iter->elements + iter->gap_end, PAGE_SIZE - iter->gap_end); iter = iter->next; } - close(file); } }; diff --git a/src/server/client.cpp b/src/server/client.cpp index d6fc0fc..45f7501 100644 --- a/src/server/client.cpp +++ b/src/server/client.cpp @@ -2,15 +2,15 @@ #define pos(x, y) (x) + (y) * window_w struct Client { - int sockfd; + Socket io; Point cursor; Point window_start; - Client(const Buffer &b) : cursor(b), window_start(cursor) {} + Client(const Buffer &b, int fd) : io(fd), cursor(b), window_start(cursor) {} void parse_message() { int8_t message[MAX_MSG_SIZE] = {}; - read(sockfd, message, MAX_MSG_SIZE - 1); + io.recv(message, MAX_MSG_SIZE - 1); switch (message[0]) { case OP_MOVE1: move(message[1]); @@ -58,7 +58,7 @@ struct Client { } } - write(sockfd, view, window_w * window_h); + io.send(view, window_w * window_h); delete[] view; } diff --git a/src/server/jet.cpp b/src/server/jet.cpp index 5cc3ee4..e29005a 100644 --- a/src/server/jet.cpp +++ b/src/server/jet.cpp @@ -1,72 +1,33 @@ #include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include - #include +#include +#include + #include #include #include #include -#define PORT 6969 -#define MAX_EVENTS 10 +Client *clients[1024] = {}; +Buffer scratch("scratch"); + +void new_connection(int fd) { + if (clients[fd]) { + delete clients[fd]; + } + clients[fd] = new Client(scratch, fd); +} -int create_listener() { - int s = socket(AF_INET, SOCK_STREAM, 0); - sockaddr_in addr = { AF_INET, htons(PORT), htonl(INADDR_LOOPBACK)}; - int opt = 1; - setsockopt(s, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)); - bind(s, (sockaddr *) &addr, sizeof(sockaddr_in)); - listen(s, MAX_EVENTS); - return s; +void existing_connection(int fd) { + clients[fd]->parse_message(); } int main() { - Buffer scratch("scratch"); scratch.read_file("test.txt"); - int listener = create_listener(); - - int epollfd = epoll_create1(0); - - epoll_event ev; - ev.events = EPOLLIN; - ev.data.fd = listener; - epoll_ctl(epollfd, EPOLL_CTL_ADD, listener, &ev); - - epoll_event events[MAX_EVENTS]; - Client *clients[1024] = {}; - - while (true) { - int nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1); - - for (int i = 0; i < nfds; i++) { - if (events[i].data.fd == listener) { - int clientfd = accept(listener, 0, 0); - ev.events = EPOLLIN | EPOLLET; - ev.data.fd = clientfd; - if (clients[clientfd]) { - delete clients[clientfd]; - } - Client *c = new Client(scratch); - c->sockfd = clientfd; - clients[clientfd] = c; - epoll_ctl(epollfd, EPOLL_CTL_ADD, clientfd, &ev); - } else { - clients[events[i].data.fd]->parse_message(); - } - } - } - - close(listener); + Socket listener; + listener.listen(new_connection, existing_connection); } diff --git a/src/server/point.cpp b/src/server/point.cpp index ab9f70f..cf38bed 100644 --- a/src/server/point.cpp +++ b/src/server/point.cpp @@ -1,7 +1,7 @@ #include #include -struct Point { +class Point { Page *page; uint16_t index; -- cgit v1.2.3