From 1f97c82f8fdcfa6e85e07933330f8ecb30a0165e Mon Sep 17 00:00:00 2001 From: Max Qian Date: Mon, 25 Mar 2024 23:00:47 +0800 Subject: [PATCH] update doc --- CMakeLists.txt | 5 +- doc/atom/algorithm/base.md | 97 +++++ doc/atom/algorithm/fraction.md | 93 +++++ doc/atom/algorithm/huffman.md | 90 +++++ doc/atom/algorithm/md5.md | 75 ++++ doc/atom/async/async.md | 114 ++++++ doc/atom/async/lock.md | 142 +++++++ doc/atom/async/queue.md | 71 ++++ doc/atom/async/timer.md | 94 +++++ doc/atom/async/trigger.md | 73 ++++ doc/atom/connection/fifoclient.md | 42 ++ doc/atom/connection/fifoserver.md | 44 +++ doc/atom/connection/shared_memory.md | 92 +++++ doc/atom/connection/sockethub.md | 128 ++++++ doc/atom/connection/sshclient.md | 109 ++++++ doc/atom/connection/udp_server.md | 103 +++++ doc/atom/io/compress.md | 41 ++ doc/atom/io/file.md | 84 ++++ doc/atom/io/io.md | 202 ++++++++++ doc/atom/log/global_logger.md | 68 ++++ doc/atom/log/logger.md | 91 +++++ doc/atom/log/syslog.md | 108 ++++++ doc/atom/search/cache.md | 363 ++++++++++++++++++ doc/atom/search/mysql.md | 325 ++++++++++++++++ doc/atom/search/search.md | 91 +++++ doc/atom/search/sqlite.md | 243 ++++++++++++ doc/atom/serial/serial.md | 126 ++++++ doc/atom/serial/ttybase.md | 239 ++++++++++++ doc/atom/server/commander.md | 150 ++++++++ doc/atom/server/daemon.md | 117 ++++++ doc/atom/server/deserialize.md | 74 ++++ doc/atom/server/global_ptr.md | 133 +++++++ doc/atom/server/json_checker.md | 100 +++++ doc/atom/server/message_bus.md | 164 ++++++++ doc/atom/server/message_queue.md | 83 ++++ doc/atom/server/serialize.md | 92 +++++ doc/atom/server/variables.md | 141 +++++++ doc/atom/system/command.md | 109 ++++++ doc/atom/system/crash_quotes.md | 131 +++++++ doc/atom/system/lregistry.md | 122 ++++++ doc/atom/system/os.md | 128 ++++++ doc/atom/system/pidwatcher.md | 108 ++++++ doc/atom/system/process.md | 153 ++++++++ doc/atom/system/register.md | 153 ++++++++ doc/atom/system/storage.md | 92 +++++ doc/atom/system/system.md | 108 ++++++ doc/atom/system/user.md | 78 ++++ doc/atom/type/args.md | 170 ++++++++ doc/atom/type/autotype.md | 67 ++++ doc/atom/type/ini.md | 177 +++++++++ doc/atom/type/small_vector.md | 115 ++++++ doc/atom/web/curl.md | 293 ++++++++++++++ doc/atom/web/downloader.md | 110 ++++++ doc/atom/web/httpclient.md | 221 +++++++++++ doc/atom/web/httplite.md | 201 ++++++++++ doc/atom/web/httpparser.md | 201 ++++++++++ doc/atom/web/time.md | 103 +++++ doc/components/README.md | 94 +++++ doc/{component.md => components/README_ZH.md} | 78 ++-- src/App.cpp | 29 +- src/AppComponent.hpp | 86 ++++- src/atom/algorithm/mathutils.cpp | 105 +++++ src/atom/algorithm/mathutils.hpp | 34 ++ src/atom/async/lock.hpp | 100 ++++- src/atom/async/timer.hpp | 2 +- src/atom/connection/fifoclient.hpp | 30 +- src/atom/connection/fifoserver.hpp | 31 +- src/atom/search/mysql.hpp | 2 +- src/atom/serial/serial.hpp | 49 +++ src/atom/system/crash_quotes.hpp | 3 +- src/atom/system/lregistry.cpp | 169 ++++++++ src/atom/system/lregistry.hpp | 119 ++++++ src/atom/system/register.cpp | 44 +-- src/atom/system/register.hpp | 20 +- src/controller/AsyncClientController.hpp | 10 +- .../lithium-web/src/pages/info/device.astro | 29 +- 76 files changed, 8137 insertions(+), 144 deletions(-) create mode 100644 doc/atom/algorithm/base.md create mode 100644 doc/atom/algorithm/fraction.md create mode 100644 doc/atom/algorithm/huffman.md create mode 100644 doc/atom/algorithm/md5.md create mode 100644 doc/atom/async/async.md create mode 100644 doc/atom/async/lock.md create mode 100644 doc/atom/async/queue.md create mode 100644 doc/atom/async/timer.md create mode 100644 doc/atom/async/trigger.md create mode 100644 doc/atom/connection/fifoclient.md create mode 100644 doc/atom/connection/fifoserver.md create mode 100644 doc/atom/connection/shared_memory.md create mode 100644 doc/atom/connection/sockethub.md create mode 100644 doc/atom/connection/sshclient.md create mode 100644 doc/atom/connection/udp_server.md create mode 100644 doc/atom/io/compress.md create mode 100644 doc/atom/io/file.md create mode 100644 doc/atom/io/io.md create mode 100644 doc/atom/log/global_logger.md create mode 100644 doc/atom/log/logger.md create mode 100644 doc/atom/log/syslog.md create mode 100644 doc/atom/search/cache.md create mode 100644 doc/atom/search/mysql.md create mode 100644 doc/atom/search/search.md create mode 100644 doc/atom/search/sqlite.md create mode 100644 doc/atom/serial/serial.md create mode 100644 doc/atom/serial/ttybase.md create mode 100644 doc/atom/server/commander.md create mode 100644 doc/atom/server/daemon.md create mode 100644 doc/atom/server/deserialize.md create mode 100644 doc/atom/server/global_ptr.md create mode 100644 doc/atom/server/json_checker.md create mode 100644 doc/atom/server/message_bus.md create mode 100644 doc/atom/server/message_queue.md create mode 100644 doc/atom/server/serialize.md create mode 100644 doc/atom/server/variables.md create mode 100644 doc/atom/system/command.md create mode 100644 doc/atom/system/crash_quotes.md create mode 100644 doc/atom/system/lregistry.md create mode 100644 doc/atom/system/os.md create mode 100644 doc/atom/system/pidwatcher.md create mode 100644 doc/atom/system/process.md create mode 100644 doc/atom/system/register.md create mode 100644 doc/atom/system/storage.md create mode 100644 doc/atom/system/system.md create mode 100644 doc/atom/system/user.md create mode 100644 doc/atom/type/args.md create mode 100644 doc/atom/type/autotype.md create mode 100644 doc/atom/type/ini.md create mode 100644 doc/atom/type/small_vector.md create mode 100644 doc/atom/web/curl.md create mode 100644 doc/atom/web/downloader.md create mode 100644 doc/atom/web/httpclient.md create mode 100644 doc/atom/web/httplite.md create mode 100644 doc/atom/web/httpparser.md create mode 100644 doc/atom/web/time.md create mode 100644 doc/components/README.md rename doc/{component.md => components/README_ZH.md} (50%) create mode 100644 src/atom/algorithm/mathutils.cpp create mode 100644 src/atom/algorithm/mathutils.hpp create mode 100644 src/atom/system/lregistry.cpp create mode 100644 src/atom/system/lregistry.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 29d21f60..8e86f647 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,12 +175,13 @@ set(component_module set(config_module ${lithium_src_dir}/config/configor.cpp + ${lithium_src_dir}/config/HubsConfig.cpp ) if (ENABLE_ASYNC_FLAG) set(server_module - ${lithium_src_dir}/websocket/Game.cpp - ${lithium_src_dir}/websocket/Peer.cpp + ${lithium_src_dir}/websocket/Hub.cpp + ${lithium_src_dir}/websocket/Connection.cpp ${lithium_src_dir}/websocket/Registry.cpp ${lithium_src_dir}/websocket/Session.cpp ) diff --git a/doc/atom/algorithm/base.md b/doc/atom/algorithm/base.md new file mode 100644 index 00000000..c7e06c5d --- /dev/null +++ b/doc/atom/algorithm/base.md @@ -0,0 +1,97 @@ +# Base Encoding & Decoding Functions + +## encodeBase16 + +**Brief:** Encodes a vector of unsigned characters into a Base16 string. + +This function takes a vector of unsigned characters and encodes it into a Base16 string representation. Base16 encoding, also known as hexadecimal encoding, represents each byte in the input data as a pair of hexadecimal digits (0-9, A-F). + +- **Parameters:** + + - `data`: The vector of unsigned characters to be encoded. + +- **Return:** + - The Base16 encoded string. + +## decodeBase16 + +**Brief:** Decodes a Base16 string into a vector of unsigned characters. + +This function takes a Base16 encoded string and decodes it into a vector of unsigned characters. Base16 encoding, also known as hexadecimal encoding, represents each byte in the input data as a pair of hexadecimal digits (0-9, A-F). + +- **Parameters:** + + - `data`: The Base16 encoded string to be decoded. + +- **Return:** + - The decoded vector of unsigned characters. + +## encodeBase32 + +**Brief:** Encodes a string to Base32. + +- **Parameters:** + + - `input`: The string to encode. + +- **Return:** + - The encoded string. + +## decodeBase32 + +**Brief:** Decodes a Base32 string. + +- **Parameters:** + + - `input`: The string to decode. + +- **Return:** + - The decoded string. + +## base64Encode + +**Brief:** Base64 encoding function. + +- **Parameters:** + + - `bytes_to_encode`: Data to be encoded. + +- **Return:** + - Encoded string. + +## base64Decode + +**Brief:** Base64 decoding function. + +- **Parameters:** + + - `encoded_string`: String to decode. + +- **Return:** + - Decoded data as a vector of unsigned characters. + +## encodeBase85 + +**Brief:** Encodes a vector of unsigned characters into a Base85 string. + +This function takes a vector of unsigned characters and encodes it into a Base85 string representation. Base85 encoding is a binary-to-text encoding scheme that encodes 4 bytes into 5 ASCII characters. + +- **Parameters:** + + - `data`: The vector of unsigned characters to be encoded. + +- **Return:** + - The Base85 encoded string. + +## decodeBase85 + +**Brief:** Decodes a Base85 string into a vector of unsigned characters. + +This function takes a Base85 encoded string and decodes it into a vector of unsigned characters. Base85 encoding is a binary-to-text encoding scheme that encodes 4 bytes into 5 ASCII characters. + +- **Parameters:** + + - `data`: The Base85 encoded string to be decoded. + +- **Return:** + - The decoded vector of unsigned characters. diff --git a/doc/atom/algorithm/fraction.md b/doc/atom/algorithm/fraction.md new file mode 100644 index 00000000..ac9de0b5 --- /dev/null +++ b/doc/atom/algorithm/fraction.md @@ -0,0 +1,93 @@ +# Fraction Class + +The Fraction class represents a fraction and provides basic fraction operations and functionalities. + +## Member Functions + +### Constructors + +#### `Fraction(int num_value, int den_value)` + +Constructs a fraction object with the given numerator and denominator. + +#### `Fraction(int num_value)` + +Constructs a fraction object with the given integer as the numerator, defaulting the denominator to 1. + +#### `Fraction(const char *str)` + +Constructs a fraction object from the given string. + +#### `Fraction()` + +Default constructor that constructs a fraction object with a value of 0. + +### Member Methods + +#### `int getNumerator() const` + +Gets the numerator of the fraction. + +#### `int getDenominator() const` + +Gets the denominator of the fraction. + +#### `void alterValue(int num_value, int den_value)` + +Changes the value of the fraction to the specified numerator and denominator. + +#### `void alterValue(const Fraction &f)` + +Changes the value of the fraction to the value of another fraction object. + +#### `Fraction inverse()` + +Returns the reciprocal of the fraction. + +### Operator Overloading + +#### `+`, `-`, `*`, `/` + +Implements addition, subtraction, multiplication, and division for fractions. + +#### `==`, `!=`, `>`, `>=`, `<`, `<=` + +Implements comparison operators for fractions. + +#### `<<`, `>>` + +Implements input and output stream operations for fraction objects. + +#### Negation Operator + +Negates a fraction to its opposite value. + +### Friend Functions + +#### `operator>>` + +Reads a fraction object's value from the input stream. + +#### `operator<<` + +Writes a fraction object's value to the output stream. + +## Examples + +```cpp +Fraction f1(1, 2); +Fraction f2(3, 4); +Fraction result = f1 + f2; // result = 5/4 +std::cout << result; // Output: 5/4 +``` + +```cpp +Fraction f1(2, 3); +Fraction f2(1, 6); +bool isEqual = (f1 == f2); // isEqual = false +``` + +```cpp +Fraction f1(3, 5); +Fraction f2 = -f1; // f2 = -3/5 +``` diff --git a/doc/atom/algorithm/huffman.md b/doc/atom/algorithm/huffman.md new file mode 100644 index 00000000..0af1c140 --- /dev/null +++ b/doc/atom/algorithm/huffman.md @@ -0,0 +1,90 @@ +# Huffman Coding + +## HuffmanNode Struct + +**Brief:** Represents a node in a Huffman tree. + +- `char data`: The character stored in the node. +- `int frequency`: The frequency of the node. +- `HuffmanNode *left`: Pointer to the left child node. +- `HuffmanNode *right`: Pointer to the right child node. + +### Constructor + +- **Parameters:** + - `data`: The character to be stored in the node. + - `frequency`: The frequency of the node. + +## createHuffmanTree + +**Brief:** Creates a Huffman tree. + +- **Parameters:** + + - `frequencies`: Table of character frequencies. + +- **Return:** + - `HuffmanNode*`: Pointer to the root node of the Huffman tree. + +## generateHuffmanCodes + +**Brief:** Recursively generates Huffman codes. + +- **Parameters:** + - `root`: Pointer to the current node. + - `code`: Current code for the node. + - `huffmanCodes`: Map to store the Huffman codes. + +## compressText + +**Brief:** Compresses text using Huffman coding. + +- **Parameters:** + + - `text`: Text to be compressed. + - `huffmanCodes`: Map containing the Huffman codes. + +- **Return:** + - `std::string`: Compressed text. + +## decompressText + +**Brief:** Decompresses text using Huffman coding. + +- **Parameters:** + + - `compressedText`: Compressed text. + - `root`: Pointer to the root node of the Huffman tree. + +- **Return:** + - `std::string`: Decompressed text. + +### Example Usage + +```cpp +#include +#include + +// Define character frequencies +std::unordered_map frequencies = { + {'a', 10}, + {'b', 15}, + {'c', 30}, + {'d', 5}, + {'e', 20} +}; + +// Create Huffman tree +HuffmanNode *root = createHuffmanTree(frequencies); + +// Generate Huffman codes +std::unordered_map huffmanCodes; +generateHuffmanCodes(root, "", huffmanCodes); + +// Compress text using Huffman coding +std::string text = "abcde"; +std::string compressedText = compressText(text, huffmanCodes); + +// Decompress text using Huffman coding +std::string decompressedText = decompressText(compressedText, root); +``` diff --git a/doc/atom/algorithm/md5.md b/doc/atom/algorithm/md5.md new file mode 100644 index 00000000..ec6cf57d --- /dev/null +++ b/doc/atom/algorithm/md5.md @@ -0,0 +1,75 @@ +# MD5 Class + +The MD5 class provides functionality to calculate the MD5 hash of input data using the MD5 algorithm. + +## Member Functions + +### Public Methods + +#### `static std::string encrypt(const std::string &input)` + +Encrypts the input string using the MD5 algorithm and returns the MD5 hash of the input string. + +### Private Methods + +#### `void init()` + +Initializes internal variables and a buffer for MD5 computation. + +#### `void update(const std::string &input)` + +Updates the MD5 computation with additional input data. + +#### `std::string finalize()` + +Finalizes the MD5 computation and returns the resulting hash of all the input data provided so far. + +#### `void processBlock(const uint8_t *block)` + +Processes a 64-byte block of input data. + +### Static Helper Functions + +#### `static uint32_t F(uint32_t x, uint32_t y, uint32_t z)` + +The F function for the MD5 algorithm. + +#### `static uint32_t G(uint32_t x, uint32_t y, uint32_t z)` + +The G function for the MD5 algorithm. + +#### `static uint32_t H(uint32_t x, uint32_t y, uint32_t z)` + +The H function for the MD5 algorithm. + +#### `static uint32_t I(uint32_t x, uint32_t y, uint32_t z)` + +The I function for the MD5 algorithm. + +#### `static uint32_t leftRotate(uint32_t x, uint32_t n)` + +Performs a left rotate operation on the input. + +#### `static uint32_t reverseBytes(uint32_t x)` + +Reverses the bytes in the input. + +## Member Variables + +- `uint32_t _a, _b, _c, _d`: Internal state variables for MD5 computation. +- `uint64_t _count`: Total count of input bits. +- `std::vector _buffer`: Buffer for input data. + +## Example Usage + +```cpp +#include "MD5.h" +#include + +int main() { + std::string input = "Hello, World!"; + std::string md5Hash = MD5::encrypt(input); + std::cout << "MD5 Hash: " << md5Hash << std::endl; + return 0; +} +``` diff --git a/doc/atom/async/async.md b/doc/atom/async/async.md new file mode 100644 index 00000000..9444b0ec --- /dev/null +++ b/doc/atom/async/async.md @@ -0,0 +1,114 @@ +# Async Framework + +The Async Framework provides a simple way to perform asynchronous tasks in C++. It allows you to start, cancel, and retrieve the result of a task asynchronously. + +## AsyncWorker Class + +### Overview + +Class for performing asynchronous tasks. + +### Template Parameter + +- `ResultType`: The type of the result returned by the task. + +### Public Methods + +- `void StartAsync(Func &&func, Args &&...args)`: Starts the task asynchronously. +- `ResultType GetResult()`: Gets the result of the task. +- `void Cancel()`: Cancels the task. +- `bool IsDone() const`: Checks if the task is done. +- `bool IsActive() const`: Checks if the task is active. +- `bool Validate(std::function validator)`: Validates the result using a validator function. +- `void SetCallback(std::function callback)`: Sets a callback function. +- `void SetTimeout(std::chrono::seconds timeout)`: Sets a timeout for the task. +- `void WaitForCompletion()`: Waits for the task to complete. + +### Private Members + +- `std::future task_`: Represents the asynchronous task. +- `std::function callback_`: Callback function to be called when the task is done. +- `std::chrono::seconds timeout_{0}`: Timeout duration for the task. + +## AsyncWorkerManager Class + +### Overview + +Class for managing multiple AsyncWorker instances. + +### Template Parameter + +- `ResultType`: The type of the result returned by the tasks. + +### Public Methods + +- `std::shared_ptr> CreateWorker(Func &&func, Args &&...args)`: Creates a new AsyncWorker instance and starts the task asynchronously. +- `void CancelAll()`: Cancels all managed tasks. +- `bool AllDone() const`: Checks if all tasks are done. +- `void WaitForAll()`: Waits for all tasks to complete. +- `bool IsDone(std::shared_ptr> worker) const`: Checks if a specific task is done. +- `void Cancel(std::shared_ptr> worker)`: Cancels a specific task. + +## Global Functions + +## asyncRetry + +- Async execution with retry. +- Parameters: + - `Func func` + - `int attemptsLeft` + - `std::chrono::milliseconds delay` + - `Args... args` +- Returns: A shared pointer to the created AsyncWorker instance. + +## getWithTimeout + +- Gets the result of the task with a timeout. +- Parameters: + - `std::future &future` + - `std::chrono::milliseconds timeout` +- Returns: The result of the task. + +## Usage Examples + +```cpp +// Create an AsyncWorker object +AsyncWorker worker; + +// Start a task asynchronously +worker.StartAsync([](int x, int y) { return x + y; }, 5, 10); + +// Wait for the task to complete +worker.WaitForCompletion(); + +// Get the result +int result = worker.GetResult(); +``` + +```cpp +// Create an AsyncWorkerManager object +AsyncWorkerManager manager; + +// Create and start a new task +auto worker = manager.CreateWorker([]() { return 42; }); + +// Check if the task is done +if (manager.IsDone(worker)) { + // Task is done +} + +// Cancel the task +manager.Cancel(worker); + +// Wait for all tasks to complete +manager.WaitForAll(); +``` + +```cpp +// Using asyncRetry +auto future = asyncRetry([]() { return std::string("Hello, World!"); }, 3, std::chrono::milliseconds(100)); + +// Getting result with timeout +std::future task; +std::string result = getWithTimeout(task, std::chrono::milliseconds(500)); +``` diff --git a/doc/atom/async/lock.md b/doc/atom/async/lock.md new file mode 100644 index 00000000..6c21ec26 --- /dev/null +++ b/doc/atom/async/lock.md @@ -0,0 +1,142 @@ +# Extra Locks + +## Spinlock + +A simple spinlock implementation using atomic_flag. + +### Class Definition + +```cpp +class Spinlock { + // ... +public: + Spinlock() = default; + Spinlock(const Spinlock &) = delete; + Spinlock &operator=(const Spinlock &) = delete; + + void lock(); + void unlock(); +}; +``` + +### Usage Example + +```cpp +Spinlock spinlock; + +// Lock the spinlock +spinlock.lock(); + +// Critical section + +// Unlock the spinlock +spinlock.unlock(); +``` + +## TicketSpinlock + +A ticket spinlock implementation using atomic operations. + +### Class Definition + +```cpp +class TicketSpinlock { + // ... +public: + TicketSpinlock() = default; + TicketSpinlock(const TicketSpinlock &) = delete; + TicketSpinlock &operator=(const TicketSpinlock &) = delete; + + class LockGuard { + // ... + }; + + using scoped_lock = LockGuard; + + uint64_t lock(); + void unlock(const uint64_t ticket); +}; +``` + +### Usage Example + +```cpp +TicketSpinlock ticketSpinlock; + +// Create a lock guard and acquire the lock +{ + TicketSpinlock::LockGuard lockGuard(ticketSpinlock); + + // Critical section +} + +// Lock and unlock using ticket numbers +uint64_t ticket = ticketSpinlock.lock(); + +// Critical section + +ticketSpinlock.unlock(ticket); +``` + +## UnfairSpinlock + +An unfair spinlock implementation using atomic_flag. + +### Class Definition + +```cpp +class UnfairSpinlock { + // ... +public: + UnfairSpinlock() = default; + UnfairSpinlock(const UnfairSpinlock &) = delete; + UnfairSpinlock &operator=(const UnfairSpinlock &) = delete; + + void lock(); + void unlock(); +}; +``` + +### Usage Example + +```cpp +UnfairSpinlock unfairSpinlock; + +// Lock the spinlock +unfairSpinlock.lock(); + +// Critical section + +// Unlock the spinlock +unfairSpinlock.unlock(); +``` + +## ScopedLock + +Scoped lock for any type of spinlock. + +### Class Definition + +```cpp +template +class ScopedLock { + // ... +public: + explicit ScopedLock(Mutex &mutex); + ~ScopedLock(); +}; +``` + +### Usage Example + +```cpp +Spinlock spinlock; + +// Acquire the lock using scoped lock +{ + ScopedLock scopedLock(spinlock); + + // Critical section +} +// Lock will be automatically released when 'scopedLock' goes out of scope +``` diff --git a/doc/atom/async/queue.md b/doc/atom/async/queue.md new file mode 100644 index 00000000..0b502bcc --- /dev/null +++ b/doc/atom/async/queue.md @@ -0,0 +1,71 @@ +# ThreadSafeQueue Template Class + +The `ThreadSafeQueue` template class provides a thread-safe queue implementation in C++ for concurrent operations. + +## Class Definition + +```cpp +template +struct ThreadSafeQueue : public NonCopyable { + // Constructor + ThreadSafeQueue(); + + // Methods + void put(T element); + std::optional take(); + std::queue destroy(); + size_t size() const; + bool empty() const; + void clear(); + std::optional front(); + std::optional back(); + template + void emplace(Args &&...args); + template + std::optional waitFor(Predicate predicate); + void waitUntilEmpty(); + template + std::vector extractIf(UnaryPredicate pred); + template + void sort(Compare comp); + template + ThreadSafeQueue transform(std::function func); + template + std::vector> groupBy(std::function func); +}; +``` + +## Usage Example + +```cpp +// Example usage of ThreadSafeQueue +ThreadSafeQueue tsq; + +// Put elements into the queue +tsq.put(10); +tsq.put(20); +tsq.put(30); + +// Take elements from the queue +std::optional element = tsq.take(); +if (element.has_value()) { + std::cout << "Taken element: " << element.value() << std::endl; +} + +// Check if the queue is empty +bool isEmpty = tsq.empty(); +std::cout << "Is queue empty? " << (isEmpty ? "Yes" : "No") << std::endl; + +// Clear the queue +tsq.clear(); + +// Check the size of the queue +size_t queueSize = tsq.size(); +std::cout << "Queue size: " << queueSize << std::endl; +``` + +## Notes + +- This class provides thread-safe operations for a queue data structure. +- It uses mutexes and condition variables to ensure thread safety. +- Various operations like putting, taking, sorting, transforming, and grouping elements are supported. diff --git a/doc/atom/async/timer.md b/doc/atom/async/timer.md new file mode 100644 index 00000000..5297afdb --- /dev/null +++ b/doc/atom/async/timer.md @@ -0,0 +1,94 @@ +# Timer Module Documentation + +## TimerTask Class + +Represents a task to be scheduled and executed by the Timer. + +### Constructor + +```cpp +TimerTask(std::function func, unsigned int delay, int repeatCount, int priority); +``` + +## Public Member Functions + +- `bool operator<(const TimerTask &other) const`: Comparison operator based on next execution time. +- `void run()`: Executes the task's associated function. +- `std::chrono::steady_clock::time_point getNextExecutionTime() const`: Get the next scheduled execution time of the task. + +### Public Members + +- `std::function m_func`: The function to be executed. +- `unsigned int m_delay`: The delay before the first execution. +- `int m_repeatCount`: The number of repetitions remaining. +- `int m_priority`: The priority of the task. +- `std::chrono::steady_clock::time_point m_nextExecutionTime`: The next execution time. + +## Timer Class + +Represents a timer for scheduling and executing tasks. + +### Constructor + +```cpp +Timer(); +``` + +### Destructor + +```cpp +~Timer(); +``` + +### Public Member Functions + +- `template std::future::type> setTimeout(Function &&func, unsigned int delay, Args &&...args)`: Schedules a task to be executed once after a specified delay. +- `template void setInterval(Function &&func, unsigned int interval, int repeatCount, int priority, Args &&...args)`: Schedules a task to be executed repeatedly at a specified interval. +- `std::chrono::steady_clock::time_point now() const`: Get the current time. +- `void cancelAllTasks()`: Cancels all scheduled tasks. +- `void pause()`: Pauses the execution of scheduled tasks. +- `void resume()`: Resumes the execution of scheduled tasks. +- `void stop()`: Stops the timer and cancels all tasks. +- `template void setCallback(Function &&func)`: Sets a callback function to be called when a task is executed. +- `int getTaskCount() const`: Get the count of scheduled tasks. + +### Private Member Functions + +- `template std::future::type> addTask(Function &&func, unsigned int delay, int repeatCount, int priority, Args &&...args)`: Adds a task to the task queue. +- `void run()`: Main execution loop for processing and running tasks. + +### Private Members + +- `std::jthread m_thread` or `std::thread m_thread`: The thread for running the timer loop. +- `std::priority_queue m_taskQueue`: The priority queue for scheduled tasks. +- `std::mutex m_mutex`: Mutex for thread synchronization. +- `std::condition_variable m_cond`: Condition variable for thread synchronization. +- `std::function m_callback`: The callback function to be called when a task is executed. +- `bool m_stop`: Flag indicating whether the timer should stop. +- `bool m_paused`: Flag indicating whether the timer is paused. + +### Example Usage + +```cpp +// Create a Timer object +Timer timer; + +// Schedule a task to be executed once after 1000 milliseconds +auto future = timer.setTimeout([]() { + std::cout << "Task executed!" << std::endl; +}, 1000); + +// Schedule a task to be repeated every 500 milliseconds, 5 times +timer.setInterval([]() { + std::cout << "Repeated task" << std::endl; +}, 500, 5, 1); + +// Pause the timer +timer.pause(); + +// Resume the timer +timer.resume(); + +// Stop the timer +timer.stop(); +``` diff --git a/doc/atom/async/trigger.md b/doc/atom/async/trigger.md new file mode 100644 index 00000000..3bc8debc --- /dev/null +++ b/doc/atom/async/trigger.md @@ -0,0 +1,73 @@ +# Trigger Class + +The `Trigger` class provides a mechanism to register callbacks for specific events and trigger those callbacks when the events occur. It supports registering callbacks with different priorities, scheduling triggers with delays, and asynchronous triggering of events. + +## Usage Example + +```cpp +// Define a Trigger object with int parameter type +Trigger trigger; + +// Define a callback function +Trigger::Callback callback = [](int param) { + std::cout << "Callback triggered with param: " << param << std::endl; +}; + +// Register the callback for an event +trigger.registerCallback("event1", callback, Trigger::CallbackPriority::Normal); + +// Trigger the event with parameter 42 +trigger.trigger("event1", 42); +``` + +## Methods + +### `registerCallback` + +Register a callback function for a specific event. + +### `unregisterCallback` + +Unregister a callback function for a specific event. + +### `trigger` + +Trigger the callback functions registered for a specific event. + +### `scheduleTrigger` + +Schedule the triggering of an event with a specified delay. + +### `scheduleAsyncTrigger` + +Schedule the asynchronous triggering of an event and return a future object. + +### `cancelTrigger` + +Cancel the scheduled triggering of a specific event. + +### `cancelAllTriggers` + +Cancel the scheduled triggering of all events. + +## Private Members + +- `m_mutex`: Mutex used for synchronizing access to the callback data structure. +- `m_callbacks`: Hash map to store registered callbacks for events. + +### Example Usage of Scheduling a Trigger + +```cpp +// Schedule a trigger with a delay of 500 milliseconds +trigger.scheduleTrigger("event2", 55, std::chrono::milliseconds(500)); +``` + +### Example Usage of Asynchronous Triggering + +```cpp +// Schedule an asynchronous trigger and get a future object +std::future future = trigger.scheduleAsyncTrigger("event3", 77); + +// Wait for the asynchronous trigger to complete +future.wait(); +``` diff --git a/doc/atom/connection/fifoclient.md b/doc/atom/connection/fifoclient.md new file mode 100644 index 00000000..a215df71 --- /dev/null +++ b/doc/atom/connection/fifoclient.md @@ -0,0 +1,42 @@ +# FifoClient Class + +The `FifoClient` class provides functionality to connect to a FIFO pipe, send messages through the pipe, and disconnect from the pipe. + +## Usage Example + +```cpp +// Create a FifoClient object with a specified FIFO path +FifoClient client("/path/to/fifo"); + +// Connect to the FIFO pipe +client.connect(); + +// Send a message through the FIFO pipe +client.sendMessage("Hello, FIFO!"); + +// Disconnect from the FIFO pipe +client.disconnect(); +``` + +## Methods + +### `FifoClient` + +Constructor for initializing the FifoClient with the FIFO pipe path. + +### `connect` + +Connects to the FIFO pipe. + +### `sendMessage` + +Sends a message through the FIFO pipe. + +### `disconnect` + +Disconnects from the FIFO pipe. + +## Private Members + +- `fifoPath`: The path to the FIFO pipe. +- `pipeHandle` (Windows) / `pipeFd` (Unix/Linux): Handle or file descriptor for the FIFO pipe. diff --git a/doc/atom/connection/fifoserver.md b/doc/atom/connection/fifoserver.md new file mode 100644 index 00000000..b52fb451 --- /dev/null +++ b/doc/atom/connection/fifoserver.md @@ -0,0 +1,44 @@ +# FifoServer Class + +The `FifoServer` class provides functionality to start a server that listens on a FIFO pipe, receive messages from the pipe, and stop the server. + +## Usage Example + +```cpp +// Create a FifoServer object with a specified FIFO path +FifoServer server("/path/to/fifo"); + +// Start the FIFO server to listen for incoming messages +server.start(); + +// Receive a message from the FIFO pipe +std::string message = server.receiveMessage(); +std::cout << "Received message: " << message << std::endl; + +// Stop the FIFO server +server.stop(); +``` + +## Methods + +### `FifoServer` + +Constructor for initializing the FifoServer with the FIFO pipe path. + +### `start` + +Starts the FIFO server to listen for incoming messages. + +### `receiveMessage` + +Receives a message from the FIFO pipe and returns it as a string. + +### `stop` + +Stops the FIFO server. + +## Private Members + +- `fifoPath`: The path to the FIFO pipe. +- `bufferSize`: The size of the buffer for receiving messages. +- `pipeHandle` (Windows) / `pipeFd` (Unix/Linux): Handle or file descriptor for the FIFO pipe. diff --git a/doc/atom/connection/shared_memory.md b/doc/atom/connection/shared_memory.md new file mode 100644 index 00000000..44c16120 --- /dev/null +++ b/doc/atom/connection/shared_memory.md @@ -0,0 +1,92 @@ +# SharedMemory Class + +## Overview + +The `SharedMemory` class provides a way to implement shared memory for inter-process communication. It allows data to be written to and read from shared memory, with support for synchronization and thread safety. + +## Constructor + +### Signature + +```cpp +explicit SharedMemory(const std::string &name, bool create = true); +``` + +### Example + +```cpp +SharedMemory sharedMem("example_shared_mem", true); +``` + +## Destructor + +### Signature + +```cpp +~SharedMemory(); +``` + +## Methods + +### 1. write + +#### Signature + +```cpp +void write(const T &data, std::chrono::milliseconds timeout = std::chrono::milliseconds(0)); +``` + +#### Example + +```cpp +int dataToWrite = 42; +sharedMem.write(dataToWrite); +``` + +### 2. read + +#### Signature + +```cpp +T read(std::chrono::milliseconds timeout = std::chrono::milliseconds(0)) const; +``` + +#### Example + +```cpp +int dataRead = sharedMem.read(); +``` + +### 3. clear + +#### Signature + +```cpp +void clear(); +``` + +#### Example + +```cpp +sharedMem.clear(); +``` + +### 4. isOccupied + +#### Signature + +```cpp +bool isOccupied() const; +``` + +#### Example + +```cpp +bool occupied = sharedMem.isOccupied(); +``` + +## Usage Notes + +- The template type `T` must be trivially copyable and have a standard layout. +- The class provides support for both Windows and Unix-like systems for shared memory management. +- Mutual exclusion is ensured using an atomic flag and mutex to maintain data consistency in concurrent access scenarios. diff --git a/doc/atom/connection/sockethub.md b/doc/atom/connection/sockethub.md new file mode 100644 index 00000000..ed4be61a --- /dev/null +++ b/doc/atom/connection/sockethub.md @@ -0,0 +1,128 @@ +# SocketHub Class Documentation + +The `SocketHub` class is designed to manage socket connections and provides functionalities for starting and stopping a socket service while managing multiple client connections. + +## Constructor + +### SocketHub() + +This is the constructor for the `SocketHub` class. + +#### Example + +```cpp +SocketHub socket; // Create an instance of the SocketHub class +``` + +## Destructor + +### ~SocketHub() + +The destructor is responsible for cleaning up resources associated with the `SocketHub` class instance. + +#### Example + +```cpp +SocketHub* socket = new SocketHub(); +delete socket; // Cleanup resources when the object is no longer needed +``` + +## Public Methods + +### void start(int port) + +Starts the socket service and listens on the specified port. + +#### Parameters + +- `port`: The port number to listen on. + +#### Example + +```cpp +SocketHub socket; +socket.start(8080); // Start the socket service on port 8080 +``` + +### void stop() + +Stops the socket service and closes all connections. + +#### Example + +```cpp +socket.stop(); // Stop the socket service and close all connections +``` + +### void addHandler(std::function handler) + +Adds a message handler to the `SocketHub`. + +#### Parameters + +- `handler`: The message handler function. + +#### Example + +```cpp +void handleMessage(std::string message) { + // Handle the incoming message + std::cout << "Received message: " << message << std::endl; +} + +SocketHub socket; +socket.addHandler(handleMessage); // Add the message handling function +``` + +## Private Methods + +### bool initWinsock() + +Initializes Winsock. + +#### Returns + +- `true` on success, `false` on failure. + +### void cleanupWinsock() + +Cleans up Winsock resources. + +### void closeSocket(SOCKET socket) / void closeSocket(int socket) + +Closes the specified socket. + +### void acceptConnections() + +Accepts client connections and adds them to the clients list. + +### void handleClientMessages(SOCKET clientSocket) / void handleClientMessages(int clientSocket) + +Handles messages from a client. + +### void cleanupSocket() + +Cleans up socket resources, closing all client connections. + +These private methods are used internally by the `SocketHub` class and are not intended for direct usage by external code. + +## Usage + +```cpp +int main() { + SocketHub socket; + socket.start(8080); + + // Define a message handling function + auto handleMessage = [](std::string message) { + std::cout << "Received message: " << message << std::endl; + }; + + socket.addHandler(handleMessage); + + // Other operations... + + socket.stop(); + return 0; +} +``` diff --git a/doc/atom/connection/sshclient.md b/doc/atom/connection/sshclient.md new file mode 100644 index 00000000..b0e2e5ed --- /dev/null +++ b/doc/atom/connection/sshclient.md @@ -0,0 +1,109 @@ +# SSHClient Class Documentation + +## Overview + +The `SSHClient` class provides functionality for SSH client connection and various file operations on a remote server. + +### Class Definition + +```cpp +class SSHClient { +public: + explicit SSHClient(const std::string &host, int port = 22); + ~SSHClient(); + + void Connect(const std::string &username, const std::string &password, int timeout = 10); + bool IsConnected(); + void Disconnect(); + void ExecuteCommand(const std::string &command, std::vector &output); + void ExecuteCommands(const std::vector &commands, std::vector> &output); + bool FileExists(const std::string &remote_path); + void CreateDirectory(const std::string &remote_path, int mode = S_NORMAL); + void RemoveFile(const std::string &remote_path); + void RemoveDirectory(const std::string &remote_path); + std::vector ListDirectory(const std::string &remote_path); + void Rename(const std::string &old_path, const std::string &new_path); + void GetFileInfo(const std::string &remote_path, sftp_attributes &attrs); + void DownloadFile(const std::string &remote_path, const std::string &local_path); + void UploadFile(const std::string &local_path, const std::string &remote_path); + +private: + std::string m_host; + int m_port; + ssh_session m_ssh_session; + sftp_session m_sftp_session; +}; +``` + +## Constructor + +### Description + +Creates an instance of the `SSHClient` class with the specified host and port. + +### Example + +```cpp +SSHClient ssh("example.com", 22); +``` + +## Connect + +### Description + +Connects to the SSH server using provided credentials. + +### Example + +```cpp +ssh.Connect("username", "password"); +``` + +## ExecuteCommand + +### Description + +Executes a single command on the SSH server and retrieves the output. + +### Example + +```cpp +std::vector output; +ssh.ExecuteCommand("ls -l", output); +``` + +## ListDirectory + +### Description + +Lists the contents of a directory on the remote server. + +### Example + +```cpp +std::vector contents = ssh.ListDirectory("/path/to/directory"); +``` + +## DownloadFile + +### Description + +Downloads a file from the remote server to a local destination. + +### Example + +```cpp +ssh.DownloadFile("/path/to/remote/file.txt", "/path/to/local/file.txt"); +``` + +## UploadFile + +### Description + +Uploads a local file to the remote server. + +### Example + +```cpp +ssh.UploadFile("/path/to/local/file.txt", "/path/to/remote/file.txt"); +``` diff --git a/doc/atom/connection/udp_server.md b/doc/atom/connection/udp_server.md new file mode 100644 index 00000000..4b7bd908 --- /dev/null +++ b/doc/atom/connection/udp_server.md @@ -0,0 +1,103 @@ +# UdpSocketHub Class + +## Description + +The `UdpSocketHub` class is a simple UDP socket server class that handles incoming messages and allows sending messages to specified addresses. + +## Constructor + +### `UdpSocketHub()` + +- Initializes the server state. + +#### Example + +```cpp +UdpSocketHub udpServer; +``` + +## Destructor + +### `~UdpSocketHub()` + +- Ensures proper resource cleanup. + +## Methods + +### `start(int port)` + +- Starts the UDP server on the specified port. + +#### Parameters + +- `port`: The port number on which the server will listen for incoming messages. + +#### Example + +```cpp +udpServer.start(8888); +``` + +### `stop()` + +- Stops the server and cleans up resources. + +#### Example + +```cpp +udpServer.stop(); +``` + +### `addHandler(std::function handler)` + +- Adds a message handler function that will be called whenever a new message is received. + +#### Parameters + +- `handler`: A function to handle incoming messages. It takes a string as input. + +#### Example + +```cpp +udpServer.addHandler([](std::string message) { + std::cout << "Received message: " << message << std::endl; +}); +``` + +### `sendTo(const std::string &message, const std::string &ip, int port)` + +- Sends a message to the specified IP address and port. + +#### Parameters + +- `message`: The message to be sent. +- `ip`: The target IP address. +- `port`: The target port number. + +#### Example + +```cpp +udpServer.sendTo("Hello, UDP!", "192.168.1.100", 9999); +``` + +## Private Members + +- `m_running`: Indicates whether the server is running. +- `m_serverSocket`: The socket descriptor for the server. +- `m_acceptThread`: The thread for handling incoming messages. +- `m_handler`: The function to handle incoming messages. + +### Private Methods + +#### `initNetworking()` + +- Initializes networking. Required for Windows. +- Returns true if successful, false otherwise. + +#### `cleanupNetworking()` + +- Cleans up networking resources. Required for Windows. + +#### `handleMessages()` + +- The main loop for receiving messages. Runs in a separate thread. diff --git a/doc/atom/io/compress.md b/doc/atom/io/compress.md new file mode 100644 index 00000000..eef7f09f --- /dev/null +++ b/doc/atom/io/compress.md @@ -0,0 +1,41 @@ +# File Compression and Decompression Functions + +## compress_file + +Compresses a single file by adding the .gz suffix to the file name. + +```cpp +bool success = compress_file("/path/to/file.txt", "/output/folder"); +``` + +## decompress_file + +Decompresses a single compressed file by removing the .gz suffix from the file name. + +```cpp +bool success = decompress_file("/path/to/compressed_file.gz", "/output/folder"); +``` + +## compress_folder + +Compresses all files in a specified folder by adding the .gz suffix to each file. + +```cpp +bool success = compress_folder("/absolute/path/to/folder"); +``` + +## create_zip + +Creates a ZIP file containing the contents of a specified folder. + +```cpp +bool success = create_zip("/source/folder", "/output/archive.zip"); +``` + +## extract_zip + +Extracts the contents of a ZIP file to a specified destination folder. + +```cpp +bool success = extract_zip("/source/archive.zip", "/destination/folder"); +``` diff --git a/doc/atom/io/file.md b/doc/atom/io/file.md new file mode 100644 index 00000000..c7b796cf --- /dev/null +++ b/doc/atom/io/file.md @@ -0,0 +1,84 @@ +# FileManager Class + +## Brief + +The FileManager class provides functionality for creating, opening, reading, writing, moving, and deleting files. + +## Constructor + +```cpp +FileManager fileManager; +``` + +## createFile + +Creates a new file with the given filename. + +```cpp +bool success = fileManager.createFile("example.txt"); +``` + +## openFile + +Opens an existing file with the specified filename. + +```cpp +bool success = fileManager.openFile("example.txt"); +``` + +## readFile + +Reads the contents of the currently open file into a string variable. + +```cpp +std::string contents; +bool success = fileManager.readFile(contents); +``` + +## writeFile + +Writes the provided content to the currently open file. + +```cpp +bool success = fileManager.writeFile("This is some text to write to the file."); +``` + +## moveFile + +Moves a file from the old filename to the new filename. + +```cpp +bool success = fileManager.moveFile("old_file.txt", "new_file.txt"); +``` + +## deleteFile + +Deletes the file with the given filename. + +```cpp +bool success = fileManager.deleteFile("file_to_delete.txt"); +``` + +## getFileSize + +Gets the size of the currently open file in bytes. + +```cpp +long fileSize = fileManager.getFileSize(); +``` + +## calculateSHA256 + +Calculates the SHA256 hash of the currently open file. + +```cpp +std::string hash = fileManager.calculateSHA256(); +``` + +## getFileDirectory + +Static method to get the directory path of a file. + +```cpp +std::string directory = FileManager::getFileDirectory("path/to/file.txt"); +``` diff --git a/doc/atom/io/io.md b/doc/atom/io/io.md new file mode 100644 index 00000000..f70144ff --- /dev/null +++ b/doc/atom/io/io.md @@ -0,0 +1,202 @@ +# File and Directory Manipulation Functions + +## createDirectory + +Creates a directory with the specified path. + +```cpp +bool success = createDirectory("/path/to/directory"); +``` + +## createDirectory (overload) + +Creates a directory with the specified date and root directory. + +```cpp +createDirectory("2024-03-25", "/root/directory"); +``` + +## removeDirectory + +Removes an empty directory with the specified path. + +```cpp +bool success = removeDirectory("/path/to/directory"); +``` + +## renameDirectory + +Renames a directory with the specified old and new paths. + +```cpp +bool success = renameDirectory("/old/path", "/new/path"); +``` + +## moveDirectory + +Moves a directory from one path to another. + +```cpp +bool success = moveDirectory("/old/path", "/new/path"); +``` + +## copyFile + +Copies a file from source path to destination path. + +```cpp +bool success = copyFile("/source/file.txt", "/destination/file.txt"); +``` + +## moveFile + +Moves a file from source path to destination path. + +```cpp +bool success = moveFile("/source/file.txt", "/destination/file.txt"); +``` + +## renameFile + +Renames a file with the specified old and new paths. + +```cpp +bool success = renameFile("/old/file.txt", "/new/file.txt"); +``` + +## removeFile + +Removes a file with the specified path. + +```cpp +bool success = removeFile("/path/to/file.txt"); +``` + +## createSymlink + +Creates a symbolic link with the specified target and symlink paths. + +```cpp +bool success = createSymlink("/target/file.txt", "/symlink/file.txt"); +``` + +## removeSymlink + +Removes a symbolic link with the specified path. + +```cpp +bool success = removeSymlink("/path/to/symlink"); +``` + +## fileSize + +Returns the size of a file in bytes. + +```cpp +std::uintmax_t size = fileSize("/path/to/file.txt"); +``` + +## traverseDirectories + +Traverse the directories recursively and collect all folder paths. + +```cpp +std::vector folders; +traverseDirectories("/start/directory", folders); +``` + +## convertToLinuxPath + +Convert Windows path to Linux path. + +```cpp +std::string linuxPath = convertToLinuxPath("C:\\Windows\\file.txt"); +``` + +## convertToWindowsPath + +Convert Linux path to Windows path. + +```cpp +std::string windowsPath = convertToWindowsPath("/home/user/file.txt"); +``` + +## isFolderNameValid + +Check if the folder name is valid. + +```cpp +bool valid = isFolderNameValid("folder_name"); +``` + +## isFileNameValid + +Check if the file name is valid. + +```cpp +bool valid = isFileNameValid("file_name.txt"); +``` + +## isFolderExists + +Check if the folder exists. + +```cpp +bool exists = isFolderExists("/path/to/folder"); +``` + +## isFileExists + +Check if the file exists. + +```cpp +bool exists = isFileExists("/path/to/file.txt"); +``` + +## isFolderEmpty + +Check if the folder is empty. + +```cpp +bool empty = isFolderEmpty("/path/to/folder"); +``` + +## isAbsolutePath + +Check if the path is an absolute path. + +```cpp +bool absolute = isAbsolutePath("/absolute/path"); +``` + +## normPath + +Normalize a given path. + +```cpp +std::string normalizedPath = normPath("/path/to/normalize"); +``` + +## changeWorkingDirectory + +Change the current working directory. + +```cpp +bool success = changeWorkingDirectory("/new/work/directory"); +``` + +## getFileTimes + +Get the creation and modification times of a file. + +```cpp +std::pair times = getFileTimes("/path/to/file.txt"); +``` + +## checkFileTypeInFolder + +Check the file type in a folder. + +```cpp +std::vector filePaths = checkFileTypeInFolder("/path/to/folder", "txt", FileOption::Extension); +``` diff --git a/doc/atom/log/global_logger.md b/doc/atom/log/global_logger.md new file mode 100644 index 00000000..0e24fae3 --- /dev/null +++ b/doc/atom/log/global_logger.md @@ -0,0 +1,68 @@ +# Logger Class + +## Brief + +The Logger class provides logging functionality with support for dynamic log level adjustment, asynchronous logging, and multiple subscribers. + +## Constructor + +```cpp +Logger logger; +``` + +## addSubscriber + +Adds a subscriber to receive log messages. + +```cpp +class CustomSubscriber : public Logger::Subscriber { +public: + void log(LogLevel level, const std::string &message) override { + // Custom log handling + } +}; + +std::shared_ptr subscriber = std::make_shared(); +logger.addSubscriber(subscriber); +``` + +## setLogLevel + +Sets the log level for filtering log messages. + +```cpp +logger.setLogLevel(LogLevel::Info); +``` + +## log + +Logs a message with the specified log level. + +```cpp +logger.log(LogLevel::Error, "An error message"); +``` + +## getLogLevelString + +Gets the string representation of a log level. + +```cpp +std::string levelString = Logger::getLogLevelString(LogLevel::Debug); +// Expected output: "Debug" +``` + +## workerFunction + +Worker function for asynchronous processing of log messages. + +```cpp +std::thread workerThread(&Logger::workerFunction, &logger); +``` + +## writeToLogFile + +Writes a log message to a log file. + +```cpp +logger.writeToLogFile("Error", "An error message"); +``` diff --git a/doc/atom/log/logger.md b/doc/atom/log/logger.md new file mode 100644 index 00000000..a45a5c22 --- /dev/null +++ b/doc/atom/log/logger.md @@ -0,0 +1,91 @@ +# LoggerManager Class + +## Brief + +The LoggerManager class is used for scanning, analyzing, and uploading log files. + +## Constructor + +```cpp +LoggerManager loggerManager; +``` + +## scanLogsFolder + +Scans log files in a specified folder. + +```cpp +loggerManager.scanLogsFolder("/path/to/folder"); +``` + +## searchLogs + +Searches for log entries containing a specific keyword. + +```cpp +std::vector foundLogs = loggerManager.searchLogs("error"); +``` + +- Ensure that the `LogEntry` structure is defined and contains necessary log information. + +## uploadFile + +Uploads a specific file. + +```cpp +loggerManager.uploadFile("/path/to/file"); +``` + +## analyzeLogs + +Analyzes the content of log files. + +```cpp +loggerManager.analyzeLogs(); +``` + +- This method performs various log analysis tasks. + +## parseLog + +Parses a log file. + +```cpp +loggerManager.parseLog("/path/to/logfile.log"); +``` + +## extractErrorMessages + +Extracts error messages from log entries. + +```cpp +std::vector errors = loggerManager.extractErrorMessages(); +``` + +## computeMd5Hash + +Calculates the MD5 hash value of a file. + +```cpp +std::string md5Hash = loggerManager.computeMd5Hash("/path/to/file"); +``` + +## getErrorType + +Gets the error type from an error message. + +```cpp +std::string errorType = loggerManager.getErrorType("Error: Something went wrong"); +``` + +## getMostCommonErrorMessage + +Gets the most common error message from a collection of error messages. + +```cpp +std::string commonError = loggerManager.getMostCommonErrorMessage(errors); +``` + +--- + +The `LoggerManager` class provides functionality for managing log files, including scanning, searching, analyzing, and uploading. It also offers methods for parsing logs, extracting error messages, computing MD5 hashes, and finding common error messages. Utilize these features to effectively manage and analyze log data in your application. diff --git a/doc/atom/log/syslog.md b/doc/atom/log/syslog.md new file mode 100644 index 00000000..d58b82e2 --- /dev/null +++ b/doc/atom/log/syslog.md @@ -0,0 +1,108 @@ +# SyslogWrapper Class + +The `SyslogWrapper` class encapsulates the functionality of system logging. + +## Constructor + +## `SyslogWrapper()` + +- Default constructor sets log level to `Info` and outputs to "Event". + +```cpp +SyslogWrapper logger; +logger.info("System initialized."); // Expected output: [Info] System initialized. +``` + +## `SyslogWrapper(LogLevel logLevel, const std::string &target = "")` + +- Constructor with parameters to specify log level and output target. + +```cpp +SyslogWrapper customLogger(LogLevel::Warning, "Console"); +customLogger.warning("Memory low"); // Expected output: [Warning] Memory low +``` + +## Destructor + +## `~SyslogWrapper() noexcept` + +- Destructor to close handles or perform cleanup tasks. + +## Logging Methods + +## `void log(LogLevel level, const char *format, Args &&...args)` + +- Log method supporting formatted strings with variable arguments. + +```cpp +logger.log(LogLevel::Debug, "Value: %d", 42); // Expected output: [Debug] Value: 42 +``` + +## `void log(LogLevel level, const char *format, Arg &&arg, Args &&...args)` + +- Overloaded log method for a single argument followed by variable arguments. + +```cpp +customLogger.log(LogLevel::Error, "Error code: %d", 404, "Not Found"); // Expected output: [Error] Error code: 404 Not Found +``` + +## Log Level Methods + +## `void setLogLevel(LogLevel logLevel)` + +- Set the log level. + +```cpp +logger.setLogLevel(LogLevel::Error); +logger.info("This info message will not be logged."); // No output +``` + +## `LogLevel getLogLevel() const` + +- Get the current log level. + +## Logging Convenience Methods + +## `void debug(const char *format, Args &&...args)` + +- Log debug information. + +```cpp +logger.debug("Debug message: %s", "Debugging in progress"); // Expected output: [Debug] Debug message: Debugging in progress +``` + +## `void info(const char *format, Args &&...args)` + +- Log information. + +```cpp +logger.info("Information: %s", "System is running smoothly"); // Expected output: [Info] Information: System is running smoothly +``` + +## `void warning(const char *format, Args &&...args)` + +- Log warning information. + +```cpp +logger.warning("Warning: %s", "Low disk space"); // Expected output: [Warning] Warning: Low disk space +``` + +## `void error(const char *format, Args &&...args)` + +- Log error information. + +```cpp +logger.error("Error: %s", "File not found"); // Expected output: [Error] Error: File not found +``` + +## Private Members + +- `HANDLE m_eventHandle;` (Windows specific) +- `std::string m_target;` +- `LogLevel m_logLevel;` +- `std::mutex m_mutex;` + +## Special Note: + +- Ensure proper synchronization while accessing logging methods in a multithreaded environment by using the mutex `m_mutex`. +- Make sure to handle platform-specific considerations when using `m_eventHandle`. diff --git a/doc/atom/search/cache.md b/doc/atom/search/cache.md new file mode 100644 index 00000000..c2890a0c --- /dev/null +++ b/doc/atom/search/cache.md @@ -0,0 +1,363 @@ +# ResourceCache Class Documentation + +The ResourceCache class provides a cache for storing and managing resources of type T. It supports functionalities to insert, retrieve, remove, and manage resources with expiration times. This document provides an overview of the class and usage examples for each member function. + +## Class Template + +```cpp +template +class ResourceCache { + // ... (class definition as provided) +}; +``` + +## Constructor + +### ResourceCache(int maxSize) + +Constructs a ResourceCache with a maximum size. + +#### Usage Example + +```cpp +// Create a cache with a maximum size of 100 +ResourceCache cache(100); +``` + +--- + +## Member Functions + +### insert + +Inserts a resource into the cache with an expiration time. + +```cpp +void insert(const std::string &key, const T &value, std::chrono::seconds expirationTime); +``` + +#### Usage Example + +```cpp +// Insert a resource with key "data1", value 42, and expiration time of 60 seconds +cache.insert("data1", 42, std::chrono::seconds(60)); +``` + +### contains + +Checks if the cache contains a resource with the given key. + +```cpp +bool contains(const std::string &key) const; +``` + +#### Usage Example + +```cpp +// Check if the cache contains the resource with key "data1" +if (cache.contains("data1")) { + std::cout << "Resource found in the cache." << std::endl; +} else { + std::cout << "Resource not found in the cache." << std::endl; +} +``` + +### get + +Retrieves a resource from the cache by key. + +```cpp +const T &get(const std::string &key); +``` + +#### Usage Example + +```cpp +// Retrieve the resource with key "data1" from the cache +int data = cache.get("data1"); +std::cout << "Retrieved data: " << data << std::endl; +``` + +### remove + +Removes a resource from the cache by key. + +```cpp +void remove(const std::string &key); +``` + +#### Usage Example + +```cpp +// Remove the resource with key "data1" from the cache +cache.remove("data1"); +``` + +### asyncGet + +Retrieves a resource from the cache by key asynchronously. + +```cpp +std::future asyncGet(const std::string &key); +``` + +#### Usage Example + +```cpp +// Retrieve the resource with key "data1" from the cache asynchronously +std::future futureData = cache.asyncGet("data1"); +// Wait for the future and get the retrieved data +int data = futureData.get(); +std::cout << "Retrieved data: " << data << std::endl; +``` + +### asyncInsert + +Inserts a resource into the cache with an expiration time asynchronously. + +```cpp +std::future asyncInsert(const std::string &key, const T &value, const std::chrono::seconds &expirationTime); +``` + +#### Usage Example + +```cpp +// Insert a resource with key "data1", value 42, and expiration time of 60 seconds asynchronously +auto futureInsert = cache.asyncInsert("data1", 42, std::chrono::seconds(60)); +// Wait for the insertion to complete +futureInsert.wait(); +``` + +### clear + +Clears the cache. + +```cpp +void clear(); +``` + +#### Usage Example + +```cpp +// Clear the cache +cache.clear(); +``` + +### size + +Returns the number of elements in the cache. + +```cpp +size_t size() const; +``` + +#### Usage Example + +```cpp +// Get the number of elements in the cache +size_t numElements = cache.size(); +std::cout << "Number of elements in the cache: " << numElements << std::endl; +``` + +### empty + +Checks if the cache is empty. + +```cpp +bool empty() const; +``` + +#### Usage Example + +```cpp +// Check if the cache is empty +if (cache.empty()) { + std::cout << "The cache is empty." << std::endl; +} else { + std::cout << "The cache is not empty." << std::endl; +} +``` + +### evictOldest + +Evicts the oldest resource from the cache. + +```cpp +void evictOldest(); +``` + +#### Usage Example + +```cpp +// Evict the oldest resource from the cache +cache.evictOldest(); +``` + +### isExpired + +Checks if a resource with the given key has expired. + +```cpp +bool isExpired(const std::string &key) const; +``` + +#### Usage Example + +```cpp +// Check if the resource with key "data1" has expired +if (cache.isExpired("data1")) { + std::cout << "The resource has expired." << std::endl; +} else { + std::cout << "The resource has not expired." << std::endl; +} +``` + +### asyncLoad + +Loads a resource asynchronously. + +```cpp +std::future asyncLoad(const std::string &key, std::function loadDataFunction); +``` + +#### Usage Example + +```cpp +// Load the resource with key "data1" asynchronously using a custom load function +std::future futureLoad = cache.asyncLoad("data1", []() { + // Custom load function implementation + return 42; +}); +// Wait for the loading to complete +futureLoad.wait(); +``` + +### setMaxSize + +Sets the maximum size of the cache. + +```cpp +void setMaxSize(int maxSize); +``` + +#### Usage Example + +```cpp +// Set the maximum size of the cache to 200 +cache.setMaxSize(200); +``` + +### setExpirationTime + +Sets the expiration time of a resource. + +```cpp +void setExpirationTime(const std::string &key, std::chrono::seconds expirationTime); +``` + +#### Usage Example + +```cpp +// Set the expiration time of the resource with key "data1" to 120 seconds +cache.setExpirationTime("data1", std::chrono::seconds(120)); +``` + +### readFromFile + +Reads a resource from a file asynchronously. + +```cpp +void readFromFile(const std::string &filePath, const std::function &deserializer); +``` + +#### Usage Example + +```cpp +// Read a resource from a file asynchronously and deserialize using a custom deserializer function +cache.readFromFile("data.txt", [](const std::string &data) { + // Custom deserialization logic + return stoi(data); +}); +``` + +### writeToFile + +Writes a resource to a file asynchronously. + +```cpp +void writeToFile(const std::string &filePath, const std::function &serializer); +``` + +#### Usage Example + +```cpp +// Write a resource to a file asynchronously using a custom serializer function +cache.writeToFile("data.txt", [](const int &data) { + // Custom serialization logic + return std::to_string(data); +}); +``` + +### removeExpired + +Removes expired resources from the cache. + +```cpp +void removeExpired(); +``` + +#### Usage Example + +```cpp +// Remove expired resources from the cache +cache.removeExpired(); +``` + +### readFromJsonFile + +Reads a resource from a JSON file asynchronously. + +```cpp +void readFromJsonFile(const std::string &filePath, const std::function &fromJson); +``` + +#### Usage Example + +```cpp +// Read a resource from a JSON file asynchronously and deserialize using a custom function +cache.readFromJsonFile("data.json", [](const json &jsonData) { + // Custom deserialization from JSON logic + return jsonData.get(); +}); +``` + +### writeToJsonFile + +Writes a resource to a JSON file asynchronously. + +```cpp +void writeToJsonFile(const std::string &filePath, const std::function &toJson); +``` + +#### Usage Example + +```cpp +// Write a resource to a JSON file asynchronously using a custom function +cache.writeToJsonFile("data.json", [](const T &data) { + // Custom serialization to JSON logic + json jsonData = data; // Assuming T is convertible to json + return jsonData; +}); +``` + +## Private Member Function + +### evict + +Evicts the oldest resource from the cache. + +Note: This function is not intended for external use. + +```cpp +void evict(); +``` diff --git a/doc/atom/search/mysql.md b/doc/atom/search/mysql.md new file mode 100644 index 00000000..3e6d0be2 --- /dev/null +++ b/doc/atom/search/mysql.md @@ -0,0 +1,325 @@ +# MysqlDB Class Documentation + +## Introduction + +The `MysqlDB` class provides functionalities to interact with a MySQL database. It allows executing queries, retrieving data, and managing transactions. + +### Example Usage + +```cpp +// Instantiate MysqlDB object +MysqlDB db("localhost", "root", "password", "my_database"); +``` + +## Constructor + +### Method Signature + +```cpp +explicit MysqlDB(const char *host, const char *user, const char *password, const char *database); +``` + +### Usage Example + +```cpp +MysqlDB db("localhost", "root", "password", "my_database"); +``` + +### Expected Output + +No output if successful. May throw an exception if connection fails. + +## Destructor + +### Method Signature + +```cpp +~MysqlDB(); +``` + +### Usage Example + +```cpp +// Destructor is called automatically when object goes out of scope +``` + +### Expected Output + +Closes the database connection. + +## executeQuery + +### Method Signature + +```cpp +bool executeQuery(const char *query); +``` + +### Usage Example + +```cpp +bool success = db.executeQuery("INSERT INTO table_name (column1, column2) VALUES (value1, value2)"); +``` + +### Expected Output + +Returns true if the query was successfully executed, false otherwise. + +## selectData + +### Method Signature + +```cpp +void selectData(const char *query); +``` + +### Usage Example + +```cpp +db.selectData("SELECT * FROM table_name"); +``` + +### Expected Output + +Prints the result of the SELECT query. + +## getIntValue + +### Method Signature + +```cpp +int getIntValue(const char *query); +``` + +### Usage Example + +```cpp +int result = db.getIntValue("SELECT COUNT(*) FROM table_name"); +``` + +### Expected Output + +Returns the integer value from the query result. + +## getDoubleValue + +### Method Signature + +```cpp +double getDoubleValue(const char *query); +``` + +### Usage Example + +```cpp +double result = db.getDoubleValue("SELECT AVG(salary) FROM employee_table"); +``` + +### Expected Output + +Returns the double value from the query result. + +## getTextValue + +### Method Signature + +```cpp +const char *getTextValue(const char *query); +``` + +### Usage Example + +```cpp +const char *text = db.getTextValue("SELECT name FROM user_table WHERE id=1"); +``` + +### Expected Output + +Returns the text value from the query result. Note Caller must handle memory management appropriately. + +## searchData + +### Method Signature + +```cpp +bool searchData(const char *query, const char *searchTerm); +``` + +### Usage Example + +```cpp +bool found = db.searchData("SELECT title FROM article_table", "MySQL"); +``` + +### Expected Output + +Returns true if the search term is found in the query result, false otherwise. + +## updateData + +### Method Signature + +```cpp +bool updateData(const char *query); +``` + +### Usage Example + +```cpp +bool success = db.updateData("UPDATE employee_table SET salary=60000 WHERE id=123"); +``` + +### Expected Output + +Returns true if the data was successfully updated, false otherwise. + +## deleteData + +### Method Signature + +```cpp +bool deleteData(const char *query); +``` + +### Usage Example + +```cpp +bool success = db.deleteData("DELETE FROM student_table WHERE graduation_year<2020"); +``` + +### Expected Output + +Returns true if the data was successfully deleted, false otherwise. + +## beginTransaction + +### Method Signature + +```cpp +bool beginTransaction(); +``` + +### Usage Example + +```cpp +bool success = db.beginTransaction(); +``` + +### Expected Output + +Returns true if the transaction was successfully started, false otherwise. + +## commitTransaction + +### Method Signature + +```cpp +bool commitTransaction(); +``` + +### Usage Example + +```cpp +bool success = db.commitTransaction(); +``` + +### Expected Output + +Returns true if the transaction was successfully committed, false otherwise. + +## rollbackTransaction + +### Method Signature + +```cpp +bool rollbackTransaction(); +``` + +### Usage Example + +```cpp +bool success = db.rollbackTransaction(); +``` + +### Expected Output + +Returns true if the transaction was successfully rolled back, false otherwise. + +## handleMySQLError + +### Method Signature + +```cpp +void handleMySQLError(); +``` + +### Usage Example + +```cpp +// Typically called internally to handle errors +``` + +### Expected Output + +Prints the error message if there is any MySQL error. + +## validateData + +### Method Signature + +```cpp +bool validateData(const char *query, const char *validationQuery); +``` + +### Usage Example + +```cpp +bool isValid = db.validateData("SELECT * FROM user_table WHERE id=1", "SELECT COUNT(*) FROM user_table"); +``` + +### Expected Output + +Returns true if the data is valid according to the validation query, false otherwise. + +## selectDataWithPagination + +### Method Signature + +```cpp +void selectDataWithPagination(const char *query, int limit, int offset); +``` + +### Usage Example + +```cpp +db.selectDataWithPagination("SELECT * FROM large_table", 10, 0); +``` + +### Expected Output + +Prints the result of the SELECT query with pagination support. + +## setErrorMessageCallback + +### Method Signature + +```cpp +void setErrorMessageCallback(const stdfunction &errorCallback); +``` + +### Usage Example + +```cpp +db.setErrorMessageCallback([](const char *errorMessage) { + stdcerr << "Error " << errorMessage << stdendl; +}); +``` + +### Expected Output + +Sets a callback function for handling error messages. + +## Private Members + +- `MYSQL *db` Pointer to the MySQL connection handle. +- `stdfunction errorCallback` The callback function for error messages. diff --git a/doc/atom/search/search.md b/doc/atom/search/search.md new file mode 100644 index 00000000..e2a4fed4 --- /dev/null +++ b/doc/atom/search/search.md @@ -0,0 +1,91 @@ +# Matching Strategies Library + +## MatchStrategy Class + +Abstract base class for matching strategies. + +### Usage Example + +```cpp +MatchStrategy *strategy = new FuzzyMatch(); +std::vector result = strategy->match("query", index); +// Expected output: Vector of matched strings +``` + +--- + +## FuzzyMatch Class + +Fuzzy matching strategy based on edit distance. + +### Usage Example + +```cpp +FuzzyMatch fuzzy; +std::vector result = fuzzy.match("query", index, 3); +// Expected output: Vector of matched strings +``` + +--- + +## RegexMatch Class + +Regular expression matching strategy. + +### Usage Example + +```cpp +RegexMatch regex; +std::vector result = regex.match("query", index, 0); +// Expected output: Vector of matched strings +``` + +Note: Matching threshold is not used in this strategy. + +--- + +## HammingMatch Class + +Hamming distance matching strategy. + +### Usage Example + +```cpp +HammingMatch hamming(2); +std::vector result = hamming.match("query", index, 0); +// Expected output: Vector of matched strings +``` + +Note: Maximum Hamming distance allowed for a match is specified during object construction. + +--- + +## TfIdfMatch Class + +TF-IDF matching strategy. + +### Usage Example + +```cpp +std::vector data = {"data1", "data2"}; +TfIdfMatch tfidf(data); +std::vector result = tfidf.match("query", index, 0); +// Expected output: Vector of matched strings +``` + +--- + +## SearchEngine Class + +Search engine class that uses a specific matching strategy. + +### Usage Example + +```cpp +std::vector data = {"data1", "data2"}; +SearchEngine engine(data, new FuzzyMatch()); +engine.setMatchStrategy(new RegexMatch()); +engine.addData("newData"); +std::vector result = engine.search("query", 3); +// Expected output: Vector of matched strings +``` diff --git a/doc/atom/search/sqlite.md b/doc/atom/search/sqlite.md new file mode 100644 index 00000000..4851ba33 --- /dev/null +++ b/doc/atom/search/sqlite.md @@ -0,0 +1,243 @@ +# SqliteDB Class Documentation + +## Overview + +The `SqliteDB` class provides methods to interact with an SQLite database. It encapsulates functionality for executing queries, fetching data, updating records, and managing database transactions. + +### Constructor + +```cpp +SqliteDB(const char *dbPath); +``` + +#### Usage Example + +```cpp +SqliteDB db("path/to/database.db"); +``` + +--- + +## executeQuery Method + +Executes a query on the database. + +```cpp +bool executeQuery(const char *query); +``` + +#### Usage Example + +```cpp +bool success = db.executeQuery("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)"); +// Expected output: true if query execution is successful +``` + +--- + +## selectData Method + +Executes a SELECT query and fetches the data. + +```cpp +void selectData(const char *query); +``` + +#### Usage Example + +```cpp +db.selectData("SELECT * FROM users"); +// Expected output: Fetches and processes the data from the 'users' table +``` + +--- + +## getIntValue Method + +Fetches an integer value from the result of a query. + +```cpp +int getIntValue(const char *query); +``` + +#### Usage Example + +```cpp +int userId = db.getIntValue("SELECT id FROM users WHERE name='John'"); +// Expected output: Integer value representing the user ID +``` + +--- + +## getDoubleValue Method + +Fetches a double value from the result of a query. + +```cpp +double getDoubleValue(const char *query); +``` + +#### Usage Example + +```cpp +double averageAge = db.getDoubleValue("SELECT AVG(age) FROM users"); +// Expected output: Average age as a double value +``` + +--- + +## getTextValue Method + +Fetches a text value from the result of a query. + +```cpp +const unsigned char *getTextValue(const char *query); +``` + +#### Usage Example + +```cpp +const unsigned char *userName = db.getTextValue("SELECT name FROM users WHERE id=1"); +// Expected output: Text value representing the user's name +``` + +--- + +## searchData Method + +Searches for a specified term in the query result. + +```cpp +bool searchData(const char *query, const char *searchTerm); +``` + +#### Usage Example + +```cpp +bool found = db.searchData("SELECT * FROM users", "John"); +// Expected output: true if 'John' is found in the search results +``` + +--- + +## updateData Method + +Updates data in the database. + +```cpp +bool updateData(const char *query); +``` + +#### Usage Example + +```cpp +bool success = db.updateData("UPDATE users SET age=30 WHERE name='John'"); +// Expected output: true if the update operation is successful +``` + +--- + +## deleteData Method + +Deletes data from the database. + +```cpp +bool deleteData(const char *query); +``` + +#### Usage Example + +```cpp +bool success = db.deleteData("DELETE FROM users WHERE age>60"); +// Expected output: true if the delete operation is successful +``` + +--- + +## beginTransaction, commitTransaction, rollbackTransaction Methods + +Methods for managing database transactions. + +```cpp +bool beginTransaction(); +bool commitTransaction(); +bool rollbackTransaction(); +``` + +#### Usage Example + +```cpp +db.beginTransaction(); +// Perform multiple database operations +db.commitTransaction(); // or db.rollbackTransaction() if needed +``` + +--- + +## handleSQLError Method + +Handles SQLite errors. + +```cpp +void handleSQLError(); +``` + +#### Note + +This method is called internally to handle SQLite errors within the class. + +--- + +## validateData Method + +Validates data based on a specific query condition. + +```cpp +bool validateData(const char *query, const char *validationQuery); +``` + +#### Usage Example + +```cpp +bool valid = db.validateData("SELECT * FROM users WHERE age > 18", "SELECT COUNT(*) FROM users"); +// Expected output: true if the data meets the validation condition +``` + +--- + +## selectDataWithPagination Method + +Performs pagination on the query result and fetches data. + +```cpp +void selectDataWithPagination(const char *query, int limit, int offset); +``` + +#### Usage Example + +```cpp +db.selectDataWithPagination("SELECT * FROM users", 10, 0); +// Expected output: Fetches the first 10 records from the 'users' table +``` + +--- + +## setErrorMessageCallback Method + +Sets an error message callback function. + +```cpp +void setErrorMessageCallback(const std::function &errorCallback); +``` + +#### Usage Example + +```cpp +db.setErrorMessageCallback([](const char *errorMessage) { + std::cerr << "SQLite Error: " << errorMessage << std::endl; +}); +``` + +#### Note + +This method allows setting a custom error message handler for SQLite errors. diff --git a/doc/atom/serial/serial.md b/doc/atom/serial/serial.md new file mode 100644 index 00000000..0ea5e5e1 --- /dev/null +++ b/doc/atom/serial/serial.md @@ -0,0 +1,126 @@ +# SerialPort Class Documentation + +## Overview + +The `SerialPort` class provides functionality to interact with serial ports. It allows opening, closing, reading, and writing data to a serial port with specified configurations. + +### Constructor + +```cpp +explicit SerialPort(const std::string &portName, int baudRate, int dataBits, Parity parity, StopBits stopBits); +``` + +#### Usage Example + +```cpp +SerialPort serial("COM1", 9600, 8, Parity::None, StopBits::One); +``` + +--- + +## open Method + +Opens the serial port for communication. + +```cpp +bool open(); +``` + +#### Usage Example + +```cpp +bool isOpen = serial.open(); +// Expected output: true if the serial port is successfully opened +``` + +--- + +## close Method + +Closes the serial port. + +```cpp +void close(); +``` + +#### Usage Example + +```cpp +serial.close(); +``` + +--- + +## read Method + +Reads data from the serial port into a buffer. + +```cpp +bool read(char *buffer, int bufferSize); +``` + +#### Usage Example + +```cpp +char data[256]; +bool success = serial.read(data, 256); +// Expected output: true if data is successfully read into the buffer +``` + +--- + +## write Method + +Writes data to the serial port. + +```cpp +bool write(const char *data, int dataSize); +``` + +#### Usage Example + +```cpp +const char *message = "Hello, Serial!"; +bool success = serial.write(message, strlen(message)); +// Expected output: true if data is successfully written to the serial port +``` + +--- + +## getAvailablePorts Method (in SerialPortFactory) + +Returns a list of available serial ports. + +```cpp +static std::vector getAvailablePorts(); +``` + +#### Usage Example + +```cpp +std::vector ports = SerialPortFactory::getAvailablePorts(); +// Expected output: A vector containing the names of available serial ports +``` + +--- + +## createSerialPort Method (in SerialPortFactory) + +Creates a new `SerialPort` instance with specified configurations. + +```cpp +static SerialPort createSerialPort(const std::string &portName, int baudRate, int dataBits, Parity parity, StopBits stopBits); +``` + +#### Usage Example + +```cpp +SerialPort newSerial = SerialPortFactory::createSerialPort("COM2", 115200, 8, Parity::Even, StopBits::Two); +``` + +--- + +## Special Notes + +1. For Windows platform, the `HANDLE` type is used for handling the serial port. +2. For non-Windows platforms, an integer handle is used for the serial port. diff --git a/doc/atom/serial/ttybase.md b/doc/atom/serial/ttybase.md new file mode 100644 index 00000000..4abe70ee --- /dev/null +++ b/doc/atom/serial/ttybase.md @@ -0,0 +1,239 @@ +# TTYBase Class + +The `TTYBase` class provides functionality for interacting with terminal devices. + +## Constructor + +## `TTYBase(const char *driverName)` + +Creates a `TTYBase` object with the specified driver name. + +**Example:** + +```cpp +TTYBase tty("ttyS0"); +``` + +--- + +## Destructor + +## `virtual ~TTYBase()` + +Destroys the `TTYBase` object and cleans up any resources. + +**Example:** + +```cpp +// No direct example as this is implicitly called when object goes out of scope +``` + +--- + +## `read` Method + +## `TTY_RESPONSE read(uint8_t *buffer, uint32_t nbytes, uint8_t timeout, uint32_t *nbytes_read)` + +Reads data from the terminal device. + +**Parameters:** + +- `buffer`: Pointer to store data. +- `nbytes`: Number of bytes to read. +- `timeout`: Number of seconds to wait for terminal before timeout error. +- `nbytes_read`: Number of bytes read. + +**Example:** + +```cpp +uint8_t data[256]; +uint32_t bytesRead; +TTYBase::TTY_RESPONSE response = tty.read(data, 128, 5, &bytesRead); +if (response == TTYBase::TTY_OK) { + // Process the data read +} else { + // Handle error +} +``` + +--- + +## `readSection` Method + +## `TTY_RESPONSE readSection(uint8_t *buffer, uint32_t nsize, uint8_t stop_byte, uint8_t timeout, uint32_t *nbytes_read)` + +Reads data with a delimiter from the terminal device. + +**Parameters:** + +- `buffer`: Pointer to store data. +- `nsize`: Size of buffer. +- `stop_byte`: Stop character to terminate reading. +- `timeout`: Timeout value in seconds. +- `nbytes_read`: Number of bytes read. + +**Example:** + +```cpp +uint8_t data[256]; +uint32_t bytesRead; +TTYBase::TTY_RESPONSE response = tty.readSection(data, 256, '\n', 5, &bytesRead); +if (response == TTYBase::TTY_OK) { + // Process the data read until newline character is encountered +} else { + // Handle error +} +``` + +--- + +## `write` Method + +## `TTY_RESPONSE write(const uint8_t *buffer, uint32_t nbytes, uint32_t *nbytes_written)` + +Writes data to the terminal device. + +**Parameters:** + +- `buffer`: Data buffer to write. +- `nbytes`: Number of bytes to write. +- `nbytes_written`: Number of bytes actually written. + +**Example:** + +```cpp +uint8_t data[] = {0x01, 0x02, 0x03}; +uint32_t bytesWritten; +TTYBase::TTY_RESPONSE response = tty.write(data, 3, &bytesWritten); +if (response == TTYBase::TTY_OK) { + // Data successfully written +} else { + // Handle error +} +``` + +--- + +## `writeString` Method + +## `TTY_RESPONSE writeString(const char *string, uint32_t *nbytes_written)` + +Writes a null-terminated string to the terminal device. + +**Parameters:** + +- `string`: Null-terminated string to write. +- `nbytes_written`: Number of bytes written. + +**Example:** + +```cpp +const char *message = "Hello, World!"; +uint32_t bytesWritten; +TTYBase::TTY_RESPONSE response = tty.writeString(message, &bytesWritten); +if (response == TTYBase::TTY_OK) { + // String successfully written +} else { + // Handle error +} +``` + +--- + +## `connect` Method + +## `TTY_RESPONSE connect(const char *device, uint32_t bit_rate, uint8_t word_size, uint8_t parity, uint8_t stop_bits)` + +Establishes a connection to a terminal device. + +**Parameters:** + +- `device`: Device node (e.g., /dev/ttyS0). +- `bit_rate`: Bit rate for communication. +- `word_size`: Number of data bits (7 or 8). +- `parity`: Parity setting (0=no parity, 1=even, 2=odd). +- `stop_bits`: Number of stop bits (1 or 2). + +**Example:** + +```cpp +TTYBase::TTY_RESPONSE response = tty.connect("/dev/ttyS0", 9600, 8, 0, 1); +if (response == TTYBase::TTY_OK) { + // Connection successful +} else { + // Handle connection error +} +``` + +--- + +## `disconnect` Method + +## `TTY_RESPONSE disconnect()` + +Closes the tty connection and flushes the bus. + +**Example:** + +```cpp +TTYBase::TTY_RESPONSE response = tty.disconnect(); +if (response == TTYBase::TTY_OK) { + // Disconnected successfully +} else { + // Handle disconnection error +} +``` + +--- + +## `setDebug` Method + +## `void setDebug(HYDROGEN::Logger::VerbosityLevel channel)` + +Enables or disables debug logging for TTY traffic. + +**Parameters:** + +- `channel`: Logging verbosity level. + +**Special Note:** + +- Use debug logging cautiously as it may impact driver function due to verbose traffic. + +**Example:** + +```cpp +tty.setDebug(HYDROGEN::Logger::DBG_INFO); +``` + +--- + +## `error` Method + +## `const std::string error(TTY_RESPONSE code) const` + +Retrieves the error message corresponding to the given TTY response code. + +**Example:** + +```cpp +TTYBase::TTY_RESPONSE response = tty.read(data, 128, 5, &bytesRead); +if (response != TTYBase::TTY_OK) { + std::string errorMessage = tty.error(response); + // Print or handle error message +} +``` + +--- + +## `getPortFD` Method + +## `int getPortFD() const` + +Returns the file descriptor of the port. + +**Example:** + +```cpp +int portFD = tty.getPortFD(); +``` diff --git a/doc/atom/server/commander.md b/doc/atom/server/commander.md new file mode 100644 index 00000000..cb1ceed1 --- /dev/null +++ b/doc/atom/server/commander.md @@ -0,0 +1,150 @@ +# Command Dispatcher + +The `CommandDispatcher` class is a generic command dispatcher for handling and dispatching commands. It allows registration of handler functions for specific commands, along with optional undo handlers and decorators to modify or enhance the behavior of the registered handlers. This document provides a detailed explanation of the class interface along with usage examples and expected outputs. + +## Class Template Parameters + +- `Result`: The result type of the command handler function. +- `Argument`: The argument type of the command handler function. + +## Class Declaration + +```cpp +template +class CommandDispatcher : public NonCopyable { +public: + using HandlerFunc = std::function; + using DecoratorFunc = std::shared_ptr>; + using LoopDecoratorFunc = std::shared_ptr>; + using ConditionalDecoratorFunc = + std::shared_ptr>; + + // Constructor and destructor + CommandDispatcher() = default; + ~CommandDispatcher(); + + // Factory methods + static std::shared_ptr createShared(); + static std::unique_ptr createUnique(); + + // Member functions for registration and dispatching + void registerHandler(const std::string &name, const HandlerFunc &handler, + const HandlerFunc &undoHandler = nullptr); + template + void registerMemberHandler(const std::string &name, T *object, + Result (T::*memberFunc)(const Argument &)); + void registerDecorator(const std::string &name, + const DecoratorFunc &decorator); + void registerLoopDecorator(const std::string &name, + const LoopDecoratorFunc &decorator); + void registerConditionalDecorator(const std::string &name, + const ConditionalDecoratorFunc &decorator); + HandlerFunc getHandler(const std::string &name); + bool hasHandler(const std::string &name); + Result dispatch(const std::string &name, const Argument &data); + bool undo(); // Not yet implemented + bool redo(); // Not yet implemented + bool removeAll(); + void registerFunctionDescription(const std::string &name, + const std::string &description); + std::string getFunctionDescription(const std::string &name); + void removeFunctionDescription(const std::string &name); + void clearFunctionDescriptions(); + void setMaxHistorySize(size_t maxSize); + size_t getMaxHistorySize() const; + +private: + // Data members + std::unordered_map m_handlers; + std::unordered_map m_decorators; + std::unordered_map m_undoHandlers; + std::unordered_map m_descriptions; + std::stack> m_commandHistory; + std::stack> m_undoneCommands; + mutable std::shared_mutex m_sharedMutex; + size_t m_maxHistorySize = 100; +}; +``` + +## Usage Examples + +### 1. Registering a Handler + +```cpp +// Create a CommandDispatcher instance +auto dispatcher = CommandDispatcher::createShared(); + +// Define a handler function +CommandDispatcher::HandlerFunc handlerFunc = + [](const std::string &arg) { return arg.length(); }; + +// Register the handler for a command +dispatcher->registerHandler("length", handlerFunc); + +// Dispatch the command +int result = dispatcher->dispatch("length", "example"); +std::cout << "Length: " << result << std::endl; // Expected output: Length: 7 +``` + +### 2. Registering a Member Function Handler + +```cpp +class StringHandler { +public: + int getLength(const std::string &str) { + return str.length(); + } +}; + +// Create an instance of the handler class +StringHandler handler; + +// Register the member function handler +dispatcher->registerMemberHandler("length", &handler, &StringHandler::getLength); + +// Dispatch the command +int result = dispatcher->dispatch("length", "example"); +std::cout << "Length: " << result << std::endl; // Expected output: Length: 7 +``` + +### 3. Registering a Decorator + +```cpp +// Define a decorator function +auto decoratorFunc = std::make_shared::HandlerFunc>>( + [](CommandDispatcher::HandlerFunc func) { + return [=](const std::string &arg) { + std::cout << "Before executing command" << std::endl; + int result = func(arg); + std::cout << "After executing command" << std::endl; + return result; + }; + }); + +// Register the decorator for a command +dispatcher->registerDecorator("length", decoratorFunc); + +// Dispatch the command +int result = dispatcher->dispatch("length", "example"); +std::cout << "Length: " << result << std::endl; // Expected output: Before executing command + // Length: 7 + // After executing command +``` + +### 4. Setting Maximum History Size + +```cpp +// Set the maximum history size +dispatcher->setMaxHistorySize(50); + +// Get the maximum history size +size_t maxSize = dispatcher->getMaxHistorySize(); +std::cout << "Max history size: " << maxSize << std::endl; // Expected output: Max history size: 50 +``` + +## Notes + +- The `undo()` and `redo()` methods are not yet implemented. They will be available in future versions. +- The `removeAll()` method removes all registered handler functions. +- Function descriptions can be registered using `registerFunctionDescription()` and retrieved using `getFunctionDescription()`. +- The command history is managed internally for undo and redo operations, but those functionalities are not yet ready for use. diff --git a/doc/atom/server/daemon.md b/doc/atom/server/daemon.md new file mode 100644 index 00000000..33091d62 --- /dev/null +++ b/doc/atom/server/daemon.md @@ -0,0 +1,117 @@ +# DaemonGuard Class Documentation + +The `DaemonGuard` class is designed for managing process information and starting child processes to execute tasks. It provides methods for starting processes, handling daemon processes, and converting process information to a string. + +## Class Declaration + +```cpp +class DaemonGuard { +public: + DaemonGuard() {} + + std::string ToString() const; + + int RealStart(int argc, char **argv, + std::function mainCb); + + int RealDaemon(int argc, char **argv, + std::function mainCb); + + int StartDaemon(int argc, char **argv, + std::function mainCb, + bool isDaemon); + +private: +#ifdef _WIN32 + HANDLE m_parentId = 0; + HANDLE m_mainId = 0; +#else + pid_t m_parentId = 0; + pid_t m_mainId = 0; +#endif + time_t m_parentStartTime = 0; + time_t m_mainStartTime = 0; + int m_restartCount = 0; +}; +``` + +## Usage Examples + +### 1. RealStart Method + +```cpp +// Create an instance of DaemonGuard +DaemonGuard daemon; + +// Define a callback function +std::function callback = [](int argc, char **argv) { + // Task implementation + return 0; +}; + +// Start a child process using RealStart +int result = daemon.RealStart(argc, argv, callback); +``` + +### 2. RealDaemon Method + +```cpp +// Create an instance of DaemonGuard +DaemonGuard daemon; + +// Start a daemon process using RealDaemon +int result = daemon.RealDaemon(argc, argv, callback); +``` + +### 3. StartDaemon Method + +```cpp +// Create an instance of DaemonGuard +DaemonGuard daemon; + +// Start a process with or without creating a daemon +bool createDaemon = true; +int result = daemon.StartDaemon(argc, argv, callback, createDaemon); +``` + +### Additional Notes + +- The `SignalHandler`, `WritePidFile`, and `CheckPidFile` functions are external utility functions related to process management but are not part of the `DaemonGuard` class. + +## SignalHandler Function + +```cpp +/** + * @brief Signal handler function. + * + * @param signum The signal number. + */ +void SignalHandler(int signum) { + // Signal handling logic +} +``` + +## WritePidFile Function + +```cpp +/** + * @brief Writes the process ID to a file. + */ +void WritePidFile() { + // Implementation to write PID to a file +} +``` + +## CheckPidFile Function + +```cpp +/** + * @brief Checks if the process ID file exists. + * + * @return True if the process ID file exists, false otherwise. + */ +bool CheckPidFile() { + // Implementation to check the existence of the PID file + return false; // Placeholder return value +} +``` diff --git a/doc/atom/server/deserialize.md b/doc/atom/server/deserialize.md new file mode 100644 index 00000000..78d37e4c --- /dev/null +++ b/doc/atom/server/deserialize.md @@ -0,0 +1,74 @@ +# DeserializationEngine Class Documentation + +The `DeserializationEngine` class is responsible for deserializing data using different deserialization engines. It allows adding multiple deserialization engines and selecting the current engine for deserialization. + +## Class Declaration + +```cpp +class DeserializationEngine { +public: + DeserializationEngine() = default; + ~DeserializationEngine() = default; + + void addDeserializeEngine(const std::string &name, const std::shared_ptr &engine); + + bool setCurrentDeserializeEngine(const std::string &name); + + template + std::optional deserialize(const std::string &data) const; + +private: + std::unordered_map> deserializationEngines_; + std::string currentDeserializationEngine_; + mutable std::mutex mutex_; +}; +``` + +## Usage Examples + +### 1. Adding a DeserializeEngine + +```cpp +DeserializationEngine engine; + +// Create a JsonDeserializer instance +std::shared_ptr jsonEngine = std::make_shared(); + +// Add JsonDeserializer as a deserialization engine +engine.addDeserializeEngine("json", jsonEngine); +``` + +### 2. Setting the Current DeserializeEngine + +```cpp +// Set the current deserialization engine to "json" +bool success = engine.setCurrentDeserializeEngine("json"); + +if (success) { + std::cout << "Current deserialization engine set to 'json'." << std::endl; +} else { + std::cout << "Failed to set current deserialization engine." << std::endl; +} +``` + +### 3. Deserializing Data + +```cpp +// Assuming 'engine' has a valid deserialization engine set + +// Deserialize JSON data into a specific type +std::optional result = engine.deserialize("{\"key\": \"value\"}"); + +if (result.has_value()) { + std::cout << "Deserialization successful. Result: " << result.value() << std::endl; +} else { + std::cout << "Deserialization failed." << std::endl; +} +``` + +## Additional Notes + +- The `ENABLE_FASTHASH` conditional compilation flag is used to select the appropriate hash map implementation. +- The `deserialize` method uses the current deserialization engine set in the class. + +This concludes the documentation for the `DeserializationEngine` class, showcasing how to add deserialization engines, set the current engine, and deserialize data using the selected engine. diff --git a/doc/atom/server/global_ptr.md b/doc/atom/server/global_ptr.md new file mode 100644 index 00000000..6262c36b --- /dev/null +++ b/doc/atom/server/global_ptr.md @@ -0,0 +1,133 @@ +# GlobalSharedPtrManager Class Documentation + +The `GlobalSharedPtrManager` class manages a collection of shared pointers and weak pointers. It provides functions to add, remove, and retrieve shared pointers and weak pointers by key. + +## getInstance + +Returns the singleton instance of the `GlobalSharedPtrManager`. + +### Example + +```cpp +GlobalSharedPtrManager &manager = GlobalSharedPtrManager::getInstance(); +``` + +## getSharedPtr + +Retrieves a shared pointer from the shared pointer map with the specified key. + +### Example + +```cpp +auto sharedPtr = manager.getSharedPtr("key1"); +if (sharedPtr) { + // Shared pointer found +} else { + // Shared pointer not found +} +``` + +## getWeakPtr + +Retrieves a weak pointer from the shared pointer map with the specified key. + +### Example + +```cpp +auto weakPtr = manager.getWeakPtr("key2"); +if (!weakPtr.expired()) { + auto sharedPtr = weakPtr.lock(); + // Use sharedPtr +} else { + // Weak pointer expired +} +``` + +## addSharedPtr + +Adds a shared pointer to the shared pointer map with the specified key. + +### Example + +```cpp +std::shared_ptr mySharedPtr = std::make_shared(3.14); +manager.addSharedPtr("key3", mySharedPtr); +``` + +## removeSharedPtr + +Removes a shared pointer from the shared pointer map with the specified key. + +### Example + +```cpp +manager.removeSharedPtr("key3"); +``` + +## addWeakPtr + +Adds a weak pointer to the shared pointer map with the specified key. + +### Example + +```cpp +std::weak_ptr myWeakPtr = mySharedPtr; +manager.addWeakPtr("key4", myWeakPtr); +``` + +## getSharedPtrFromWeakPtr + +Retrieves a shared pointer from a weak pointer in the shared pointer map with the specified key. + +### Example + +```cpp +auto sharedPtr = manager.getSharedPtrFromWeakPtr("key4"); +if (sharedPtr) { + // Shared pointer retrieved successfully +} else { + // Weak pointer expired or shared object deleted +} +``` + +## removeExpiredWeakPtrs + +Removes all expired weak pointers from the shared pointer map. + +### Example + +```cpp +manager.removeExpiredWeakPtrs(); +``` + +## addDeleter + +Adds a custom deleter function for the shared object associated with the specified key. + +### Example + +```cpp +auto customDeleter = [](int *ptr) { delete ptr; }; +manager.addDeleter("key5", customDeleter); +``` + +## deleteObject + +Deletes the shared object associated with the specified key. + +### Example + +```cpp +int *ptr = new int(42); +manager.deleteObject("key5", ptr); +``` + +## printSharedPtrMap + +Prints the contents of the shared pointer map. + +### Example + +```cpp +manager.printSharedPtrMap(); +``` diff --git a/doc/atom/server/json_checker.md b/doc/atom/server/json_checker.md new file mode 100644 index 00000000..6f03e26f --- /dev/null +++ b/doc/atom/server/json_checker.md @@ -0,0 +1,100 @@ +# JsonChecker Class + +## Brief + +Json Checker class is used to check if the JSON data matches the specified type. + +## Details + +This class offers the ability to add default and custom rules for specific types, as well as to check if the JSON data matches the specified type or expected value. + +## Usage Example + +```cpp +// Create an instance of JsonChecker +JsonChecker checker; + +// Check if the JSON data matches the specified type +json jsonData = ...; // JSON data to be checked +bool result = checker.checkType(jsonData, "integer"); +``` + +## Expected Output + +The `result` variable should contain `true` or `false` based on whether the JSON data matches the "integer" type. + +## Constructor + +```cpp +/** + * Default constructor for JsonChecker. + */ +JsonChecker(); +``` + +## Adding Default Rule + +```cpp +// Adding a default rule for a specific type +checker.addDefaultRule("integer", [](const json &data) { + return data.is_number_integer(); +}); +``` + +## Adding Custom Rule + +```cpp +// Adding a custom rule for a specific type +checker.addCustomRule("customString", [](const json &data) { + // Add custom validation logic here + return true; // Replace with actual validation logic +}); +``` + +## Checking Type + +```cpp +// Checking if the JSON data matches the specified type +json jsonData = ...; // JSON data to be checked +bool result = checker.checkType(jsonData, "integer"); +``` + +## Checking Value + +```cpp +// Checking if the JSON data matches the expected value +json jsonData = ...; // JSON data to be checked +int expectedValue = 10; // Expected value +bool result = checker.checkValue(jsonData, expectedValue); +``` + +## Validating Format + +```cpp +// Validating the format of the JSON string data using a regular expression +json jsonData = ...; // JSON data to be validated +std::string format = R"(\d{4}-\d{2}-\d{2})"; // Regular expression format +bool result = checker.validateFormat(jsonData, format); +``` + +## Setting Failure Message + +```cpp +// Setting the failure message +checker.onFailure("Validation failed!"); +``` + +## Setting Failure Callback + +```cpp +// Setting the failure callback function +checker.setFailureCallback([](const std::string &message) { + // Custom failure handling logic +}); +``` + +## Notes + +- Replace `...` with actual JSON data in the examples. +- These examples assume the presence of a `json` type, which can be replaced with the appropriate JSON library or type used in the project. +- The `ENABLE_FASTHASH` preprocessor directive is assumed to be defined appropriately. diff --git a/doc/atom/server/message_bus.md b/doc/atom/server/message_bus.md new file mode 100644 index 00000000..619dd00c --- /dev/null +++ b/doc/atom/server/message_bus.md @@ -0,0 +1,164 @@ +# MessageBus Class Documentation + +The `MessageBus` class provides a simple message bus implementation for handling message subscriptions, publishing, and processing. + +## Constructor + +### Example + +```cpp +MessageBus bus(500); // Create a MessageBus object with a maximum queue size of 500 +``` + +## Common Methods + +### createShared() + +Creates and returns a shared pointer to a new `MessageBus` object. + +#### Example + +```cpp +auto sharedBus = MessageBus::createShared(); +``` + +### createUnique() + +Creates and returns a unique pointer to a new `MessageBus` object. + +#### Example + +```cpp +auto uniqueBus = MessageBus::createUnique(); +``` + +## MessageBus Methods + +### Subscribe() + +Subscribes a callback function to a specific topic. + +#### Example + +```cpp +bus.Subscribe("topic_name", [](const int& message) { + std::cout << "Received message: " << message << std::endl; +}); +``` + +### Publish() + +Publishes a message to a specific topic. + +#### Example + +```cpp +bus.Publish("topic_name", 42); +``` + +_Expected Output_: "Published message to topic: topic_name" + +### TryReceive() + +Tries to receive a message with a timeout. + +#### Example + +```cpp +int receivedMessage; +if (bus.TryReceive(receivedMessage)) { + std::cout << "Received message: " << receivedMessage << std::endl; +} +``` + +### StartProcessingThread() + +Starts a processing thread for a specific message type. + +#### Example + +```cpp +bus.StartProcessingThread(); +``` + +### StopProcessingThread() + +Stops the processing thread for a specific message type. + +#### Example + +```cpp +bus.StopProcessingThread(); +``` + +### StopAllProcessingThreads() + +Stops all processing threads. + +#### Example + +```cpp +bus.StopAllProcessingThreads(); +``` + +### GlobalSubscribe() + +Subscribes a global callback function that will be triggered for all message types. + +#### Example + +```cpp +bus.GlobalSubscribe([](const int& message) { + std::cout << "Global message received: " << message << std::endl; +}); +``` + +### Unsubscribe() + +Unsubscribes a callback function from a specific topic. + +#### Example + +```cpp +bus.Unsubscribe("topic_name", callback_function); +``` + +### UnsubscribeFromNamespace() + +Unsubscribes a callback function from a specific namespace. + +#### Example + +```cpp +bus.UnsubscribeFromNamespace("namespace_name", callback_function); +``` + +### UnsubscribeAll() + +Unsubscribes from all topics within a namespace. + +#### Example + +```cpp +bus.UnsubscribeAll("namespace_name"); +``` + +### GlobalUnsubscribe() + +Unsubscribes a global callback function. + +#### Example + +```cpp +bus.GlobalUnsubscribe(callback_function); +``` + +### TryPublish() + +Tries to publish a message with a timeout. + +#### Example + +```cpp +bus.TryPublish("topic_name", 42); +``` \ No newline at end of file diff --git a/doc/atom/server/message_queue.md b/doc/atom/server/message_queue.md new file mode 100644 index 00000000..539fea50 --- /dev/null +++ b/doc/atom/server/message_queue.md @@ -0,0 +1,83 @@ +# MessageQueue Class Documentation + +The `MessageQueue` class provides a message queue implementation that allows subscribers to receive messages of type T. + +## Template Class Definition + +### Template Parameter + +- **T**: The type of messages that can be published and subscribed to. + +## Constructor + +The class does not have a constructor as it is a template class. + +## Public Methods + +### subscribe() + +Subscribes a callback function to receive messages. + +```cpp +messageQueue.subscribe([](const int& message) { + std::cout << "Received message: " << message << std::endl; +}, "Subscriber1"); +``` + +### unsubscribe() + +Unsubscribes a callback function from receiving messages. + +```cpp +messageQueue.unsubscribe(callbackFunction); +``` + +### publish() + +Publishes a new message to all subscribed callback functions. + +```cpp +messageQueue.publish(42); +``` + +_Expected Output_: "Published message: 42" + +### startProcessingThread() + +Starts the processing thread(s) to receive and handle messages. + +This method will start the processing thread(s) to handle incoming messages. + +```cpp +messageQueue.startProcessingThread(); +``` + +### stopProcessingThread() + +Stops the processing thread(s) from receiving and handling messages. + +This method will stop the processing thread(s) from handling any more messages. + +```cpp +messageQueue.stopProcessingThread(); +``` + +## Private Members + +### Subscriber Struct + +Contains information about a subscribed callback function. + +- **name**: The name of the subscriber. +- **callback**: The callback function to be called when a new message is received. + +### Member Variables + +- **m_messages**: Queue containing all published messages. +- **m_subscribers**: Vector containing all subscribed callback functions. +- **m_mutex**: Mutex used to protect access to the message queue. +- **m_subscriberMutex**: Mutex used to protect access to the subscriber vector. +- **m_condition**: Condition variable used to notify processing threads of new messages. +- **m_isRunning**: Flag to indicate whether the processing thread(s) should continue running. +- **m_processingThreads**: Vector containing all processing threads. +- **m_numThreads**: Number of processing threads to spawn (initialized with `std::thread::hardware_concurrency()`). diff --git a/doc/atom/server/serialize.md b/doc/atom/server/serialize.md new file mode 100644 index 00000000..25521640 --- /dev/null +++ b/doc/atom/server/serialize.md @@ -0,0 +1,92 @@ +# Serialization Engine + +## Introduction + +Serialization engine is designed to provide a way to render data into different formats such as JSON, XML, YAML, and INI. It allows flexibility in choosing the serialization format and provides an easy way to add new serialization engines. + +## Serialization Class + +The `Serialization` class serves as the base class for all specific serialization engines. It provides a virtual function `serialize` to render data into a string. + +```cpp +// Create a JSON serialization engine +std::shared_ptr jsonEngine = std::make_shared(); +SerializationEngine engine; +engine.addSerializationEngine("json", jsonEngine); +``` + +## JsonSerializationEngine + +This class is responsible for serializing data into JSON format. + +```cpp +// Serialize data using JSON serialization engine +std::string jsonData = engine.serialize(myData); +``` + +**Expected Output:** +A JSON-formatted string representing the serialized data. + +## XmlSerializationEngine + +This class is responsible for serializing data into XML format. + +```cpp +// Serialize data using XML serialization engine +std::string xmlData = engine.serialize(myData); +``` + +**Expected Output:** +An XML-formatted string representing the serialized data. + +## YamlSerializationEngine + +This class is responsible for serializing data into YAML format. + +```cpp +// Serialize data using YAML serialization engine +std::string yamlData = engine.serialize(myData); +``` + +**Expected Output:** +A YAML-formatted string representing the serialized data. + +## IniSerializationEngine + +This class is responsible for serializing data into INI format. + +```cpp +// Serialize data using INI serialization engine +std::string iniData = engine.serialize(myData); +``` + +**Expected Output:** +An INI-formatted string representing the serialized data. + +## SerializationEngine Class + +The `SerializationEngine` class manages the serialization engines and provides an interface to add, select, and use different serialization engines. + +```cpp +// Add a serialization engine to the SerializationEngine +engine.addSerializationEngine("yaml", yamlEngine); + +// Set the current serialization engine to JSON +bool success = engine.setCurrentSerializationEngine("json"); + +// Serialize data using the selected serialization engine +std::optional serializedData = engine.serialize(myData); +if (serializedData.has_value()) { + std::cout << "Serialized data: " << *serializedData << std::endl; +} else { + std::cerr << "Serialization failed." << std::endl; +} +``` + +**Expected Output:** +If serialization is successful, it prints the serialized data; otherwise, it outputs a serialization failure message. + +## Notes + +- The `SerializationEngine` class uses a mutex to ensure thread safety when accessing and modifying the serialization engines. +- The usage of `std::optional` allows handling potential serialization failures gracefully. diff --git a/doc/atom/server/variables.md b/doc/atom/server/variables.md new file mode 100644 index 00000000..3942f827 --- /dev/null +++ b/doc/atom/server/variables.md @@ -0,0 +1,141 @@ +# VariableRegistry Class + +The `VariableRegistry` class is designed to register, retrieve, and observe variable values. + +## Constructor + +### `explicit VariableRegistry(const std::string &name)` + +- **Description:** Constructor to create a `VariableRegistry` object with a specified name. + + ```cpp + VariableRegistry registry("MyRegistry"); + ``` + +## Public Methods + +### RegisterVariable + +```cpp +template +bool RegisterVariable(const std::string &name, const T &initialValue, + const std::string description = ""); +``` + +- **Description:** Registers a new variable with an initial value and an optional description. + + ```cpp + registry.RegisterVariable("myVar", 42); // Register a variable named "myVar" with initial value 42 + ``` + +### SetVariable + +```cpp +template +bool SetVariable(const std::string &name, const T &value); +``` + +- **Description:** Sets the value of a registered variable. + + ```cpp + registry.SetVariable("myVar", 100); // Set the value of "myVar" to 100 + ``` + +### GetVariable + +```cpp +template +std::optional GetVariable(const std::string &name) const; +``` + +- **Description:** Retrieves the value of a registered variable. + + ```cpp + auto value = registry.GetVariable("myVar"); + if (value.has_value()) { + std::cout << "Value of myVar: " << value.value() << std::endl; + } + ``` + +### AddObserver + +```cpp +void AddObserver(const std::string &name, const Observer &observer); +``` + +- **Description:** Adds an observer to monitor changes in a variable's value. + + ```cpp + VariableRegistry::Observer observer{"myObserver", [](const std::string &name) { + std::cout << "Value of " << name << " changed." << std::endl; + }}; + registry.AddObserver("myVar", observer); + ``` + +### NotifyObservers + +```cpp +template +void NotifyObservers(const std::string &name, const T &value) const; +``` + +- **Description:** Notifies all observers that a variable's value has changed. + + ```cpp + registry.NotifyObservers("myVar", 200); + ``` + +### GetAll + +```cpp +[[nodiscard]] emhash8::HashMap GetAll() const; +``` + +- **Description:** Retrieves a map of all registered variables. + + ```cpp + auto allVariables = registry.GetAll(); + ``` + +### RemoveAll + +- **Description:** Clears all registered variables. + + ```cpp + registry.RemoveAll(); + ``` + +### AddGetter + +```cpp +template +void AddGetter(const std::string &name, const std::function &getter); +``` + +- **Description:** Adds a callback function to retrieve the value of a variable. + + ```cpp + registry.AddGetter("myVar", []() { return 500; }); + ``` + +### AddSetter + +```cpp +template +void AddSetter(const std::string &name, const std::function &setter); +``` + +- **Description:** Adds a callback function to monitor changes in a variable. + + ```cpp + registry.AddSetter("myVar", [](const std::any &newValue) { + // Custom validation logic here + }); + ``` + +## Notes + +- Ensure to use `RegisterVariable` before calling `SetVariable` or `GetVariable` for a specific variable. +- Callback functions added via `AddGetter` and `AddSetter` should match the variable type registered. + +This `VariableRegistry` class provides a flexible and efficient way to manage and observe variables in your application. diff --git a/doc/atom/system/command.md b/doc/atom/system/command.md new file mode 100644 index 00000000..c4c1082e --- /dev/null +++ b/doc/atom/system/command.md @@ -0,0 +1,109 @@ +# Command Execution Utilities + +## ProcessHandle Structure + +```cpp +#ifdef _WIN32 +struct ProcessHandle { + HANDLE handle; +}; +#else +struct ProcessHandle { + pid_t pid; +}; +#endif +``` + +## executeCommand + +Executes a command and returns the command output as a string. + +```cpp +[[nodiscard]] std::string executeCommand( + const std::string &command, bool openTerminal, + std::function processLine); +``` + +```cpp +std::string output = executeCommand("ls -l", false, [](const std::string &line) { + std::cout << "Output line: " << line << std::endl; +}); +``` + +```shell +// Output of "ls -l" command +Output line: +Output line: +... +``` + +## executeCommands + +Executes a list of commands. + +```cpp +void executeCommands(const std::vector &commands); +``` + +```cpp +executeCommands({"ls -l", "pwd"}); +``` + +## executeCommand (overloaded) + +Executes a command and returns the process handle. + +```cpp +[[nodiscard]] ProcessHandle executeCommand(const std::string &command); +``` + +```cpp +ProcessHandle handle = executeCommand("echo 'Hello, World!'"); +``` + +## killProcess + +Kills a process using the process handle. + +```cpp +void killProcess(const ProcessHandle &handle); +``` + +### Note + +- Ensure the `ProcessHandle` is valid and corresponds to a running process. + +## executeCommandWithEnv + +Executes a command with environment variables and returns the output as a string. + +```cpp +[[nodiscard]] std::string executeCommandWithEnv( + const std::string &command, + const std::map &envVars); +``` + +```cpp +std::string output = executeCommandWithEnv("echo $MY_VAR", {{"MY_VAR", "123"}}); +``` + +## executeCommandWithStatus + +Executes a command and returns the output along with the exit status. + +```cpp +[[nodiscard]] std::pair executeCommandWithStatus( + const std::string &command); +``` + +```cpp +auto result = executeCommandWithStatus("ls -l"); +std::cout << "Output: " << result.first << std::endl; +std::cout << "Exit Status: " << result.second << std::endl; +``` + +```shell +// Output of "ls -l" command +Output: +Exit Status: 0 +``` diff --git a/doc/atom/system/crash_quotes.md b/doc/atom/system/crash_quotes.md new file mode 100644 index 00000000..e04b211e --- /dev/null +++ b/doc/atom/system/crash_quotes.md @@ -0,0 +1,131 @@ +# Quote and QuoteManager Classes Documentation + +## Quote Class + +Represents a quote with its text and author. + +### Constructor + +```cpp +explicit Quote(const std::string &text, const std::string &author); +``` + +### `getText()` + +Returns the text of the quote. + +```cpp +const std::string &getText() const; +``` + +### `getAuthor()` + +Returns the author of the quote. + +```cpp +const std::string &getAuthor() const; +``` + +## QuoteManager Class + +Manages a collection of quotes. + +### `addQuote()` + +Adds a quote to the collection. + +```cpp +void addQuote(const Quote "e); +``` + +### `removeQuote()` + +Removes a quote from the collection. + +```cpp +void removeQuote(const Quote "e); +``` + +### `shuffleQuotes()` + +Shuffles the quotes in the collection. + +### `clearQuotes()` + +Clears all quotes in the collection. + +### `loadQuotesFromFile()` + +Loads quotes from a file into the collection. + +```cpp +void loadQuotesFromFile(const std::string &filename); +``` + +### `saveQuotesToFile()` + +Saves quotes in the collection to a file. + +```cpp +void saveQuotesToFile(const std::string &filename) const; +``` + +### `searchQuotes()` + +Searches for quotes containing a keyword and returns a vector of matching quotes. + +```cpp +std::vector searchQuotes(const std::string &keyword) const; +``` + +### `filterQuotesByAuthor()` + +Filters quotes by author and returns a vector of quotes by the specified author. + +```cpp +std::vector filterQuotesByAuthor(const std::string &author) const; +``` + +### `getRandomQuote()` + +Gets a random quote from the collection. + +```cpp +std::string getRandomQuote() const; +``` + +### Debug Method (Conditional Compilation) + +```cpp +#ifdef DEBUG +void displayQuotes() const; +#endif +``` + +This method is only available when compiled in debug mode. It displays all quotes in the collection. + +### Example Usage + +```cpp +// Create a new quote +Quote quote("To be or not to be", "William Shakespeare"); + +// Add the quote to the QuoteManager +QuoteManager manager; +manager.addQuote(quote); + +// Save quotes to a file +manager.saveQuotesToFile("quotes.txt"); + +// Load quotes from a file +manager.loadQuotesFromFile("quotes.txt"); + +// Search quotes by keyword +auto searchResults = manager.searchQuotes("be"); + +// Filter quotes by author +auto shakespeareQuotes = manager.filterQuotesByAuthor("William Shakespeare"); + +// Get a random quote +std::string randomQuote = manager.getRandomQuote(); +``` diff --git a/doc/atom/system/lregistry.md b/doc/atom/system/lregistry.md new file mode 100644 index 00000000..b6677093 --- /dev/null +++ b/doc/atom/system/lregistry.md @@ -0,0 +1,122 @@ +# Registry Class and Member Functions + +The `Registry` class handles registry operations in Windows. + +## Constructor + +Creates a `Registry` object. + +```cpp +Registry myRegistry; +``` + +## loadRegistryFromFile + +Loads registry data from a file. + +```cpp +myRegistry.loadRegistryFromFile(); +``` + +## createKey + +Creates a new key in the registry. + +```cpp +myRegistry.createKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp"); +``` + +Ensure proper permissions to create a new key. + +## deleteKey + +Deletes a key from the registry. + +```cpp +myRegistry.deleteKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp"); +``` + +## setValue + +Sets a value for a key in the registry. + +```cpp +myRegistry.setValue("HKEY_CURRENT_USER\\Software\\MyApp", "Version", "1.0"); +``` + +## getValue + +Gets the value associated with a key and value name from the registry. + +```cpp +std::string value = myRegistry.getValue("HKEY_CURRENT_USER\\Software\\MyApp", "Version"); +// Expected Output: "1.0" +``` + +## deleteValue + +Deletes a value from a key in the registry. + +```cpp +myRegistry.deleteValue("HKEY_CURRENT_USER\\Software\\MyApp", "Version"); +``` + +## backupRegistryData + +Backs up the registry data. + +```cpp +myRegistry.backupRegistryData(); +``` + +## restoreRegistryData + +Restores the registry data from a backup file. + +```cpp +myRegistry.restoreRegistryData("C:\\backup\\myapp_backup.reg"); +``` + +## keyExists + +Checks if a key exists in the registry. + +```cpp +bool exists = myRegistry.keyExists("HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp"); +// Expected Output: true or false +``` + +## valueExists + +Checks if a value exists for a key in the registry. + +```cpp +bool exists = myRegistry.valueExists("HKEY_CURRENT_USER\\Software\\MyApp", "Version"); +// Expected Output: true or false +``` + +## getValueNames + +Retrieves all value names for a given key from the registry. + +```cpp +std::vector valueNames = myRegistry.getValueNames("HKEY_CURRENT_USER\\Software\\MyApp"); +``` + +## RegistryImpl Class + +This is the implementation class for the `Registry` class. + +### Usage Note + +This class is used internally by the `Registry` class for managing registry data. + +## saveRegistryToFile + +Saves the registry data to a file. + +## notifyEvent + +Notifies an event related to registry operations. + +This function is used for notifying events such as key creation or deletion. diff --git a/doc/atom/system/os.md b/doc/atom/system/os.md new file mode 100644 index 00000000..348d6670 --- /dev/null +++ b/doc/atom/system/os.md @@ -0,0 +1,128 @@ +# C++ System Utility Functions Documentation + +## Utsname Struct + +Represents information about the operating system. + +### Members + +- `sysname`: Operating system name +- `nodename`: Network host name +- `release`: Operating system release version +- `version`: Operating system internal version +- `machine`: Hardware identifier + +## walk Function + +Recursively walks through a directory and its subdirectories. + +```cpp +void walk(const fs::path &root); +``` + +```cpp +// Example Usage of walk function +walk("/path/to/directory"); +``` + +## jwalk Function + +Recursively walks through a directory and its subdirectories, returning file information as a JSON string. + +```cpp +std::string jwalk(const std::string &root); +``` + +```cpp +// Example Usage of jwalk function +std::string jsonFiles = jwalk("/path/to/directory"); +// Expected Output: JSON string containing file information. + +``` + +## fwalk Function + +Recursively walks through a directory and its subdirectories, applying a callback function to each file. + +```cpp +void fwalk(const fs::path &root, const std::function &callback); +``` + +```cpp +// Example Usage of fwalk function +fwalk("/path/to/directory", [](const fs::path &file) { + // Custom callback function for each file +}); +``` + +## Environ Function + +Retrieves environment variables as a key-value map. + +```cpp +std::unordered_map Environ(); +``` + +```cpp +// Example Usage of Environ function +auto envMap = Environ(); +// Expected Output: Unordered map containing environment variables and values. +``` + +## ctermid Function + +Returns the name of the controlling terminal. + +```cpp +std::string ctermid(); +``` + +```cpp +// Example Usage of ctermid function +std::string termName = ctermid(); +// Expected Output: Name of the controlling terminal. +``` + +## getpriority Function + +Retrieves the priority of the current process. + +```cpp +int getpriority(); +``` + +```cpp +// Example Usage of getpriority function +int priority = getpriority(); +// Expected Output: Priority of the current process. +``` + +## getlogin Function + +Retrieves the login name of the user. + +```cpp +std::string getlogin(); +``` + +```cpp +// Example Usage of getlogin function +std::string username = getlogin(); +// Expected Output: Login name of the user associated with the process. +``` + +## uname Function + +Retrieves the operating system name and related information. + +```cpp +Utsname uname(); +``` + +```cpp +// Example Usage of uname function +Utsname systemInfo = uname(); +// Access individual fields like systemInfo.sysname, systemInfo.release, etc. +``` + +This documentation provides detailed information about various C++ system utility functions along with usage examples and expected outputs. Ensure to replace placeholder paths like `"/path/to/directory"` with actual paths when testing these functions in your implementation. diff --git a/doc/atom/system/pidwatcher.md b/doc/atom/system/pidwatcher.md new file mode 100644 index 00000000..490eee0d --- /dev/null +++ b/doc/atom/system/pidwatcher.md @@ -0,0 +1,108 @@ +# PidWatcher Class Documentation + +## Description + +The `PidWatcher` class provides functionality to monitor and manage processes based on their names. + +### Public Members + +- `SetExitCallback`: Set a callback function to be executed when the process exits. +- `SetMonitorFunction`: Set a monitor function to run at a specified interval. +- `GetPidByName`: Get the process ID (PID) by process name. +- `Start`: Start monitoring a specific process. +- `Stop`: Stop monitoring the process. +- `Switch`: Switch the target process being monitored. + +## Constructor + +```cpp +PidWatcher(); +``` + +## Destructor + +```cpp +~PidWatcher(); +``` + +## SetExitCallback Function + +```cpp +void SetExitCallback(Callback callback); +``` + +```cpp +// Setting an exit callback function +pidWatcher.SetExitCallback([]() { + // Custom exit callback function +}); +``` + +## SetMonitorFunction Function + +```cpp +void SetMonitorFunction(Callback callback, std::chrono::milliseconds interval); +``` + +```cpp +// Setting a monitor function with a 1-second interval +pidWatcher.SetMonitorFunction([]() { + // Custom monitor callback function +}, std::chrono::seconds(1)); +``` + +## GetPidByName Function + +```cpp +pid_t GetPidByName(const std::string &name) const; +``` + +```cpp +// Getting the PID of a process by name +pid_t pid = pidWatcher.GetPidByName("example_process"); +// Expected Output: PID of the process with the given name. +``` + +## Start Function + +```cpp +bool Start(const std::string &name); +``` + +```cpp +// Starting monitoring of a process by name +bool started = pidWatcher.Start("example_process"); +// Expected Output: true if monitoring started successfully, false otherwise. +``` + +## Stop Function + +```cpp +void Stop(); +``` + +```cpp +// Stopping the monitoring of the current process +pidWatcher.Stop(); +// Note: This will stop monitoring the currently monitored process. +``` + +## Switch Function + +```cpp +bool Switch(const std::string &name); +``` + +```cpp +// Switching the target process being monitored +bool switched = pidWatcher.Switch("new_process"); +// Expected Output: true if the switch was successful, false otherwise. +``` + +## MonitorThread Function + +Private function to run the monitoring thread. + +## ExitThread Function + +Private function to run the exit callback thread. diff --git a/doc/atom/system/process.md b/doc/atom/system/process.md new file mode 100644 index 00000000..ee32dfce --- /dev/null +++ b/doc/atom/system/process.md @@ -0,0 +1,153 @@ +# ProcessManager Class Documentation + +## Description + +The `ProcessManager` class provides functionality to manage processes, including creating, terminating, and monitoring processes, as well as running scripts and retrieving process information. + +### Public Members + +- `createProcess`: Create a new process to execute a command. +- `terminateProcess`: Terminate a process by PID or name. +- `hasProcess`: Check if a specific process exists. +- `getRunningProcesses`: Get a list of running processes with detailed information. +- `getProcessOutput`: Get the output of a specific process. +- `waitForCompletion`: Wait for all processes to complete and clear the process list. +- `runScript`: Run a script as a process. + +## Constructor + +```cpp +ProcessManager(); +``` + +## Constructor with Max Processes + +```cpp +ProcessManager(int maxProcess); +``` + +## createShared Function + +```cpp +static std::shared_ptr createShared(); +static std::shared_ptr createShared(int maxProcess); +``` + +```cpp +// Creating a shared ProcessManager instance +auto processManager = ProcessManager::createShared(10); +``` + +## createProcess Function + +```cpp +bool createProcess(const std::string &command, const std::string &identifier); +``` + +```cpp +// Creating a new process +bool created = processManager->createProcess("ls -l", "process1"); +// Expected Output: true if the process creation was successful, false otherwise. +``` + +## terminateProcess Function + +```cpp +bool terminateProcess(pid_t pid, int signal = SIGTERM); +bool terminateProcessByName(const std::string &name, int signal = SIGTERM); +``` + +```cpp +// Terminating a process by PID +bool terminated = processManager->terminateProcess(12345, SIGKILL); +// Expected Output: true if the process was successfully terminated, false otherwise. +``` + +## hasProcess Function + +```cpp +bool hasProcess(const std::string &identifier); +``` + +```cpp +// Checking if a process exists +bool exists = processManager->hasProcess("process1"); +// Expected Output: true if the process exists, false otherwise. +``` + +## getRunningProcesses Function + +```cpp +std::vector getRunningProcesses(); +``` + +```cpp +// Getting a list of running processes +std::vector runningProcesses = processManager->getRunningProcesses(); +// Expected Output: List of running processes with detailed information. +``` + +## getProcessOutput Function + +```cpp +std::vector getProcessOutput(const std::string &identifier); +``` + +```cpp +// Getting output of a specific process +std::vector output = processManager->getProcessOutput("process1"); +// Expected Output: Output information of the specific process. +``` + +## waitForCompletion Function + +```cpp +void waitForCompletion(); +``` + +```cpp +// Waiting for all processes to complete +processManager->waitForCompletion(); +// Note: This will wait for all running processes to finish before clearing the process list. +``` + +## runScript Function + +```cpp +bool runScript(const std::string &script, const std::string &identifier); +``` + +```cpp +// Running a script as a process +bool scriptRan = processManager->runScript("/path/to/script.sh", "script_process"); +// Expected Output: true if the script was executed as a process, false otherwise. +``` + +### Private Members + +- `m_maxProcesses`: Maximum number of processes allowed. +- `cv`: Condition variable used for waiting for process completion. +- `processes`: List of currently running processes with detailed information. +- `mtx`: Mutex used for manipulating the process list. + +## GetAllProcesses Function + +```cpp +std::vector> GetAllProcesses(); +``` + +````cpp +// Getting information of all processes +std::vector> allProcesses = GetAllProcesses(); +// Expected Output: List of pairs containing PID and process names of all processes. + +## GetSelfProcessInfo Function +```cpp +Process GetSelfProcessInfo(); +```` + +```cpp +// Getting information of the current process +Process selfProcessInfo = GetSelfProcessInfo(); +// Expected Output: Information about the current process. +``` diff --git a/doc/atom/system/register.md b/doc/atom/system/register.md new file mode 100644 index 00000000..9467927a --- /dev/null +++ b/doc/atom/system/register.md @@ -0,0 +1,153 @@ +# Registry Manipulation Functions + +This document describes a set of functions for manipulating the Windows registry. + +## getRegistrySubKeys + +Get all subkey names under a specified registry key. + +```cpp +bool getRegistrySubKeys(HKEY hRootKey, const std::string &subKey, + std::vector &subKeys); +``` + +```cpp +std::vector subKeys; +if (getRegistrySubKeys(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft", subKeys)) { + for (const auto &key : subKeys) { + std::cout << key << std::endl; + } +} +``` + +## getRegistryValues + +Get all value names and data under a specified registry key. + +```cpp +bool getRegistryValues( + HKEY hRootKey, const std::string &subKey, + std::vector> &values); +``` + +```cpp +std::vector> values; +if (getRegistryValues(HKEY_CURRENT_USER, "Software\\Classes", values)) { + for (const auto &value : values) { + std::cout << value.first << ": " << value.second << std::endl; + } +} +``` + +## modifyRegistryValue + +Modify the data of a specified value under a registry key. + +```cpp +bool modifyRegistryValue(HKEY hRootKey, const std::string &subKey, + const std::string &valueName, + const std::string &newValue); +``` + +```cpp +if (modifyRegistryValue(HKEY_CURRENT_USER, "Control Panel\\Desktop", "Wallpaper", "new_wallpaper.jpg")) { + std::cout << "Value modified successfully." << std::endl; +} +``` + +## deleteRegistrySubKey + +Delete a specified registry key and all its subkeys. + +```cpp +bool deleteRegistrySubKey(HKEY hRootKey, const std::string &subKey); +``` + +```cpp +if (deleteRegistrySubKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\MyApp")) { + std::cout << "Key and subkeys deleted successfully." << std::endl; +} +``` + +## deleteRegistryValue + +Delete a specified value under a registry key. + +```cpp +bool deleteRegistryValue(HKEY hRootKey, const std::string &subKey, + const std::string &valueName); +``` + +```cpp +if (deleteRegistryValue(HKEY_CURRENT_USER, "Software\\MyApp", "Setting")) { + std::cout << "Value deleted successfully." << std::endl; +} +``` + +## recursivelyEnumerateRegistrySubKeys + +Recursively enumerate all subkeys and values under a specified registry key. + +```cpp +void recursivelyEnumerateRegistrySubKeys(HKEY hRootKey, const std::string &subKey); +``` + +### Special Note + +This function will output all subkeys and values under the specified key. + +## backupRegistry + +Backup a specified registry key and all its subkeys and values. + +```cpp +bool backupRegistry(HKEY hRootKey, const std::string &subKey, + const std::string &backupFilePath); +``` + +```cpp +if (backupRegistry(HKEY_LOCAL_MACHINE, "SOFTWARE\\MyApp", "C:\\backup\\myapp_backup.reg")) { + std::cout << "Registry backed up successfully." << std::endl; +} +``` + +## findRegistryKey + +Recursively search for subkey names containing a specified string under a registry key. + +```cpp +void findRegistryKey(HKEY hRootKey, const std::string &subKey, + const std::string &searchKey); +``` + +```cpp +findRegistryKey(HKEY_CURRENT_USER, "Software", "Microsoft"); +``` + +## findRegistryValue + +Recursively search for value names and data containing a specified string under a registry key. + +```cpp +void findRegistryValue(HKEY hRootKey, const std::string &subKey, + const std::string &searchValue); +``` + +```cpp +findRegistryValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft", "Version"); +``` + +## exportRegistry + +Export a specified registry key and all its subkeys and values to a .reg file. + +```cpp +bool exportRegistry(HKEY hRootKey, const std::string &subKey, + const std::string &exportFilePath); +``` + +```cpp +if (exportRegistry(HKEY_CURRENT_USER, "Software\\MyApp", "C:\\exports\\myapp_export.reg")) { + std::cout << "Registry exported successfully." << std::endl; +} +``` diff --git a/doc/atom/system/storage.md b/doc/atom/system/storage.md new file mode 100644 index 00000000..6a0757d8 --- /dev/null +++ b/doc/atom/system/storage.md @@ -0,0 +1,92 @@ +# StorageMonitor Class and Member Functions + +## Description + +The `StorageMonitor` class monitors storage space changes for all mounted devices and triggers registered callback functions when storage space changes occur. + +## Constructor + +Default constructor for `StorageMonitor`. + +```cpp +StorageMonitor monitor; +``` + +## registerCallback + +Registers a callback function to be triggered when storage space changes occur. + +```cpp +monitor.registerCallback([](const std::string &path) { + std::cout << "Storage space changed at path: " << path << std::endl; +}); +``` + +## startMonitoring + +Starts monitoring storage space. + +```cpp +bool success = monitor.startMonitoring(); +// Expected Output: true or false +``` + +## stopMonitoring + +Stops monitoring storage space. + +```cpp +monitor.stopMonitoring(); +``` + +## triggerCallbacks + +Triggers all registered callback functions. + +```cpp +monitor.triggerCallbacks("/mnt/usb"); +``` + +## isNewMediaInserted + +Checks if a new storage device is inserted at the specified path. + +```cpp +bool inserted = monitor.isNewMediaInserted("/mnt/usb"); +// Expected Output: true or false +``` + +## listAllStorage + +Lists all mounted storage spaces. (Debug feature) + +## listFiles + +Lists files in the specified path. (Debug feature) + +```cpp +monitor.listFiles("/mnt/usb"); +``` + +## monitorUdisk + +Monitors USB disks on Linux systems. + +### Special Note + +This function is specific to Linux systems. + +```cpp +#ifdef __linux__ +monitorUdisk(monitor); +#endif +``` + +## Member Variables + +- `m_storagePaths`: Contains all mounted storage space paths. +- `m_lastCapacity`: Stores the last recorded storage space capacity. +- `m_lastFree`: Stores the last recorded available storage space. +- `m_mutex`: Mutex for thread-safe protection of data structures. +- `m_callbacks`: List of registered callback functions. +- `m_isRunning`: Flag indicating if monitoring is running. diff --git a/doc/atom/system/system.md b/doc/atom/system/system.md new file mode 100644 index 00000000..68e3a6b3 --- /dev/null +++ b/doc/atom/system/system.md @@ -0,0 +1,108 @@ +# Process Management Library Documentation + +## ProcessInfo Struct + +- Stores information about a process. +- Attributes: + - `processID` (int): The process ID. + - `parentProcessID` (int): The parent process ID. + - `basePriority` (int): The base priority of the process. + - `executableFile` (std::string): The executable file associated with the process. + +```cpp +ProcessInfo info; +info.processID = 12345; +info.parentProcessID = 6789; +info.basePriority = 10; +info.executableFile = "example.exe"; +``` + +## Function: CheckSoftwareInstalled + +- Checks if the specified software is installed. + +- `software_name` (const std::string&): The name of the software. + +- `true` if the software is installed, `false` otherwise. + +```cpp +bool isInstalled = CheckSoftwareInstalled("Example Software"); +// Expected output: false +``` + +## Function: checkExecutableFile + +- Checks if the specified file exists. + +- `fileName` (const std::string&): The name of the file. +- `fileExt` (const std::string&): The extension of the file. + +- `true` if the file exists, `false` otherwise. + +## Function: IsRoot + +- Checks if the current user has root/administrator privileges. + +- `true` if the user has root/administrator privileges, `false` otherwise. + +## Function: GetCurrentUsername + +- Retrieves the current username. + +- The current username as a string. + +## Function: Shutdown + +- Shuts down the system. + +- `true` if the system is successfully shutdown, `false` if an error occurs. + +## Function: Reboot + +- Reboots the system. + +- `true` if the system is successfully rebooted, `false` if an error occurs. + +## Function: GetProcessInfo + +- Retrieves process information and file addresses. + +- A vector of pairs containing process information and file addresses. + +## Function: CheckDuplicateProcess + +- Checks for duplicate processes with the same program name. + +- `program_name` (const std::string&): The program name to check for duplicates. + +## Function: isProcessRunning + +- Checks if the specified process is running. + +- `processName` (const std::string&): The name of the process to check. + +- `true` if the process is running, `false` otherwise. + +## Function: GetProcessDetails + +- Retrieves detailed process information. + +- A vector of ProcessInfo structs containing process details. + +## Function: GetProcessInfoByID (Platform-specific) + +- Retrieves process information by process ID. + +- `_WIN32: DWORD processID`, `!_WIN32: int processID`: The process ID. +- `processInfo`: ProcessInfo struct to store the retrieved information. + +- `true` if the process information is successfully retrieved, `false` if an error occurs. + +## Function: GetProcessInfoByName + +- Retrieves process information by process name. + +- `processName` (const std::string&): The process name. +- `processInfo`: ProcessInfo struct to store the retrieved information. + +- `true` if the process information is successfully retrieved, `false` if an error occurs. diff --git a/doc/atom/system/user.md b/doc/atom/system/user.md new file mode 100644 index 00000000..16cb8e71 --- /dev/null +++ b/doc/atom/system/user.md @@ -0,0 +1,78 @@ +# User Information Library Documentation + +## Function: GetUserGroups + +- Retrieves the user groups associated with the current user. + +- A vector of wide strings containing user groups. + +```cpp +std::vector userGroups = GetUserGroups(); +// Expected output: {"group1", "group2", "group3"} +``` + +## Function: getUsername + +- Retrieves the username of the current user. + +- The username as a string. + +```cpp +std::string username = getUsername(); +// Expected output: "john_doe" +``` + +## Function: getHostname + +- Retrieves the hostname of the system. + +- The hostname as a string. + +```cpp +std::string hostname = getHostname(); +// Expected output: "mycomputer" +``` + +## Function: getUserId + +- Retrieves the user ID of the current user. + +- The user ID as an integer. + +```cpp +int userId = getUserId(); +// Expected output: 1001 +``` + +## Function: getGroupId + +- Retrieves the group ID of the current user. + +- The group ID as an integer. + +```cpp +int groupId = getGroupId(); +// Expected output: 1001 +``` + +## Function: getHomeDirectory + +- Retrieves the user's profile directory. + +- The user's profile directory as a string. + +```cpp +std::string homeDirectory = getHomeDirectory(); +// Expected output: "/home/john_doe" +``` + +## Function: getLoginShell + +- Retrieves the login shell of the user. + +- The login shell as a string. + +```cpp +std::string loginShell = getLoginShell(); +// Expected output: "/bin/bash" +``` diff --git a/doc/atom/type/args.md b/doc/atom/type/args.md new file mode 100644 index 00000000..62b92f72 --- /dev/null +++ b/doc/atom/type/args.md @@ -0,0 +1,170 @@ +# ArgumentContainer Class + +## Introduction + +The `ArgumentContainer` class is a container for storing and retrieving arguments. It provides methods to set, get, remove, and check the existence of parameters. + +## Class Definition + +### Methods + +#### set + +Set the value of a parameter. + +```cpp +template +void set(const std::string &name, const T &value); +``` + +Usage: + +```cpp +ArgumentContainer container; +container.set("age", 30); +``` + +Expected Output: N/A + +#### get + +Get the value of a parameter. + +```cpp +template +std::optional get(const std::string &name) const; +``` + +Usage: + +```cpp +auto age = container.get("age"); +if (age.has_value()) { + std::cout << "Age: " << age.value() << std::endl; +} +``` + +Expected Output: Age: 30 + +#### remove + +Remove a specified parameter. + +```cpp +bool remove(const std::string &name); +``` + +Usage: + +```cpp +bool removed = container.remove("age"); +``` + +Expected Output: N/A + +#### contains + +Check if a parameter exists. + +```cpp +bool contains(const std::string &name) const; +``` + +Usage: + +```cpp +if (container.contains("age")) { + std::cout << "Parameter 'age' exists." << std::endl; +} +``` + +Expected Output: Parameter 'age' exists. + +#### size + +Get the number of parameters. + +```cpp +std::size_t size() const; +``` + +Usage: + +```cpp +std::cout << "Number of parameters: " << container.size() << std::endl; +``` + +Expected Output: Number of parameters: 0 + +#### getNames + +Get all parameter names. + +```cpp +std::vector getNames() const; +``` + +Usage: + +```cpp +std::vector names = container.getNames(); +``` + +Expected Output: Empty vector if no parameters are set. + +#### operator[] + +Overload the index operator [] to get and set the value of a parameter. + +```cpp +template +T &operator[](const std::string &name); +``` + +Usage: + +```cpp +container["age"] = 30; +int age = container["age"]; +``` + +Expected Output: N/A + +#### operator= + +Overload the assignment operator = to set the value of a parameter. + +```cpp +template +void operator=(const std::pair &argument); +``` + +Usage: + +```cpp +container = std::make_pair("age", 30); +``` + +Expected Output: N/A + +#### toJson + +Convert the container to JSON format. + +```cpp +std::string toJson() const; +``` + +Usage: + +```cpp +std::string json = container.toJson(); +``` + +Expected Output: JSON representation of the container. + +### Special Notes + +- The template methods `set`, `get`, `operator[]`, and `operator=` allow flexibility in handling different types of parameters. +- The class uses `std::any` for storing values of any type. +- It supports both `emhash8::HashMap` and `std::unordered_map` as underlying containers based on compilation flags. diff --git a/doc/atom/type/autotype.md b/doc/atom/type/autotype.md new file mode 100644 index 00000000..c0d8c869 --- /dev/null +++ b/doc/atom/type/autotype.md @@ -0,0 +1,67 @@ +# C++ Template Class Examples + +## Any Class + +The `Any` class provides a way to store and retrieve values of any type. It uses template-based polymorphism to achieve this flexibility. + +```cpp +Any a1 = 5; +int value = a1.cast(); +std::cout << "Value: " << value << std::endl; +``` + +Expected Output: Value: 5 + +- The `Any` class uses type erasure to store any type of value. +- The `cast` method is used to retrieve the stored value with the specified type. + +## AutoType Class + +The `AutoType` class is a template class that provides automatic type deduction for arithmetic operations. It enables automatic type conversion when performing arithmetic operations on objects of different types. + +```cpp +AutoType a = makeAutoType(5); +AutoType b = makeAutoType(3.5); +auto result = a + b; +std::cout << "Result: " << result.m_value << std::endl; +``` + +Expected Output: Result: 8.5 + +- The `AutoType` class overloads various arithmetic operators to support automatic type deduction for arithmetic operations. +- The `makeAutoType` function template is used to create `AutoType` objects with automatic type deduction. + +## TuplePrinter Class + +The `TuplePrinter` class is a template class that provides functionality to print the elements of a tuple in reverse order. + +```cpp +std::tuple myTuple = std::make_tuple(10, 3.14, "Hello"); +TuplePrinter::print(myTuple); +``` + +Expected Output: Hello, 3.14, 10 + +- The `TuplePrinter` class uses template recursion to iterate through the elements of the tuple in reverse order. +- The `if constexpr` statement is used to enable compile-time branching based on the size of the tuple. + +## Overall Example + +```cpp +Any a1 = 5; +int value = a1.cast(); +std::cout << "Value: " << value << std::endl; + +AutoType a = makeAutoType(5); +AutoType b = makeAutoType(3.5); +auto result = a + b; +std::cout << "Result: " << result.m_value << std::endl; + +std::tuple myTuple = std::make_tuple(10, 3.14, "Hello"); +TuplePrinter::print(myTuple); +``` + +Expected Output: +Value: 5 +Result: 8.5 +Hello, 3.14, 10 diff --git a/doc/atom/type/ini.md b/doc/atom/type/ini.md new file mode 100644 index 00000000..8254f165 --- /dev/null +++ b/doc/atom/type/ini.md @@ -0,0 +1,177 @@ +# INIFile Class + +The `INIFile` class provides functionality to load, save, set, get, and manipulate data in INI files. It also supports conversion of the data to JSON and XML formats. + +## Public Methods + +### Load + +```cpp +void load(const std::string &filename); +``` + +- **Description:** Loads an INI file. +- **Usage Example:** + +```cpp +INIFile iniFile; +iniFile.load("config.ini"); +``` + +### Save + +```cpp +void save(const std::string &filename); +``` + +- **Description:** Saves the current state to an INI file. +- **Usage Example:** + +```cpp +INIFile iniFile; +iniFile.save("config_saved.ini"); +``` + +### Set + +```cpp +template +void set(const std::string §ion, const std::string &key, const T &value); +``` + +- **Description:** Sets a value in the INI file. +- **Usage Example:** + +```cpp +INIFile iniFile; +iniFile.set("Section1", "Key1", 42); +``` + +### Get + +```cpp +template +std::optional get(const std::string §ion, const std::string &key) const; +``` + +- **Description:** Gets a value from the INI file. +- **Usage Example:** + +```cpp +INIFile iniFile; +auto value = iniFile.get("Section1", "Key1"); +if (value.has_value()) { + std::cout << "Value: " << value.value() << std::endl; +} +``` + +### Has + +```cpp +bool has(const std::string §ion, const std::string &key) const; +``` + +- **Description:** Checks if a key exists in the specified section. +- **Usage Example:** + +```cpp +INIFile iniFile; +bool exists = iniFile.has("Section1", "Key1"); +``` + +### HasSection + +```cpp +bool hasSection(const std::string §ion) const; +``` + +- **Description:** Checks if a section exists in the INI file. +- **Usage Example:** + +```cpp +INIFile iniFile; +bool exists = iniFile.hasSection("Section1"); +``` + +### Operator[] + +```cpp +std::unordered_map operator[](const std::string §ion); +``` + +- **Description:** Returns the content of a section as a map. +- **Usage Example:** + +```cpp +INIFile iniFile; +auto sectionData = iniFile["Section1"]; +``` + +### toJson + +```cpp +std::string toJson() const; +``` + +- **Description:** Converts the data in the INI file to a JSON string. +- **Usage Example:** + +```cpp +INIFile iniFile; +std::string jsonStr = iniFile.toJson(); +``` + +### toXml + +```cpp +std::string toXml() const; +``` + +- **Description:** Converts the data in the INI file to an XML string. +- **Usage Example:** + +```cpp +INIFile iniFile; +std::string xmlStr = iniFile.toXml(); +``` + +## Private Methods + +### parseLine + +```cpp +void parseLine(const std::string &line, std::string ¤tSection); +``` + +- **Description:** Parses a line from the INI file and updates the current section. + +### trim + +```cpp +std::string trim(const std::string &str); +``` + +- **Description:** Trims leading and trailing spaces from a string. + +## Overall Example + +```cpp +INIFile iniFile; +iniFile.load("config.ini"); + +iniFile.set("Section1", "Key1", 42); +iniFile.set("Section1", "Key2", "Value"); + +if (iniFile.has("Section1", "Key1")) { + auto value = iniFile.get("Section1", "Key1"); + if (value.has_value()) { + std::cout << "Value: " << value.value() << std::endl; + } +} + +std::string jsonStr = iniFile.toJson(); +std::string xmlStr = iniFile.toXml(); + +std::cout << "JSON Representation: " << jsonStr << std::endl; +std::cout << "XML Representation: " << xmlStr << std::endl; +``` diff --git a/doc/atom/type/small_vector.md b/doc/atom/type/small_vector.md new file mode 100644 index 00000000..43d0b83c --- /dev/null +++ b/doc/atom/type/small_vector.md @@ -0,0 +1,115 @@ +# SmallVector Template Class + +The `SmallVector` class is a template class that provides a dynamic array implementation with small buffer optimization. It uses a fixed-size inline storage for a small number of elements and switches to dynamic allocation when the number of elements exceeds the capacity of the inline storage. + +## Constructor + +```cpp +SmallVector vec; +vec.push_back(1); +vec.push_back(2); +vec.push_back(3); +``` + +Expected Output: N/A + +- The constructor initializes the vector with inline storage and sets the initial size and capacity. + +## Copy Constructor + +```cpp +SmallVector vec1; +vec1.push_back(1); +vec1.push_back(2); +SmallVector vec2 = vec1; +``` + +Expected Output: N/A + +- Copies elements from another `SmallVector` instance with proper handling for inline and dynamic data. + +## Move Constructor + +```cpp +SmallVector vec1; +vec1.push_back(1); +vec1.push_back(2); +SmallVector vec2 = std::move(vec1); +``` + +Expected Output: N/A + +- Moves elements from another `SmallVector` instance with efficient handling of data ownership. + +## Destructor + +```cpp +{ + SmallVector vec; + vec.push_back(1); + // Destructor called automatically when vec goes out of scope +} +``` + +Expected Output: N/A + +- Properly deallocates memory if dynamic allocation was used. + +## Assignment Operator + +```cpp +SmallVector vec1; +vec1.push_back(1); +SmallVector vec2; +vec2 = vec1; +``` + +Expected Output: N/A + +- Handles assignment of one `SmallVector` to another. + +## Element Access and Modification + +```cpp +SmallVector vec; +vec.push_back(1); +vec.push_back(2); +int value = vec[1]; +std::cout << "Value at index 1: " << value << std::endl; +``` + +Expected Output: Value at index 1: 2 + +- Provides access to elements using the subscript operator. + +## Additional Operations + +```cpp +SmallVector vec; +vec.push_back(1); +vec.push_back(2); +vec.pop_back(); +std::cout << "Size: " << vec.size() << std::endl; +``` + +Expected Output: Size: 1 + +- Supports operations like adding, removing elements, clearing the vector, and checking size and capacity. + +## Overall Example + +```cpp +SmallVector vec1; +vec1.push_back(1); +vec1.push_back(2); + +SmallVector vec2 = vec1; +vec2.push_back(3); + +for (size_t i = 0; i < vec2.size(); ++i) { + std::cout << vec2[i] << " "; +} +std::cout << std::endl; +``` + +Expected Output: 1 2 3 diff --git a/doc/atom/web/curl.md b/doc/atom/web/curl.md new file mode 100644 index 00000000..aa559686 --- /dev/null +++ b/doc/atom/web/curl.md @@ -0,0 +1,293 @@ +# CurlWrapper Class Documentation + +## Introduction + +The `CurlWrapper` class is a C++ wrapper for making HTTP requests using the libcurl library. It provides various methods to set request options, perform synchronous and asynchronous requests, and handle response callbacks. This documentation provides detailed information about the class and its usage, along with code examples for each method. + +### Class Definition + +```cpp +class CurlWrapper { + // ... +}; +``` + +## Constructor and Destructor + +### Constructor + +```cpp +/** + * @brief Constructor for CurlWrapper. + */ +CurlWrapper(); +``` + +#### Usage Example + +```cpp +CurlWrapper curl; +``` + +### Destructor + +```cpp +/** + * @brief Destructor for CurlWrapper. + */ +~CurlWrapper(); +``` + +#### Note + +- The destructor automatically cleans up the libcurl handles. + +## Setting Request Options + +### Set URL + +```cpp +/** + * @brief Set the URL to which the HTTP request will be sent. + * + * @param url The URL to set. + */ +void setUrl(const std::string &url); +``` + +```cpp +curl.setUrl("http://www.example.com/api"); +``` + +### Set Request Method + +```cpp +/** + * @brief Set the request method for the HTTP request (e.g., GET, POST). + * + * @param method The request method to set. + */ +void setRequestMethod(const std::string &method); +``` + +```cpp +curl.setRequestMethod("POST"); +``` + +### Set Header + +```cpp +/** + * @brief Set a header for the HTTP request. + * + * @param key The header key. + * @param value The header value. + */ +void setHeader(const std::string &key, const std::string &value); +``` + +```cpp +curl.setHeader("Content-Type", "application/json"); +``` + +### Set Timeout + +```cpp +/** + * @brief Set the timeout for the HTTP request. + * + * @param timeout The timeout value in seconds. + */ +void setTimeout(long timeout); +``` + +```cpp +curl.setTimeout(30); +``` + +### Set Follow Location + +```cpp +/** + * @brief Set whether to follow HTTP redirects automatically. + * + * @param follow Boolean value indicating whether to follow redirects. + */ +void setFollowLocation(bool follow); +``` + +```cpp +curl.setFollowLocation(true); +``` + +### Set Request Body Data + +```cpp +/** + * @brief Set the request body data for POST requests. + * + * @param data The request body data to set. + */ +void setRequestBody(const std::string &data); +``` + +```cpp +curl.setRequestBody("{ \"key\": \"value\" }"); +``` + +### Set Upload File + +```cpp +/** + * @brief Set the file path for uploading a file in the request. + * + * @param filePath The file path to upload. + */ +void setUploadFile(const std::string &filePath); +``` + +```cpp +curl.setUploadFile("/path/to/file.txt"); +``` + +## Handling Callbacks + +### Set On Error Callback + +```cpp +/** + * @brief Set a callback function to handle errors that occur during the request. + * + * @param callback The callback function to set. + */ +void setOnErrorCallback(std::function callback); +``` + +```cpp +curl.setOnErrorCallback([](CURLcode errorCode) { + std::cerr << "Error occurred: " << curl_easy_strerror(errorCode) << std::endl; +}); +``` + +### Set On Response Callback + +```cpp +/** + * @brief Set a callback function to handle the response data received from the server. + * + * @param callback The callback function to set. + */ +void setOnResponseCallback(std::function callback); +``` + +```cpp +curl.setOnResponseCallback([](const std::string &response) { + std::cout << "Response received: " << response << std::endl; +}); +``` + +## Performing Requests + +### Perform Synchronous Request + +```cpp +/** + * @brief Perform a synchronous HTTP request and return the response data. + * + * @return The response data received from the server. + */ +std::string performRequest(); +``` + +```cpp +std::string response = curl.performRequest(); +std::cout << "Synchronous Response: " << response << std::endl; +``` + +### Perform Asynchronous Request + +```cpp +/** + * @brief Perform an asynchronous HTTP request and invoke a callback + * function when the response is received. + * + * @param callback The callback function to invoke with the response data. + */ +void asyncPerform(std::function callback); +``` + +```cpp +curl.asyncPerform([](const std::string &response) { + std::cout << "Asynchronous Response: " << response << std::endl; +}); +``` + +### Wait for All Asynchronous Requests + +```cpp +/** + * @brief Wait for all asynchronous requests to complete. + */ +void waitAll(); +``` + +- This method waits for all previously initiated asynchronous requests to complete. + +## Internal Implementation + +- The following methods and data members are used internally by the `CurlWrapper` class and are not intended for external use. + +### Private Data Members + +- `CURL *handle`: libcurl easy handle for individual requests +- `CURLM *multiHandle`: libcurl multi handle for managing multiple requests +- `std::vector headers`: Vector to store custom headers for the request +- `std::function onErrorCallback`: Callback function for handling errors +- `std::function onResponseCallback`: Callback function for handling response data +- `std::mutex mutex`: Mutex for thread safety +- `std::condition_variable cv`: Condition variable for synchronization +- `std::string responseData`: Response data received from the server + +### Static Write Callback + +```cpp +/** + * @brief Callback function used by libcurl to write response data into + * responseData member variable. + * + * @param contents Pointer to the response data. + * @param size Size of each data element. + * @param nmemb Number of data elements. + * @param userp User pointer. + * @return Total size of the data written. + */ +static size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp); +``` + +## Overall Example + +```cpp +int main() { + CurlWrapper curl; + curl.setUrl("http://www.example.com/api"); + curl.setRequestMethod("POST"); + curl.setHeader("Content-Type", "application/json"); + curl.setRequestBody("{ \"key\": \"value\" }"); + + // Perform Synchronous Request + std::string syncResponse = curl.performRequest(); + std::cout << "Synchronous Response: " << syncResponse << std::endl; + + // Perform Asynchronous Request + curl.asyncPerform([](const std::string &asyncResponse) { + std::cout << "Asynchronous Response: " << asyncResponse << std::endl; + }); + + // Wait for Asynchronous Request to Complete + curl.waitAll(); + + return 0; +} +``` + +This example demonstrates setting up a `CurlWrapper` instance, setting request options, performing synchronous and asynchronous requests, and handling the responses. diff --git a/doc/atom/web/downloader.md b/doc/atom/web/downloader.md new file mode 100644 index 00000000..7c4465be --- /dev/null +++ b/doc/atom/web/downloader.md @@ -0,0 +1,110 @@ +# DownloadManager Class Documentation + +## Description + +The `DownloadManager` class is designed to manage download tasks, allowing users to add, remove, start, pause, resume tasks and get information about downloaded bytes. + +```cpp +// Create a DownloadManager instance with a file to save task list +DownloadManager manager("task_list.txt"); + +// Add a new download task with high priority +manager.add_task("https://example.com/file.zip", "downloads/file.zip", 2); + +// Start downloading tasks using default settings +manager.start(); + +// Pause a specific task by index +manager.pause_task(0); + +// Resume the paused task +manager.resume_task(0); + +// Get the number of downloaded bytes for a task +size_t downloaded_bytes = manager.get_downloaded_bytes(0); +``` + +## Constructor + +### `DownloadManager(const std::string &task_file)` + +Constructs a DownloadManager object with the specified task file path. + +## Public Methods + +### `void add_task(const std::string &url, const std::string &filepath, int priority = 0)` + +Adds a new download task with the given URL, local file path, and optional priority. + +### `bool remove_task(size_t index)` + +Removes a task at the specified index from the task list. Returns true if successful. + +### `void start(size_t thread_count = std::thread::hardware_concurrency(), size_t download_speed = 0)` + +Starts downloading tasks with the specified number of threads and download speed limit. + +### `void pause_task(size_t index)` + +Pauses the task at the specified index. + +### `void resume_task(size_t index)` + +Resumes the paused task at the specified index. + +### `size_t get_downloaded_bytes(size_t index)` + +Returns the number of bytes downloaded for the task at the given index. + +## Private Methods + +### `std::optional get_next_task_index()` + +Returns the index of the next task to download or empty if the task queue is empty. + +### `std::optional get_next_task()` + +Returns the next task to download or empty if the task queue is empty. + +### `void run(size_t download_speed)` + +Starts the download threads with the specified download speed limit. + +### `void download_task(DownloadTask &task, size_t download_speed)` + +Downloads the specified task with the given download speed limit. + +### `void save_task_list_to_file()` + +Saves the current task list to the file specified during object construction. + +## Member Variables + +- `task_file_` : File path to save the task list. +- `tasks_` : List of download tasks. +- `task_queue_` : Priority queue for tasks based on priority. +- `mutex_` : Mutex for thread synchronization. +- `running_` : Atomic flag indicating if downloads are in progress. +- `start_time_` : Time point when download manager starts. + +- The priority queue ensures tasks are processed based on priority level. +- Thread safety is maintained using mutex for accessing shared data. + +```cpp +int main() { + DownloadManager manager("task_list.txt"); + + manager.add_task("https://example.com/file1.zip", "downloads/file1.zip", 2); + manager.add_task("https://example.com/file2.zip", "downloads/file2.zip", 1); + + manager.start(2, 1024); // Start downloading with 2 threads and speed limit of 1KB/s + + manager.pause_task(0); // Pause the first task + + manager.resume_task(0); // Resume the first task + + size_t downloaded_bytes = manager.get_downloaded_bytes(1); // Get downloaded bytes for the second task + + return 0; +} +``` diff --git a/doc/atom/web/httpclient.md b/doc/atom/web/httpclient.md new file mode 100644 index 00000000..1143c799 --- /dev/null +++ b/doc/atom/web/httpclient.md @@ -0,0 +1,221 @@ +# HttpClient Class Documentation + +## Overview + +The `HttpClient` class is used for making HTTP requests using `HttpClientImpl`. It provides methods for sending GET, POST, PUT, and DELETE requests, as well as for setting SSL configurations and scanning ports. + +### Constructor + +```cpp +explicit HttpClient(const std::string &host, int port, bool sslEnabled); +``` + +- Constructs an HttpClient object with the specified `host`, `port`, and `sslEnabled` flag. + +```cpp +// Create an HttpClient object with SSL enabled +HttpClient client("example.com", 443, true); +``` + +--- + +### Method: sendGetRequest + +```cpp +bool sendGetRequest(const std::string &path, const std::map ¶ms, nlohmann::json &response, std::string &err); +``` + +- Sends an HTTP GET request to the specified `path` with optional `params`, and populates `response` with the server response. + +```cpp +std::map params = {{"key1", "value1"}, {"key2", "value2"}}; +nlohmann::json jsonResponse; +std::string error; + +bool success = client.sendGetRequest("/endpoint", params, jsonResponse, error); +if (success) { + // Process jsonResponse +} else { + // Handle error +} +``` + +--- + +### Method: sendPostRequest + +```cpp +bool sendPostRequest(const std::string &path, const std::map ¶ms, const nlohmann::json &data, nlohmann::json &response, std::string &err); +``` + +- Sends an HTTP POST request to the specified `path` with optional `params` and `data`, and populates `response` with the server response. + +```cpp +nlohmann::json postData = { + {"key", "value"} +}; +bool success = client.sendPostRequest("/endpoint", {}, postData, jsonResponse, error); +``` + +--- + +### Method: sendPutRequest + +```cpp +bool sendPutRequest(const std::string &path, const std::map ¶ms, const nlohmann::json &data, nlohmann::json &response, std::string &err); +``` + +- Sends an HTTP PUT request to the specified `path` with optional `params` and `data`, and populates `response` with the server response. + +```cpp +bool success = client.sendPutRequest("/endpoint", {}, postData, jsonResponse, error); +``` + +--- + +### Method: sendDeleteRequest + +```cpp +bool sendDeleteRequest(const std::string &path, const std::map ¶ms, nlohmann::json &response, std::string &err); +``` + +- Sends an HTTP DELETE request to the specified `path` with optional `params`, and populates `response` with the server response. + +```cpp +bool success = client.sendDeleteRequest("/endpoint", {}, jsonResponse, error); +``` + +--- + +### Method: setSslEnabled + +```cpp +void setSslEnabled(bool enabled); +``` + +- Sets whether SSL is enabled for the HTTP client. + +```cpp +client.setSslEnabled(true); +``` + +--- + +### Method: setCaCertPath + +```cpp +void setCaCertPath(const std::string &path); +``` + +- Sets the path to the CA certificate for SSL verification. + +```cpp +client.setCaCertPath("/path/to/ca_cert.pem"); +``` + +--- + +### Method: setClientCertPath + +```cpp +void setClientCertPath(const std::string &path); +``` + +- Sets the path to the client certificate for client authentication. + +```cpp +client.setClientCertPath("/path/to/client_cert.pem"); +``` + +--- + +### Method: setClientKeyPath + +```cpp +void setClientKeyPath(const std::string &path); +``` + +- Sets the path to the client key for client authentication. + +```cpp +client.setClientKeyPath("/path/to/client_key.pem"); +``` + +--- + +### Method: scanPort + +```cpp +bool scanPort(int startPort, int endPort, std::vector &openPorts); +``` + +- Scans the range of ports between `startPort` and `endPort` and populates `openPorts` with the list of open ports. + +```cpp +std::vector openPorts; +bool success = client.scanPort(80, 100, openPorts); +if (success) { + // Process openPorts +} else { + // Handle error +} +``` + +--- + +### Method: checkServerStatus + +```cpp +bool checkServerStatus(std::string &status); +``` + +- Checks the status of the server and populates `status` with the server status. + +```cpp +std::string serverStatus; +bool success = client.checkServerStatus(serverStatus); +if (success) { + // Process serverStatus +} else { + // Handle error +} +``` + +--- + +### Complete Example + +Here's a complete example of using the HttpClient class: + +```cpp +int main() { + HttpClient client("example.com", 443, true); + + nlohmann::json jsonResponse; + std::string error; + + // Send a GET request + bool successGet = client.sendGetRequest("/endpoint", {}, jsonResponse, error); + + // Send a POST request + nlohmann::json postData = {{"key", "value"}}; + bool successPost = client.sendPostRequest("/endpoint", {}, postData, jsonResponse, error); + + // Set SSL configuration + client.setCaCertPath("/path/to/ca_cert.pem"); + client.setClientCertPath("/path/to/client_cert.pem"); + client.setClientKeyPath("/path/to/client_key.pem"); + + // Scan ports + std::vector openPorts; + bool successScan = client.scanPort(80, 100, openPorts); + + // Check server status + std::string serverStatus; + bool successStatus = client.checkServerStatus(serverStatus); + + return 0; +} +``` + +This concludes the documentation for the HttpClient class. diff --git a/doc/atom/web/httplite.md b/doc/atom/web/httplite.md new file mode 100644 index 00000000..8c6c6ef7 --- /dev/null +++ b/doc/atom/web/httplite.md @@ -0,0 +1,201 @@ +# HttpClient Class Documentation + +The `HttpClient` class is used to establish a connection to a server and send requests while receiving responses. + +```cpp +HttpClient(); +``` + +- Constructs an HttpClient object. + +```cpp +HttpClient client; +bool success = client.initialize(); +if (success) { + // Initialization successful +} else { + // Initialization failed +} +``` + +--- + +## Method: setErrorHandler + +```cpp +void setErrorHandler(std::function errorHandler); +``` + +- Sets the error handling function for the HttpClient. + +```cpp +client.setErrorHandler([](const std::string &error) { + // Handle error, e.g., logging or displaying an error message +}); +``` + +--- + +## Method: connectToServer + +```cpp +bool connectToServer(const std::string &host, int port, bool useHttps); +``` + +- Connects to the server with the specified `host`, `port`, and whether to use HTTPS. + +```cpp +bool connected = client.connectToServer("example.com", 80, false); +if (connected) { + // Connected successfully +} else { + // Connection failed +} +``` + +--- + +## Method: sendRequest + +```cpp +bool sendRequest(const std::string &request); +``` + +- Sends a request to the server with the specified `request` content. + +```cpp +bool requestSent = client.sendRequest("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"); +if (requestSent) { + // Request sent successfully +} else { + // Failed to send request +} +``` + +--- + +## Method: receiveResponse + +```cpp +HttpResponse receiveResponse(); +``` + +- Receives the server's response. + +```cpp +HttpResponse response = client.receiveResponse(); +// Process response +``` + +--- + +## HttpRequestBuilder Class Documentation + +The `HttpRequestBuilder` class is used to construct HTTP requests. + +```cpp +HttpRequestBuilder(HttpMethod method, const std::string &url); +``` + +- Constructs an HttpRequestBuilder object with the specified `method` and `url`. + +```cpp +HttpRequestBuilder builder(HttpMethod::GET, "http://example.com/api/resource"); +``` + +--- + +## Method: setBody + +```cpp +HttpRequestBuilder &setBody(const std::string &bodyText); +``` + +- Sets the body content of the request. + +```cpp +builder.setBody("Some request body content"); +``` + +--- + +## Method: setContentType + +```cpp +HttpRequestBuilder &setContentType(const std::string &contentTypeValue); +``` + +- Sets the content type of the request. + +```cpp +builder.setContentType("application/json"); +``` + +--- + +## Method: setTimeout + +```cpp +HttpRequestBuilder &setTimeout(std::chrono::seconds timeoutValue); +``` + +- Sets the timeout for the request. + +```cpp +builder.setTimeout(std::chrono::seconds(30)); +``` + +--- + +## Method: addHeader + +```cpp +HttpRequestBuilder &addHeader(const std::string &key, const std::string &value); +``` + +- Adds a header to the request. + +```cpp +builder.addHeader("Authorization", "Bearer token123"); +``` + +--- + +## Method: send + +```cpp +HttpResponse send(); +``` + +- Sends the constructed HTTP request and receives the response. + +```cpp +HttpResponse response = builder.send(); +// Process response +``` + +--- + +## Complete Example + +Here's a complete example of using the HttpClient and HttpRequestBuilder classes: + +```cpp +int main() { + HttpClient client; + client.setErrorHandler([](const std::string &error) { + // Handle error + }); + + bool connected = client.connectToServer("example.com", 80, false); + if (connected) { + HttpRequestBuilder builder(HttpMethod::GET, "/api/resource"); + HttpResponse response = builder.send(); + // Process response + } else { + // Connection failed + } + + return 0; +} +``` diff --git a/doc/atom/web/httpparser.md b/doc/atom/web/httpparser.md new file mode 100644 index 00000000..d2308bfb --- /dev/null +++ b/doc/atom/web/httpparser.md @@ -0,0 +1,201 @@ +# HttpHeaderParser Class Documentation + +## Overview + +The `HttpHeaderParser` class is responsible for parsing and manipulating HTTP headers. + +### Constructor + +```cpp +HttpHeaderParser(); +``` + +- Constructs a new `HttpHeaderParser` object. + +```cpp +HttpHeaderParser parser; +``` + +--- + +### Destructor + +```cpp +~HttpHeaderParser(); +``` + +- Destroys the `HttpHeaderParser` object. + +--- + +### Method: parseHeaders + +```cpp +void parseHeaders(const std::string &rawHeaders); +``` + +- Parses the raw HTTP headers and stores them internally. + +```cpp +std::string rawHeaders = "Content-Type: application/json\r\n"; +rawHeaders += "Content-Length: 123\r\n\r\n"; +parser.parseHeaders(rawHeaders); +``` + +--- + +### Method: setHeaderValue + +```cpp +void setHeaderValue(const std::string &key, const std::string &value); +``` + +- Sets the value of a specific header field. + +```cpp +parser.setHeaderValue("Content-Type", "text/html"); +``` + +--- + +### Method: setHeaders + +```cpp +void setHeaders(const std::map> &headers); +``` + +- Sets multiple header fields at once. + +```cpp +std::map> headers = { + {"Content-Type", {"application/json"}}, + {"Content-Length", {"123"}} +}; +parser.setHeaders(headers); +``` + +--- + +### Method: getHeaderValues + +```cpp +std::vector getHeaderValues(const std::string &key) const; +``` + +- Retrieves the values of a specific header field. + +```cpp +std::vector values = parser.getHeaderValues("Content-Type"); +for (const auto &value : values) { + std::cout << "Value: " << value << std::endl; +} +``` + +--- + +### Method: removeHeader + +```cpp +void removeHeader(const std::string &key); +``` + +- Removes a specific header field. + +```cpp +parser.removeHeader("Content-Length"); +``` + +--- + +### Method: printHeaders + +```cpp +void printHeaders() const; +``` + +- Prints all the parsed headers to the console. + +```cpp +parser.printHeaders(); +``` + +--- + +### Method: getAllHeaders + +```cpp +std::map> getAllHeaders() const; +``` + +- Retrieves all the parsed headers. + +```cpp +std::map> headers = parser.getAllHeaders(); +// Process the retrieved headers +``` + +--- + +### Method: hasHeader + +```cpp +bool hasHeader(const std::string &key) const; +``` + +- Checks if a specific header field exists. + +```cpp +bool exists = parser.hasHeader("Content-Type"); +if (exists) { + std::cout << "Header exists" << std::endl; +} else { + std::cout << "Header does not exist" << std::endl; +} +``` + +--- + +### Method: clearHeaders + +```cpp +void clearHeaders(); +``` + +- Clears all the parsed headers. + +```cpp +parser.clearHeaders(); +``` + +--- + +### Note + +- The `HttpHeaderParser` uses the Pimpl idiom, where the implementation details are hidden behind a pointer to implementation (`m_pImpl`). This allows for better encapsulation and reduces compile-time dependencies. + +### Complete Example + +Here's a complete example of using the `HttpHeaderParser` class: + +```cpp +int main() { + HttpHeaderParser parser; + + std::string rawHeaders = "Content-Type: application/json\r\n"; + rawHeaders += "Content-Length: 123\r\n\r\n"; + parser.parseHeaders(rawHeaders); + + parser.setHeaderValue("Content-Type", "text/html"); + + std::vector values = parser.getHeaderValues("Content-Type"); + for (const auto &value : values) { + std::cout << "Value: " << value << std::endl; + } + + parser.removeHeader("Content-Length"); + + parser.printHeaders(); + + return 0; +} +``` diff --git a/doc/atom/web/time.md b/doc/atom/web/time.md new file mode 100644 index 00000000..69073afe --- /dev/null +++ b/doc/atom/web/time.md @@ -0,0 +1,103 @@ +# System Time Management API Documentation + +## Function: getSystemTime + +```cpp +std::time_t getSystemTime(); +``` + +- Retrieves the current system time in seconds since Unix epoch. + +```cpp +std::time_t currentTime = getSystemTime(); +std::cout << "Current system time: " << currentTime << " seconds since Unix epoch" << std::endl; +``` + +Expected Output + +```txt +Current system time: 1648323625 seconds since Unix epoch +``` + +--- + +## Function: setSystemTime + +```cpp +void setSystemTime(int year, int month, int day, int hour, int minute, int second); +``` + +- Sets the system time to the specified date and time. + +```cpp +setSystemTime(2024, 3, 25, 15, 0, 0); // Set the system time to March 25, 2024, 3:00:00 PM +``` + +--- + +## Function: setSystemTimezone + +```cpp +bool setSystemTimezone(const std::string &timezone); +``` + +- Sets the system timezone to the specified timezone. + +```cpp +bool success = setSystemTimezone("America/New_York"); +if (success) { + std::cout << "Timezone set successfully" << std::endl; +} else { + std::cout << "Failed to set timezone" << std::endl; +} +``` + +--- + +## Function: syncTimeFromRTC + +```cpp +bool syncTimeFromRTC(); +``` + +- Synchronizes the system time with an RTC (real-time clock) device. + +```cpp +bool syncSuccess = syncTimeFromRTC(); +if (syncSuccess) { + std::cout << "System time synchronized with RTC" << std::endl; +} else { + std::cout << "Failed to synchronize system time with RTC" << std::endl; +} +``` + +--- + +## Complete Example + +Here's a complete example of using the system time management functions: + +```cpp +int main() { + std::time_t currentTime = getSystemTime(); + std::cout << "Current system time: " << currentTime << " seconds since Unix epoch" << std::endl; + + setSystemTime(2024, 3, 25, 15, 0, 0); + + bool tzSetSuccess = setSystemTimezone("America/New_York"); + if (tzSetSuccess) { + std::cout << "Timezone set successfully" << std::endl; + } else { + std::cout << "Failed to set timezone" << std::endl; + } + + bool syncSuccess = syncTimeFromRTC(); + if (syncSuccess) { + std::cout << "System time synchronized with RTC" << std::endl; + } else { + std::cout << "Failed to synchronize system time with RTC" << std::endl; + } + + return 0; +} +``` diff --git a/doc/components/README.md b/doc/components/README.md new file mode 100644 index 00000000..00b795c1 --- /dev/null +++ b/doc/components/README.md @@ -0,0 +1,94 @@ +# Lithium & Atom Components: Advanced Concepts + +Atom's component mechanism forms the foundation of all elements within the ecosystem. Components, as the name suggests, are fundamental building blocks that enhance the server's functionality. + +## Loading Mechanism + +Due to the unique nature of C++, unlike Java where classes can be loaded by name, the loading mechanism for components involves loading dynamic libraries and obtaining corresponding shared class pointers. + +## Component Structure + +Each component consists of a dynamic library and a corresponding `package.json` file. Additional files like `package.xml` can be included to describe component dependencies if necessary. + +Example structure: + +```plaintext +component-demo +├── package.json +└── component-demo.so +``` + +In this example, the `component-demo` component includes a `component-demo.so` dynamic library (the filename can differ from the folder name) and a `package.json` file. + +## `package.json` + +The `package.json` serves as the configuration file for components, containing essential information such as component name, version, author, etc. The `main` section is crucial as it defines the entry function of the component and its type. + +## Dynamic Library + +The loading logic of dynamic libraries can be found in `atom/module/module_loader.cpp`. On Windows, we utilize the `dl-win` library, so the function form is consistent with Linux platforms. + +A simple test function can be written to load the dynamic library: + +```cpp +#include +#include + +int main() +{ + void* handle = dlopen("./component-demo.so", RTLD_LAZY); + if (handle == nullptr) + { + std::cout << dlerror() << std::endl; + return -1; + } + + return 0; +} +``` + +It's essential for the dynamic library to contain the functions declared in `package.json`, or else it won't load correctly. + +## Component Registration + +Component registration and management are handled by `ComponentManager`. The directory structure for component management in the Lithium server is as follows: + +```plaintext +components +├── component-finder.cpp +├── component_finder.hpp +├── component_info.cpp +├── component_info.hpp +├── component_manager.cpp +├── component_manager.hpp +├── package_manager.cpp +├── package_manager.hpp +├── project_info.cpp +└── project_info.hpp +├── project_manager.cpp +└── project_manager.hpp +├── sandbox.cpp +└── sandbox.hpp +``` + +Each component's function: + +- `component-finder`: Responsible for locating components by traversing folders in the `modules` directory that meet specific criteria (at least one dynamic library and one `package.json` file). +- `component_info`: Defines component information to handle data from `package.json`. +- `component_manager`: Manages component loading and unloading. +- `package_manager`: Manages component packages. +- `project_info`: Defines project information, managing dependencies between components and preventing circular references. +- `project_manager`: Manages projects, facilitating component updates, providing Git project management, and basic CI build mechanisms. +- `sandbox`: Isolates component runtime environments, creating a secure execution environment for `standalone components`, particularly effective on Linux. + +## Device Components + +Device components, unlike regular components, follow a protocol similar to INDI but with a simpler protocol. They will be implemented separately as `atom.driver` for driver library functionality. + +## Component Communication + +### Shared Components + +Communication between shared components is achieved using the `MessageBus (Global)` implementation. + +This advanced documentation elaborates on the precise terminology and provides a more detailed explanation of module concepts for better understanding and implementation within the Atom framework. diff --git a/doc/component.md b/doc/components/README_ZH.md similarity index 50% rename from doc/component.md rename to doc/components/README_ZH.md index 455208e5..f1f00128 100644 --- a/doc/component.md +++ b/doc/components/README_ZH.md @@ -1,14 +1,14 @@ # Lithium & Atom Components -Atom的组件机制是元素天文所有组建的基础,正如其名,组件是最基础的,你可以通过组件增强服务器的功能。 +Atom 的组件机制是元素天文所有组建的基础,正如其名,组件是最基础的,你可以通过组件增强服务器的功能。 ## 加载机制 -由于c++的特殊性,导致无法像java那样通过类名加载类,所以组件的加载机制是通过加载动态库后获取对应的共享类指针完成的 +由于 c++的特殊性,导致无法像 java 那样通过类名加载类,所以组件的加载机制是通过加载动态库后获取对应的共享类指针完成的 ## 组件组成 -每个组件都是有动态库和对应的package.json组成的,如果后需要有需要的话,可以加入package.xml之类的文件来描述组件的依赖关系。 +每个组件都是有动态库和对应的 package.json 组成的,如果后需要有需要的话,可以加入 package.xml 之类的文件来描述组件的依赖关系。 举一个例子: @@ -18,43 +18,39 @@ Atom的组件机制是元素天文所有组建的基础,正如其名,组件 └── component-demo.so ``` -在这个例子中,我们的component-demo组件中包含一个component-demo.so(可以与文件夹名称不同,而且后缀名根据平台而定)动态库,以及package.json文件。 +在这个例子中,我们的 component-demo 组件中包含一个 component-demo.so(可以与文件夹名称不同,而且后缀名根据平台而定)动态库,以及 package.json 文件。 ### package.json -package.json是组件的配置文件,它包含了组件的基本信息,比如组件的名称,版本,作者等。 +package.json 是组件的配置文件,它包含了组件的基本信息,比如组件的名称,版本,作者等。 ```json { - "name": "example", - "version": "0.0.0", - "type": "shared", - "description": "An example project", - "license": "LGPL-3.0-or-later", - "author": "Max Qian", - "repository": { - "type": "git", - "url": "https://github.com/maxqian/cobalt-example.git" - }, - "bugs": { - "url": "https://github.com/maxqian/cobalt-example/issues" - }, - "homepage": "https://github.com/maxqian/cobalt-example", - "keywords": [ - "atom", - "example", - "component", - ], - "scripts": { - "dev": "run", - }, - "dependencies": ["atom.core"], - "main": { - "example1": { - "func": "getExample1", - "type" : "shared" - } + "name": "example", + "version": "0.0.0", + "type": "shared", + "description": "An example project", + "license": "LGPL-3.0-or-later", + "author": "Max Qian", + "repository": { + "type": "git", + "url": "https://github.com/maxqian/cobalt-example.git" + }, + "bugs": { + "url": "https://github.com/maxqian/cobalt-example/issues" + }, + "homepage": "https://github.com/maxqian/cobalt-example", + "keywords": ["atom", "example", "component"], + "scripts": { + "dev": "run" + }, + "dependencies": ["atom.core"], + "main": { + "example1": { + "func": "getExample1", + "type": "shared" } + } } ``` @@ -64,7 +60,7 @@ Warning: 每种组件的加载机制不太一样,请注意区分。 ### 动态库 -动态库的加载具体加载逻辑请参考`atom/module/module_loader.cpp`,在Windows下平台我们使用了`dl-win`库,因此函数形式与Linux下一致。 +动态库的加载具体加载逻辑请参考`atom/module/module_loader.cpp`,在 Windows 下平台我们使用了`dl-win`库,因此函数形式与 Linux 下一致。 你可以自己写一个小函数进行测试,后续也会提供对应的构建工具 @@ -85,11 +81,11 @@ int main() } ``` -动态库中必须要存在package.json中声明的函数,否则将无法正常加载。 +动态库中必须要存在 package.json 中声明的函数,否则将无法正常加载。 ## 组件注册 -组件的注册与管理使用`ComponentManager`完成,下面是Lithium服务器中组件管理的目录架构 +组件的注册与管理使用`ComponentManager`完成,下面是 Lithium 服务器中组件管理的目录架构 ```txt components @@ -110,17 +106,17 @@ int main() ``` 其中每个组件的功能: -`component-finder`是组件的查找器,主要负责遍历`modules`目录下所有符合条件的文件夹,具体的条件为存在至少一个动态库和package.json文件 -`component_info`是组件信息的定义,主要用来处理package.json中的组件信息 +`component-finder`是组件的查找器,主要负责遍历`modules`目录下所有符合条件的文件夹,具体的条件为存在至少一个动态库和 package.json 文件 +`component_info`是组件信息的定义,主要用来处理 package.json 中的组件信息 `component_manager`是组件管理器,主要用来管理组件的加载和卸载 `package_manager`是包管理器,主要用来管理组件的包 `project_info`是项目信息的定义,主要用来组件之间的依赖关系和防止循环引用 -`project_manager`是项目管理器,主要用来管理项目的加载和卸载,可以更加方便的更新组件,提供Git项目管理和基础的CI构建机制 -`sanbox`是沙盒,主要用来隔离组件的运行环境,创建`独立组件`的安全运行环境,在Linux下的运行效果较好 +`project_manager`是项目管理器,主要用来管理项目的加载和卸载,可以更加方便的更新组件,提供 Git 项目管理和基础的 CI 构建机制 +`sanbox`是沙盒,主要用来隔离组件的运行环境,创建`独立组件`的安全运行环境,在 Linux 下的运行效果较好 ### 设备组件 -设备组件不同于普通的组件,它的交互机制类似于INDI,但是协议更加简单,后续会单独作为atom.driver驱动库进行实现。 +设备组件不同于普通的组件,它的交互机制类似于 INDI,但是协议更加简单,后续会单独作为 atom.driver 驱动库进行实现。 ## 组件通信 diff --git a/src/App.cpp b/src/App.cpp index 1613e648..c541ba05 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -22,7 +22,7 @@ Description: Main #include "controller/AsyncStaticController.hpp" #include "controller/AsyncSystemController.hpp" #include "controller/AsyncUploadController.hpp" -//#include "controller/AsyncWebSocketController.hpp" +// #include "controller/AsyncWebSocketController.hpp" #include "controller/AsyncClientController.hpp" #else @@ -45,7 +45,6 @@ Description: Main #include "atom/system/crash.hpp" #include "atom/web/utils.hpp" - #include #include #include @@ -77,9 +76,14 @@ void runServer() { Lithium::MyApp->GetConfig("config/server") .value("port", 8000)); // Create scope Environment components #else + DLOG_F(INFO, "Server host:", Lithium::MyApp->GetConfig({"key", "config/server"}) + .value("host", "0.0.0.0")); + DLOG_F(INFO, "Server port:", Lithium::MyApp->GetConfig({"key", "config/server"}) + .value("port", 8000)); AppComponent components( - Lithium::MyApp->GetConfig("config/server").value("host", "0.0.0.0"), - Lithium::MyApp->GetConfig("config/server") + Lithium::MyApp->GetConfig({"key", "config/server"}) + .value("host", "0.0.0.0"), + Lithium::MyApp->GetConfig({"key", "config/server"}) .value("port", 8000)); // Create scope Environment components #endif DLOG_F(INFO, "App component loaded"); @@ -93,22 +97,21 @@ void runServer() { "AsyncConfigController"); ADD_CONTROLLER(StaticController, docEndpoints, router, - "AsyncStaticController"); + "AsyncStaticController"); ADD_CONTROLLER(SystemController, docEndpoints, router, - "AsyncSystemController"); + "AsyncSystemController"); - //ADD_CONTROLLER(WebSocketController, docEndpoints, router, - // "AsyncWebSocketController"); + // ADD_CONTROLLER(WebSocketController, docEndpoints, router, + // "AsyncWebSocketController"); - ADD_CONTROLLER(IOController, docEndpoints, router, - "AsyncIOController"); + ADD_CONTROLLER(IOController, docEndpoints, router, "AsyncIOController"); ADD_CONTROLLER(ProcessController, docEndpoints, router, - "AsyncProcessController"); + "AsyncProcessController"); ADD_CONTROLLER(ClientController, docEndpoints, router, - "AsyncClientController"); + "AsyncClientController"); DLOG_F(INFO, "Starting to load API doc controller"); #if ENABLE_ASYNC @@ -121,7 +124,7 @@ void runServer() { DLOG_F(INFO, "API doc controller loaded"); /* Load websocket route */ - //router->addController(WebSocketController::createShared()); + // router->addController(WebSocketController::createShared()); /* Get connection handler component */ OATPP_COMPONENT(std::shared_ptr, diff --git a/src/AppComponent.hpp b/src/AppComponent.hpp index 68560011..0d1ec5c0 100644 --- a/src/AppComponent.hpp +++ b/src/AppComponent.hpp @@ -12,11 +12,14 @@ Description: App Components **************************************************/ -#ifndef AppComponent_hpp -#define AppComponent_hpp +#ifndef LITHIUM_APP_COMPONENT_HPP +#define LITHIUM_APP_COMPONENT_HPP #include "config.h" +#include "config/Config.hpp" +#include "config/HubsConfig.hpp" + #include "websocket/Registry.hpp" #if ENABLE_ASYNC #include "oatpp-websocket/AsyncConnectionHandler.hpp" @@ -51,6 +54,7 @@ Description: App Components #include "oatpp-openssl/server/ConnectionProvider.hpp" #include "oatpp-zlib/EncoderProvider.hpp" +#include #include // for std::thread::hardware_concurrency // #include "data/SystemCustom.hpp" @@ -67,6 +71,8 @@ class AppComponent { oatpp::String m_host; v_uint16 m_port; + oatpp::base::CommandLineArguments m_cmdArgs; // command line arguments + public: /** * Create components @@ -80,6 +86,42 @@ class AppComponent { */ SwaggerComponent swaggerComponent; + /** + * Create config component + */ + OATPP_CREATE_COMPONENT(oatpp::Object, appConfig) + ([this] { + auto config = ConfigDto::createShared(); + + auto hostServer = ServerConfigDto::createShared(); + hostServer->host = "0.0.0.0"; + hostServer->port = 8000; + + auto clientServer = ServerConfigDto::createShared(); + clientServer->host = "0.0.0.0"; + clientServer->port = 8001; + + config->hostAPIServer = hostServer; + config->clientAPIServer = clientServer; + + return config; + }()); + + /** + * Hub configs + */ + OATPP_CREATE_COMPONENT(std::shared_ptr, hubConfig) + ([] { + auto config = std::make_shared(nullptr); + auto Hub1 = HubConfigDto::createShared(); + auto Hub2 = HubConfigDto::createShared(); + Hub1->hubId = "device"; + Hub2->hubId = "script"; + config->putHubConfig(Hub1); + config->putHubConfig(Hub2); + return config; + }()); + #if ENABLE_ASYNC /** * Create Async Executor @@ -94,6 +136,9 @@ class AppComponent { }()); #endif + /** + * Create Debug virtual interface component + */ #if ENABLE_DEBUG OATPP_CREATE_COMPONENT(std::shared_ptr, virtualInterface) @@ -102,13 +147,20 @@ class AppComponent { }()); #endif + /** + * Create Router component + */ + OATPP_CREATE_COMPONENT(std::shared_ptr, + httpRouter) + ([] { return oatpp::web::server::HttpRouter::createShared(); }()); + /** * Create ObjectMapper component to serialize/deserialize DTOs in * Controller's API */ OATPP_CREATE_COMPONENT(std::shared_ptr, apiObjectMapper) - ([] { + (Constants::COMPONENT_REST_API, [] { /* create serializer and deserializer configurations */ auto serializeConfig = oatpp::parser::json::mapping::Serializer::Config::createShared(); @@ -146,6 +198,12 @@ class AppComponent { return mapper; }()); + /** + * Create hubs sessions Registry component. + */ + OATPP_CREATE_COMPONENT(std::shared_ptr, hubsSessionsRegistry) + ([] { return std::make_shared(); }()); + /** * Create ConnectionProvider component which listens on the port */ @@ -157,37 +215,25 @@ class AppComponent { connectionProvider; if (m_port == 0) { #if ENABLE_DEBUG - OATPP_LOGD("Debug", "Debug server is starting ..."); OATPP_COMPONENT( std::shared_ptr, interface); connectionProvider = oatpp::network::virtual_::server:: ConnectionProvider::createShared(interface); -#else - OATPP_LOGE("Debug", - "Debug mode is not enabled,please enable when compile"); #endif } else { -#if ENABLE_IPV6 connectionProvider = oatpp::network::tcp::server::ConnectionProvider::createShared( - {m_host, m_port, oatpp::network::Address::IP_6}); +#if ENABLE_IPV6 + { m_host, m_port, oatpp::network::Address::IP_6 } #else - connectionProvider = - oatpp::network::tcp::server::ConnectionProvider::createShared( - {m_host, m_port, oatpp::network::Address::IP_4}); + {m_host, m_port, oatpp::network::Address::IP_4} #endif + ); } return connectionProvider; }()); - /** - * Create Router component - */ - OATPP_CREATE_COMPONENT(std::shared_ptr, - httpRouter) - ([] { return oatpp::web::server::HttpRouter::createShared(); }()); - /** * Create ConnectionHandler component which uses Router component to route * requests @@ -254,4 +300,4 @@ class AppComponent { }()); }; -#endif /* AppComponent_hpp */ \ No newline at end of file +#endif /* LITHIUM_APP_COMPONENT_HPP */ \ No newline at end of file diff --git a/src/atom/algorithm/mathutils.cpp b/src/atom/algorithm/mathutils.cpp new file mode 100644 index 00000000..5a632eca --- /dev/null +++ b/src/atom/algorithm/mathutils.cpp @@ -0,0 +1,105 @@ +/* + * mathutils.cpp + * + * Copyright (C) 2023-2024 Max Qian + */ + +/************************************************* + +Date: 2023-11-10 + +Description: Extra Math Library + +**************************************************/ + +#include "mathutils.hpp" + +#if defined(_MSC_VER) +#include +#endif + +namespace Atom::Algorithm { + +uint64_t mulDiv64(uint64_t operant, uint64_t multiplier, + uint64_t divider) { +#if defined(__GNUC__) && defined(__SIZEOF_INT128__) + __uint128_t a = operant; + __uint128_t b = multiplier; + __uint128_t c = divider; + + return (uint64_t)(a * b / c); +#elif defined(_MSC_VER) +#if defined(_M_IX86) + // Your x86 specific code here +#elif defined(_M_X64) +#pragma warning(push) +#pragma warning(disable : 4244) // C4244: 'conversion' conversion from 'type1' + // to 'type2', possible loss of data + uint64_t a = operant; + uint64_t b = multiplier; + uint64_t c = divider; + + // Normalize divisor + unsigned long shift; + _BitScanReverse64(&shift, c); + shift = 63 - shift; + + c <<= shift; + + // Multiply + a = _umul128(a, b, &b); + if (((b << shift) >> shift) != b) { + // Overflow + return 0xFFFFFFFFFFFFFFFF; + } + b = __shiftleft128(a, b, shift); + a <<= shift; + + uint32_t div; + uint32_t q0, q1; + uint64_t t0, t1; + + // 1st Reduction + div = (uint32_t)(c >> 32); + t0 = b / div; + if (t0 > 0xFFFFFFFF) + t0 = 0xFFFFFFFF; + q1 = (uint32_t)t0; + while (1) { + t0 = _umul128(c, (uint64_t)q1 << 32, &t1); + if (t1 < b || (t1 == b && t0 <= a)) + break; + q1--; + } + b -= t1; + if (t0 > a) + b--; + a -= t0; + + if (b > 0xFFFFFFFF) { + // Overflow + return 0xFFFFFFFFFFFFFFFF; + } + + // 2nd reduction + t0 = ((b << 32) | (a >> 32)) / div; + if (t0 > 0xFFFFFFFF) + t0 = 0xFFFFFFFF; + q0 = (uint32_t)t0; + + while (1) { + t0 = _umul128(c, q0, &t1); + if (t1 < b || (t1 == b && t0 <= a)) + break; + q0--; + } + + return ((uint64_t)q1 << 32) | q0; +#pragma warning(pop) +#endif +#else +#error MulDiv64 is no supported! +#endif +} + +} // namespace Atom::Algorithm diff --git a/src/atom/algorithm/mathutils.hpp b/src/atom/algorithm/mathutils.hpp new file mode 100644 index 00000000..5f7762ac --- /dev/null +++ b/src/atom/algorithm/mathutils.hpp @@ -0,0 +1,34 @@ +/* + * mathutils.hpp + * + * Copyright (C) 2023-2024 Max Qian + */ + +/************************************************* + +Date: 2023-11-10 + +Description: Extra Math Library + +**************************************************/ + +#ifndef ATOM_ALGORITHM_MATHUTILS_HPP +#define ATOM_ALGORITHM_MATHUTILS_HPP + +#include + +namespace Atom::Algorithm { +/** + * @brief Performs a 64-bit multiplication followed by division. + * + * This function calculates the result of (operant * multiplier) / divider. + * + * @param operant The first operand for multiplication. + * @param multiplier The second operand for multiplication. + * @param divider The divisor for the division operation. + * @return The result of (operant * multiplier) / divider. + */ +uint64_t mulDiv64(uint64_t operant, uint64_t multiplier, uint64_t divider); +} // namespace Atom::Algorithm + +#endif \ No newline at end of file diff --git a/src/atom/async/lock.hpp b/src/atom/async/lock.hpp index 9c8e3814..78a7bc76 100644 --- a/src/atom/async/lock.hpp +++ b/src/atom/async/lock.hpp @@ -33,19 +33,42 @@ namespace Atom::Async { #error "Unknown architecture, CPU relax code required" #endif +/** + * @brief A simple spinlock implementation using atomic_flag. + */ class Spinlock { std::atomic_flag flag_ = ATOMIC_FLAG_INIT; public: + /** + * @brief Default constructor. + */ Spinlock() = default; + + /** + * @brief Disables copy. + */ Spinlock(const Spinlock &) = delete; + + /** + * @brief Disables copy. + */ Spinlock &operator=(const Spinlock &) = delete; + /** + * @brief Acquires the lock. + */ void lock(); + /** + * @brief Releases the lock. + */ void unlock(); }; +/** + * @brief A ticket spinlock implementation using atomic operations. + */ class TicketSpinlock { std::atomic ticket_{0}; std::atomic serving_{0}; @@ -54,24 +77,48 @@ class TicketSpinlock { TicketSpinlock() = default; TicketSpinlock(const TicketSpinlock &) = delete; TicketSpinlock &operator=(const TicketSpinlock &) = delete; - + /** + * @brief Lock guard for TicketSpinlock. + */ class LockGuard { TicketSpinlock &spinlock_; const uint64_t ticket_; public: - LockGuard(TicketSpinlock &spinlock) + /** + * @brief Constructs the lock guard and acquires the lock. + * + * @param spinlock The TicketSpinlock to guard. + */ + explicit LockGuard(TicketSpinlock &spinlock) : spinlock_(spinlock), ticket_(spinlock_.lock()) {} + + /** + * @brief Destructs the lock guard and releases the lock. + */ ~LockGuard() { spinlock_.unlock(ticket_); } }; using scoped_lock = LockGuard; + /** + * @brief Acquires the lock and returns the ticket number. + * + * @return The acquired ticket number. + */ uint64_t lock(); + /** + * @brief Releases the lock given a specific ticket number. + * + * @param ticket The ticket number to release. + */ void unlock(const uint64_t ticket); }; +/** + * @brief An unfair spinlock implementation using atomic_flag. + */ class UnfairSpinlock { std::atomic_flag flag_ = ATOMIC_FLAG_INIT; @@ -80,49 +127,92 @@ class UnfairSpinlock { UnfairSpinlock(const UnfairSpinlock &) = delete; UnfairSpinlock &operator=(const UnfairSpinlock &) = delete; + /** + * @brief Acquires the lock. + */ void lock(); + /** + * @brief Releases the lock. + */ void unlock(); }; -// Scoped lock for Spinlock +/** + * @brief Scoped lock for any type of spinlock. + * + * @tparam Mutex Type of the spinlock (e.g., Spinlock, TicketSpinlock, + * UnfairSpinlock). + */ template class ScopedLock { Mutex &mutex_; public: + /** + * @brief Constructs the scoped lock and acquires the lock on the provided mutex. + * + * @param mutex The mutex to lock. + */ explicit ScopedLock(Mutex &mutex) : mutex_(mutex) { mutex_.lock(); } + /** + * @brief Destructs the scoped lock and releases the lock. + */ ~ScopedLock() { mutex_.unlock(); } ScopedLock(const ScopedLock &) = delete; ScopedLock &operator=(const ScopedLock &) = delete; }; -// Scoped lock for TicketSpinlock +/** + * @brief Scoped lock for TicketSpinlock. + * + * @tparam Mutex Type of the spinlock (i.e., TicketSpinlock). + */ template class ScopedTicketLock { Mutex &mutex_; const uint64_t ticket_; public: + /** + * @brief Constructs the scoped lock and acquires the lock on the provided mutex. + * + * @param mutex The mutex to lock. + */ explicit ScopedTicketLock(Mutex &mutex) : mutex_(mutex), ticket_(mutex_.lock()) {} + /** + * @brief Destructs the scoped lock and releases the lock. + */ ~ScopedTicketLock() { mutex_.unlock(ticket_); } ScopedTicketLock(const ScopedTicketLock &) = delete; ScopedTicketLock &operator=(const ScopedTicketLock &) = delete; }; -// Scoped lock for UnfairSpinlock +/** + * @brief Scoped lock for UnfairSpinlock. + * + * @tparam Mutex Type of the spinlock (i.e., UnfairSpinlock). + */ template class ScopedUnfairLock { Mutex &mutex_; public: + /** + * @brief Constructs the scoped lock and acquires the lock on the provided mutex. + * + * @param mutex The mutex to lock. + */ explicit ScopedUnfairLock(Mutex &mutex) : mutex_(mutex) { mutex_.lock(); } + /** + * @brief Destructs the scoped lock and releases the lock. + */ ~ScopedUnfairLock() { mutex_.unlock(); } ScopedUnfairLock(const ScopedUnfairLock &) = delete; diff --git a/src/atom/async/timer.hpp b/src/atom/async/timer.hpp index 44f20d2b..d16a4643 100644 --- a/src/atom/async/timer.hpp +++ b/src/atom/async/timer.hpp @@ -41,7 +41,7 @@ class TimerTask { * for infinite repetition. * @param priority The priority of the task. */ - TimerTask(std::function func, unsigned int delay, int repeatCount, + explicit TimerTask(std::function func, unsigned int delay, int repeatCount, int priority); /** diff --git a/src/atom/connection/fifoclient.hpp b/src/atom/connection/fifoclient.hpp index 281c2cf8..e6530c2b 100644 --- a/src/atom/connection/fifoclient.hpp +++ b/src/atom/connection/fifoclient.hpp @@ -27,23 +27,45 @@ Description: FIFO CLient #endif namespace Atom::Connection { +/** + * @brief The FifoClient class provides functionality to connect to a FIFO + * (First In First Out) pipe, send messages through the pipe, and disconnect + * from the pipe. + */ class FifoClient { public: - FifoClient(const std::string &fifoPath); + /** + * @brief Constructor for FifoClient. + * @param fifoPath The path to the FIFO pipe. + */ + explicit FifoClient(const std::string &fifoPath); + /** + * @brief Connects to the FIFO pipe. + */ void connect(); + + /** + * @brief Sends a message through the FIFO pipe. + * @param message The message to send. + */ void sendMessage(const std::string &message); + + /** + * @brief Disconnects from the FIFO pipe. + */ void disconnect(); private: - std::string fifoPath; + std::string fifoPath; /**< The path to the FIFO pipe. */ #ifdef _WIN32 - HANDLE pipeHandle; + HANDLE pipeHandle; /**< Handle to the pipe (Windows). */ #else - int pipeFd; + int pipeFd; /**< File descriptor for the pipe (Unix/Linux). */ #endif }; + } // namespace Atom::Connection #endif // FIFOSERVER_H diff --git a/src/atom/connection/fifoserver.hpp b/src/atom/connection/fifoserver.hpp index d89c1fca..14c0e2cd 100644 --- a/src/atom/connection/fifoserver.hpp +++ b/src/atom/connection/fifoserver.hpp @@ -27,24 +27,47 @@ Description: FIFO Server #endif namespace Atom::Connection { +/** + * @brief The FifoServer class provides functionality to start a server that + * listens on a FIFO (First In First Out) pipe, receive messages from the pipe, + * and stop the server. + */ class FifoServer { public: + /** + * @brief Constructor for FifoServer. + * @param fifoPath The path to the FIFO pipe. + */ FifoServer(const std::string &fifoPath); + /** + * @brief Starts the FIFO server to listen for incoming messages. + */ void start(); + + /** + * @brief Receives a message from the FIFO pipe. + * @return The received message as a string. + */ std::string receiveMessage(); + + /** + * @brief Stops the FIFO server. + */ void stop(); private: - std::string fifoPath; - static const int bufferSize = 1024; + std::string fifoPath; /**< The path to the FIFO pipe. */ + static const int bufferSize = + 1024; /**< The size of the buffer for receiving messages. */ #ifdef _WIN32 - HANDLE pipeHandle; + HANDLE pipeHandle; /**< Handle to the pipe (Windows). */ #else - int pipeFd; + int pipeFd; /**< File descriptor for the pipe (Unix/Linux). */ #endif }; + } // namespace Atom::Connection #endif // ATOM_CONNECTION_FIFOSERVER_HPP diff --git a/src/atom/search/mysql.hpp b/src/atom/search/mysql.hpp index 458cf920..1c03d303 100644 --- a/src/atom/search/mysql.hpp +++ b/src/atom/search/mysql.hpp @@ -33,7 +33,7 @@ class MysqlDB { * @param password The password for the MySQL database. * @param database The name of the database to connect to. */ - MysqlDB(const char *host, const char *user, const char *password, + explicit MysqlDB(const char *host, const char *user, const char *password, const char *database); /** diff --git a/src/atom/serial/serial.hpp b/src/atom/serial/serial.hpp index 19302feb..34323a28 100644 --- a/src/atom/serial/serial.hpp +++ b/src/atom/serial/serial.hpp @@ -39,20 +39,53 @@ enum class StopBits { class SerialPort { public: + /** + * @brief Constructs a SerialPort object. + * @param portName The name of the serial port (e.g., "COM1"). + * @param baudRate The baud rate of the serial port. + * @param dataBits The number of data bits (e.g., 8). + * @param parity The parity bit (e.g., Parity::None). + * @param stopBits The number of stop bits (e.g., StopBits::One). + */ explicit SerialPort(const std::string &portName, int baudRate, int dataBits, Parity parity, StopBits stopBits); + /** + * @brief Destroys the SerialPort object. + */ ~SerialPort(); + /** + * @brief Opens the serial port for communication. + * @return true if the port is successfully opened, false otherwise. + */ bool open(); + /** + * @brief Closes the serial port. + */ void close(); + /** + * @brief Reads data from the serial port. + * @param buffer The buffer to store the read data. + * @param bufferSize The size of the buffer. + * @return true if data is successfully read, false otherwise. + */ bool read(char *buffer, int bufferSize); + /** + * @brief Writes data to the serial port. + * @param data The data to be written. + * @param dataSize The size of the data. + * @return true if data is successfully written, false otherwise. + */ bool write(const char *data, int dataSize); private: + /** + * @brief Sets the parameters of the serial port. + */ void setParameters(); private: @@ -69,10 +102,26 @@ class SerialPort { #endif }; +/** + * @brief A factory class for creating serial ports. + */ class SerialPortFactory { public: + /** + * @brief Gets a list of available serial ports. + * @return A vector of strings containing the names of available serial ports. + */ static std::vector getAvailablePorts(); + /** + * @brief Creates a serial port with the specified parameters. + * @param portName The name of the serial port. + * @param baudRate The baud rate of the serial port. + * @param dataBits The number of data bits. + * @param parity The parity bit. + * @param stopBits The number of stop bits. + * @return A serial port object. + */ static SerialPort createSerialPort(const std::string &portName, int baudRate, int dataBits, Parity parity, StopBits stopBits); diff --git a/src/atom/system/crash_quotes.hpp b/src/atom/system/crash_quotes.hpp index 063c4f0e..6aa0f99e 100644 --- a/src/atom/system/crash_quotes.hpp +++ b/src/atom/system/crash_quotes.hpp @@ -19,7 +19,6 @@ Description: Quote manager for crash report. #include namespace Atom::System { - /** * @brief Represents a quote with its text and author. */ @@ -31,7 +30,7 @@ class Quote { * @param text The text of the quote. * @param author The author of the quote. */ - Quote(const std::string &text, const std::string &author); + explicit Quote(const std::string &text, const std::string &author); /** * @brief Gets the text of the quote. diff --git a/src/atom/system/lregistry.cpp b/src/atom/system/lregistry.cpp new file mode 100644 index 00000000..864b02c1 --- /dev/null +++ b/src/atom/system/lregistry.cpp @@ -0,0 +1,169 @@ +/* + * lregister.cpp + * + * Copyright (C) 2023-2024 Max Qian + */ + +/************************************************* + +Date: 2023-6-17 + +Description: A self-contained registry manager. + +**************************************************/ + +#include "lregistry.hpp" + +#include +#include + +#include "atom/log/loguru.hpp" + +namespace Atom::System { + +class Registry::RegistryImpl { +public: + std::map> registryData; + + void saveRegistryToFile(); + void notifyEvent(std::string eventType, std::string keyName); +}; + +Registry::Registry() : pImpl(std::make_unique()) {} + +// Implementation of Registry class methods +void Registry::loadRegistryFromFile() { + pImpl->saveRegistryToFile(); // Delegate to implementation +} + +void Registry::createKey(std::string keyName) { + pImpl->saveRegistryToFile(); // Delegate to implementation + pImpl->notifyEvent("KeyCreated", keyName); // Delegate to implementation +} + +void Registry::deleteKey(std::string keyName) { + pImpl->saveRegistryToFile(); // Delegate to implementation + pImpl->notifyEvent("KeyDeleted", keyName); // Delegate to implementation +} + +void Registry::setValue(std::string keyName, std::string valueName, + std::string data) { + pImpl->registryData[keyName][valueName] = + data; // Access implementation directly + pImpl->saveRegistryToFile(); // Delegate to implementation + pImpl->notifyEvent("ValueSet", keyName); // Delegate to implementation +} + +std::string Registry::getValue(std::string keyName, std::string valueName) { + if (pImpl->registryData.find(keyName) != pImpl->registryData.end() && + pImpl->registryData[keyName].find(valueName) != + pImpl->registryData[keyName].end()) { + return pImpl + ->registryData[keyName] + [valueName]; // Access implementation directly + } else { + return "Value not found"; + } +} + +void Registry::deleteValue(std::string keyName, std::string valueName) { + if (pImpl->registryData.find(keyName) != pImpl->registryData.end()) { + pImpl->registryData[keyName].erase( + valueName); // Access implementation directly + pImpl->saveRegistryToFile(); // Delegate to implementation + pImpl->notifyEvent("ValueDeleted", + keyName); // Delegate to implementation + } +} + +void Registry::backupRegistryData() { + std::time_t currentTime = std::time(nullptr); + std::string backupFileName = + "registry_backup_" + std::to_string(currentTime) + ".txt"; + + std::ofstream backupFile(backupFileName); + if (backupFile.is_open()) { + for (const auto &key : pImpl->registryData) { + backupFile << key.first << std::endl; + for (const auto &value : key.second) { + backupFile << value.first << "=" << value.second << std::endl; + } + backupFile << std::endl; + } + backupFile.close(); + DLOG_F(INFO, "Registry data backed up successfully to file: {}", + backupFileName); + } else { + LOG_F(ERROR, "Error: Unable to create backup file"); + } +} + +void Registry::restoreRegistryData(std::string backupFile) { + std::ifstream backup(backupFile); + if (backup.is_open()) { + pImpl->registryData.clear(); // Clear existing data before restoring + + std::string line; + std::string currentKey; + while (std::getline(backup, line)) { + if (!line.empty() && line.find('=') == std::string::npos) { + currentKey = line; + pImpl->registryData[currentKey] = + std::map(); + } else if (line.find('=') != std::string::npos) { + size_t splitPos = line.find('='); + std::string valueName = line.substr(0, splitPos); + std::string data = line.substr(splitPos + 1); + pImpl->registryData[currentKey][valueName] = data; + } + } + + backup.close(); + DLOG_F(INFO, "Registry data restored successfully from backup file: {}", + backupFile); + } else { + LOG_F(ERROR, "Error: Unable to open backup file for restore"); + } +} + +bool Registry::keyExists(std::string keyName) const { + return pImpl->registryData.find(keyName) != pImpl->registryData.end(); +} + +bool Registry::valueExists(std::string keyName, std::string valueName) const { + auto keyIter = pImpl->registryData.find(keyName); + return keyIter != pImpl->registryData.end() && + keyIter->second.find(valueName) != keyIter->second.end(); +} + +std::vector Registry::getValueNames(std::string keyName) const { + std::vector valueNames; + if (pImpl->registryData.find(keyName) != pImpl->registryData.end()) { + for (const auto &pair : pImpl->registryData.at(keyName)) { + valueNames.push_back(pair.first); + } + } + return valueNames; +} +void Registry::RegistryImpl::saveRegistryToFile() { + std::ofstream file("registry_data.txt"); + if (file.is_open()) { + for (auto const &key : registryData) { + file << key.first << std::endl; + for (auto const &value : key.second) { + file << value.first << "=" << value.second << std::endl; + } + file << std::endl; + } + file.close(); + } else { + LOG_F(ERROR, "Error: Unable to save registry data to file"); + } +} + +void Registry::RegistryImpl::notifyEvent(std::string eventType, + std::string keyName) { + DLOG_F(INFO, "Event: {} occurred for key: {}", eventType, keyName); +} + +} // namespace Atom::System diff --git a/src/atom/system/lregistry.hpp b/src/atom/system/lregistry.hpp new file mode 100644 index 00000000..c05b41df --- /dev/null +++ b/src/atom/system/lregistry.hpp @@ -0,0 +1,119 @@ +/* + * lregister.hpp + * + * Copyright (C) 2023-2024 Max Qian + */ + +/************************************************* + +Date: 2023-6-17 + +Description: A self-contained registry manager. + +**************************************************/ + +#ifndef ATOM_SYSTEM_REGISTRY_HPP +#define ATOM_SYSTEM_REGISTRY_HPP + +#include +#include +#include + +namespace Atom::System { +/** + * @brief The Registry class handles registry operations. + */ +class Registry { +public: + Registry(); + /** + * @brief Loads registry data from a file. + */ + void loadRegistryFromFile(); + + /** + * @brief Creates a new key in the registry. + * + * @param keyName The name of the key to create. + */ + void createKey(std::string keyName); + + /** + * @brief Deletes a key from the registry. + * + * @param keyName The name of the key to delete. + */ + void deleteKey(std::string keyName); + + /** + * @brief Sets a value for a key in the registry. + * + * @param keyName The name of the key. + * @param valueName The name of the value to set. + * @param data The data to set for the value. + */ + void setValue(std::string keyName, std::string valueName, std::string data); + + /** + * @brief Gets the value associated with a key and value name from the + * registry. + * + * @param keyName The name of the key. + * @param valueName The name of the value to retrieve. + * @return The value associated with the key and value name. + */ + std::string getValue(std::string keyName, std::string valueName); + + /** + * @brief Deletes a value from a key in the registry. + * + * @param keyName The name of the key. + * @param valueName The name of the value to delete. + */ + void deleteValue(std::string keyName, std::string valueName); + + /** + * @brief Backs up the registry data. + */ + void backupRegistryData(); + + /** + * @brief Restores the registry data from a backup file. + * + * @param backupFile The backup file to restore data from. + */ + void restoreRegistryData(std::string backupFile); + + /** + * @brief Checks if a key exists in the registry. + * + * @param keyName The name of the key to check for existence. + * @return true if the key exists, false otherwise. + */ + bool keyExists(std::string keyName) const; + + /** + * @brief Checks if a value exists for a key in the registry. + * + * @param keyName The name of the key. + * @param valueName The name of the value to check for existence. + * @return true if the value exists, false otherwise. + */ + bool valueExists(std::string keyName, std::string valueName) const; + + /** + * @brief Retrieves all value names for a given key from the registry. + * + * @param keyName The name of the key. + * @return A vector of value names associated with the given key. + */ + std::vector getValueNames(std::string keyName) const; + +private: + class RegistryImpl; // Forward declaration of the implementation class + std::unique_ptr pImpl; // Pointer to the implementation class +}; + +} // namespace Atom::System + +#endif diff --git a/src/atom/system/register.cpp b/src/atom/system/register.cpp index 7c6ef81a..1d4c92a7 100644 --- a/src/atom/system/register.cpp +++ b/src/atom/system/register.cpp @@ -18,7 +18,7 @@ Description: Some registry functions for Windows #include "atom/log/loguru.hpp" -bool GetRegistrySubKeys(HKEY hRootKey, const std::string &subKey, +bool getRegistrySubKeys(HKEY hRootKey, const std::string &subKey, std::vector &subKeys) { HKEY hKey; LONG lRes = RegOpenKeyEx(hRootKey, subKey.c_str(), 0, KEY_READ, &hKey); @@ -51,7 +51,7 @@ bool GetRegistrySubKeys(HKEY hRootKey, const std::string &subKey, return true; } -bool GetRegistryValues( +bool getRegistryValues( HKEY hRootKey, const std::string &subKey, std::vector> &values) { HKEY hKey; @@ -102,7 +102,7 @@ bool GetRegistryValues( return true; } -bool ModifyRegistryValue(HKEY hRootKey, const std::string &subKey, +bool modifyRegistryValue(HKEY hRootKey, const std::string &subKey, const std::string &valueName, const std::string &newValue) { HKEY hKey; @@ -127,7 +127,7 @@ bool ModifyRegistryValue(HKEY hRootKey, const std::string &subKey, return true; } -bool DeleteRegistrySubKey(HKEY hRootKey, const std::string &subKey) { +bool deleteRegistrySubKey(HKEY hRootKey, const std::string &subKey) { LONG lRes = RegDeleteKey(hRootKey, subKey.c_str()); if (lRes != ERROR_SUCCESS) { LOG_F(ERROR, "Could not delete subkey: {}", lRes); @@ -137,7 +137,7 @@ bool DeleteRegistrySubKey(HKEY hRootKey, const std::string &subKey) { return true; } -bool DeleteRegistryValue(HKEY hRootKey, const std::string &subKey, +bool deleteRegistryValue(HKEY hRootKey, const std::string &subKey, const std::string &valueName) { HKEY hKey; LONG lRes = RegOpenKeyEx(hRootKey, subKey.c_str(), 0, KEY_SET_VALUE, &hKey); @@ -157,7 +157,7 @@ bool DeleteRegistryValue(HKEY hRootKey, const std::string &subKey, return true; } -void RecursivelyEnumerateRegistrySubKeys(HKEY hRootKey, +void recursivelyEnumerateRegistrySubKeys(HKEY hRootKey, const std::string &subKey) { HKEY hKey; LONG lRes = RegOpenKeyEx(hRootKey, subKey.c_str(), 0, KEY_READ, &hKey); @@ -191,7 +191,7 @@ void RecursivelyEnumerateRegistrySubKeys(HKEY hRootKey, RegCloseKey(hKey); } -bool BackupRegistry(HKEY hRootKey, const std::string &subKey, +bool backupRegistry(HKEY hRootKey, const std::string &subKey, const std::string &backupFilePath) { LONG lRes = RegSaveKey(hRootKey, subKey.c_str(), NULL); if (lRes != ERROR_SUCCESS) { @@ -208,7 +208,7 @@ bool BackupRegistry(HKEY hRootKey, const std::string &subKey, return true; } -void FindRegistryKey(HKEY hRootKey, const std::string &subKey, +void findRegistryKey(HKEY hRootKey, const std::string &subKey, const std::string &searchKey) { HKEY hKey; LONG lRes = RegOpenKeyEx(hRootKey, subKey.c_str(), 0, KEY_READ, &hKey); @@ -244,7 +244,7 @@ void FindRegistryKey(HKEY hRootKey, const std::string &subKey, RegCloseKey(hKey); } -void FindRegistryValue(HKEY hRootKey, const std::string &subKey, +void findRegistryValue(HKEY hRootKey, const std::string &subKey, const std::string &searchValue) { HKEY hKey; LONG lRes = RegOpenKeyEx(hRootKey, subKey.c_str(), 0, KEY_READ, &hKey); @@ -284,7 +284,7 @@ void FindRegistryValue(HKEY hRootKey, const std::string &subKey, RegCloseKey(hKey); } -bool ExportRegistry(HKEY hRootKey, const std::string &subKey, +bool exportRegistry(HKEY hRootKey, const std::string &subKey, const std::string &exportFilePath) { LONG lRes = RegSaveKey(hRootKey, subKey.c_str(), NULL); if (lRes != ERROR_SUCCESS) { @@ -301,26 +301,4 @@ bool ExportRegistry(HKEY hRootKey, const std::string &subKey, return true; } -/* -int main() -{ - std::vector subKeys; - if (GetRegistrySubKeys(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows -NT\\CurrentVersion", subKeys)) { std::cout << "Sub Keys:" << std::endl; for -(const auto& subKey : subKeys) { std::cout << " " << subKey << std::endl; - } - } - - std::vector> values; - if (GetRegistryValues(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows -NT\\CurrentVersion", values)) { std::cout << "Values:" << std::endl; for (const -auto& value : values) { std::cout << " " << value.first << " = " << -value.second << std::endl; - } - } - - return 0; -} -*/ - -#endif \ No newline at end of file +#endif diff --git a/src/atom/system/register.hpp b/src/atom/system/register.hpp index a0ca8744..de8a6d4b 100644 --- a/src/atom/system/register.hpp +++ b/src/atom/system/register.hpp @@ -28,7 +28,7 @@ Description: Some registry functions for Windows * @param subKeys 子键名称的字符串向量。 * @return true 表示成功,false 表示失败。 */ -bool GetRegistrySubKeys(HKEY hRootKey, const std::string &subKey, +bool getRegistrySubKeys(HKEY hRootKey, const std::string &subKey, std::vector &subKeys); /** @@ -38,7 +38,7 @@ bool GetRegistrySubKeys(HKEY hRootKey, const std::string &subKey, * @param values 名称和数据的字符串对向量。 * @return true 表示成功,false 表示失败。 */ -bool GetRegistryValues( +bool getRegistryValues( HKEY hRootKey, const std::string &subKey, std::vector> &values); @@ -50,7 +50,7 @@ bool GetRegistryValues( * @param newValue 新的值数据。 * @return true 表示成功,false 表示失败。 */ -bool ModifyRegistryValue(HKEY hRootKey, const std::string &subKey, +bool modifyRegistryValue(HKEY hRootKey, const std::string &subKey, const std::string &valueName, const std::string &newValue); @@ -60,7 +60,7 @@ bool ModifyRegistryValue(HKEY hRootKey, const std::string &subKey, * @param subKey 要删除的键的名称,可以包括多个嵌套的键,用反斜杠分隔。 * @return true 表示成功,false 表示失败。 */ -bool DeleteRegistrySubKey(HKEY hRootKey, const std::string &subKey); +bool deleteRegistrySubKey(HKEY hRootKey, const std::string &subKey); /** * @brief 删除指定注册表键下的指定值。 @@ -69,7 +69,7 @@ bool DeleteRegistrySubKey(HKEY hRootKey, const std::string &subKey); * @param valueName 要删除的值的名称。 * @return true 表示成功,false 表示失败。 */ -bool DeleteRegistryValue(HKEY hRootKey, const std::string &subKey, +bool deleteRegistryValue(HKEY hRootKey, const std::string &subKey, const std::string &valueName); /** @@ -77,7 +77,7 @@ bool DeleteRegistryValue(HKEY hRootKey, const std::string &subKey, * @param hRootKey 根键句柄。 * @param subKey 指定键的名称,可以包括多个嵌套的键,用反斜杠分隔。 */ -void RecursivelyEnumerateRegistrySubKeys(HKEY hRootKey, +void recursivelyEnumerateRegistrySubKeys(HKEY hRootKey, const std::string &subKey); /** @@ -87,7 +87,7 @@ void RecursivelyEnumerateRegistrySubKeys(HKEY hRootKey, * @param backupFilePath 备份文件的完整路径。 * @return true 表示成功,false 表示失败。 */ -bool BackupRegistry(HKEY hRootKey, const std::string &subKey, +bool backupRegistry(HKEY hRootKey, const std::string &subKey, const std::string &backupFilePath); /** @@ -96,7 +96,7 @@ bool BackupRegistry(HKEY hRootKey, const std::string &subKey, * @param subKey 指定键的名称,可以包括多个嵌套的键,用反斜杠分隔。 * @param searchKey 要查找的字符串。 */ -void FindRegistryKey(HKEY hRootKey, const std::string &subKey, +void findRegistryKey(HKEY hRootKey, const std::string &subKey, const std::string &searchKey); /** @@ -105,7 +105,7 @@ void FindRegistryKey(HKEY hRootKey, const std::string &subKey, * @param subKey 指定键的名称,可以包括多个嵌套的键,用反斜杠分隔。 * @param searchValue 要查找的字符串。 */ -void FindRegistryValue(HKEY hRootKey, const std::string &subKey, +void findRegistryValue(HKEY hRootKey, const std::string &subKey, const std::string &searchValue); /** @@ -115,7 +115,7 @@ void FindRegistryValue(HKEY hRootKey, const std::string &subKey, * @param exportFilePath 导出文件的完整路径。 * @return true 表示成功,false 表示失败。 */ -bool ExportRegistry(HKEY hRootKey, const std::string &subKey, +bool exportRegistry(HKEY hRootKey, const std::string &subKey, const std::string &exportFilePath); #endif diff --git a/src/controller/AsyncClientController.hpp b/src/controller/AsyncClientController.hpp index d6b068bc..81668c25 100644 --- a/src/controller/AsyncClientController.hpp +++ b/src/controller/AsyncClientController.hpp @@ -22,7 +22,6 @@ Description: Async Client Controller #include "oatpp/network/ConnectionHandler.hpp" #include "oatpp/web/server/api/ApiController.hpp" - #include "oatpp/core/macro/codegen.hpp" #include "oatpp/core/macro/component.hpp" @@ -42,6 +41,15 @@ class ClientController : public oatpp::web::server::api::ApiController { Constants::COMPONENT_REST_API)) : oatpp::web::server::api::ApiController(objectMapper) {} + // ---------------------------------------------------------------- + // Pointer creator + // ---------------------------------------------------------------- + + static std::shared_ptr createShared( + OATPP_COMPONENT(std::shared_ptr, objectMapper)) { + return std::make_shared(objectMapper); + } + public: /** * Join existing game diff --git a/websrc/lithium-web/src/pages/info/device.astro b/websrc/lithium-web/src/pages/info/device.astro index b80e658d..25dcaa99 100644 --- a/websrc/lithium-web/src/pages/info/device.astro +++ b/websrc/lithium-web/src/pages/info/device.astro @@ -7,7 +7,12 @@ - +