From a193e6a9fee8760000561ba4fe1a6ec13ea0018d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Tom=C3=A1s?= Date: Sat, 11 Jul 2020 21:09:08 -0300 Subject: Implement IPC using binary format --- client.cpp | 78 +++++++++++++++++++++++++++++++++++--------------------------- ipc.cpp | 42 +++++++++++++++++++++++++-------- jet.cpp | 26 ++------------------- jet2.cpp | 31 +++++++++++++++---------- 4 files changed, 97 insertions(+), 80 deletions(-) diff --git a/client.cpp b/client.cpp index 176aa80..408c2e9 100644 --- a/client.cpp +++ b/client.cpp @@ -1,41 +1,52 @@ -#define MAX_ARGS 16 +#define MAX_MSG_SIZE 128 #define pos(x, y) (x) + (y) * window_w -struct ArgList { - int len, cap; - int *args; - - ArgList(int cap) : len(0), cap(cap) { - args = new int[cap]; - for (int i = 0; i < cap; args[i++] = 0); - } - ~ArgList() { delete[] args; } - - int pop() { - return args[--len]; - } - - void push(int value) { - args[len++] = value; - } - -}; - struct Client { int sockfd; Point cursor; Point window_start; - ArgList args; - Client(const Buffer &b) : - cursor(b), - window_start(cursor), - args(MAX_ARGS) - {} + Client(const Buffer &b) : cursor(b), window_start(cursor) {} + + void parse_message() { + uint8_t message[MAX_MSG_SIZE] = {}; + read(sockfd, message, MAX_MSG_SIZE - 1); + uint8_t *iter = message; + while (*iter) { + switch (*iter) { + case OP_MOVE1: + move(iter[1]); + iter += 2; + break; + case OP_MOVE2: + move(decode2(iter, 1)); + iter += 3; + break; + case OP_MOVE4: + move(decode4(iter, 1)); + iter += 5; + break; + case OP_MOVE8: + move(decode8(iter, 1)); + iter += 9; + break; + case OP_INSERT: + push(iter[1]); + iter += 2; + break; + case OP_DELETE: + pop(); + iter += 1; + break; + case OP_SHOW: + show(decode2(iter, 1), decode2(iter, 3)); + iter += 6; + break; + } + } + } - void show() { - int window_h = args.pop(); - int window_w = args.pop(); + void show(int16_t window_w, int16_t window_h) { char *view = new char[window_w * window_h]; Point window_end(window_start); @@ -65,8 +76,7 @@ struct Client { delete[] view; } - void move() { - int target = args.pop(); + void move(int64_t target) { while (target > 0) { cursor++; target--; @@ -77,8 +87,8 @@ struct Client { } } - void push() { - cursor.push(args.pop()); + void push(int8_t input) { + cursor.push(input); } void pop() { diff --git a/ipc.cpp b/ipc.cpp index 7b6ea5d..9c96d5a 100644 --- a/ipc.cpp +++ b/ipc.cpp @@ -1,15 +1,37 @@ enum Operation { - OP_I1, - OP_I2, - OP_I4, - OP_I8, - OP_U1, - OP_U2, - OP_U4, - OP_U8, - OP_STR, - OP_MOVE, + OP_NULL = 0, + OP_MOVE1, + OP_MOVE2, + OP_MOVE4, + OP_MOVE8, OP_INSERT, OP_DELETE, OP_SHOW }; + +void encode2(int16_t data, uint8_t *message, size_t offset) { + message[offset] = data & 0x00ff; + message[offset + 1] = (data & 0xff00) >> 8; +} + +int16_t decode2(uint8_t *message, size_t offset) { + return message[offset] | ((int16_t)message[offset + 1] << 8); +} + +void encode4(int32_t data, uint8_t *message, size_t offset) { + encode2( data & 0x0000ffff, message, offset); + encode2((data & 0xffff0000) >> 16, message, offset + 2); +} + +int32_t decode4(uint8_t *message, size_t offset) { + return decode2(message, offset) | ((int32_t)decode2(message, offset + 2) << 16); +} + +void encode8(int64_t data, uint8_t *message, size_t offset) { + encode4( data & 0x00000000ffffffff, message, offset); + encode4((data & 0xffffffff00000000) >> 32, message, offset + 4); +} + +int64_t decode8(uint8_t *message, size_t offset) { + return decode4(message, offset) | ((int64_t)decode4(message, offset + 4) << 32); +} diff --git a/jet.cpp b/jet.cpp index 1ae3eeb..2006a77 100644 --- a/jet.cpp +++ b/jet.cpp @@ -1,6 +1,6 @@ #include -#include #include +#include #include #include @@ -19,7 +19,6 @@ #include "client.cpp" #define PORT 6969 -#define MAX_COMMAND_SIZE 128 #define MAX_EVENTS 10 int create_listener() { @@ -32,24 +31,6 @@ int create_listener() { return s; } -void parse_command(char *command, Client *client) { - char *token = strtok(command, " \n"); - while (token) { - if (strcmp(token, "show") == 0) { - client->show(); - } else if (strcmp(token, "move") == 0) { - client->move(); - } else if (strcmp(token, "push") == 0) { - client->push(); - } else if (strcmp(token, "pop") == 0) { - client->pop(); - } else { - client->args.push(atoi(token)); - } - token = strtok(0, " \n"); - } -} - int main() { Buffer scratch("scratch"); scratch.read_file("LICENSE"); @@ -82,10 +63,7 @@ int main() { clients[clientfd] = c; epoll_ctl(epollfd, EPOLL_CTL_ADD, clientfd, &ev); } else { - char command[MAX_COMMAND_SIZE] = {}; - int clientfd = events[i].data.fd; - read(clientfd, command, MAX_COMMAND_SIZE - 1); - parse_command(command, clients[clientfd]); + clients[events[i].data.fd]->parse_message(); } } } diff --git a/jet2.cpp b/jet2.cpp index 994ba14..1a088dd 100644 --- a/jet2.cpp +++ b/jet2.cpp @@ -38,15 +38,19 @@ int main(int argc, char *argv[]) { while (!quit) { clear(); - char msg[32] = {}; - int len = sprintf(msg, "%d%d%d%d%d", OP_I4, window_width, OP_I4, window_height, OP_SHOW); - write(s, msg, len); + uint8_t msg[5]; + msg[0] = OP_SHOW; + encode2(window_width, msg, 1); + encode2(window_height, msg, 3); + write(s, msg, 5); read(s, view, window_width * window_height); for (int i = 0; i < window_width * window_height; i++) { printw("%c", view[i]); } - memset(msg, 0, 32); + uint8_t mov[2]; + uint8_t del[1]; + uint8_t ins[2]; int input = getch(); if (mode == NORMAL_MODE) { switch (input) { @@ -57,12 +61,14 @@ int main(int argc, char *argv[]) { mode = INSERT_MODE; break; case 'h': - len = sprintf(msg, "%d%d%d", OP_I1, -1, OP_MOVE); - write(s, msg, len); + mov[0] = OP_MOVE1; + mov[1] = -1; + write(s, mov, 2); break; case 'l': - len = sprintf(msg, "%d%d%d", OP_I1, 1, OP_MOVE); - write(s, msg, len); + mov[0] = OP_MOVE1; + mov[1] = 1; + write(s, mov, 2); break; } } else { @@ -71,12 +77,13 @@ int main(int argc, char *argv[]) { mode = NORMAL_MODE; break; case KEY_BACKSPACE: - len = sprintf(msg, "%d", OP_DELETE); - write(s, msg, len); + del[0] = OP_DELETE; + write(s, del, 1); break; default: - len = sprintf(msg, "%d%d%d", OP_I1, input, OP_INSERT); - write(s, msg, len); + ins[0] = OP_INSERT; + ins[1] = input; + write(s, ins, 2); } } } -- cgit v1.2.3