diff options
Diffstat (limited to 'src/server/client.cpp')
-rw-r--r-- | src/server/client.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/server/client.cpp b/src/server/client.cpp new file mode 100644 index 0000000..bed62c5 --- /dev/null +++ b/src/server/client.cpp @@ -0,0 +1,93 @@ +#define MAX_MSG_SIZE 128 +#define pos(x, y) (x) + (y) * window_w + +struct Client { + int sockfd; + Point cursor; + Point window_start; + + Client(const Buffer &b) : cursor(b), window_start(cursor) {} + + void parse_message() { + int8_t message[MAX_MSG_SIZE] = {}; + read(sockfd, message, MAX_MSG_SIZE - 1); + int8_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(size_t window_w, size_t window_h) { + char *view = new char[window_w * window_h]; + + Point window_end(window_start); + for (int i = 0; i < window_h; i++) { + for (int j = 0; j < window_w; j++) { + view[pos(j, i)] = window_end.element(); + if (window_end.element() == '\n') { + for (int k = j + 1; k < window_w; k++) { + view[pos(k, i)] = 0; + } + j = window_w; + } else if (window_end.element() == '\t') { + for (int k = j + 1; k < j + 8; k++) { + view[pos(k, i)] = 0; + } + j = j + 7; + } + window_end++; + } + } + + write(sockfd, view, window_w * window_h); + delete[] view; + } + + void move(int64_t target) { + while (target > 0) { + cursor++; + target--; + } + while (target < 0) { + cursor--; + target++; + } + } + + void push(int8_t input) { + cursor.push(input); + } + + void pop() { + cursor.pop(); + } +}; |