├── .gitignore ├── CMakeLists.txt ├── Data ├── Data.h ├── File.cpp ├── File.h ├── Folder.cpp ├── Folder.h ├── Hash.cpp ├── Hash.h └── Settings.h ├── LICENSE ├── Main ├── Main.cpp ├── Show.h ├── ToDoShow.cpp ├── UnitTest.cpp └── UnitTest.h └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | Test/ 3 | bin/ 4 | *.vcxproj* 5 | *.sln 6 | *.make 7 | Makefile 8 | *.cmake 9 | CMakeFiles/ 10 | CMakeCache.txt 11 | Debug/ 12 | Release/ 13 | to_do_show.txt 14 | prodLib/ 15 | prodRelease/ 16 | showdata/ 17 | build/ 18 | .vscode/ 19 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB_RECURSE cpp_data_files 2 | "Data/*.cpp" 3 | "Data/*.h") 4 | file(GLOB_RECURSE main_files 5 | "Main/*.cpp" 6 | "Main/*.h") 7 | file (GLOB_RECURSE lib_include_files 8 | "vendor/include/") 9 | file(GLOB_RECURSE mysqlcpp_lib_flies 10 | "vendor/lib/mysqlcppconn-static" 11 | "vendor/lib/mysqlcppconnx-static") 12 | 13 | cmake_minimum_required(VERSION 3.0) 14 | 15 | # [Data] 16 | project(Data VERSION 1.0 LANGUAGES CXX) 17 | set(CMAKE_CXX_STANDARD 20) 18 | 19 | add_library(mysql_libs STATIC IMPORTED) 20 | find_library(mysql_libs ${mysqlcpp_lib_flies} PATHS vendor/lib) 21 | 22 | add_library(Data STATIC ${cpp_data_files} ${lib_include_files}) 23 | 24 | # [Main] 25 | project(Main VERSION 1.0 LANGUAGES CXX) 26 | set(CMAKE_CXX_STANDARD 20) 27 | 28 | add_executable(Main ${main_files}) 29 | 30 | target_link_libraries(Main PRIVATE Data) 31 | 32 | set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Main) -------------------------------------------------------------------------------- /Data/Data.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Hash.h" 3 | #include "File.h" 4 | #include "Folder.h" 5 | // [Feature] Change SQL to MySQL, PostgreSQL, SQLite 6 | // [Feature] Add SQLite 7 | // [Feature] FtpServer (open remote folder) -------------------------------------------------------------------------------- /Data/File.cpp: -------------------------------------------------------------------------------- 1 | #include "File.h" 2 | 3 | namespace Data { 4 | File::File(const std::string& path_to_file, size_t size) 5 | : path_to_file(path_to_file) { 6 | content.reserve(size); 7 | if (size) for (int i = 0; i < size; i++) 8 | content.emplace_back(std::to_string(0)); 9 | }; 10 | 11 | void File::push(const std::string& data) { 12 | content.emplace_back(data); 13 | }; 14 | 15 | std::string File::pop() { 16 | std::string temp = content[content.size() - 1]; 17 | content.pop_back(); 18 | return temp; 19 | }; 20 | 21 | std::string File::pop(const size_t& index) { 22 | std::string temp = content[index]; 23 | content.erase(content.begin() + index); 24 | return temp; 25 | }; 26 | 27 | void File::remove(const size_t& index) { 28 | content.erase(content.begin() + index); 29 | }; 30 | 31 | std::string& File::operator[](const size_t& index) { 32 | std::shared_ptr temp = std::make_shared(""); 33 | if (index < content.size()) return content[index]; 34 | return *temp; 35 | }; 36 | 37 | size_t File::size() { 38 | return content.size(); 39 | }; 40 | 41 | void File::changePathToFile(const std::string& path_to_file) { 42 | this->path_to_file = path_to_file; 43 | }; 44 | 45 | bool File::isEmpty() { 46 | std::fstream file(path_to_file, std::ios::in); 47 | if (file.peek() == std::ifstream::traits_type::eof()) return true; 48 | return false; 49 | }; 50 | 51 | void File::createFile() { 52 | std::fstream file(path_to_file, std::ios::out); 53 | file.close(); 54 | }; 55 | 56 | void File::removeFile() { 57 | std::remove(path_to_file.c_str()); 58 | }; 59 | 60 | std::vector::iterator File::begin() { 61 | return content.begin(); 62 | }; 63 | 64 | std::vector::iterator File::end() { 65 | return content.end(); 66 | }; 67 | 68 | void File::save(IHash* hash) { 69 | std::string temp = ""; 70 | 71 | #if DATAHASHBYPARTS 72 | for (const std::string& el : content) 73 | { 74 | if (hash != nullptr) temp += hash->hash_function(std::string(el + DATASEPERATOR)); 75 | else temp += std::string(el + DATASEPERATOR); 76 | }; 77 | #else 78 | for (const std::string& el : content) 79 | temp += el + DATASEPERATOR; 80 | if (hash != nullptr) temp = hash->hash_function(temp); 81 | #endif 82 | 83 | std::fstream file(path_to_file, std::ios::out); 84 | file << temp; 85 | file.close(); 86 | }; 87 | 88 | void File::read(IHash* hash) { 89 | content.clear(); 90 | 91 | std::fstream file(path_to_file, std::ios::in); 92 | std::string line = "", temp = ""; 93 | 94 | #if DATAHASHBYPARTS 95 | while (!file.eof()) { 96 | std::getline(file, line); 97 | if (hash != nullptr) temp += hash->un_hash_function(line); 98 | else temp += line; 99 | }; 100 | #else 101 | while (!file.eof()) { 102 | std::getline(file, line); 103 | temp += line; 104 | }; 105 | if (hash != nullptr) temp = hash->un_hash_function(temp); 106 | #endif 107 | 108 | line = ""; 109 | for (int index = 0; index < temp.size() - DATASEPERATOR.size() + 1; index++) { 110 | std::string find_next_sep = temp.substr(index, DATASEPERATOR.size()); 111 | if (find_next_sep == DATASEPERATOR) { 112 | content.emplace_back(line); 113 | line = ""; 114 | index += DATASEPERATOR.size() - 1; 115 | } 116 | else line += temp[index]; 117 | }; 118 | 119 | file.close(); 120 | }; 121 | 122 | bool File::isDifferent(IHash* hash) { 123 | std::fstream file(path_to_file, std::ios::in); 124 | std::string temp = "", data = ""; 125 | 126 | while (!file.eof()) { 127 | std::getline(file, data); 128 | temp += data; 129 | }; 130 | 131 | if (hash != nullptr) temp = hash->un_hash_function(temp); 132 | 133 | data = ""; 134 | for (const std::string& el : content) 135 | data += el + DATASEPERATOR; 136 | 137 | file.close(); 138 | 139 | if (data != temp) return true; 140 | return false; 141 | }; 142 | }; -------------------------------------------------------------------------------- /Data/File.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "Settings.h" 6 | #include "Hash.h" 7 | 8 | namespace Data { 9 | class File { 10 | public: 11 | File(const std::string& path_to_file = DEFAULTPATHTOFILE, size_t size = 0); 12 | size_t size(); 13 | bool isEmpty(); 14 | bool isDifferent(IHash* hash = nullptr); // [FEATURE] Optimize this function 15 | // [FEATURE] Thread isDifferentAsync 16 | void changePathToFile(const std::string& path_to_file); 17 | void createFile(); 18 | void removeFile(); 19 | void push(const std::string& data); 20 | std::string pop(); 21 | std::string pop(const size_t& index); 22 | void remove(const size_t& index); 23 | void save(IHash* hash = nullptr); // [FEATURE] simplify this function, optimize and hash whole file 24 | // [FEATURE] Thread saveAsync 25 | void read(IHash* hash = nullptr); // [FEATURE] simplify this function, optimize and un hash whole file 26 | // [FEATURE] Thread readAsync 27 | std::string& operator[](const size_t& index); // [FEATURE] Add for -> ptr variant 28 | std::vector::iterator begin(); 29 | std::vector::iterator end(); 30 | 31 | private: 32 | std::vector content; 33 | std::string path_to_file; 34 | }; 35 | }; -------------------------------------------------------------------------------- /Data/Folder.cpp: -------------------------------------------------------------------------------- 1 | #include "Folder.h" 2 | 3 | namespace Data { 4 | Folder::Folder(const std::filesystem::path& path_to_folder) 5 | : path_to_folder(path_to_folder) {}; 6 | 7 | void Folder::createFolder() { 8 | std::filesystem::create_directory(path_to_folder); 9 | }; 10 | 11 | void Folder::removeFolder() { 12 | std::filesystem::remove_all(path_to_folder); 13 | }; 14 | 15 | std::vector Folder::filesList() { 16 | return files; 17 | }; 18 | 19 | void Folder::fetchFilesList() { 20 | files.clear(); 21 | for (const std::filesystem::directory_entry& entry : std::filesystem::directory_iterator(path_to_folder)) 22 | files.emplace_back(entry.path().filename().string()); 23 | }; 24 | 25 | void Folder::updateList() { 26 | if (filesListIsDifferent()) 27 | fetchFilesList(); 28 | } 29 | bool Folder::fileExist(const std::string& file_name) { 30 | bool file_exist = false; 31 | for (std::string& file : files) 32 | if (file == file_name) file_exist = true; 33 | return file_exist; 34 | }; 35 | 36 | size_t Folder::count() { 37 | return files.size(); 38 | }; 39 | 40 | void Folder::createFile(const std::string& file_name) { 41 | std::fstream file((path_to_folder / file_name).string(), std::ios::out); 42 | file.close(); 43 | }; 44 | 45 | void Folder::removeFile(const std::string& file_name) { 46 | std::remove((path_to_folder / file_name).string().c_str()); 47 | }; 48 | 49 | std::shared_ptr Folder::openFile(const std::string& file_name) { 50 | return std::make_shared((path_to_folder / file_name).string()); 51 | }; 52 | 53 | void Folder::clean() { 54 | removeFolder(); 55 | createFolder(); 56 | }; 57 | 58 | bool Folder::exist() { 59 | return std::filesystem::exists(path_to_folder); 60 | }; 61 | 62 | bool Folder::isEmpty() { 63 | return std::filesystem::is_empty(path_to_folder) ? true : false; 64 | }; 65 | 66 | bool Folder::filesListIsDifferent() { 67 | std::vector temp; 68 | 69 | for (const std::filesystem::directory_entry& entry : std::filesystem::directory_iterator(path_to_folder)) 70 | temp.emplace_back(entry.path().filename().string()); 71 | 72 | if (temp.size() != files.size()) return true; 73 | for (int i = 0; i < temp.size(); i++) 74 | if (temp[i] != files[i]) return true; 75 | return false; 76 | }; 77 | 78 | std::vector::iterator Folder::begin() { 79 | return files.begin(); 80 | }; 81 | 82 | std::vector::iterator Folder::end() { 83 | return files.end(); 84 | }; 85 | }; -------------------------------------------------------------------------------- /Data/Folder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "File.h" 7 | 8 | namespace Data { 9 | class Folder { 10 | public: 11 | Folder(const std::filesystem::path& path_to_folder = DEFAULTPATHTOFOLDER); 12 | size_t count(); 13 | bool exist(); 14 | bool isEmpty(); 15 | std::vector filesList(); 16 | bool filesListIsDifferent(); // [FEATURE] Optimize this function 17 | // [FEATURE] filesListIsDifferentAsync 18 | void createFolder(); 19 | void removeFolder(); 20 | void createFile(const std::string& file_name); 21 | void removeFile(const std::string& file_name); 22 | void fetchFilesList(); // [FEATURE] Optimize this function 23 | // [FEATURE] fetchFilesListAsync 24 | void updateList(); 25 | bool fileExist(const std::string& file_name); 26 | std::shared_ptr openFile(const std::string& file_name); 27 | void clean(); 28 | std::vector::iterator begin(); 29 | std::vector::iterator end(); 30 | 31 | private: 32 | std::vector files; 33 | std::filesystem::path path_to_folder; 34 | }; 35 | }; -------------------------------------------------------------------------------- /Data/Hash.cpp: -------------------------------------------------------------------------------- 1 | #include "Hash.h" 2 | 3 | namespace Data { 4 | BaseHash::BaseHash(const char* hash_key) 5 | :hash_key(hash_key) {}; 6 | 7 | std::string BaseHash::hash_function(std::string data) { 8 | std::string ret = ""; 9 | for (int index = 0; index < data.size(); index++) { 10 | int temp = (int)((int)data[index] + (int)hash_key[index % (sizeof(hash_key)/8)] + 100); 11 | ret += std::to_string(temp); 12 | }; 13 | return ret; 14 | }; 15 | 16 | std::string BaseHash::un_hash_function(std::string data) { 17 | std::string ret = ""; 18 | int hash_count = 0; 19 | for (int index = 0; index < data.size(); index += 3) { 20 | std::string hash_string = ""; 21 | hash_string += data[index]; 22 | hash_string += data[index + 1]; 23 | hash_string += data[index + 2]; 24 | ret += (char)(std::stoi(hash_string) - (int)hash_key[hash_count % (sizeof(hash_key) / 8)] - 100); 25 | hash_count++; 26 | }; 27 | return ret; 28 | }; 29 | }; -------------------------------------------------------------------------------- /Data/Hash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace Data { 5 | class IHash { 6 | public: 7 | virtual std::string hash_function(std::string data) = 0; 8 | virtual std::string un_hash_function(std::string data) = 0; 9 | }; 10 | 11 | // [WARNING] No polish chars 12 | class BaseHash : public IHash { 13 | public: 14 | BaseHash(const char* hash_key); 15 | std::string hash_function(std::string data); 16 | std::string un_hash_function(std::string data); 17 | 18 | private: 19 | const char* hash_key = ""; 20 | }; 21 | 22 | // [FEATURE] Add more hash functions 23 | }; -------------------------------------------------------------------------------- /Data/Settings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | const static inline std::string DATASEPERATOR = "sep;"; 6 | const static inline std::string DEFAULTPATHTOFILE = "data.txt"; 7 | const static inline std::filesystem::path DEFAULTPATHTOFOLDER = ""; 8 | 9 | #define DATAHASHBYPARTS false -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Kokomichrzan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Main/Main.cpp: -------------------------------------------------------------------------------- 1 | #include "UnitTest.h" 2 | #include "Show.h" 3 | 4 | int main() { 5 | UnitTest test; 6 | 7 | ToDoShow(); 8 | 9 | return 0; 10 | } -------------------------------------------------------------------------------- /Main/Show.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Data/Data.h" 3 | 4 | #include 5 | #include 6 | 7 | void ToDoShow(); -------------------------------------------------------------------------------- /Main/ToDoShow.cpp: -------------------------------------------------------------------------------- 1 | #include "Show.h" 2 | 3 | const static inline std::string PASSWORD = "Hello"; 4 | const static inline std::string HASHKEY = "abacs"; 5 | const static inline std::string DEFFOLDER = "showdata"; 6 | const static inline std::string DEFFILE = "to_do_show.txt"; 7 | 8 | void ToDoShow() { 9 | bool running = true; 10 | std::string password = ""; 11 | 12 | std::cout << "Password: "; 13 | std::cin >> password; 14 | 15 | if (password == PASSWORD) { 16 | Data::Folder folder(DEFFOLDER); 17 | Data::BaseHash hash(HASHKEY.c_str()); 18 | if (!folder.exist()) folder.createFolder(); 19 | 20 | bool file_exist = false; 21 | folder.fetchFilesList(); 22 | for (std::string& el : folder) 23 | if (el == DEFFILE) file_exist = true; 24 | if (!file_exist) folder.createFile(DEFFILE); 25 | 26 | std::shared_ptr file(folder.openFile(DEFFILE)); 27 | 28 | if (file->isEmpty()) { 29 | file->push("Welcome"); 30 | file->save(&hash); 31 | }; 32 | 33 | while (running) { 34 | system("cls"); 35 | file->read(&hash); 36 | uint8_t action = 0; 37 | std::string data = ""; 38 | 39 | for (uint8_t index = 0; index < file->size(); index++) 40 | std::cout << index + 1 << ". " << (*file)[index] << "\n"; 41 | 42 | std::cout << "Chose Action: \n"; 43 | std::cout << "1. Add\n"; 44 | std::cout << "2. Remove\n"; 45 | std::cout << "3. Exit\n"; 46 | std::cout << "> "; 47 | std::cin >> action; 48 | 49 | switch (action) { 50 | case '1': 51 | std::cout << "> "; 52 | std::cin >> data; 53 | file->push(data); 54 | break; 55 | case '2': 56 | std::cout << "> "; 57 | std::cin >> action; 58 | std::cout << file->pop(action) << " removed"; 59 | break; 60 | default: 61 | running = false; 62 | break; 63 | } 64 | 65 | file->save(&hash); 66 | }; 67 | }; 68 | }; -------------------------------------------------------------------------------- /Main/UnitTest.cpp: -------------------------------------------------------------------------------- 1 | #include "UnitTest.h" 2 | 3 | UnitTest::UnitTest() { 4 | std::cout << "Unit Test Started" << std::endl; 5 | 6 | // Folder 7 | Folder_CreateFolderAndRemoveFolder_FolderCreatedAndRemoved("Data1"); 8 | Folder_CreateFolderAndRemoveFolder_FolderCreatedAndRemoved("Data2"); 9 | Folder_CreateFolderAndRemoveFolder_FolderCreatedAndRemoved("Data3"); 10 | Folder_CreateFolderAndRemoveFolder_FolderCreatedAndRemoved("Data4"); 11 | 12 | Folder_CreateAndRemoveFile_FileCreatedAndRemoved("Data1.txt"); 13 | Folder_CreateAndRemoveFile_FileCreatedAndRemoved("Data2.txt"); 14 | Folder_CreateAndRemoveFile_FileCreatedAndRemoved("Data3.txt"); 15 | Folder_CreateAndRemoveFile_FileCreatedAndRemoved("Data4.txt"); 16 | 17 | Folder_OpenFile_FileOpened("Data1.txt", "Hello World!!!"); 18 | Folder_OpenFile_FileOpened("Data2.txt", "Witaj Swiecie!!!"); 19 | Folder_OpenFile_FileOpened("Data3.txt", "Hallo Welt!!!"); 20 | Folder_OpenFile_FileOpened("Data4.txt", "Bonjour le monde!!!"); 21 | 22 | Folder_Exist_ExistReturnProperValue("Data1"); 23 | Folder_Exist_ExistReturnProperValue("Data2"); 24 | Folder_Exist_ExistReturnProperValue("Data3"); 25 | Folder_Exist_ExistReturnProperValue("Data4"); 26 | 27 | Folder_IsEmpty_ReturnsProperValue("Data1"); 28 | Folder_IsEmpty_ReturnsProperValue("Data2"); 29 | Folder_IsEmpty_ReturnsProperValue("Data3"); 30 | Folder_IsEmpty_ReturnsProperValue("Data4"); 31 | 32 | Folder_GetFilesList_FilesListGot({ "file1.txt", "file2.txt", "file3.txt" }); 33 | Folder_GetFilesList_FilesListGot({ "data1.txt", "data2.txt", "data3.txt" }); 34 | Folder_GetFilesList_FilesListGot({ "hello1.txt", "hello2.txt", "hello3.txt" }); 35 | Folder_GetFilesList_FilesListGot({ "world1.txt", "world2.txt", "world3.txt" }); 36 | 37 | Folder_IsDifferent_CheckIfFilesAreDifferent({ "file1.txt", "file2.txt", "file3.txt" }, "file4.txt"); 38 | Folder_IsDifferent_CheckIfFilesAreDifferent({ "data1.txt", "data2.txt", "data3.txt" }, "data4.txt"); 39 | Folder_IsDifferent_CheckIfFilesAreDifferent({ "hello1.txt", "hello2.txt", "hello3.txt" }, "hello4.txt"); 40 | Folder_IsDifferent_CheckIfFilesAreDifferent({ "world1.txt", "world2.txt", "world3.txt" }, "world4.txt"); 41 | 42 | Folder_GetFilesCount_FilesCountGot({ "file1.txt", "file2.txt", "file3.txt" }); 43 | Folder_GetFilesCount_FilesCountGot({ "data1.txt", "data2.txt", "data3.txt" , "data4.txt"}); 44 | Folder_GetFilesCount_FilesCountGot({ "hello1.txt", "hello2.txt", "hello3.txt" , "hello4.txt", "hello5.txt"}); 45 | Folder_GetFilesCount_FilesCountGot({ "world1.txt", "world2.txt", "world3.txt" , "world4.txt", "world5.txt", "world6.txt"}); 46 | 47 | Folder_CleanFolder_FolderCleaned({ "file1.txt", "file2.txt", "file3.txt" }); 48 | Folder_CleanFolder_FolderCleaned({ "data1.txt", "data2.txt", "data3.txt" }); 49 | Folder_CleanFolder_FolderCleaned({ "hello1.txt", "hello2.txt", "hello3.txt" }); 50 | Folder_CleanFolder_FolderCleaned({ "world1.txt", "world2.txt", "world3.txt" }); 51 | 52 | // File 53 | File_GetSize_SizeReturned(10); 54 | File_GetSize_SizeReturned(0); 55 | File_GetSize_SizeReturned(100); 56 | File_GetSize_SizeReturned(1000); 57 | File_GetSize_SizeReturned(10000); 58 | File_GetSize_SizeReturned(100000); 59 | 60 | File_PushData_DataPushed("Hello World!!!"); 61 | File_PushData_DataPushed("Witaj Swiecie!!!"); 62 | File_PushData_DataPushed("Hallo Welt!!!"); 63 | File_PushData_DataPushed("Bonjour le monde!!!"); 64 | File_PushData_DataPushed("Hola Mundo!!!"); 65 | File_PushData_DataPushed("Ciao mondo!!!"); 66 | 67 | File_PopData_DataPopped("Hello World!!!"); 68 | File_PopData_DataPopped("Witaj Swiecie!!!"); 69 | File_PopData_DataPopped("Hallo Welt!!!"); 70 | File_PopData_DataPopped("Bonjour le monde!!!"); 71 | File_PopData_DataPopped("Hola Mundo!!!"); 72 | File_PopData_DataPopped("Ciao mondo!!!"); 73 | 74 | File_PopDataAt_DataPoppedAt(); 75 | 76 | File_ManageData_DataManaged("Hello", "World"); 77 | File_ManageData_DataManaged("Witaj", "Swiecie"); 78 | File_ManageData_DataManaged("Hallo", " Welt"); 79 | File_ManageData_DataManaged("Bonjour", " le monde"); 80 | File_ManageData_DataManaged("Hola", "Mundo"); 81 | File_ManageData_DataManaged("Ciao", "Mondo"); 82 | 83 | File_SaveAndRead_DataSavedAndRead("Hello World!!!"); 84 | File_SaveAndRead_DataSavedAndRead("Witaj Swiecie!!!"); 85 | File_SaveAndRead_DataSavedAndRead("Hallo Welt!!!"); 86 | File_SaveAndRead_DataSavedAndRead("Bonjour le monde!!!"); 87 | File_SaveAndRead_DataSavedAndRead("Hola Mundo!!!"); 88 | File_SaveAndRead_DataSavedAndRead("Ciao mondo!!!"); 89 | 90 | File_FileIsDifferent_FileIsDifferentWorks("Hello", "World"); 91 | File_FileIsDifferent_FileIsDifferentWorks("Witaj", "Swiecie"); 92 | File_FileIsDifferent_FileIsDifferentWorks("Hallo", " Welt"); 93 | File_FileIsDifferent_FileIsDifferentWorks("Bonjour", " le monde"); 94 | File_FileIsDifferent_FileIsDifferentWorks("Hola", "Mundo"); 95 | File_FileIsDifferent_FileIsDifferentWorks("Ciao", "Mondo"); 96 | 97 | File_CreateAndRemoveFile_FileCreatedAndRemoved("data.txt"); 98 | File_CreateAndRemoveFile_FileCreatedAndRemoved("HelloThere.txt"); 99 | File_CreateAndRemoveFile_FileCreatedAndRemoved("World.txt"); 100 | File_CreateAndRemoveFile_FileCreatedAndRemoved("HelloWorld.txt"); 101 | 102 | File_HashFile_FileHashed("Hello World!!!"); 103 | File_HashFile_FileHashed("Witaj Swiecie!!!"); 104 | File_HashFile_FileHashed("Hallo Welt!!!"); 105 | File_HashFile_FileHashed("Bonjour le monde!!!"); 106 | 107 | File_IsEmpty_IsEmptyWorks(); 108 | 109 | if (ran == passed) 110 | std::cout << passed << "/" << ran << " All tests passed" << std::endl; 111 | else 112 | std::cout << passed << "/" << ran << " Some tests failed" << std::endl; 113 | 114 | std::cout << "Type any to continue\n"; 115 | std::getchar(); 116 | } 117 | 118 | void UnitTest::File_GetSize_SizeReturned(size_t size) { 119 | ran++; 120 | // Arrange 121 | Data::File file_class = Data::File("data.txt", 0); 122 | for (size_t i = 0; i < size; i++) { 123 | file_class.push("Hello World!!!"); 124 | } 125 | // Act 126 | size_t data_size = file_class.size(); 127 | // Assert 128 | if (data_size == size) { 129 | passed++; 130 | std::cout << "File_GetSize_SizeReturned Passed" << std::endl; 131 | } 132 | else 133 | std::cout << "File_GetSize_SizeReturned Failed" << std::endl; 134 | } 135 | 136 | void UnitTest::File_PushData_DataPushed(std::string data) { 137 | ran++; 138 | // Arrange 139 | Data::File file_class = Data::File("data.txt", 0); 140 | // Assert p1 141 | if (file_class.size() == 0) { 142 | // Act p2 143 | file_class.push(data); 144 | std::string data1 = data; 145 | data = ""; 146 | // Assert p2 147 | if (file_class.size() == 1 && file_class[file_class.size() - 1] == data1) { 148 | passed++; 149 | std::cout << "File_PushData_DataPushed Passed" << std::endl; 150 | } 151 | else 152 | std::cout << "File_PushData_DataPushed Failed on p2" << std::endl; 153 | } 154 | else 155 | std::cout << "File_PushData_DataPushed Failed on p1" << std::endl; 156 | }; 157 | 158 | void UnitTest::File_PopData_DataPopped(std::string data) { 159 | ran++; 160 | // Arrange 161 | Data::File file_class = Data::File("data.txt", 0); 162 | file_class.push(data); 163 | // Act 164 | std::string popped_data = file_class.pop(); 165 | // Assert 166 | if (popped_data == data && file_class.size() == 0) { 167 | passed++; 168 | std::cout << "File_PopData_DataPopped Passed" << std::endl; 169 | } 170 | else 171 | std::cout << "File_PopData_DataPopped Failed" << std::endl; 172 | } 173 | 174 | void UnitTest::File_PopDataAt_DataPoppedAt(std::vector data, const int id) { 175 | ran++; 176 | // Arrange 177 | Data::File file_class = Data::File("data.txt", 0); 178 | for (const std::string& d : data) 179 | file_class.push(d); 180 | std::vector in_data = data; 181 | in_data.erase(in_data.begin() + id); 182 | // Act 183 | std::string popped_data = file_class.pop(id); 184 | // Assert part 1 185 | if (popped_data == data[id]) { 186 | bool same = true; 187 | if (in_data.size() != file_class.size()) same = false; 188 | for (int i = 0; i < file_class.size(); i++) 189 | if (file_class[i] != in_data[i]) same = false; 190 | if (same) { 191 | passed++; 192 | std::cout << "File_PopDataAt_DataPoppedAt Passed" << std::endl; 193 | } 194 | else 195 | std::cout << "File_PopDataAt_DataPoppedAt Failed on Compare" << std::endl; 196 | } 197 | else 198 | std::cout << "File_PopDataAt_DataPoppedAt Failed on Return" << std::endl; 199 | }; 200 | 201 | void UnitTest::File_ManageData_DataManaged(std::string data_entry, std::string data_change) { 202 | ran++; 203 | // Arrange 204 | Data::File file_class = Data::File("data.txt", 0); 205 | file_class.push(data_entry); 206 | // Act 207 | file_class[0] = data_change; 208 | // Assert 209 | if (file_class[0] == data_change) { 210 | passed++; 211 | std::cout << "File_ManageData_DataManaged Passed" << std::endl; 212 | } 213 | else 214 | std::cout << "File_ManageData_DataManaged Failed" << std::endl; 215 | }; 216 | 217 | void UnitTest::File_SaveAndRead_DataSavedAndRead(std::string data) { 218 | ran++; 219 | // Arrange 220 | Data::File file_class = Data::File("data.txt", 0); 221 | file_class.push(data); 222 | // Act 223 | file_class.save(); 224 | file_class.pop(); 225 | file_class.read(); 226 | // Assert 227 | if (file_class.size() == 1 && file_class[0] == data) { 228 | passed++; 229 | std::cout << "File_SaveAndRead_DataSavedAndRead Passed" << std::endl; 230 | } 231 | else 232 | std::cout << "File_SaveAndRead_DataSavedAndRead Failed" << std::endl; 233 | // clean up 234 | file_class.removeFile(); 235 | } 236 | 237 | void UnitTest::File_CreateAndRemoveFile_FileCreatedAndRemoved(const std::string& filename) { 238 | ran++; 239 | // Arrange 240 | Data::File file_class = Data::File(filename, 0); 241 | // Act p1 242 | file_class.createFile(); 243 | // Assert p1 244 | if (std::filesystem::exists(filename)) { 245 | // Act p2 246 | file_class.removeFile(); 247 | // Assert p2 248 | if (!std::filesystem::exists(filename)) { 249 | passed++; 250 | std::cout << "File_CreateAndRemoveFile_FileCreatedAndRemoved Passed" << std::endl; 251 | } 252 | else 253 | std::cout << "File_CreateAndRemoveFile_FileCreatedAndRemoved Failed p2" << std::endl; 254 | } 255 | else 256 | std::cout << "File_CreateAndRemoveFile_FileCreatedAndRemoved Failed p1" << std::endl; 257 | // clean up 258 | file_class.removeFile(); 259 | }; 260 | 261 | void UnitTest::File_IsEmpty_IsEmptyWorks() { 262 | ran++; 263 | // Arrange 264 | Data::File file_class = Data::File("data.txt", 0); 265 | // Act p1 266 | bool is_empty = file_class.isEmpty(); 267 | // Assert p1 268 | if (is_empty) { 269 | // Act p2 270 | file_class.push("Hello World!!!"); 271 | file_class.save(); 272 | is_empty = file_class.isEmpty(); 273 | // Assert p2 274 | if (!is_empty) { 275 | passed++; 276 | std::cout << "File_IsEmpty_IsEmptyWorks Passed" << std::endl; 277 | } 278 | else { 279 | std::cout << "File_IsEmpty_IsEmptyWorks Failed on p2" << std::endl; 280 | } 281 | } 282 | else 283 | std::cout << "File_IsEmpty_IsEmptyWorks Failed on p1" << std::endl; 284 | // clean up 285 | file_class.removeFile(); 286 | } 287 | 288 | void UnitTest::File_FileIsDifferent_FileIsDifferentWorks(std::string data_entry, std::string data_change) { 289 | ran++; 290 | // Arrange 291 | Data::File file_class = Data::File("data.txt", 0); 292 | file_class.push(data_entry); 293 | file_class.save(); 294 | // Act p1 295 | bool is_different = file_class.isDifferent(); 296 | // Assert p1 297 | if (!is_different) { 298 | // Act p2 299 | file_class[0] = data_change; 300 | is_different = file_class.isDifferent(); 301 | // Assert p2 302 | if (is_different) { 303 | passed++; 304 | std::cout << "File_FileIsDifferent_FileIsDifferentWorks Passed" << std::endl; 305 | } 306 | else { 307 | std::cout << "File_FileIsDifferent_FileIsDifferentWorks Failed on p2" << std::endl; 308 | } 309 | } 310 | else 311 | std::cout << "File_FileIsDifferent_FileIsDifferentWorks Failed on p1" << std::endl; 312 | } 313 | 314 | void UnitTest::File_HashFile_FileHashed(std::string data) 315 | { 316 | ran++; 317 | // Arrange 318 | Data::File file_class = Data::File("data.txt", 0); 319 | file_class.push(data); 320 | Data::BaseHash hash = Data::BaseHash("a"); 321 | Data::BaseHash hash1 = Data::BaseHash("b"); 322 | // Act 323 | file_class.save(&hash); 324 | file_class.read(&hash1); 325 | // Assert part 1 326 | if (file_class[0] != data) { 327 | // Act part 2 328 | file_class.read(&hash); 329 | // Assert part 2 330 | if (file_class[0] == data && file_class.size() == 1) { 331 | passed++; 332 | std::cout << "File_HashFile_FileHashed Passed" << std::endl; 333 | } 334 | else 335 | std::cout << "File_HashFile_FileHashed Failed on p2" << std::endl; 336 | } 337 | else 338 | std::cout << "File_HashFile_FileHashed Failed on p1" << std::endl; 339 | // clean up 340 | file_class.removeFile(); 341 | }; 342 | 343 | void UnitTest::Folder_CreateFolderAndRemoveFolder_FolderCreatedAndRemoved(std::filesystem::path path) { 344 | ran++; 345 | // Arrange 346 | Data::Folder folder_class = Data::Folder(path); 347 | folder_class.removeFolder(); 348 | // Act p1 349 | folder_class.createFolder(); 350 | // Assert p1 351 | if (std::filesystem::exists(path)) { 352 | // Act p2 353 | folder_class.removeFolder(); 354 | // Assert p2 355 | if (!std::filesystem::exists(path)) { 356 | passed++; 357 | std::cout << "Folder_CreateFolderAndRemoveFolder_FolderCreatedAndRemoved Passed" << std::endl; 358 | } 359 | else 360 | std::cout << "Folder_CreateFolderAndRemoveFolder_FolderCreatedAndRemoved Failed on p2" << std::endl; 361 | } 362 | else 363 | std::cout << "Folder_CreateFolderAndRemoveFolder_FolderCreatedAndRemoved Failed on p1" << std::endl; 364 | }; 365 | 366 | void UnitTest::Folder_CreateAndRemoveFile_FileCreatedAndRemoved(const std::string& file_name) { 367 | ran++; 368 | // Arrange 369 | Data::Folder folder_class = Data::Folder("testdata"); 370 | folder_class.createFolder(); 371 | folder_class.removeFile(file_name); 372 | // Act p1 373 | folder_class.createFile(file_name); 374 | // Assert p1 375 | if (std::filesystem::exists("testdata/" + file_name)) { 376 | // Act p2 377 | folder_class.removeFile(file_name); 378 | // Assert p2 379 | if (!std::filesystem::exists("testdata/" + file_name)) { 380 | passed++; 381 | std::cout << "Folder_CreateAndRemoveFile_FileCreatedAndRemoved Passed" << std::endl; 382 | } 383 | else 384 | std::cout << "Folder_CreateAndRemoveFile_FileCreatedAndRemoved Failed on p2" << std::endl; 385 | } 386 | else 387 | std::cout << "Folder_CreateAndRemoveFile_FileCreatedAndRemoved Failed on p1" << std::endl; 388 | // clean up 389 | folder_class.removeFolder(); 390 | } 391 | 392 | void UnitTest::Folder_OpenFile_FileOpened(const std::string& file_name, const std::string& data) { 393 | ran++; 394 | // Arrange 395 | Data::Folder c_folder_class = Data::Folder("testdata"); 396 | c_folder_class.createFolder(); 397 | c_folder_class.createFile(file_name); 398 | // Act 399 | std::shared_ptr c_file_class = c_folder_class.openFile(file_name); 400 | c_file_class->push(data); 401 | c_file_class->save(); 402 | c_file_class->pop(); 403 | c_file_class->read(); 404 | // Assert 405 | if (std::filesystem::exists("testdata/" + file_name) && c_file_class->size() == 1 && (*c_file_class)[0] == data) { 406 | 407 | passed++; 408 | std::cout << "Folder_OpenAndCloseFile_FileOpenedAndClosed Passed" << std::endl; 409 | } 410 | else 411 | std::cout << "Folder_OpenAndCloseFile_FileOpenedAndClosed Failed on p1" << std::endl; 412 | // clean up 413 | 414 | c_folder_class.removeFolder(); 415 | } 416 | 417 | void UnitTest::Folder_Exist_ExistReturnProperValue(std::filesystem::path path) { 418 | ran++; 419 | // Arrange 420 | Data::Folder folder_class = Data::Folder(path); 421 | folder_class.removeFolder(); 422 | // Act p1 423 | bool exist = folder_class.exist(); 424 | // Assert p1 425 | if (!exist) { 426 | // Act p2 427 | folder_class.createFolder(); 428 | exist = folder_class.exist(); 429 | if (exist) { 430 | passed++; 431 | std::cout << "Folder_Exist_ExistReturnProperValue Passed" << std::endl; 432 | } 433 | else { 434 | std::cout << "Folder_Exist_ExistReturnProperValue Failed on p2" << std::endl; 435 | } 436 | } 437 | else { 438 | std::cout << "Folder_Exist_ExistReturnProperValue Failed on p1" << std::endl; 439 | } 440 | // clean up 441 | folder_class.removeFolder(); 442 | } 443 | void UnitTest::Folder_IsEmpty_ReturnsProperValue(std::filesystem::path path) { 444 | ran++; 445 | // Arrange 446 | Data::Folder folder_class = Data::Folder(path); 447 | folder_class.removeFolder(); 448 | folder_class.createFolder(); 449 | // Act p1 450 | bool is_empty = folder_class.isEmpty(); 451 | if (is_empty) { 452 | // Act p2 453 | folder_class.createFile("data.txt"); 454 | is_empty = folder_class.isEmpty(); 455 | // Assert p2 456 | if (!is_empty) { 457 | passed++; 458 | std::cout << "Folder_IsEmpty_ReturnsProperValue Passed" << std::endl; 459 | } 460 | else { 461 | std::cout << "Folder_IsEmpty_ReturnsProperValue Failed on p2" << std::endl; 462 | } 463 | } 464 | else { 465 | std::cout << "Folder_IsEmpty_ReturnsProperValue Failed on p1" << std::endl; 466 | } 467 | // clean up 468 | folder_class.removeFolder(); 469 | } 470 | 471 | void UnitTest::Folder_GetFilesList_FilesListGot(std::vector inner_files) { 472 | ran++; 473 | // Arrange 474 | Data::Folder folder_class = Data::Folder("testdata"); 475 | folder_class.removeFolder(); 476 | folder_class.createFolder(); 477 | std::sort(inner_files.begin(), inner_files.end()); 478 | for (const std::string& file : inner_files) 479 | folder_class.createFile(file); 480 | // Act 481 | folder_class.fetchFilesList(); 482 | std::vector files = folder_class.filesList(); 483 | std::sort(files.begin(), files.end()); 484 | // Assert 485 | if (files.size() == inner_files.size() && files == inner_files) { 486 | passed++; 487 | std::cout << "Folder_GetFilesList_FilesListGot Passed" << std::endl; 488 | } 489 | else 490 | std::cout << "Folder_GetFilesList_FilesListGot Failed" << std::endl; 491 | // clean up 492 | folder_class.removeFolder(); 493 | } 494 | void UnitTest::Folder_IsDifferent_CheckIfFilesAreDifferent(std::vector inner_files, const std::string& new_file) { 495 | ran++; 496 | // Arrange 497 | Data::Folder folder_class = Data::Folder("testdata"); 498 | folder_class.removeFolder(); 499 | folder_class.createFolder(); 500 | for (const std::string& file : inner_files) 501 | folder_class.createFile(file); 502 | // Act p1 503 | folder_class.fetchFilesList(); 504 | bool is_different = folder_class.filesListIsDifferent(); 505 | // Assert p1 506 | if (!is_different) { 507 | // Act p2 508 | folder_class.createFile(new_file); 509 | is_different = folder_class.filesListIsDifferent(); 510 | // Assert p2 511 | if (is_different) { 512 | passed++; 513 | std::cout << "Folder_IsDifferent_CheckIfFilesAreDifferent Passed" << std::endl; 514 | } 515 | else 516 | std::cout << "Folder_IsDifferent_CheckIfFilesAreDifferent Failed on p2" << std::endl; 517 | } 518 | else 519 | std::cout << "Folder_IsDifferent_CheckIfFilesAreDifferent Failed on p1" << std::endl; 520 | // clean up 521 | folder_class.removeFolder(); 522 | } 523 | void UnitTest::Folder_GetFilesCount_FilesCountGot(std::vector inner_files) { 524 | ran++; 525 | // Arrange 526 | Data::Folder folder_class = Data::Folder("testdata"); 527 | folder_class.removeFolder(); 528 | folder_class.createFolder(); 529 | for (const std::string& file : inner_files) 530 | folder_class.createFile(file); 531 | // Act 532 | folder_class.fetchFilesList(); 533 | size_t files_count = folder_class.count(); 534 | // Assert 535 | if (files_count == inner_files.size()) { 536 | passed++; 537 | std::cout << "Folder_GetFilesCount_FilesCountGot Passed" << std::endl; 538 | } 539 | else 540 | std::cout << "Folder_GetFilesCount_FilesCountGot Failed" << std::endl; 541 | // clean up 542 | folder_class.removeFolder(); 543 | } 544 | void UnitTest::Folder_CleanFolder_FolderCleaned(std::vector inner_files) { 545 | ran++; 546 | // Arrange 547 | Data::Folder folder_class = Data::Folder("testdata"); 548 | folder_class.removeFolder(); 549 | folder_class.createFolder(); 550 | for (const std::string& file : inner_files) 551 | folder_class.createFile(file); 552 | // Act 553 | folder_class.clean(); 554 | // Assert 555 | if (folder_class.isEmpty()) { 556 | passed++; 557 | std::cout << "Folder_CleanFolder_FolderCleaned Passed" << std::endl; 558 | } 559 | else 560 | std::cout << "Folder_CleanFolder_FolderCleaned Failed" << std::endl; 561 | // clean up 562 | folder_class.removeFolder(); 563 | }; -------------------------------------------------------------------------------- /Main/UnitTest.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Data/Data.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class UnitTest { 9 | public: 10 | UnitTest(); 11 | 12 | void Folder_CreateFolderAndRemoveFolder_FolderCreatedAndRemoved(std::filesystem::path path = "data"); 13 | void Folder_CreateAndRemoveFile_FileCreatedAndRemoved(const std::string& file_name); 14 | void Folder_OpenFile_FileOpened(const std::string& file_name, const std::string& data); 15 | void Folder_Exist_ExistReturnProperValue(std::filesystem::path path = "data"); 16 | void Folder_IsEmpty_ReturnsProperValue(std::filesystem::path path = "data"); 17 | void Folder_GetFilesList_FilesListGot(std::vector inner_files = { "file1.txt", "file2.txt", "file3.txt" }); 18 | void Folder_IsDifferent_CheckIfFilesAreDifferent(std::vector inner_files = { "file1.txt", "file2.txt", "file3.txt" }, const std::string& new_file = "file4.txt"); 19 | void Folder_GetFilesCount_FilesCountGot(std::vector inner_files = { "file1.txt", "file2.txt", "file3.txt" }); 20 | void Folder_CleanFolder_FolderCleaned(std::vector inner_files = { "file1.txt", "file2.txt", "file3.txt" }); 21 | 22 | void File_GetSize_SizeReturned(size_t size = 3); 23 | void File_PushData_DataPushed(std::string data = "Hello World!!!"); 24 | void File_PopData_DataPopped(std::string data = "Hello World!!!"); 25 | void File_PopDataAt_DataPoppedAt(std::vector data = { "A", "B", "C" }, const int id = 0); 26 | void File_ManageData_DataManaged(std::string data_entry = "Hello", std::string data_change = "World"); 27 | void File_SaveAndRead_DataSavedAndRead(std::string data = "Hello World!!!"); 28 | void File_CreateAndRemoveFile_FileCreatedAndRemoved(const std::string& filename); 29 | void File_IsEmpty_IsEmptyWorks(); 30 | void File_FileIsDifferent_FileIsDifferentWorks(std::string data_entry = "Hello", std::string data_change = "World"); 31 | void File_HashFile_FileHashed(std::string data = "Hello World!!!"); 32 | 33 | private: 34 | unsigned int ran = 0; 35 | unsigned int passed = 0; 36 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

🔥C++ Data Lib🔥

3 | 4 |

🌐About🌐

5 | This is Easy Lib for Saving, Loading, Managing Data and Files <3 6 | 7 |

📃Usage📃

8 | 1. Download Tag add Files to project And Include Header File
9 | Array:
10 | 2.1 Create
11 | Data::Array [ClassName] = Data::Array({Path}, {Size});
12 | 2.2 Update FilesList
13 | [ClassName].UpdateList();
14 | 2.3 Get FilesList
15 | [ClassName].FileList[{element}];
16 | 2.4 Read Data From File in this dir to Array
17 | [ClassName].Read({FileName}, {UnHash function(optional) for line});
18 | 2.5 Save Data from Array to File
19 | [ClassName].Save({FileName}, {Hash function(optional) for line});
20 | 2.6 Create File
21 | [ClassName].Create({FileName});
22 | 2.7 Remove File
23 | [ClassName].Remove({FileName});
24 | 2.8 Check if IsEmpty
25 | [ClassName].IsEmpty({FileName});
26 | 2.9 Check if files was changed in Dir
27 | [ClassName].Check();
28 | 2.10 Acces to Data Array
29 | [ClassName].Content
30 | 31 | Vector:
32 | 2.1 Create
33 | Data::Vector [ClassName] = Data::Vector({Path}, {Size});
34 | 2.2 Update FilesList
35 | [ClassName].UpdateList();
36 | 2.3 Get FilesList
37 | [ClassName].FileList[{element}];
38 | 2.4 Read Data From File in this dir to Array
39 | [ClassName].Read({FileName}, {UnHash function(optional) for line});
40 | 2.5 Save Data from Array to File
41 | [ClassName].Save({FileName}, {Hash function(optional) for line});
42 | 2.6 Create File
43 | [ClassName].Create({FileName});
44 | 2.7 Remove File
45 | [ClassName].Remove({FileName});
46 | 2.8 Check if IsEmpty
47 | [ClassName].IsEmpty({FileName});
48 | 2.9 Check if files was changed in Dir
49 | [ClassName].Check();
50 | 2.10 Acces to Data Vector
51 | [ClassName].Content
52 | 53 |

🔥Features🔥

54 |
55 |
56 | 57 | * Vectors. 58 | * Arrays. 59 | * List All Files in Dir. 60 | * Remove File. 61 | * Create File. 62 | * Create Dir. 63 | * Load Data From File. 64 | * Save Data to File. 65 | * Manage Conetent Data. 66 | * Check if File is empty. 67 | * Check if Files are change. 68 | * Custom Hash Function For Every Line 69 | * Save in dec Format 70 |
71 | --------------------------------------------------------------------------------