summaryrefslogtreecommitdiff
path: root/src/server/client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/client.cpp')
-rw-r--r--src/server/client.cpp93
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();
+ }
+};