From 3838d8e94aadf61578ca5f6acc90e7a5a4369db0 Mon Sep 17 00:00:00 2001 From: ZhuangYumin Date: Tue, 12 Dec 2023 03:21:56 +0000 Subject: [PATCH] docs: begin to setup main structure and write BlockSS --- .gitignore | 1 + CMakeLists.txt | 1 + backend/include/bs-utility.h | 64 +++++++++++++++++++++++++++++++++++ backend/include/builtin-cli.h | 5 +++ backend/include/engine.h | 4 +++ backend/include/schedule.h | 4 +++ backend/src/bs-utility.cpp | 13 +++++++ backend/src/builtin-cli.cpp | 16 +++++++++ backend/src/engine.cpp | 1 + backend/src/main.cpp | 61 ++++++++++++++++++++++++++++++++- backend/src/schedule.cpp | 2 ++ 11 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 backend/include/bs-utility.h create mode 100644 backend/src/bs-utility.cpp diff --git a/.gitignore b/.gitignore index 3b5f4e3..a34aa49 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /.devcontainer /.vscode /maintenance/test +/maintenance/demo .clang-format /frontend/Web/node_modules /frontend/client/node_modules diff --git a/CMakeLists.txt b/CMakeLists.txt index bb175b2..1341227 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.15.2) project(BookStore) file(GLOB_RECURSE main_src backend/src/*.cpp) include_directories(${PROJECT_SOURCE_DIR}/backend/include) +include_directories(${PROJECT_SOURCE_DIR}/external) add_executable(code ${main_src}) add_subdirectory(maintenance/test) include(maintenance/test/ctest_config) \ No newline at end of file diff --git a/backend/include/bs-utility.h b/backend/include/bs-utility.h new file mode 100644 index 0000000..a7a24ef --- /dev/null +++ b/backend/include/bs-utility.h @@ -0,0 +1,64 @@ +#ifndef PROTECTOR_UTILITY_H +#define PROTECTOR_UTILITY_H +#include +#include +#include +#include +#include +#include +#include +#include +class FatalError : public std::exception { + public: + FatalError(const char *__message, int __code) + : message(__message), code(__code) {} + + const char *what() const noexcept override { return message.c_str(); } + const int GetCode() const noexcept { return code; } + + private: + std::string message; + int code; +}; +class BlockingStringStream { + public: + BlockingStringStream() {} + + // Declaration of major std::stringstream interfaces + template + BlockingStringStream &operator<<(const T &val); + + template + BlockingStringStream &operator>>(T &val); + BlockingStringStream &getline(std::string &str, char delim = '\n'); + std::stringstream internalStream; + + private: + std::mutex mutex; + std::condition_variable condition; +}; +// Implementation of operator<< +template +BlockingStringStream &BlockingStringStream::operator<<(const T &val) { + { + std::lock_guard lock(mutex); + if (internalStream.peek() == EOF) internalStream.clear(); + internalStream << val; + } + condition.notify_one(); + return *this; +} + +// Implementation of operator>> +template +BlockingStringStream &BlockingStringStream::operator>>(T &val) { + std::unique_lock lock(mutex); + + // Wait until data is available + condition.wait(lock, [this] { return internalStream.peek() != EOF; }); + + internalStream >> val; + + return *this; +} +#endif // PROTECTOR_UTILITY_H \ No newline at end of file diff --git a/backend/include/builtin-cli.h b/backend/include/builtin-cli.h index e69de29..2bf957c 100644 --- a/backend/include/builtin-cli.h +++ b/backend/include/builtin-cli.h @@ -0,0 +1,5 @@ +#ifndef PROTECTOR_BUILDTIN_CLI_H +#define PROTECTOR_BUILDTIN_CLI_H +#include +void BookStoreMain(bool,std::string); +#endif //PROTECTOR_BUILDTIN_CLI_H \ No newline at end of file diff --git a/backend/include/engine.h b/backend/include/engine.h index e69de29..f5b5468 100644 --- a/backend/include/engine.h +++ b/backend/include/engine.h @@ -0,0 +1,4 @@ +#ifndef PROTECTOR_ENGINE_H +#define PROTECTOR_ENGINE_H + +#endif // PROTECTOR_ENGINE_H \ No newline at end of file diff --git a/backend/include/schedule.h b/backend/include/schedule.h index e69de29..d1f2058 100644 --- a/backend/include/schedule.h +++ b/backend/include/schedule.h @@ -0,0 +1,4 @@ +#ifndef PROTECTOR_SCHEDULE_H +#define PROTECTOR_SCHEDULE_H + +#endif // PROTECTOR_SCHEDULE_H \ No newline at end of file diff --git a/backend/src/bs-utility.cpp b/backend/src/bs-utility.cpp new file mode 100644 index 0000000..b9e46b4 --- /dev/null +++ b/backend/src/bs-utility.cpp @@ -0,0 +1,13 @@ +#include "bs-utility.h" + +BlockingStringStream &BlockingStringStream::getline(std::string &str, + char delim) { + std::unique_lock lock(mutex); + + // Wait until data is available + condition.wait(lock, [this] { return internalStream.peek() != EOF; }); + + std::getline(internalStream, str, delim); + + return *this; +} \ No newline at end of file diff --git a/backend/src/builtin-cli.cpp b/backend/src/builtin-cli.cpp index e69de29..c9231b8 100644 --- a/backend/src/builtin-cli.cpp +++ b/backend/src/builtin-cli.cpp @@ -0,0 +1,16 @@ +#include "builtin-cli.h" + +#include + +#include "schedule.h" +#include "bs-utility.h" +void BookStoreMain(bool is_server, std::string config_dir) { + std::ios::sync_with_stdio(false); + if (!is_server) { + ; // TODO: run as client + } else { + throw FatalError("Server mode is not implemented yet", 1); + std::cin.tie(nullptr); + std::cout.rdbuf(nullptr); + } +} \ No newline at end of file diff --git a/backend/src/engine.cpp b/backend/src/engine.cpp index e69de29..11856cc 100644 --- a/backend/src/engine.cpp +++ b/backend/src/engine.cpp @@ -0,0 +1 @@ +#include "engine.h" \ No newline at end of file diff --git a/backend/src/main.cpp b/backend/src/main.cpp index c3aeba4..23d1fec 100644 --- a/backend/src/main.cpp +++ b/backend/src/main.cpp @@ -1 +1,60 @@ -int main() { return 0; } \ No newline at end of file +#include +#include + +#include "bs-utility.h" +#include "builtin-cli.h" +#include "clipp/clipp.h" +void test() { + BlockingStringStream bss; + + std::thread writer([&bss]() { + for (int i = 1; i <= 5; ++i) { + bss << "Data " << i << '\n'; + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + }); + + std::thread reader([&bss]() { + std::string data; + for (int i = 1; i <= 5; ++i) { + // Use getline with string delimiter + bss.getline(data, '\n'); + std::cout << "Received: " << data << std::endl; + } + }); + reader.join(); + writer.join(); +} +int main(int argc, char **argv) { + test(); + return 0; + bool is_server = false; + std::string config_dir = ""; + bool custom_config_dir = false; + auto cli = + (clipp::option("-s", "--server").set(is_server).doc("run as server"), + clipp::option("-c", "--config") + .set(custom_config_dir) + .doc("use config directory") & + clipp::value("config directory", config_dir)); + if (!clipp::parse(argc, argv, cli)) { + std::cout << clipp::make_man_page(cli, argv[0]); + return 0; + } + if (!custom_config_dir) config_dir = "./"; + try { + BookStoreMain(is_server, config_dir); + } catch (const FatalError &e) { + std::cerr << "\e[7m\e[31m[Fatal Error] " << e.GetCode() << " : " << e.what() + << "\e[0m" << std::endl; + return e.GetCode(); + } catch (const std::exception &e) { + std::cerr << "\e[7m\e[31m[other std::exception] " << e.what() << "\e[0m" + << std::endl; + return 255; + } catch (...) { + std::cerr << "\e[7m\e[31m[Unknown Exception]\e[0m" << std::endl; + return 255; + } + return 0; +} \ No newline at end of file diff --git a/backend/src/schedule.cpp b/backend/src/schedule.cpp index e69de29..5d049a1 100644 --- a/backend/src/schedule.cpp +++ b/backend/src/schedule.cpp @@ -0,0 +1,2 @@ +#include "schedule.h" +#include "engine.h" \ No newline at end of file