about summary refs log tree commit diff stats
path: root/src/client
diff options
context:
space:
mode:
authorChristian Krinitsin <mail@krinitsin.com>2025-03-21 16:17:20 +0100
committerChristian Krinitsin <mail@krinitsin.com>2025-03-21 16:17:20 +0100
commitf1af8679481cfc4199b6423d723f67188145ea46 (patch)
tree62d25d33bab6a2ba150659a35155977131e67237 /src/client
parent2a22b4123dce661b0500dc07012d61215bdce161 (diff)
downloadBT-Programming-Assignment-f1af8679481cfc4199b6423d723f67188145ea46.tar.gz
BT-Programming-Assignment-f1af8679481cfc4199b6423d723f67188145ea46.zip
client: add client class with input processing
Diffstat (limited to 'src/client')
-rw-r--r--src/client/client.cpp134
-rw-r--r--src/client/client.h32
-rw-r--r--src/client/main.cpp112
3 files changed, 169 insertions, 109 deletions
diff --git a/src/client/client.cpp b/src/client/client.cpp
new file mode 100644
index 0000000..d88df5f
--- /dev/null
+++ b/src/client/client.cpp
@@ -0,0 +1,134 @@
+#include "client.h"
+#include "shared_memory.h"
+#include <optional>
+
+Client::Client()
+{
+    shm_fd = shm_open(SHM_NAME, O_RDWR, 0666);
+    if (shm_fd == -1) {
+        std::cout << "Server not running" << '\n';
+        return;
+    }
+
+    shared_memory =
+        (SharedMemory*)mmap(0, sizeof(SharedMemory), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
+}
+
+Client::~Client()
+{
+    munmap(shared_memory, sizeof(SharedMemory));
+    close(shm_fd);
+}
+
+void Client::start_client()
+{
+    while (true) {
+        char operation;
+        int k, v;
+        std::cout << "Choose the operation (i: Insert, g: Get, r: Remove, p: Print, e: Exit)"
+                  << '\n';
+        std::cin >> operation;
+        switch (operation) {
+        case 'e':
+            return;
+        case 'i':
+            std::cout << "Insert: Enter the k-v pair(<int> <int>):" << '\n';
+            if (!(std::cin >> k >> v)) {
+                std::cout << "Invalid input" << '\n';
+                std::cin.clear();
+                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+                break;
+            };
+            send_request(
+                shared_memory, INSERT, std::optional(serialize(k)), std::optional(serialize(v)));
+            break;
+        case 'g': {
+            std::cout << "Get: Enter the key(<int>):" << '\n';
+            if (!(std::cin >> k)) {
+                std::cout << "Invalid input" << '\n';
+                std::cin.clear();
+                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+                break;
+            };
+            int index = send_request(shared_memory, GET, std::optional(serialize(k)), std::nullopt);
+            std::string response = process_result(shared_memory, index);
+            std::cout << "Got: " << response << '\n';
+            break;
+        }
+        case 'r':
+            std::cout << "Remove: Enter key(<int>):" << '\n';
+            if (!(std::cin >> k)) {
+                std::cout << "Invalid input" << '\n';
+                std::cin.clear();
+                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+                break;
+            };
+            send_request(shared_memory, DELETE, std::optional(serialize(k)), std::nullopt);
+            break;
+        case 'p':
+            send_request(shared_memory, PRINT, std::nullopt, std::nullopt);
+            break;
+        default:
+            break;
+        }
+        std::cout << '\n';
+    }
+}
+
+bool Client::request_processed(SharedMemory* shared_memory, int index)
+{
+    if (shared_memory->full) {
+        return false;
+    }
+    if (shared_memory->tail == shared_memory->head && !shared_memory->full) {
+        return true;
+    }
+
+    for (int i = shared_memory->head - 1; i != shared_memory->tail; i = (i - 1) % QUEUE_SIZE) {
+        if (i == index) {
+            return false;
+        }
+    }
+
+    return shared_memory->tail != index;
+}
+
+int Client::send_request(
+    SharedMemory* shared_memory,
+    Operations type,
+    std::optional<const std::string> k,
+    std::optional<const std::string> v)
+{
+    int index;
+
+    pthread_mutex_lock(&shared_memory->mutex);
+
+    while (shared_memory->full) {
+        pthread_cond_wait(&shared_memory->cond_var, &shared_memory->mutex);
+    }
+
+    index = shared_memory->head;
+    Request* request = &shared_memory->request[index];
+    request->type = type;
+    strncpy(request->key, k.value_or("null").c_str(), MAX_KEY_SIZE);
+    strncpy(request->value, v.value_or("null").c_str(), MAX_VALUE_SIZE);
+    shared_memory->head = (1 + shared_memory->head) % QUEUE_SIZE;
+    shared_memory->full = shared_memory->head == shared_memory->tail;
+    pthread_cond_signal(&shared_memory->cond_var);
+
+    pthread_mutex_unlock(&shared_memory->mutex);
+
+    return index;
+}
+
+std::string Client::process_result(SharedMemory* shared_memory, int index)
+{
+    pthread_mutex_lock(&shared_memory->mutex);
+
+    while (!request_processed(shared_memory, index)) {
+        pthread_cond_wait(&shared_memory->cond_var, &shared_memory->mutex);
+    }
+    std::string result(shared_memory->request[index].response);
+    pthread_mutex_unlock(&shared_memory->mutex);
+    return result;
+}
diff --git a/src/client/client.h b/src/client/client.h
new file mode 100644
index 0000000..9ff5b47
--- /dev/null
+++ b/src/client/client.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <cstring>
+#include <fcntl.h>
+#include <iostream>
+#include <optional>
+#include <pthread.h>
+#include <string>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <utility>
+
+#include "shared_memory.h"
+class Client {
+public:
+    Client();
+    ~Client();
+
+    void start_client();
+
+private:
+    SharedMemory* shared_memory;
+    int shm_fd;
+
+    int send_request(
+        SharedMemory* shared_memory,
+        Operations type,
+        std::optional<const std::string> k,
+        std::optional<const std::string> v);
+    bool request_processed(SharedMemory* shared_memory, int index);
+    std::string process_result(SharedMemory* shared_memory, int index);
+};
diff --git a/src/client/main.cpp b/src/client/main.cpp
index 6dfd48f..ca2f4a3 100644
--- a/src/client/main.cpp
+++ b/src/client/main.cpp
@@ -1,115 +1,9 @@
-#include "shared_memory.h"
-#include <cstring>
-#include <fcntl.h>
-#include <iostream>
-#include <pthread.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <utility>
+#include "client.h"
 
-bool request_processed(SharedMemory* shared_memory, int index)
-{
-    if (shared_memory->full) {
-        return false;
-    }
-    if (shared_memory->tail == shared_memory->head && !shared_memory->full) {
-        return true;
-    }
-
-    for (int i = shared_memory->head - 1; i != shared_memory->tail; i = (i - 1) % QUEUE_SIZE) {
-        if (i == index) {
-            return false;
-        }
-    }
-
-    return shared_memory->tail != index;
-}
-
-void send_request(
-    SharedMemory* shared_memory,
-    Operations type,
-    std::pair<const std::string&, const std::string&> arguments)
-{
-    int index;
-
-    pthread_mutex_lock(&shared_memory->mutex);
-
-    if (shared_memory->full) {
-        std::cout << "Queue is full" << '\n';
-        pthread_cond_wait(&shared_memory->cond_var, &shared_memory->mutex);
-        return;
-    }
-
-    index = shared_memory->head;
-    Request* request = &shared_memory->request[index];
-    request->type = type;
-    strncpy(request->key, serialize(arguments.first).c_str(), MAX_KEY_SIZE);
-    strncpy(request->value, serialize(arguments.second).c_str(), MAX_VALUE_SIZE);
-    shared_memory->head = (1 + shared_memory->head) % QUEUE_SIZE;
-    shared_memory->full = shared_memory->head == shared_memory->tail;
-    pthread_cond_signal(&shared_memory->cond_var);
-
-    pthread_mutex_unlock(&shared_memory->mutex);
-
-    std::cout << "Command sent" << '\n';
-
-    if (type == Operations::GET) {
-        pthread_mutex_lock(&shared_memory->mutex);
-
-        while (!request_processed(shared_memory, index)) {
-            pthread_cond_wait(&shared_memory->cond_var, &shared_memory->mutex);
-        }
-        std::string result(shared_memory->request[index].response);
-        pthread_mutex_unlock(&shared_memory->mutex);
-        std::cout << "Result: " << result << std::endl;
-    }
-}
 
 int main()
 {
-    int shm_fd = shm_open(SHM_NAME, O_RDWR, 0666);
-    if (shm_fd == -1) {
-        std::cout << "Server not running" << '\n';
-        return -1;
-    }
-
-    SharedMemory* shared_memory =
-        (SharedMemory*)mmap(0, sizeof(SharedMemory), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
-
-    std::cout << "Start inserting.." << '\n';
-    send_request(shared_memory, INSERT, std::pair(serialize(3), serialize(3)));
-
-    std::cout << "Start inserting.." << '\n';
-    send_request(shared_memory, INSERT, std::pair(serialize(4), serialize(5)));
-
-    std::cout << "Start inserting.." << '\n';
-    send_request(shared_memory, INSERT, std::pair(serialize(6), serialize(6)));
-
-    std::cout << "Start inserting.." << '\n';
-    send_request(shared_memory, INSERT, std::pair(serialize(7), serialize(3)));
-
-    std::cout << "Start inserting.." << '\n';
-    send_request(shared_memory, INSERT, std::pair(serialize(8), serialize(3)));
-
-    std::cout << "Start inserting.." << '\n';
-    send_request(shared_memory, INSERT, std::pair(serialize(9), serialize(3)));
-
-    std::cout << "Start inserting.." << '\n';
-    send_request(shared_memory, INSERT, std::pair(serialize(10), serialize(3)));
-
-    std::cout << "Start inserting.." << '\n';
-    send_request(shared_memory, INSERT, std::pair(serialize(11), serialize(3)));
-
-    std::cout << "Start inserting.." << '\n';
-    send_request(shared_memory, INSERT, std::pair(serialize(12), serialize(3)));
-
-    std::cout << "Start inserting.." << '\n';
-    send_request(shared_memory, INSERT, std::pair(serialize(13), serialize(4)));
-
-    std::cout << "Start PRINTING.." << '\n';
-    send_request(shared_memory, PRINT, std::pair(serialize(0), serialize(0)));
+    Client client;
 
-    munmap(shared_memory, sizeof(SharedMemory));
-    close(shm_fd);
-    return 0;
+    client.start_client();
 }