diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a1abf7510c2335d1721461ed514971f28e35264..abe230b5d2d66fbc70d51396155c1d157d391122 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ OPTION(BUILD_THIRDPARTY "Specific build thrid-party module" OFF) OPTION(BUILD_CONSOLE "Specific build console module" ON) OPTION(BUILD_DATABASE "Specific build database module" ON) OPTION(BUILD_GENERIC "Specific build generic module" ON) +OPTION(BUILD_HASHALGORITHM "Specific build hash algorithm" ON) OPTION(BUILD_MATHEMATICS "Specific mathematics module" ON) OPTION(BUILD_OTHER "Specific build other module" ON) OPTION(BUILD_SERIALIZATION "Specific build serialization module" ON) @@ -41,6 +42,10 @@ IF(${BUILD_GENERIC}) ADD_SUBDIRECTORY("NahidaProject.Generic") ENDIF() +IF(${BUILD_HASHALGORITHM}) + ADD_SUBDIRECTORY("NahidaProject.HashAlgorithm") +ENDIF() + IF(${BUILD_MATHEMATICS}) ADD_SUBDIRECTORY("NahidaProject.Mathematics") ENDIF() @@ -53,10 +58,6 @@ IF(${BUILD_SERIALIZATION}) ADD_SUBDIRECTORY("NahidaProject.Serialization") ENDIF() -IF(${BUILD_SYSTEM}) - ADD_SUBDIRECTORY("NahidaProject.System") -ENDIF() - IF(${BUILD_THREAD}) ADD_SUBDIRECTORY("NahidaProject.Thread") ENDIF() diff --git a/NahidaProject.Console/Sources/ChooseDialog.cpp b/NahidaProject.Console/Sources/ChooseDialog.cpp index e62ee715ce3a03aba45ecfd4398f9457e8133f4d..357db40bf536b540e066673da8623d675a55d26d 100644 --- a/NahidaProject.Console/Sources/ChooseDialog.cpp +++ b/NahidaProject.Console/Sources/ChooseDialog.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "ChooseDialog.h" std::wstring NahidaProject::ChooseDialog::BasicMenu::TruncateString(const std::wstring& str, int maxSize) diff --git a/NahidaProject.Console/Sources/ChooseDialog.h b/NahidaProject.Console/Sources/ChooseDialog.h index a1ff3f538db0ee6c4039f3e580642eadeb2467f9..d5bacc6abdbb5d9db4a84c5e570af698f52382f2 100644 --- a/NahidaProject.Console/Sources/ChooseDialog.h +++ b/NahidaProject.Console/Sources/ChooseDialog.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #pragma once #include diff --git a/NahidaProject.Console/Sources/TerminalColor.cpp b/NahidaProject.Console/Sources/TerminalColor.cpp index aa7617590b7ab81bfda182c8d36d67e5086bc9d8..d617f2b4e9a5b79af3424a064c55685777599794 100644 --- a/NahidaProject.Console/Sources/TerminalColor.cpp +++ b/NahidaProject.Console/Sources/TerminalColor.cpp @@ -17,17 +17,28 @@ See the Mulan PSL v2 for more details. HANDLE handleOfConsole = GetStdHandle(STD_OUTPUT_HANDLE); std::ostream& NahidaProject::TerminalColor::Reset(std::ostream& os) { +#if defined(_WIN32) || defined(WIN32) +#include +#endif SetConsoleTextAttribute(handleOfConsole, 0x0008 | 0x0004 | 0x0002 | 0x0001); return os; } std::ostream& NahidaProject::TerminalColor::Red(std::ostream& os) { - SetConsoleTextAttribute(handleOfConsole, 0x0008 | 0x0004); +#if defined(_WIN32) || defined(WIN32) + SetConsoleTextAttribute(handleOfConsole, 0x0004 | 0x0006); +#else + os << "\033[01m"; +#endif return os; } std::ostream& NahidaProject::TerminalColor::Orange(std::ostream& os) { - SetConsoleTextAttribute(handleOfConsole, 0x0004 | 0x0006); +#if defined(_WIN32) || defined(WIN32) + SetConsoleTextAttribute(handleOfConsole, 0x0004 | 0x0006); +#else + os << "\033[03m"; +#endif return os; } diff --git a/NahidaProject.Console/Sources/TerminalColor.h b/NahidaProject.Console/Sources/TerminalColor.h index 9680ec0b9c93a991013c74e1842e893cb39811a7..75e96d59ceef63c4d02b02c13cec035da6df7425 100644 --- a/NahidaProject.Console/Sources/TerminalColor.h +++ b/NahidaProject.Console/Sources/TerminalColor.h @@ -11,12 +11,12 @@ NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ -#ifndef TERMINALCOLOR_H -#define TERMINALCOLOR_H #pragma once #include +#if defined(_WIN32) || defined(WIN32) #include +#endif namespace NahidaProject { class __declspec(dllexport) TerminalColor { @@ -39,5 +39,3 @@ namespace NahidaProject { static std::ostream& BackgroundPurple(std::ostream& os); }; } - -#endif \ No newline at end of file diff --git a/NahidaProject.Database/CMakeLists.txt b/NahidaProject.Database/CMakeLists.txt index 4cc7420e4ddd8a56f29dc01650b74845b0eb081e..5caaa789c50cf386fce7572bf684fbc74cef9130 100644 --- a/NahidaProject.Database/CMakeLists.txt +++ b/NahidaProject.Database/CMakeLists.txt @@ -18,8 +18,7 @@ IF(CMAKE_VERSION VERSION_GREATER 3.12) SET_PROPERTY(TARGET NahidaProject.${MODULEID} PROPERTY CXX_STANDARD 20) ENDIF() -MESSAGE(STATUS "Build module [${MODULEID}] done.") -MESSAGE(STATUS "Build module [${MODULEID}] done.") - TARGET_LINK_LIBRARIES(NahidaProject.${MODULEID}Tests PUBLIC odbc32) TARGET_LINK_LIBRARIES(NahidaProject.${MODULEID} PUBLIC odbc32) + +MESSAGE(STATUS "Build module [${MODULEID}] done.") diff --git a/NahidaProject.Generic/Sources/HTTPRequest.cpp b/NahidaProject.Generic/Sources/HTTPRequest.cpp index 5c4eeb931bf3dc6d82be2aa73a19612eb1f57f4b..bc272d29308f1257cfcc5e9c9dce577b65a7f1b8 100644 --- a/NahidaProject.Generic/Sources/HTTPRequest.cpp +++ b/NahidaProject.Generic/Sources/HTTPRequest.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "HTTPRequest.h" NahidaProject::HTTPRequest::Implement::TCPSocket::TCPSocket() noexcept : rawSocket(-1) { diff --git a/NahidaProject.Generic/Sources/HTTPRequest.h b/NahidaProject.Generic/Sources/HTTPRequest.h index 33b4acae9a37e5919be9d8d12384fddd212cb302..1dd90d65528952bafc01610fc6c2576902112609 100644 --- a/NahidaProject.Generic/Sources/HTTPRequest.h +++ b/NahidaProject.Generic/Sources/HTTPRequest.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include #include diff --git a/NahidaProject.System/CMakeLists.txt b/NahidaProject.HashAlgorithm/CMakeLists.txt similarity index 97% rename from NahidaProject.System/CMakeLists.txt rename to NahidaProject.HashAlgorithm/CMakeLists.txt index 246f07731e5b01ec8cb6df5b7c0a4fe278695bc7..84521dde8f18f342f94753f11ae109656beac2b6 100644 --- a/NahidaProject.System/CMakeLists.txt +++ b/NahidaProject.HashAlgorithm/CMakeLists.txt @@ -2,7 +2,7 @@ # 将源代码添加到此项目的可执行文件。 CMAKE_MINIMUM_REQUIRED(VERSION 3.31 FATAL_ERROR) -SET(MODULEID "System") +SET(MODULEID "HashAlgorithm") FILE(GLOB TESTFILE ${CMAKE_SOURCE_DIR}/NahidaProject.UnitTest/Sources/*.cpp ${CMAKE_SOURCE_DIR}/NahidaProject.UnitTest/Sources/*.h) FILE(GLOB ALL_SOURCECODE ${CMAKE_SOURCE_DIR}/NahidaProject.${MODULEID}/Sources/*.cpp) diff --git a/NahidaProject.HashAlgorithm/Sources/Base64.cpp b/NahidaProject.HashAlgorithm/Sources/Base64.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ace889ac7c02fb833c876b044a8656fe9cfeb796 --- /dev/null +++ b/NahidaProject.HashAlgorithm/Sources/Base64.cpp @@ -0,0 +1,147 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + +#include "Base64.h" + +std::string NahidaProject::Base64::Encode(const std::string& input) { + NahidaProject::Base64 base64; + + std::string result; + int i = 0; + int j = 0; + unsigned char charArray_3[3]; + unsigned char charArray_4[4]; + + size_t in_len = input.length(); + const char* bytesToEncode = input.c_str(); + + while (in_len--) { + charArray_3[i++] = *(bytesToEncode++); + if (i == 3) { + charArray_4[0] = (charArray_3[0] & 0xfc) >> 2; + charArray_4[1] = ((charArray_3[0] & 0x03) << 4) + ((charArray_3[1] & 0xf0) >> 4); + charArray_4[2] = ((charArray_3[1] & 0x0f) << 2) + ((charArray_3[2] & 0xc0) >> 6); + charArray_4[3] = charArray_3[2] & 0x3f; + + for (i = 0; (i < 4); i++) { + result += base64.base64Chars[charArray_4[i]]; + } + i = 0; + } + } + + if (i) { + for (j = i; j < 3; j++) { + charArray_3[j] = '\0'; + } + + charArray_4[0] = (charArray_3[0] & 0xfc) >> 2; + charArray_4[1] = ((charArray_3[0] & 0x03) << 4) + ((charArray_3[1] & 0xf0) >> 4); + charArray_4[2] = ((charArray_3[1] & 0x0f) << 2) + ((charArray_3[2] & 0xc0) >> 6); + charArray_4[3] = charArray_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) { + result += base64.base64Chars[charArray_4[j]]; + } + + while ((i++ < 3)) { + result += '='; + } + } + + return result; +} + +// 解码函数 +std::string NahidaProject::Base64::Decode(const std::string& input) { + NahidaProject::Base64 base64; + + size_t inputLenth = input.length(); + size_t i = 0; + size_t j = 0; + int in_ = 0; + unsigned char charArray_4[4], charArray_3[3]; + std::string result; + + while (inputLenth-- && (input[in_] != '=') && IsBase64(input[in_])) { + charArray_4[i++] = input[in_]; in_++; + if (i == 4) { + for (i = 0; i < 4; i++) { + charArray_4[i] = base64.base64Chars.find(charArray_4[i]); + } + + charArray_3[0] = (charArray_4[0] << 2) + ((charArray_4[1] & 0x30) >> 4); + charArray_3[1] = ((charArray_4[1] & 0xf) << 4) + ((charArray_4[2] & 0x3c) >> 2); + charArray_3[2] = ((charArray_4[2] & 0x3) << 6) + charArray_4[3]; + + for (i = 0; (i < 3); i++) { + result += charArray_3[i]; + } + i = 0; + } + } + + if (i) { + for (j = i; j < 4; j++) { + charArray_4[j] = 0; + } + + for (j = 0; j < 4; j++) { + charArray_4[j] = base64.base64Chars.find(charArray_4[j]); + } + + charArray_3[0] = (charArray_4[0] << 2) + ((charArray_4[1] & 0x30) >> 4); + charArray_3[1] = ((charArray_4[1] & 0xf) << 4) + ((charArray_4[2] & 0x3c) >> 2); + charArray_3[2] = ((charArray_4[2] & 0x3) << 6) + charArray_4[3]; + + for (j = 0; (j < i - 1); j++) { + result += charArray_3[j]; + } + } + + return result; +} + +// 从文件读取并编码 +std::string NahidaProject::Base64::EncodeFromFile(const std::string& fileName) { + FILE* file = fopen(fileName.c_str(), "rb"); + if (!file) { + return ""; + } + + std::string content; + char buffer[1024]; + size_t bytesRead; + + while ((bytesRead = fread(buffer, 1, sizeof(buffer), file)) > 0) { + content.append(buffer, bytesRead); + } + + fclose(file); + return Encode(content); +} + +// 编码并写入文件 +bool NahidaProject::Base64::DecodeToFile(const std::string& encodedData, const std::string& fileName) { + std::string decoded = Decode(encodedData); + + FILE* file = fopen(fileName.c_str(), "wb"); + if (!file) { + return false; + } + + size_t written = fwrite(decoded.c_str(), 1, decoded.length(), file); + fclose(file); + + return written == decoded.length(); +} \ No newline at end of file diff --git a/NahidaProject.System/Sources/RegisterTable.h b/NahidaProject.HashAlgorithm/Sources/Base64.h similarity index 52% rename from NahidaProject.System/Sources/RegisterTable.h rename to NahidaProject.HashAlgorithm/Sources/Base64.h index a3ce433f6bee83786d0a717dd9a95b8ed113c7cc..d7dc92f50d17f73815c74378e61c8c53afb6aa99 100644 --- a/NahidaProject.System/Sources/RegisterTable.h +++ b/NahidaProject.HashAlgorithm/Sources/Base64.h @@ -11,33 +11,21 @@ NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ -#ifndef REGISTERTABLE_H -#define REGISTERTABLE_H +#pragma once -#include +#include #include -#include namespace NahidaProject { - class __declspec(dllexport) RegisterTable { + class Base64 { private: - const char* subKey = "Software\\ExampleCache"; - public: - RegisterTable() { - - } - - ~RegisterTable() { - - } + const std::string base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + static inline bool IsBase64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); } - RegisterTable(const char* subKey) { - this->subKey = subKey; - } - - std::string GetValue(const std::string& key); - bool SetValue(const std::string& key, const std::string& value); + public: + static std::string Encode(const std::string& input); + static std::string Decode(const std::string& input); + static std::string EncodeFromFile(const std::string& fileName); + static bool DecodeToFile(const std::string& encodedData, const std::string& fileName); }; } - -#endif \ No newline at end of file diff --git a/NahidaProject.HashAlgorithm/Sources/MD5.cpp b/NahidaProject.HashAlgorithm/Sources/MD5.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4be80536a445568827b2392d42995cf1779d2f4 --- /dev/null +++ b/NahidaProject.HashAlgorithm/Sources/MD5.cpp @@ -0,0 +1,119 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + +#include "MD5.h" + +void NahidaProject::MD5::Transform(uint4 state[4], const uint1 block[64]) { + uint4 a = state[0], b = state[1], c = state[2], d = state[3]; + uint4 M[16]; + + // 将 512 位块转换为 16 个 32 位字 + for (int i = 0; i < 16; i++) { + M[i] = (uint4)block[i * 4] | ((uint4)block[i * 4 + 1] << 8) | + ((uint4)block[i * 4 + 2] << 16) | ((uint4)block[i * 4 + 3] << 24); + } + + // 主循环 + for (int i = 0; i < 64; i++) { + uint4 f, g; + + if (i < 16) { + f = F(b, c, d); + g = i; + } + else if (i < 32) { + f = G(b, c, d); + g = (5 * i + 1) % 16; + } + else if (i < 48) { + f = H(b, c, d); + g = (3 * i + 5) % 16; + } + else { + f = I(b, c, d); + g = (7 * i) % 16; + } + + f = f + a + md5K[i] + M[g]; + a = d; + d = c; + c = b; + b = b + LeftRotate(f, md5S[i]); + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; +} + +// 填充消息 +void NahidaProject::MD5::PadMessage(std::string& message) { + uint8 originalLength = message.length() * 8; + message += (char)0x80; // 添加 1 位,然后填充 0 + + // 填充 0 直到长度 ≡ 448 (mod 512) + while ((message.length() * 8) % 512 != 448) { + message += (char)0x00; + } + + // 添加原始消息长度(64 位) + for (int i = 0; i < 8; i++) { + message += (char)((originalLength >> (i * 8)) & 0xFF); + } +} + +// 将 uint4 转换为十六进制字符串 +std::string NahidaProject::MD5::Uint4ToHex(uint4 value) { + std::stringstream ss; + ss << std::hex << std::setfill('0'); + for (int i = 0; i < 4; i++) { + ss << std::setw(2) << ((value >> (i * 8)) & 0xFF); + } + return ss.str(); +} + +std::string NahidaProject::MD5::Calculate(const std::string& input) { + std::string message = input; + + // 初始化 MD5 缓冲区 + uint4 state[4] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476 }; + + // 填充消息 + PadMessage(message); + + // 处理消息块 + uint1 block[64]; + for (size_t i = 0; i < message.length(); i += 64) { + memcpy(block, message.c_str() + i, 64); + Transform(state, block); + } + + // 生成最终的哈希值 + std::stringstream result; + result << std::hex << std::setfill('0'); + for (int i = 0; i < 4; i++) { + result << std::setw(2) << (state[i] & 0xFF); + result << std::setw(2) << ((state[i] >> 8) & 0xFF); + result << std::setw(2) << ((state[i] >> 16) & 0xFF); + result << std::setw(2) << ((state[i] >> 24) & 0xFF); + } + + return result.str(); +} + +// 静态方法,方便直接调用 +std::string NahidaProject::MD5::Hash(const std::string& input) { + MD5 md5; + return md5.Calculate(input); +} diff --git a/NahidaProject.HashAlgorithm/Sources/MD5.h b/NahidaProject.HashAlgorithm/Sources/MD5.h new file mode 100644 index 0000000000000000000000000000000000000000..d92170186bf2c99fc3622749d751866e4f2d7075 --- /dev/null +++ b/NahidaProject.HashAlgorithm/Sources/MD5.h @@ -0,0 +1,62 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ +#pragma once + +#include +#include +#include +#include +#include + +namespace NahidaProject { + class MD5 { + private: + typedef unsigned char uint1; + typedef unsigned int uint4; + typedef unsigned long long uint8; + + uint4 md5S[64] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 }; + uint4 md5K[64] = { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + + uint4 LeftRotate(uint4 value, uint4 shift) { return (value << shift) | (value >> (32 - shift)); } + uint4 F(uint4 x, uint4 y, uint4 z) { return (x & y) | (~x & z); } + uint4 G(uint4 x, uint4 y, uint4 z) { return (x & z) | (y & ~z); } + uint4 H(uint4 x, uint4 y, uint4 z) { return x ^ y ^ z; } + uint4 I(uint4 x, uint4 y, uint4 z) { return y ^ (x | ~z); } + + void Transform(uint4 state[4], const uint1 block[64]); + void PadMessage(std::string& message); + std::string Uint4ToHex(uint4 value); + + public: + std::string Calculate(const std::string& input); + static std::string Hash(const std::string& input); + }; +} diff --git a/NahidaProject.HashAlgorithm/Sources/SHA256.cpp b/NahidaProject.HashAlgorithm/Sources/SHA256.cpp new file mode 100644 index 0000000000000000000000000000000000000000..552a02f74540085641a116e19b760a6d0b26c8cd --- /dev/null +++ b/NahidaProject.HashAlgorithm/Sources/SHA256.cpp @@ -0,0 +1,156 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + +#include "SHA256.h" + +void NahidaProject::SHA256::Initial() { + h[0] = 0x6a09e667; + h[1] = 0xbb67ae85; + h[2] = 0x3c6ef372; + h[3] = 0xa54ff53a; + h[4] = 0x510e527f; + h[5] = 0x9b05688c; + h[6] = 0x1f83d9ab; + h[7] = 0x5be0cd19; +} + +void NahidaProject::SHA256::ProcessBlock(const uint8_t* block) { + uint32_t w[64]; + + for (int i = 0; i < 16; i++) { + w[i] = (static_cast(block[i * 4]) << 24) | (static_cast(block[i * 4 + 1]) << 16) | (static_cast(block[i * 4 + 2]) << 8) | (static_cast(block[i * 4 + 3])); + } + + for (int i = 16; i < 64; i++) { + w[i] = Gamma1(w[i - 2]) + w[i - 7] + Gamma0(w[i - 15]) + w[i - 16]; + } + + uint32_t a = h[0]; + uint32_t b = h[1]; + uint32_t c = h[2]; + uint32_t d = h[3]; + uint32_t e = h[4]; + uint32_t f = h[5]; + uint32_t g = h[6]; + uint32_t hh = h[7]; + + for (int i = 0; i < 64; i++) { + uint32_t t1 = hh + Sigma1(e) + Ch(e, f, g) + sha256K[i] + w[i]; + uint32_t t2 = Sigma0(a) + Maj(a, b, c); + + hh = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + + h[0] += a; + h[1] += b; + h[2] += c; + h[3] += d; + h[4] += e; + h[5] += f; + h[6] += g; + h[7] += hh; +} + +void NahidaProject::SHA256::ProcessFinalBlock(const uint8_t* data, size_t length, uint64_t totalBits) { + uint8_t block[64]; + + memset(block, 0, sizeof(block)); + memcpy(block, data, length); + + block[length] = 0x80; + + if (length >= 56) { + ProcessBlock(block); + memset(block, 0, sizeof(block)); + } + + uint64_t bitLength = totalBits; + for (int i = 0; i < 8; i++) { + block[63 - i] = static_cast(bitLength >> (i * 8)); + } + + ProcessBlock(block); +} + +std::vector NahidaProject::SHA256::Hash(const std::string& input) { + Initial(); + + const uint8_t* data = reinterpret_cast(input.c_str()); + size_t length = input.length(); + uint64_t totalBits = length * 8; + + size_t fullBlocks = length / 64; + for (size_t i = 0; i < fullBlocks; i++) { + ProcessBlock(data + i * 64); + } + + size_t remaining = length % 64; + ProcessFinalBlock(data + fullBlocks * 64, remaining, totalBits); + + std::vector result(32); + for (int i = 0; i < 8; i++) { + result[i * 4] = static_cast(h[i] >> 24); + result[i * 4 + 1] = static_cast(h[i] >> 16); + result[i * 4 + 2] = static_cast(h[i] >> 8); + result[i * 4 + 3] = static_cast(h[i]); + } + + return result; +} + +std::vector NahidaProject::SHA256::Hash(const std::vector& input) { + Initial(); + + const uint8_t* data = input.data(); + size_t length = input.size(); + uint64_t totalBits = length * 8; + + size_t fullBlocks = length / 64; + for (size_t i = 0; i < fullBlocks; i++) { + ProcessBlock(data + i * 64); + } + + size_t remaining = length % 64; + ProcessFinalBlock(data + fullBlocks * 64, remaining, totalBits); + + std::vector result(32); + for (int i = 0; i < 8; i++) { + result[i * 4] = static_cast(h[i] >> 24); + result[i * 4 + 1] = static_cast(h[i] >> 16); + result[i * 4 + 2] = static_cast(h[i] >> 8); + result[i * 4 + 3] = static_cast(h[i]); + } + + return result; +} + +std::string NahidaProject::SHA256::BytesToHex(const std::vector& bytes) { + std::stringstream ss; + ss << std::hex << std::setfill('0'); + for (uint8_t byte : bytes) { + ss << std::setw(2) << static_cast(byte); + } + return ss.str(); +} + +std::string NahidaProject::SHA256::HashToString(const std::string& input) { + auto hashBytes = Hash(input); + return BytesToHex(hashBytes); +} \ No newline at end of file diff --git a/NahidaProject.HashAlgorithm/Sources/SHA256.h b/NahidaProject.HashAlgorithm/Sources/SHA256.h new file mode 100644 index 0000000000000000000000000000000000000000..ec8f8996703fe47e6c735c0cfe8ef475dafea119 --- /dev/null +++ b/NahidaProject.HashAlgorithm/Sources/SHA256.h @@ -0,0 +1,80 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace NahidaProject { + class SHA256 { + private: + uint32_t sha256K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + }; + uint32_t h[8]; + + static inline uint32_t Rotr(uint32_t x, int n) { + return (x >> n) | (x << (32 - n)); + } + + static inline uint32_t Ch(uint32_t x, uint32_t y, uint32_t z) { + return (x & y) ^ (~x & z); + } + + static inline uint32_t Maj(uint32_t x, uint32_t y, uint32_t z) { + return (x & y) ^ (x & z) ^ (y & z); + } + + static inline uint32_t Sigma0(uint32_t x) { + return Rotr(x, 2) ^ Rotr(x, 13) ^ Rotr(x, 22); + } + + static inline uint32_t Sigma1(uint32_t x) { + return Rotr(x, 6) ^ Rotr(x, 11) ^ Rotr(x, 25); + } + + static inline uint32_t Gamma0(uint32_t x) { + return Rotr(x, 7) ^ Rotr(x, 18) ^ (x >> 3); + } + + static inline uint32_t Gamma1(uint32_t x) { + return Rotr(x, 17) ^ Rotr(x, 19) ^ (x >> 10); + } + + void Initial(); + void ProcessBlock(const uint8_t* block); + void ProcessFinalBlock(const uint8_t* data, size_t length, uint64_t totalBits); + + public: + SHA256() { + Initial(); + } + + std::vector Hash(const std::string& input); + std::vector Hash(const std::vector& input); + static std::string BytesToHex(const std::vector& bytes); + std::string HashToString(const std::string& input); + }; +} diff --git a/NahidaProject.HashAlgorithm/Tests/ModuleUnitTestFile.cpp b/NahidaProject.HashAlgorithm/Tests/ModuleUnitTestFile.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c79971752b5fd72b1603a86227da0aa63e483d44 --- /dev/null +++ b/NahidaProject.HashAlgorithm/Tests/ModuleUnitTestFile.cpp @@ -0,0 +1,52 @@ +#include "..\..\NahidaProject.UnitTest\Sources\NahidaUnitTest.h" + +#include "..\Sources\Base64.h" +#include "..\Sources\MD5.h" +#include "..\Sources\SHA256.h" + +Test(Base64Test) { + std::string original = "Hello, World!"; + std::string encoded = NahidaProject::Base64::Encode(original); + std::string decoded = NahidaProject::Base64::Decode(encoded); + + AssertEqual(original, decoded); + + std::vector testTexts = {"", "a", "ab", "abc", "abcd", "Hello, 世界!", "The quick brown fox jumps over the lazy dog"}; + + for (const auto& test : testTexts) { + std::string encoded1 = NahidaProject::Base64::Encode(test); + std::string decoded1 = NahidaProject::Base64::Decode(encoded1); + AssertEqual(test, decoded1); + } +} + +Test(MD5Test) { + std::cout << "Empty string: " << NahidaProject::MD5::Hash("") << std::endl; + std::cout << "hello: " << NahidaProject::MD5::Hash("hello") << std::endl; + std::cout << "world: " << NahidaProject::MD5::Hash("world") << std::endl; + std::cout << "Hello, World!: " << NahidaProject::MD5::Hash("Hello, World!") << std::endl; + std::cout << "The quick brown fox jumps over the lazy dog: " << NahidaProject::MD5::Hash("The quick brown fox jumps over the lazy dog") << std::endl; + NahidaProject::MD5 md5; + std::cout << "Using instance: " << md5.Calculate("test") << std::endl; +} + +Test(SHA256Test) { + NahidaProject::SHA256 sha256; + + // 测试用例 + std::vector testTexts = {"", "abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "The quick brown fox jumps over the lazy dog", "Hello, World!" }; + + for (const auto& test : testTexts) { + std::string hash = sha256.HashToString(test); + std::cout << "Input: " << test << std::endl; + std::cout << "Hash: " << hash << std::endl; + } + + AssertEqual(sha256.HashToString(""), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); + AssertEqual(sha256.HashToString("abc"), "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); +} + +int main() { + RunAllTestCase(); + return 0; +} \ No newline at end of file diff --git a/NahidaProject.Mathematics/CMakeLists.txt b/NahidaProject.Mathematics/CMakeLists.txt index f1a99484ca0cbc86ea3b51e349bb8525157c2e5a..4cb8fe9eefe495645a7bfed17ca7963f27a3a916 100644 --- a/NahidaProject.Mathematics/CMakeLists.txt +++ b/NahidaProject.Mathematics/CMakeLists.txt @@ -19,5 +19,3 @@ IF(CMAKE_VERSION VERSION_GREATER 3.12) ENDIF() MESSAGE(STATUS "Build module [${MODULEID}] done.") - -MESSAGE(STATUS "Build module [${MODULEID}] done.") \ No newline at end of file diff --git a/NahidaProject.Mathematics/Sources/BigInteger.cpp b/NahidaProject.Mathematics/Sources/BigInteger.cpp index 2b583a42f422c690661ed620a5d72de5a2badfb8..424362a8204e13e490930cac5f0f224dfdbce562 100644 --- a/NahidaProject.Mathematics/Sources/BigInteger.cpp +++ b/NahidaProject.Mathematics/Sources/BigInteger.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #define MAX 10000 #include "BigInteger.h" diff --git a/NahidaProject.Mathematics/Sources/BigInteger.h b/NahidaProject.Mathematics/Sources/BigInteger.h index f6a7933e0f3d7f2673b66fc2bd563d72366b0003..66e97d0d3df5a2cbe3c8838846e7d3fc20799801 100644 --- a/NahidaProject.Mathematics/Sources/BigInteger.h +++ b/NahidaProject.Mathematics/Sources/BigInteger.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #ifndef BIGINTEGER_H #define BIGINTEGER_H #define MAX 10000 diff --git a/NahidaProject.Mathematics/Sources/RandomGenerator.cpp b/NahidaProject.Mathematics/Sources/RandomGenerator.cpp index 5e30634a94e9399eaf9acaf73982b887cb1db367..c321567264552b347b1e7b02fa91732e65d2bfde 100644 --- a/NahidaProject.Mathematics/Sources/RandomGenerator.cpp +++ b/NahidaProject.Mathematics/Sources/RandomGenerator.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "RandomGenerator.h" NahidaProject::RandomGenerator::RandomGenerator() noexcept { diff --git a/NahidaProject.Mathematics/Sources/RandomGenerator.h b/NahidaProject.Mathematics/Sources/RandomGenerator.h index d85ec8c011d3e86f85dd172eded80a5d5c78bff7..728d0cc1d18b301c2c895f2f61f9a4beff1eb93b 100644 --- a/NahidaProject.Mathematics/Sources/RandomGenerator.h +++ b/NahidaProject.Mathematics/Sources/RandomGenerator.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #ifndef RANDOMGENERATOR_H #define RANDOMGENERATOR_H diff --git a/NahidaProject.Mathematics/Sources/Statistics.cpp b/NahidaProject.Mathematics/Sources/Statistics.cpp index 415a15ef9433f663b46d835a8e0d01f2b9dde930..229a9a604b3fa35d7e9e39fcc50e95930c36496a 100644 --- a/NahidaProject.Mathematics/Sources/Statistics.cpp +++ b/NahidaProject.Mathematics/Sources/Statistics.cpp @@ -1 +1,14 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "Statistics.h" \ No newline at end of file diff --git a/NahidaProject.Mathematics/Sources/Statistics.h b/NahidaProject.Mathematics/Sources/Statistics.h index 3a7cb18d9e4dabf38a98cd692148bf62a80005c7..26e100b08cd2c231dbb17bd5c8e41e4b0629ccb5 100644 --- a/NahidaProject.Mathematics/Sources/Statistics.h +++ b/NahidaProject.Mathematics/Sources/Statistics.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #ifndef STATISTICS_H #define STATISTICS_H diff --git a/NahidaProject.Other/Sources/CowSay.cpp b/NahidaProject.Other/Sources/CowSay.cpp index cb95ea8abc7eb58cde99e3fc01d4acf16eae5c30..8f62430fe58fb9ad850643412353aaa4469117c7 100644 --- a/NahidaProject.Other/Sources/CowSay.cpp +++ b/NahidaProject.Other/Sources/CowSay.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "CowSay.h" std::string NahidaProject::CowSay::UnderscoreLength(std::string var){ diff --git a/NahidaProject.Other/Sources/CowSay.h b/NahidaProject.Other/Sources/CowSay.h index 4488681e54d10360d478d2799873a5d39080f0d1..da32f24b74501b00c7136f82d43e5301fedaab30 100644 --- a/NahidaProject.Other/Sources/CowSay.h +++ b/NahidaProject.Other/Sources/CowSay.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #ifndef COWSAY_H #define COWSAY_H diff --git a/NahidaProject.Serialization/CMakeLists.txt b/NahidaProject.Serialization/CMakeLists.txt index cb258175074a2b3d4594eadf945cb08894cbc006..cb657e20cdff0c97da027decda339935a6dc0102 100644 --- a/NahidaProject.Serialization/CMakeLists.txt +++ b/NahidaProject.Serialization/CMakeLists.txt @@ -4,13 +4,29 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.31 FATAL_ERROR) SET(MODULEID "Serialization") -FILE(GLOB TESTFILE ${CMAKE_SOURCE_DIR}/NahidaProject.UnitTest/Sources/*.cpp ${CMAKE_SOURCE_DIR}/NahidaProject.UnitTest/Sources/*.h) -FILE(GLOB ALL_SOURCECODE ${CMAKE_SOURCE_DIR}/NahidaProject.${MODULEID}/Sources/*.cpp) -FILE(GLOB ALL_HEADERFILE ${CMAKE_SOURCE_DIR}/NahidaProject.${MODULEID}/Sources/*.h) -FILE(GLOB ALL_SOURCEANDTESTCODE ${CMAKE_SOURCE_DIR}/NahidaProject.${MODULEID}/Sources/*.cpp ${CMAKE_SOURCE_DIR}/NahidaProject.${MODULEID}/Sources/*.h ${CMAKE_SOURCE_DIR}/NahidaProject.${MODULEID}/Tests/*.cpp) -ADD_EXECUTABLE(NahidaProject.${MODULEID}Tests ${ALL_SOURCEANDTESTCODE} ${TESTFILE}) -ADD_LIBRARY(NahidaProject.${MODULEID}.IMPLEMENT STATIC ${ALL_SOURCECODE}) -ADD_LIBRARY(NahidaProject.${MODULEID} SHARED ${ALL_SOURCECODE}) +FILE(GLOB TESTFILE + ${CMAKE_SOURCE_DIR}/NahidaProject.UnitTest/Sources/*.cpp + ${CMAKE_SOURCE_DIR}/NahidaProject.UnitTest/Sources/*.h +) + +FILE(GLOB_RECURSE ALL_SOURCECODE ${CMAKE_SOURCE_DIR}/NahidaProject.${MODULEID}/Sources/*.cpp) +FILE(GLOB_RECURSE ALL_HEADERFILE ${CMAKE_SOURCE_DIR}/NahidaProject.${MODULEID}/Sources/*.h) + +FILE(GLOB ALL_SOURCEANDTESTCODE + ${TESTFILE} + ${ALL_SOURCECODE} + ${ALL_HEADERFILE} + ${CMAKE_SOURCE_DIR}/NahidaProject.${MODULEID}/Tests/ModuleUnitTestFile.cpp +) + +foreach(item ${ALL_SOURCEANDTESTCODE}) + message(${item}) +endforeach() + +ADD_EXECUTABLE(NahidaProject.${MODULEID}Tests ${ALL_SOURCEANDTESTCODE}) + +ADD_LIBRARY(NahidaProject.${MODULEID}.IMPLEMENT STATIC ${ALL_SOURCECODE} ${ALL_HEADERFILE}) +ADD_LIBRARY(NahidaProject.${MODULEID} SHARED ${ALL_SOURCECODE} ${ALL_HEADERFILE}) IF(CMAKE_VERSION VERSION_GREATER 3.12) SET_PROPERTY(TARGET NahidaProject.${MODULEID}Tests PROPERTY CXX_STANDARD 20) diff --git a/NahidaProject.Serialization/Sources/CSV.cpp b/NahidaProject.Serialization/Sources/CSV.cpp index cd2366ffc4cd6c07101c276f6b09ed82df6a47f1..6a20c0375e4fb1db01d24cb83bc38d8dc8aa9a95 100644 --- a/NahidaProject.Serialization/Sources/CSV.cpp +++ b/NahidaProject.Serialization/Sources/CSV.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "CSV.h" auto NahidaProject::CSV::CSV::Quote(char c) noexcept -> CSV&& { diff --git a/NahidaProject.Serialization/Sources/CSV.h b/NahidaProject.Serialization/Sources/CSV.h index b4b4ce53862f46635a69afddc725dd2385ab03a1..db37c1a0752c5eaba59aa23f613e82a7a9549f8e 100644 --- a/NahidaProject.Serialization/Sources/CSV.h +++ b/NahidaProject.Serialization/Sources/CSV.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #ifndef CSV_H #define CSV_H diff --git a/NahidaProject.Serialization/Sources/INIReader.cpp b/NahidaProject.Serialization/Sources/INI/INIReader.cpp similarity index 100% rename from NahidaProject.Serialization/Sources/INIReader.cpp rename to NahidaProject.Serialization/Sources/INI/INIReader.cpp diff --git a/NahidaProject.Serialization/Sources/INIReader.h b/NahidaProject.Serialization/Sources/INI/INIReader.h similarity index 100% rename from NahidaProject.Serialization/Sources/INIReader.h rename to NahidaProject.Serialization/Sources/INI/INIReader.h diff --git a/NahidaProject.Serialization/Sources/INIWriter.cpp b/NahidaProject.Serialization/Sources/INI/INIWriter.cpp similarity index 100% rename from NahidaProject.Serialization/Sources/INIWriter.cpp rename to NahidaProject.Serialization/Sources/INI/INIWriter.cpp diff --git a/NahidaProject.Serialization/Sources/INIWriter.h b/NahidaProject.Serialization/Sources/INI/INIWriter.h similarity index 100% rename from NahidaProject.Serialization/Sources/INIWriter.h rename to NahidaProject.Serialization/Sources/INI/INIWriter.h diff --git a/NahidaProject.Serialization/Sources/JSON.cpp b/NahidaProject.Serialization/Sources/JSON/JSON.cpp similarity index 95% rename from NahidaProject.Serialization/Sources/JSON.cpp rename to NahidaProject.Serialization/Sources/JSON/JSON.cpp index 86260f02ab342a57a2ec0c5401f0d71e45fa40c5..ff217d7a1e2eec4c45ac68b568310ebb699c9929 100644 --- a/NahidaProject.Serialization/Sources/JSON.cpp +++ b/NahidaProject.Serialization/Sources/JSON/JSON.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "JSON.h" #include "JSONParser.h" diff --git a/NahidaProject.Serialization/Sources/JSON.h b/NahidaProject.Serialization/Sources/JSON/JSON.h similarity index 80% rename from NahidaProject.Serialization/Sources/JSON.h rename to NahidaProject.Serialization/Sources/JSON/JSON.h index f995a4519dba203b5fcc0f4f74215a37239b3e58..918fdd4aaa121c5a07ff7ed0f3b34ef8ec1ffe7a 100644 --- a/NahidaProject.Serialization/Sources/JSON.h +++ b/NahidaProject.Serialization/Sources/JSON/JSON.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #ifndef JSON_H #define JSON_H diff --git a/NahidaProject.Serialization/Sources/JSONParser.cpp b/NahidaProject.Serialization/Sources/JSON/JSONParser.cpp similarity index 91% rename from NahidaProject.Serialization/Sources/JSONParser.cpp rename to NahidaProject.Serialization/Sources/JSON/JSONParser.cpp index 29072c012a14daa9406c842ed25faa6e960e5691..99ce63cb976f0dd4880ebfbda8b51933b8589538 100644 --- a/NahidaProject.Serialization/Sources/JSONParser.cpp +++ b/NahidaProject.Serialization/Sources/JSON/JSONParser.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include #include #include diff --git a/NahidaProject.Serialization/Sources/JSONParser.h b/NahidaProject.Serialization/Sources/JSON/JSONParser.h similarity index 57% rename from NahidaProject.Serialization/Sources/JSONParser.h rename to NahidaProject.Serialization/Sources/JSON/JSONParser.h index 2ba99896f69cff24b4d465458b6b5f18af088fd8..d83db153084a468b3442731138b3ffd500809b40 100644 --- a/NahidaProject.Serialization/Sources/JSONParser.h +++ b/NahidaProject.Serialization/Sources/JSON/JSONParser.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #pragma once #include diff --git a/NahidaProject.Serialization/Sources/MessagePack.cpp b/NahidaProject.Serialization/Sources/MessagePack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a6333ef77d635fe85b27fd8e451ceefecabb6930 --- /dev/null +++ b/NahidaProject.Serialization/Sources/MessagePack.cpp @@ -0,0 +1,498 @@ +#include "MessagePack.h" + +NahidaProject::MessagePack::Type NahidaProject::MessagePack::NilNode::GetType() const { + return Type::NIL; +} + +std::string NahidaProject::MessagePack::NilNode::ToString() const { + return "nil"; +} + +NahidaProject::MessagePack::Type NahidaProject::MessagePack::BoolNode::GetType() const { + return Type::BOOLEAN; +} + +std::string NahidaProject::MessagePack::BoolNode::ToString() const { + return value ? "true" : "false"; +} + +bool NahidaProject::MessagePack::BoolNode::ToBool() const { + return value; +} + +NahidaProject::MessagePack::Type NahidaProject::MessagePack::IntNode::GetType() const { + return Type::INTEGER; +} + +std::string NahidaProject::MessagePack::IntNode::ToString() const { + return std::to_string(value); +} + +int64_t NahidaProject::MessagePack::IntNode::ToInt() const { + return value; +} + +NahidaProject::MessagePack::Type NahidaProject::MessagePack::FloatNode::GetType() const { + return Type::FLOAT; +} + +std::string NahidaProject::MessagePack::FloatNode::ToString() const { + return std::to_string(value); +} + +double NahidaProject::MessagePack::FloatNode::ToFloat() const { + return value; +} + +NahidaProject::MessagePack::Type NahidaProject::MessagePack::StringNode::GetType() const { + return Type::STRING; +} + +std::string NahidaProject::MessagePack::StringNode::ToString() const { + return "\"" + value + "\""; +} + +std::string NahidaProject::MessagePack::StringNode::ToStr() const { + return value; +} + +NahidaProject::MessagePack::Type NahidaProject::MessagePack::ArrayNode::GetType() const { + return Type::ARRAY; +} + +std::string NahidaProject::MessagePack::ArrayNode::ToString() const { + std::string result = "["; + for (size_t i = 0; i < value.size(); ++i) { + if (i > 0) result += ", "; + result += value[i]->ToString(); + } + result += "]"; + return result; +} + +const std::vector>& NahidaProject::MessagePack::ArrayNode::ToArray() const { + return value; +} + +void NahidaProject::MessagePack::ArrayNode::Add(const std::shared_ptr& node) { + value.push_back(node); +} + +NahidaProject::MessagePack::Type NahidaProject::MessagePack::MapNode::GetType() const { + return Type::MAP; +} + +std::string NahidaProject::MessagePack::MapNode::ToString() const { + std::string result = "{"; + bool first = true; + for (const auto& pair : value) { + if (!first) result += ", "; + result += "\"" + pair.first + "\": " + pair.second->ToString(); + first = false; + } + result += "}"; + return result; +} +const std::map>& NahidaProject::MessagePack::MapNode::ToMap() const { + return value; +} + +void NahidaProject::MessagePack::MapNode::Set(const std::string& key, const std::shared_ptr& node) { + value[key] = node; +} + +// 写入辅助函数 +void NahidaProject::MessagePack::WriteByte(uint8_t byte) { + buffer.push_back(byte); +} + +void NahidaProject::MessagePack::WriteBytes(const uint8_t* data, size_t size) { + buffer.insert(buffer.end(), data, data + size); +} + +void NahidaProject::MessagePack::WriteUint8(uint8_t value) { + WriteByte(value); +} + +void NahidaProject::MessagePack::WriteUint16(uint16_t value) { + uint8_t bytes[2]; + bytes[0] = (value >> 8) & 0xFF; + bytes[1] = value & 0xFF; + WriteBytes(bytes, 2); +} + +void NahidaProject::MessagePack::WriteUint32(uint32_t value) { + uint8_t bytes[4]; + bytes[0] = (value >> 24) & 0xFF; + bytes[1] = (value >> 16) & 0xFF; + bytes[2] = (value >> 8) & 0xFF; + bytes[3] = value & 0xFF; + WriteBytes(bytes, 4); +} + +void NahidaProject::MessagePack::WriteUint64(uint64_t value) { + uint8_t bytes[8]; + bytes[0] = (value >> 56) & 0xFF; + bytes[1] = (value >> 48) & 0xFF; + bytes[2] = (value >> 40) & 0xFF; + bytes[3] = (value >> 32) & 0xFF; + bytes[4] = (value >> 24) & 0xFF; + bytes[5] = (value >> 16) & 0xFF; + bytes[6] = (value >> 8) & 0xFF; + bytes[7] = value & 0xFF; + WriteBytes(bytes, 8); +} + +// 读取辅助函数 +uint8_t NahidaProject::MessagePack::ReadByte() { + if (position >= buffer.size()) { + throw std::runtime_error("Buffer overflow"); + } + return buffer[position++]; +} + +uint8_t NahidaProject::MessagePack::PeekByte() const { + if (position >= buffer.size()) { + throw std::runtime_error("Buffer overflow"); + } + return buffer[position]; +} + +uint16_t NahidaProject::MessagePack::ReadUint16() { + uint16_t value = 0; + value |= static_cast(ReadByte()) << 8; + value |= static_cast(ReadByte()); + return value; +} + +uint32_t NahidaProject::MessagePack::ReadUint32() { + uint32_t value = 0; + value |= static_cast(ReadByte()) << 24; + value |= static_cast(ReadByte()) << 16; + value |= static_cast(ReadByte()) << 8; + value |= static_cast(ReadByte()); + return value; +} + +uint64_t NahidaProject::MessagePack::ReadUint64() { + uint64_t value = 0; + value |= static_cast(ReadByte()) << 56; + value |= static_cast(ReadByte()) << 48; + value |= static_cast(ReadByte()) << 40; + value |= static_cast(ReadByte()) << 32; + value |= static_cast(ReadByte()) << 24; + value |= static_cast(ReadByte()) << 16; + value |= static_cast(ReadByte()) << 8; + value |= static_cast(ReadByte()); + return value; +} + +// 序列化函数 +void NahidaProject::MessagePack::SerializeNil() { + WriteByte(0xC0); +} + +void NahidaProject::MessagePack::SerializeBool(bool value) { + WriteByte(value ? 0xC3 : 0xC2); +} + +void NahidaProject::MessagePack::SerializeInt(int64_t value) { + if (value >= 0) { + if (value <= 127) { + WriteByte(static_cast(value)); + } + else if (value <= 0xFF) { + WriteByte(0xCC); + WriteUint8(static_cast(value)); + } + else if (value <= 0xFFFF) { + WriteByte(0xCD); + WriteUint16(static_cast(value)); + } + else if (value <= 0xFFFFFFFF) { + WriteByte(0xCE); + WriteUint32(static_cast(value)); + } + else { + WriteByte(0xCF); + WriteUint64(static_cast(value)); + } + } + else { + if (value >= -32) { + WriteByte(static_cast(value)); + } + else if (value >= -128) { + WriteByte(0xD0); + WriteUint8(static_cast(value)); + } + else if (value >= -32768) { + WriteByte(0xD1); + WriteUint16(static_cast(value)); + } + else if (value >= -2147483648LL) { + WriteByte(0xD2); + WriteUint32(static_cast(value)); + } + else { + WriteByte(0xD3); + WriteUint64(static_cast(value)); + } + } +} + +void NahidaProject::MessagePack::SerializeFloat(double value) { + WriteByte(0xCB); + union { + double d; + uint64_t i; + } converter; + converter.d = value; + WriteUint64(converter.i); +} + +void NahidaProject::MessagePack::SerializeString(const std::string& value) { + size_t size = value.size(); + if (size <= 31) { + WriteByte(0xA0 | static_cast(size)); + } + else if (size <= 0xFF) { + WriteByte(0xD9); + WriteUint8(static_cast(size)); + } + else if (size <= 0xFFFF) { + WriteByte(0xDA); + WriteUint16(static_cast(size)); + } + else if (size <= 0xFFFFFFFF) { + WriteByte(0xDB); + WriteUint32(static_cast(size)); + } + else { + throw std::runtime_error("String too large"); + } + WriteBytes(reinterpret_cast(value.c_str()), size); +} + +void NahidaProject::MessagePack::SerializeArray(const std::vector>& array) { + size_t size = array.size(); + if (size <= 15) { + WriteByte(0x90 | static_cast(size)); + } + else if (size <= 0xFFFF) { + WriteByte(0xDC); + WriteUint16(static_cast(size)); + } + else if (size <= 0xFFFFFFFF) { + WriteByte(0xDD); + WriteUint32(static_cast(size)); + } + else { + throw std::runtime_error("Array too large"); + } + for (const auto& item : array) { + Serialize(item); + } +} + +void NahidaProject::MessagePack::SerializeMap(const std::map>& map) { + size_t size = map.size(); + if (size <= 15) { + WriteByte(0x80 | static_cast(size)); + } + else if (size <= 0xFFFF) { + WriteByte(0xDE); + WriteUint16(static_cast(size)); + } + else if (size <= 0xFFFFFFFF) { + WriteByte(0xDF); + WriteUint32(static_cast(size)); + } + else { + throw std::runtime_error("Map too large"); + } + for (const auto& pair : map) { + SerializeString(pair.first); + Serialize(pair.second); + } +} + +// 反序列化函数 +std::shared_ptr NahidaProject::MessagePack::Deserialize() { + uint8_t format = ReadByte(); + + // Nil + if (format == 0xC0) { + return std::make_shared(); + } + + // Boolean + if (format == 0xC2) { + return std::make_shared(false); + } + if (format == 0xC3) { + return std::make_shared(true); + } + + // Positive FixInt + if ((format & 0x80) == 0) { + return std::make_shared(format); + } + + // Negative FixInt + if ((format & 0xE0) == 0xE0) { + return std::make_shared(static_cast(format)); + } + + // FixMap + if ((format & 0xF0) == 0x80) { + size_t size = format & 0x0F; + return DeserializeMap(size); + } + + // FixArray + if ((format & 0xF0) == 0x90) { + size_t size = format & 0x0F; + return DeserializeArray(size); + } + + // FixStr + if ((format & 0xE0) == 0xA0) { + size_t size = format & 0x1F; + return DeserializeString(size); + } + + // UInt 8 + if (format == 0xCC) { + uint8_t value = ReadByte(); + return std::make_shared(value); + } + + // UInt 16 + if (format == 0xCD) { + uint16_t value = ReadUint16(); + return std::make_shared(value); + } + + // UInt 32 + if (format == 0xCE) { + uint32_t value = ReadUint32(); + return std::make_shared(value); + } + + // UInt 64 + if (format == 0xCF) { + uint64_t value = ReadUint64(); + return std::make_shared(static_cast(value)); + } + + // Int 8 + if (format == 0xD0) { + int8_t value = static_cast(ReadByte()); + return std::make_shared(value); + } + + // Int 16 + if (format == 0xD1) { + int16_t value = static_cast(ReadUint16()); + return std::make_shared(value); + } + + // Int 32 + if (format == 0xD2) { + int32_t value = static_cast(ReadUint32()); + return std::make_shared(value); + } + + // Int 64 + if (format == 0xD3) { + int64_t value = static_cast(ReadUint64()); + return std::make_shared(value); + } + + // Float 64 + if (format == 0xCB) { + uint64_t bits = ReadUint64(); + union { + uint64_t i; + double d; + } converter; + converter.i = bits; + return std::make_shared(converter.d); + } + + // Str 8 + if (format == 0xD9) { + uint8_t size = ReadByte(); + return DeserializeString(size); + } + + // Str 16 + if (format == 0xDA) { + uint16_t size = ReadUint16(); + return DeserializeString(size); + } + + // Str 32 + if (format == 0xDB) { + uint32_t size = ReadUint32(); + return DeserializeString(size); + } + + // Array 16 + if (format == 0xDC) { + uint16_t size = ReadUint16(); + return DeserializeArray(size); + } + + // Array 32 + if (format == 0xDD) { + uint32_t size = ReadUint32(); + return DeserializeArray(size); + } + + // Map 16 + if (format == 0xDE) { + uint16_t size = ReadUint16(); + return DeserializeMap(size); + } + + // Map 32 + if (format == 0xDF) { + uint32_t size = ReadUint32(); + return DeserializeMap(size); + } + + throw std::runtime_error("Unknown format: " + std::to_string(format)); +} + +std::shared_ptr NahidaProject::MessagePack::DeserializeString(size_t size) { + if (position + size > buffer.size()) { + throw std::runtime_error("Buffer overflow"); + } + std::string value(reinterpret_cast(buffer.data() + position), size); + position += size; + return std::make_shared(value); +} + +std::shared_ptr NahidaProject::MessagePack::DeserializeArray(size_t size) { + std::vector> array; + array.reserve(size); + for (size_t i = 0; i < size; ++i) { + array.push_back(Deserialize()); + } + return std::make_shared(array); +} + +std::shared_ptr NahidaProject::MessagePack::DeserializeMap(size_t size) { + std::map> map; + for (size_t i = 0; i < size; ++i) { + auto keyNode = Deserialize(); + auto valueNode = Deserialize(); + if (keyNode->GetType() != Type::STRING) { + throw std::runtime_error("Map key must be string"); + } + map[keyNode->ToStr()] = valueNode; + } + return std::make_shared(map); +} diff --git a/NahidaProject.Serialization/Sources/MessagePack.h b/NahidaProject.Serialization/Sources/MessagePack.h new file mode 100644 index 0000000000000000000000000000000000000000..1fca04f604cc6152ce549df288bc0d4c58e135f5 --- /dev/null +++ b/NahidaProject.Serialization/Sources/MessagePack.h @@ -0,0 +1,243 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace NahidaProject { + class MessagePack { + public: + // 数据类型枚举 + enum class Type { NIL, BOOLEAN, INTEGER, FLOAT, STRING, BINARY, ARRAY, MAP, EXTENSION }; + + // 基础数据节点类 + class Node { + public: + virtual ~Node() = default; + virtual Type GetType() const = 0; + virtual std::string ToString() const = 0; + virtual bool ToBool() const { + throw std::runtime_error("Not a boolean"); + } + + virtual int64_t ToInt() const { + throw std::runtime_error("Not an integer"); + } + + virtual double ToFloat() const { + throw std::runtime_error("Not a float"); + } + + virtual std::string ToStr() const { + throw std::runtime_error("Not a string"); + } + + virtual const std::vector>& ToArray() const { + throw std::runtime_error("Not an array"); + } + virtual const std::map>& ToMap() const { + throw std::runtime_error("Not a map"); + } + }; + + // Nil 节点 + class NilNode : public Node { + public: + Type GetType() const override; + std::string ToString() const override; + }; + + // Boolean 节点 + class BoolNode : public Node { + private: + bool value; + public: + BoolNode(bool val) : value(val) { + + } + Type GetType() const override; + std::string ToString() const override; + bool ToBool() const override; + }; + + class IntNode : public Node { + private: + int64_t value; + public: + IntNode(int64_t val) : value(val) { + + } + Type GetType() const override; + std::string ToString() const override; + int64_t ToInt() const override; + }; + + class FloatNode : public Node { + private: + double value; + public: + FloatNode(double val) : value(val) { + + } + Type GetType() const override; + std::string ToString() const override; + double ToFloat() const override; + }; + + class StringNode : public Node { + private: + std::string value; + public: + StringNode(const std::string& val) : value(val) {} + Type GetType() const override; + std::string ToString() const override; + std::string ToStr() const override; + }; + + // Array 节点 + class ArrayNode : public Node { + private: + std::vector> value; + public: + ArrayNode(const std::vector>& val) : value(val) {} + Type GetType() const override; + std::string ToString() const override; + const std::vector>& ToArray() const override; + void Add(const std::shared_ptr& node); + }; + + // Map 节点 + class MapNode : public Node { + private: + std::map> value; + public: + MapNode(const std::map>& val) : value(val) {} + Type GetType() const override; + std::string ToString() const override; + const std::map>& ToMap() const override; + void Set(const std::string& key, const std::shared_ptr& node); + }; + + private: + std::vector buffer; + size_t position; + + // 写入辅助函数 + void WriteByte(uint8_t byte); + void WriteBytes(const uint8_t* data, size_t size); + void WriteUint8(uint8_t value); + void WriteUint16(uint16_t value); + void WriteUint32(uint32_t value); + void WriteUint64(uint64_t value); + // 读取辅助函数 + uint8_t ReadByte(); + uint8_t PeekByte() const; + uint16_t ReadUint16(); + uint32_t ReadUint32(); + uint64_t ReadUint64(); + void SerializeNil(); + void SerializeBool(bool value); + void SerializeInt(int64_t value); + void SerializeFloat(double value); + void SerializeString(const std::string& value); + void SerializeArray(const std::vector>& array); + void SerializeMap(const std::map>& map); + std::shared_ptr Deserialize(); + std::shared_ptr DeserializeString(size_t size); + std::shared_ptr DeserializeArray(size_t size); + std::shared_ptr DeserializeMap(size_t size); + + public: + MessagePack() : position(0) {} + + // 序列化接口 + void Serialize(const std::shared_ptr& node) { + switch (node->GetType()) { + case Type::NIL: + SerializeNil(); + break; + case Type::BOOLEAN: + SerializeBool(node->ToBool()); + break; + case Type::INTEGER: + SerializeInt(node->ToInt()); + break; + case Type::FLOAT: + SerializeFloat(node->ToFloat()); + break; + case Type::STRING: + SerializeString(node->ToStr()); + break; + case Type::ARRAY: + SerializeArray(node->ToArray()); + break; + case Type::MAP: + SerializeMap(node->ToMap()); + break; + default: + throw std::runtime_error("Unsupported type"); + } + } + + // 反序列化接口 + std::shared_ptr Deserialize(const std::vector& data) { + buffer = data; + position = 0; + return Deserialize(); + } + + // 获取序列化后的数据 + const std::vector& GetData() const { + return buffer; + } + + // 清空缓冲区 + void Clear() { + buffer.clear(); + position = 0; + } + + // 打印十六进制数据 + void PrintHex() const { + for (size_t i = 0; i < buffer.size(); ++i) { + printf("%02X ", buffer[i]); + if ((i + 1) % 16 == 0) printf("\n"); + } + if (buffer.size() % 16 != 0) printf("\n"); + } + + // 工厂函数 + static std::shared_ptr CreateNil() { + return std::make_shared(); + } + + static std::shared_ptr CreateBool(bool value) { + return std::make_shared(value); + } + + static std::shared_ptr CreateInt(int64_t value) { + return std::make_shared(value); + } + + static std::shared_ptr CreateFloat(double value) { + return std::make_shared(value); + } + + static std::shared_ptr CreateString(const std::string& value) { + return std::make_shared(value); + } + + static std::shared_ptr CreateArray() { + return std::make_shared(std::vector>()); + } + + static std::shared_ptr CreateMap() { + return std::make_shared(std::map>()); + } + }; +} diff --git a/NahidaProject.Serialization/Sources/XML/XMLComment.cpp b/NahidaProject.Serialization/Sources/XML/XMLComment.cpp new file mode 100644 index 0000000000000000000000000000000000000000..514dd1f34b01fde2d4d7fe3ca1531ebf1eea10ec --- /dev/null +++ b/NahidaProject.Serialization/Sources/XML/XMLComment.cpp @@ -0,0 +1,9 @@ +#include "XMLComment.h" + +const std::string& NahidaProject::XMLComment::GetContent() const { + return content_; +} + +std::string NahidaProject::XMLComment::ToString(int indent) const { + return std::string(indent, ' ') + ""; +} \ No newline at end of file diff --git a/NahidaProject.Serialization/Sources/XML/XMLComment.h b/NahidaProject.Serialization/Sources/XML/XMLComment.h new file mode 100644 index 0000000000000000000000000000000000000000..348452503615fec66cb0527999ef3e3f40a45752 --- /dev/null +++ b/NahidaProject.Serialization/Sources/XML/XMLComment.h @@ -0,0 +1,20 @@ +#pragma once + +#include "XMLNode.h" + +#include + +namespace NahidaProject { + class XMLComment : public NahidaProject::XMLNode { + private: + std::string content_; + + public: + explicit XMLComment(std::string content) : content_(std::move(content)) { + + } + + const std::string& GetContent() const; + std::string ToString(int indent = 0) const override; + }; +} \ No newline at end of file diff --git a/NahidaProject.Serialization/Sources/XML/XMLDocument.cpp b/NahidaProject.Serialization/Sources/XML/XMLDocument.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b2e1d4cf3e6c9866e3cc29c3510e6320191b1b1d --- /dev/null +++ b/NahidaProject.Serialization/Sources/XML/XMLDocument.cpp @@ -0,0 +1,16 @@ +#include "XMLDocument.h" + +void NahidaProject::XMLDocument::SetRoot(std::unique_ptr root) { + root_ = std::move(root); +} + +NahidaProject::XMLElement* NahidaProject::XMLDocument::GetRoot() const { + return root_.get(); +} + +std::string NahidaProject::XMLDocument::ToString() const { + if (root_) { + return "\n" + root_->ToString(); + } + return ""; +} \ No newline at end of file diff --git a/NahidaProject.Serialization/Sources/XML/XMLDocument.h b/NahidaProject.Serialization/Sources/XML/XMLDocument.h new file mode 100644 index 0000000000000000000000000000000000000000..365e1516f0fa80ba0c3b0d99c6d9563db682c147 --- /dev/null +++ b/NahidaProject.Serialization/Sources/XML/XMLDocument.h @@ -0,0 +1,19 @@ +#pragma once + +#include "XMLElement.h" + +#include + +namespace NahidaProject { + class XMLDocument { + private: + std::unique_ptr root_; + + public: + XMLDocument() = default; + + void SetRoot(std::unique_ptr root); + XMLElement* GetRoot() const; + std::string ToString() const; + }; +} \ No newline at end of file diff --git a/NahidaProject.Serialization/Sources/XML/XMLElement.cpp b/NahidaProject.Serialization/Sources/XML/XMLElement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9b53bd5b132e457f3930f603ad00acb7b9778dd0 --- /dev/null +++ b/NahidaProject.Serialization/Sources/XML/XMLElement.cpp @@ -0,0 +1,93 @@ +#include "XMLText.h" +#include "XMLNode.h" +#include "XMLElement.h" + +const std::string& NahidaProject::XMLElement::GetName() const { + return name_; +} + +const std::map& NahidaProject::XMLElement::GetAttributes() const { + return attributes_; +} + +const std::vector>& NahidaProject::XMLElement::GetChildren() const { + return children_; +} + +void NahidaProject::XMLElement::SetAttribute(const std::string& key, const std::string& value) { + attributes_[key] = value; +} + +std::string NahidaProject::XMLElement::GetAttribute(const std::string& key) const { + auto it = attributes_.find(key); + return (it != attributes_.end()) ? it->second : ""; +} + +void NahidaProject::XMLElement::AddChild(std::unique_ptr child) { + children_.push_back(std::move(child)); +} + +// 查找子元素 +std::vector NahidaProject::XMLElement::FindElements(const std::string& name) { + std::vector result; + for (auto& child : children_) { + if (auto element = dynamic_cast(child.get())) { + if (element->GetName() == name) { + result.push_back(element); + } + } + } + return result; +} + +// 获取第一个匹配名称的子元素 +NahidaProject::XMLElement* NahidaProject::XMLElement::GetElement(const std::string& name) { + for (auto& child : children_) { + if (auto element = dynamic_cast(child.get())) { + if (element->GetName() == name) { + return element; + } + } + } + return nullptr; +} + +// 获取文本内容 +std::string NahidaProject::XMLElement::GetText() const { + std::string text; + for (const auto& child : children_) { + if (auto textNode = dynamic_cast(child.get())) { + text += textNode->GetContent(); + } + } + return text; +} + +std::string NahidaProject::XMLElement::ToString(int indent) const { + std::string result; + std::string indentStr(indent, ' '); + + result += indentStr + "<" + name_; + + // 添加属性 + for (const auto& [key, value] : attributes_) { + result += " " + key + "=\"" + value + "\""; + } + + if (children_.empty()) { + result += "/>\n"; + } + else { + result += ">\n"; + + // 添加子节点 + for (const auto& child : children_) { + result += child->ToString(indent + 2); + result += "\n"; + } + + result += indentStr + ""; + } + + return result; +} \ No newline at end of file diff --git a/NahidaProject.Serialization/Sources/XML/XMLElement.h b/NahidaProject.Serialization/Sources/XML/XMLElement.h new file mode 100644 index 0000000000000000000000000000000000000000..99197256fe0112b133dd6317b12bdfa4fbaec53e --- /dev/null +++ b/NahidaProject.Serialization/Sources/XML/XMLElement.h @@ -0,0 +1,32 @@ +#pragma once + +#include "XMLNode.h" + +#include +#include +#include + +namespace NahidaProject { + class XMLElement : public NahidaProject::XMLNode { + private: + std::string name_; + std::map attributes_; + std::vector> children_; + + public: + explicit XMLElement(std::string name) : name_(std::move(name)) { + + } + + const std::string& GetName() const; + const std::map& GetAttributes() const; + const std::vector>& GetChildren() const; + void SetAttribute(const std::string& key, const std::string& value); + std::string GetAttribute(const std::string& key) const; + void AddChild(std::unique_ptr child); + std::vector FindElements(const std::string& name); + XMLElement* GetElement(const std::string& name); + std::string GetText() const; + std::string ToString(int indent = 0) const override; + }; +} \ No newline at end of file diff --git a/NahidaProject.Serialization/Sources/XML/XMLNode.cpp b/NahidaProject.Serialization/Sources/XML/XMLNode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/NahidaProject.Serialization/Sources/XML/XMLNode.h b/NahidaProject.Serialization/Sources/XML/XMLNode.h new file mode 100644 index 0000000000000000000000000000000000000000..4194b12a4ab86dbe06c6b7f1a1b03a8d11020e36 --- /dev/null +++ b/NahidaProject.Serialization/Sources/XML/XMLNode.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +namespace NahidaProject { + class XMLNode { + public: + virtual ~XMLNode() = default; + virtual std::string ToString(int indent = 0) const = 0; + }; +} \ No newline at end of file diff --git a/NahidaProject.Serialization/Sources/XML/XMLParseException.cpp b/NahidaProject.Serialization/Sources/XML/XMLParseException.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66e9ed99049db9369a5aca6ef21800b98eca9dba --- /dev/null +++ b/NahidaProject.Serialization/Sources/XML/XMLParseException.cpp @@ -0,0 +1 @@ +#include "XMLParseException.h" \ No newline at end of file diff --git a/NahidaProject.Serialization/Sources/XML/XMLParseException.h b/NahidaProject.Serialization/Sources/XML/XMLParseException.h new file mode 100644 index 0000000000000000000000000000000000000000..46b0b15f257694c4eebc431371d3fbcac8a164ae --- /dev/null +++ b/NahidaProject.Serialization/Sources/XML/XMLParseException.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +class XMLParseException : public std::runtime_error { +public: + explicit XMLParseException(const std::string& message) : std::runtime_error("XML Parse Error: " + message) { + + } +}; \ No newline at end of file diff --git a/NahidaProject.Serialization/Sources/XML/XMLParser.cpp b/NahidaProject.Serialization/Sources/XML/XMLParser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..37a68e6084b2d48cd9dfacce34360d5aac5a6fce --- /dev/null +++ b/NahidaProject.Serialization/Sources/XML/XMLParser.cpp @@ -0,0 +1,306 @@ +#include "XMLParser.h" +#include "XMLElement.h" +#include "XMLParseException.h" + +bool NahidaProject::XMLParser::IsWhitespace(char c) const { + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; +} + +bool NahidaProject::XMLParser::IsNameStartChar(char c) const { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == ':'; +} + +bool NahidaProject::XMLParser::IsNameChar(char c) const { + return IsNameStartChar(c) || (c >= '0' && c <= '9') || c == '-' || c == '.'; +} + +// 跳过空白字符 +void NahidaProject::XMLParser::SkipWhitespace() { + while (position_ < xmlData_.length() && IsWhitespace(xmlData_[position_])) { + ++position_; + } +} + +// 检查并跳过指定字符串 +bool NahidaProject::XMLParser::Match(const std::string_view& str) { + if (position_ + str.length() <= xmlData_.length() && + xmlData_.substr(position_, str.length()) == str) { + position_ += str.length(); + return true; + } + return false; +} + +// 读取直到指定字符 +std::string NahidaProject::XMLParser::ReadUntil(char delimiter) { + std::string result; + while (position_ < xmlData_.length() && xmlData_[position_] != delimiter) { + result += xmlData_[position_++]; + } + return result; +} + +// 读取名称 +std::string NahidaProject::XMLParser::ReadName() { + if (position_ >= xmlData_.length() || !IsNameStartChar(xmlData_[position_])) { + throw XMLParseException("Invalid name start character at position " + std::to_string(position_)); + } + + std::string name; + while (position_ < xmlData_.length() && IsNameChar(xmlData_[position_])) { + name += xmlData_[position_++]; + } + return name; +} + +// 解码实体引用 +std::string NahidaProject::XMLParser::DecodeEntity(const std::string& entity) { + if (entity == "lt") return "<"; + if (entity == "gt") return ">"; + if (entity == "amp") return "&"; + if (entity == "apos") return "'"; + if (entity == "quot") return "\""; + return "&" + entity + ";"; // 未知实体保持原样 +} + +// 解码文本中的实体引用 +std::string NahidaProject::XMLParser::DecodeText(const std::string& text) { + std::string result; + size_t pos = 0; + + while (pos < text.length()) { + size_t ampPos = text.find('&', pos); + if (ampPos == std::string::npos) { + result += text.substr(pos); + break; + } + + result += text.substr(pos, ampPos - pos); + pos = ampPos; + + size_t semicolonPos = text.find(';', pos); + if (semicolonPos == std::string::npos) { + result += text.substr(pos); + break; + } + + std::string entity = text.substr(pos + 1, semicolonPos - pos - 1); + result += DecodeEntity(entity); + pos = semicolonPos + 1; + } + + return result; +} + +// 解析属性值 +std::string NahidaProject::XMLParser::ParseAttributeValue() { + char quote = xmlData_[position_]; + if (quote != '"' && quote != '\'') { + throw XMLParseException("Expected attribute value quote at position " + std::to_string(position_)); + } + + ++position_; // 跳过开始引号 + std::string value; + + while (position_ < xmlData_.length() && xmlData_[position_] != quote) { + if (xmlData_[position_] == '&') { + ++position_; // 跳过 & + std::string entity = ReadUntil(';'); + ++position_; // 跳过 ; + value += DecodeEntity(entity); + } + else { + value += xmlData_[position_++]; + } + } + + if (position_ >= xmlData_.length()) { + throw XMLParseException("Unclosed attribute value"); + } + + ++position_; // 跳过结束引号 + return value; +} + +// 解析属性 +void NahidaProject::XMLParser::ParseAttributes(XMLElement& element) { + while (position_ < xmlData_.length()) { + SkipWhitespace(); + if (position_ >= xmlData_.length() || xmlData_[position_] == '>' || xmlData_[position_] == '/') { + break; + } + + std::string attrName = ReadName(); + SkipWhitespace(); + + if (!Match("=")) { + throw XMLParseException("Expected '=' after attribute name"); + } + + SkipWhitespace(); + std::string attrValue = ParseAttributeValue(); + element.SetAttribute(attrName, attrValue); + } +} + +// 解析注释 +std::unique_ptr NahidaProject::XMLParser::ParseComment() { + if (!Match("", position_); + if (endPos == std::string_view::npos) { + throw XMLParseException("Unclosed comment"); + } + + std::string content(xmlData_.substr(position_, endPos - position_)); + position_ = endPos + 3; // 跳过 --> + + return std::make_unique(content); +} + +// 解析处理指令 (如 ) +void NahidaProject::XMLParser::ParseProcessingInstruction() { + if (!Match("", position_); + if (endPos == std::string_view::npos) { + throw XMLParseException("Unclosed processing instruction"); + } + + position_ = endPos + 2; // 跳过 ?> +} + +// 解析 CDATA 部分 +std::unique_ptr NahidaProject::XMLParser::ParseCData() { + if (!Match("", position_); + if (endPos == std::string_view::npos) { + throw XMLParseException("Unclosed CDATA section"); + } + + std::string content(xmlData_.substr(position_, endPos - position_)); + position_ = endPos + 3; // 跳过 ]]> + + return std::make_unique(content); +} + +// 解析元素 +std::unique_ptr NahidaProject::XMLParser::ParseElement() { + if (!Match("<")) { + throw XMLParseException("Expected '<' at element start"); + } + + std::string elementName = ReadName(); + auto element = std::make_unique(elementName); + + // 解析属性 + ParseAttributes(*element); + + SkipWhitespace(); + + // 自闭合元素 + if (Match("/>")) { + return element; + } + + if (!Match(">")) { + throw XMLParseException("Expected '>' or '/>' at element start"); + } + + // 解析内容 + while (position_ < xmlData_.length()) { + SkipWhitespace(); + + if (Match("")) { + throw XMLParseException("Expected '>' after closing tag name"); + } + break; + } + + if (Match(" + + + + A Brief History of Time + Stephen Hawking + 1988 + 15.99 + Popular science book about cosmology + +)"; + + + NahidaProject::XMLParser parser(testXml); + + NahidaProject::XMLDocument doc = parser.Parse(); + std::cout << "Parsed XML:\n" << doc.ToString() << "\n\n"; + + NahidaProject::XMLElement* root = doc.GetRoot(); + if (root) { + std::cout << "Root element: " << root->GetName() << "\n"; + + auto books = root->FindElements("book"); + std::cout << "Found " << books.size() << " books:\n"; + + for (size_t i = 0; i < books.size(); ++i) { + auto* book = books[i]; + std::cout << "Book " << (i + 1) << ":\n"; + std::cout << " ID: " << book->GetAttribute("id") << "\n"; + std::cout << " Category: " << book->GetAttribute("category") << "\n"; + + if (auto* title = book->GetElement("title")) { + std::cout << " Title: " << title->GetText() << "\n"; + std::cout << " Language: " << title->GetAttribute("lang") << "\n"; + } + + if (auto* author = book->GetElement("author")) { + std::cout << " Author: " << author->GetText() << "\n"; + } + + if (auto* year = book->GetElement("year")) { + std::cout << " Year: " << year->GetText() << "\n"; + } + + if (auto* price = book->GetElement("price")) { + std::cout << " Price: " << price->GetText() << " " << price->GetAttribute("currency") << "\n"; + } + + std::cout << "\n"; + } + } + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + +Test(XMLWriteTest) { NahidaProject::XMLWriter xmlWriter; NahidaProject::XMLWriterNode& documentNode = xmlWriter["DocumentNode"]; documentNode["Key0"]("Index", "0")("Size", "test"); @@ -82,15 +197,6 @@ Test(XMLReadAndWriteTest) { xmlWriter.OutputFile("TestRead.xml"); - /* - XMLReader::XMLNode xmlNode; - std::cout << xmlNode.FromFile("TestRead.xml"); - xmlNode.Print(); - XMLReader::XMLNode* node2 = xmlNode.GetChildPtrByName("xml"); - XMLReader::XMLNode* node3 = node2->GetChildPtrByName("DocumentNode"); - XMLReader::XMLNode* node4 = node3->GetChildPtrByName("Key0"); - std::cout << node4->GetAttribute("Index") << std::endl; - */ ::remove("TestRead.xml"); } diff --git a/NahidaProject.System/Sources/DynamicLinkedLibraryInjector.cpp b/NahidaProject.System/Sources/DynamicLinkedLibraryInjector.cpp deleted file mode 100644 index d6aa0e57296e7059384c8fa68082ff1ffcc83ce8..0000000000000000000000000000000000000000 --- a/NahidaProject.System/Sources/DynamicLinkedLibraryInjector.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "DynamicLinkedLibraryInjector.h" - -DWORD NahidaProject::DynamicLibraryInjector::GetProcessID(const std::string& processName){ - PROCESSENTRY32 proc_entry; - proc_entry.dwSize = sizeof(proc_entry); - - auto snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); - if (!snapshot) { - return GetLastError(); - } - - Process32First(snapshot, &proc_entry); - if (!processName.compare(proc_entry.szExeFile)) { - CloseHandle(snapshot); - return proc_entry.th32ProcessID; - } - - while (Process32Next(snapshot, &proc_entry)) { - if (!processName.compare(proc_entry.szExeFile)) { - CloseHandle(snapshot); - return proc_entry.th32ProcessID; - } - } - - CloseHandle(snapshot); - return 0; -} - -bool NahidaProject::DynamicLibraryInjector::Inject(const std::string& processName, const std::string& dynamicLinkedLibraryName){ - - auto pid = GetProcessID(processName); - if (!pid) { - return false; - } - - auto proc = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid); - if (!proc) { - return false; - } - - auto kernel32 = GetModuleHandleA("kernel32.dll"); - if (!kernel32) { - return false; - } - - auto load_library = GetProcAddress(kernel32, "LoadLibraryW"); - if (!load_library) { - return false; - } - - char* dll_path = nullptr; - GetFullPathName(dynamicLinkedLibraryName.c_str(), MAX_PATH, dll_path, NULL); - - auto alloc = VirtualAllocEx(proc, NULL, sizeof(dll_path), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - if (!alloc) { - return false; - } - - WriteProcessMemory(proc, alloc, dll_path, sizeof(dll_path), NULL); - auto thread = CreateRemoteThread(proc, NULL, NULL, (LPTHREAD_START_ROUTINE)load_library, alloc, NULL, NULL); - if (!thread) { - return false; - } - - WaitForSingleObject(thread, INFINITE); - CloseHandle(proc); - return true; -} diff --git a/NahidaProject.System/Sources/DynamicLinkedLibraryInjector.h b/NahidaProject.System/Sources/DynamicLinkedLibraryInjector.h deleted file mode 100644 index be67adf9cf1d409ba3e4b91949fc103c1d440d29..0000000000000000000000000000000000000000 --- a/NahidaProject.System/Sources/DynamicLinkedLibraryInjector.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace NahidaProject { - class __declspec(dllexport) DynamicLibraryInjector { - private: - static DWORD GetProcessID(const std::string& processName); - public: - bool Inject(const std::string& processName, const std::string& dynamicLinkedLibraryName); - }; -} diff --git a/NahidaProject.System/Sources/DynamicLinkedLibraryLoader.cpp b/NahidaProject.System/Sources/DynamicLinkedLibraryLoader.cpp deleted file mode 100644 index caac165526d037a1f4b7ee95aa8eadee58dd7813..0000000000000000000000000000000000000000 --- a/NahidaProject.System/Sources/DynamicLinkedLibraryLoader.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "DynamicLinkedLibraryLoader.h" \ No newline at end of file diff --git a/NahidaProject.System/Sources/DynamicLinkedLibraryLoader.h b/NahidaProject.System/Sources/DynamicLinkedLibraryLoader.h deleted file mode 100644 index bfa99eaf87838ec3c0fc57437a4b232dc53a962e..0000000000000000000000000000000000000000 --- a/NahidaProject.System/Sources/DynamicLinkedLibraryLoader.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace NahidaProject { - - template class __declspec(dllexport) DynamicLinkedLibraryLoader { - public: - DynamicLinkedLibraryLoader(HMODULE handleOfModule, const char* functionName) : func(nullptr), handleOfModule(handleOfModule), functionName(functionName) { - - } - - DynamicLinkedLibraryLoader(HMODULE handleOfModule, std::string functionName) : func(nullptr), handleOfModule(handleOfModule) { - functionName = functionName.c_str(); - } - - R operator()(Args... args) { - if (!func) { - func = reinterpret_cast(GetProcAddress(handleOfModule, functionName)); - if (!func) { - throw std::runtime_error("Failed to load function: " + std::string(functionName)); - } - } - return func(std::forward(args)...); - } - - static void FreeDynamicLinkedLibraryLoader(HMODULE& dll) { - if (dll) { - FreeLibrary(dll); - dll = nullptr; - } - } - - private: - R(*func)(Args...); - HMODULE handleOfModule; - const char* functionName; - }; -} diff --git a/NahidaProject.System/Sources/RegisterTable.cpp b/NahidaProject.System/Sources/RegisterTable.cpp deleted file mode 100644 index 8e342a732a2d84dbcdfdc9261e090f3d7f7dfc8e..0000000000000000000000000000000000000000 --- a/NahidaProject.System/Sources/RegisterTable.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright (c) 2025 HeZongLun -NahidaProject is licensed under Mulan PSL v2. -You can use this software according to the terms and conditions of the Mulan -PSL v2. -You may obtain a copy of Mulan PSL v2 at: - http://license.coscl.org.cn/MulanPSL2 -THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -See the Mulan PSL v2 for more details. -*/ - -#include "RegisterTable.h" - -const char* sub_key = "Software\\ExampleCache"; - -bool NahidaProject::RegisterTable::SetValue(const std::string& key, const std::string& value) { - HKEY hkey = nullptr; - LSTATUS res = ::RegOpenKeyExA(HKEY_CURRENT_USER, sub_key, 0, KEY_WRITE, &hkey); - if (res != ERROR_SUCCESS) { - res = ::RegCreateKeyA(HKEY_CURRENT_USER, sub_key, &hkey); - } - if (res != ERROR_SUCCESS) { - return false; - } - std::shared_ptr close_key(nullptr, [&](void*) { - if (hkey != nullptr) { - ::RegCloseKey(hkey); - hkey = nullptr; - } - }); - res = ::RegSetValueExA(hkey, key.c_str(), 0, REG_SZ, (BYTE*)value.c_str(), value.length()); - if (res != ERROR_SUCCESS) { - return false; - } - return true; -} - -std::string NahidaProject::RegisterTable::GetValue(const std::string& key) { - HKEY hkey = nullptr; - LSTATUS res = ::RegOpenKeyExA(HKEY_CURRENT_USER, sub_key, 0, KEY_READ, &hkey); - - if (res != ERROR_SUCCESS) { - return ""; - } - - std::shared_ptr close_key(nullptr, [&](void*) { - if (hkey != nullptr) { - ::RegCloseKey(hkey); - hkey = nullptr; - } - }); - - DWORD type = REG_SZ; - DWORD size = 0; - res = ::RegQueryValueExA(hkey, key.c_str(), 0, &type, nullptr, &size); - - if (res != ERROR_SUCCESS || size <= 0) { - return ""; - } - std::vector value_data(size); - res = ::RegQueryValueExA(hkey, key.c_str(), 0, &type, value_data.data(), &size); - if (res != ERROR_SUCCESS) { - return ""; - } - - return std::string(value_data.begin(), value_data.end()); -} - diff --git a/NahidaProject.System/Sources/SerialPort.cpp b/NahidaProject.System/Sources/SerialPort.cpp deleted file mode 100644 index 7a45e00cb1f5eab2e48f4c83500af3b87a479618..0000000000000000000000000000000000000000 --- a/NahidaProject.System/Sources/SerialPort.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* -Copyright (c) 2025 HeZongLun -NahidaProject is licensed under Mulan PSL v2. -You can use this software according to the terms and conditions of the Mulan -PSL v2. -You may obtain a copy of Mulan PSL v2 at: - http://license.coscl.org.cn/MulanPSL2 -THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -See the Mulan PSL v2 for more details. -*/ - -#include "SerialPort.h" - -#include -#include -#include - - -NahidaProject::SerialPort::SerialPort(){ - -} - -NahidaProject::SerialPort::~SerialPort(){ - -} - -bool NahidaProject::SerialPort::OpenSerialPort(const char* portName, int bitPerSecond, char parity, char dataBit, char stopBit, char synchronizeFlag) { - this->synchronizeFlag = synchronizeFlag; - HANDLE hCom = NULL; - if (this->synchronizeFlag) { - //鍚屾鏂瑰紡 - hCom = CreateFileA(portName, //涓插彛鍚 - GENERIC_READ | GENERIC_WRITE, //鏀寔璇诲啓 - 0, //鐙崰鏂瑰紡锛屼覆鍙d笉鏀寔鍏变韩 - NULL,//瀹夊叏灞炴ф寚閽堬紝榛樿鍊间负NULL - OPEN_EXISTING, //鎵撳紑鐜版湁鐨勪覆鍙f枃浠 - 0, //0锛氬悓姝ユ柟寮忥紝FILE_FLAG_OVERLAPPED锛氬紓姝ユ柟寮 - NULL);//鐢ㄤ簬澶嶅埗鏂囦欢鍙ユ焺锛岄粯璁ゅ间负NULL锛屽涓插彛鑰岃█璇ュ弬鏁板繀椤荤疆涓篘ULL - } - else { - //寮傛鏂瑰紡 - hCom = CreateFileA(portName, //涓插彛鍚 - GENERIC_READ | GENERIC_WRITE, //鏀寔璇诲啓 - 0, //鐙崰鏂瑰紡锛屼覆鍙d笉鏀寔鍏变韩 - NULL,//瀹夊叏灞炴ф寚閽堬紝榛樿鍊间负NULL - OPEN_EXISTING, //鎵撳紑鐜版湁鐨勪覆鍙f枃浠 - FILE_FLAG_OVERLAPPED, //0锛氬悓姝ユ柟寮忥紝FILE_FLAG_OVERLAPPED锛氬紓姝ユ柟寮 - NULL);//鐢ㄤ簬澶嶅埗鏂囦欢鍙ユ焺锛岄粯璁ゅ间负NULL锛屽涓插彛鑰岃█璇ュ弬鏁板繀椤荤疆涓篘ULL - } - - if(hCom == (HANDLE)-1) - { - return false; - } - - //閰嶇疆缂撳啿鍖哄ぇ灏 - if(! SetupComm(hCom,1024, 1024)) - { - return false; - } - - // 閰嶇疆鍙傛暟 - DCB p; - memset(&p, 0, sizeof(p)); - p.DCBlength = sizeof(p); - p.BaudRate = bitPerSecond; // 娉㈢壒鐜 - p.ByteSize = dataBit; // 鏁版嵁浣 - - switch (parity) //鏍¢獙浣 - { - case 0: - p.Parity = NOPARITY; //鏃犳牎楠 - break; - case 1: - p.Parity = ODDPARITY; //濂囨牎楠 - break; - case 2: - p.Parity = EVENPARITY; //鍋舵牎楠 - break; - case 3: - p.Parity = MARKPARITY; //鏍囪鏍¢獙 - break; - } - - switch(stopBit) //鍋滄浣 - { - case 1: - p.StopBits = ONESTOPBIT; //1浣嶅仠姝綅 - break; - case 2: - p.StopBits = TWOSTOPBITS; //2浣嶅仠姝綅 - break; - case 3: - p.StopBits = ONE5STOPBITS; //1.5浣嶅仠姝綅 - break; - } - - if(! SetCommState(hCom, &p)) - { - // 璁剧疆鍙傛暟澶辫触 - return false; - } - - //瓒呮椂澶勭悊,鍗曚綅锛氭绉 - //鎬昏秴鏃讹紳鏃堕棿绯绘暟脳璇绘垨鍐欑殑瀛楃鏁帮紜鏃堕棿甯搁噺 - COMMTIMEOUTS TimeOuts; - TimeOuts.ReadIntervalTimeout = 1000; //璇婚棿闅旇秴鏃 - TimeOuts.ReadTotalTimeoutMultiplier = 500; //璇绘椂闂寸郴鏁 - TimeOuts.ReadTotalTimeoutConstant = 5000; //璇绘椂闂村父閲 - TimeOuts.WriteTotalTimeoutMultiplier = 500; // 鍐欐椂闂寸郴鏁 - TimeOuts.WriteTotalTimeoutConstant = 2000; //鍐欐椂闂村父閲 - SetCommTimeouts(hCom,&TimeOuts); - - PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);//娓呯┖涓插彛缂撳啿鍖 - - memcpy(pHandle, &hCom, sizeof(hCom));// 淇濆瓨鍙ユ焺 - - return true; -} - -void NahidaProject::SerialPort::CloseSerialPort() -{ - HANDLE hCom = *(HANDLE*)pHandle; - CloseHandle(hCom); -} - -int NahidaProject::SerialPort::Send(std::string dat) -{ - HANDLE hCom = *(HANDLE*)pHandle; - - if (this->synchronizeFlag) - { - // 鍚屾鏂瑰紡 - DWORD dwBytesWrite = dat.length(); //鎴愬姛鍐欏叆鐨勬暟鎹瓧鑺傛暟 - BOOL bWriteStat = WriteFile(hCom, //涓插彛鍙ユ焺 - (char*)dat.c_str(), //鏁版嵁棣栧湴鍧 - dwBytesWrite, //瑕佸彂閫佺殑鏁版嵁瀛楄妭鏁 - &dwBytesWrite, //DWORD*锛岀敤鏉ユ帴鏀惰繑鍥炴垚鍔熷彂閫佺殑鏁版嵁瀛楄妭鏁 - NULL); //NULL涓哄悓姝ュ彂閫侊紝OVERLAPPED*涓哄紓姝ュ彂閫 - if (!bWriteStat) - { - return 0; - } - return dwBytesWrite; - } - else - { - //寮傛鏂瑰紡 - DWORD dwBytesWrite = dat.length(); //鎴愬姛鍐欏叆鐨勬暟鎹瓧鑺傛暟 - DWORD dwErrorFlags; //閿欒鏍囧織 - COMSTAT comStat; //閫氳鐘舵 - OVERLAPPED m_osWrite; //寮傛杈撳叆杈撳嚭缁撴瀯浣 - - //鍒涘缓涓涓敤浜嶰VERLAPPED鐨勪簨浠跺鐞嗭紝涓嶄細鐪熸鐢ㄥ埌锛屼絾绯荤粺瑕佹眰杩欎箞鍋 - memset(&m_osWrite, 0, sizeof(m_osWrite)); - m_osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, "WriteEvent"); - - ClearCommError(hCom, &dwErrorFlags, &comStat); //娓呴櫎閫氳閿欒锛岃幏寰楄澶囧綋鍓嶇姸鎬 - BOOL bWriteStat = WriteFile(hCom, //涓插彛鍙ユ焺 - (char*)dat.c_str(), //鏁版嵁棣栧湴鍧 - dwBytesWrite, //瑕佸彂閫佺殑鏁版嵁瀛楄妭鏁 - &dwBytesWrite, //DWORD*锛岀敤鏉ユ帴鏀惰繑鍥炴垚鍔熷彂閫佺殑鏁版嵁瀛楄妭鏁 - &m_osWrite); //NULL涓哄悓姝ュ彂閫侊紝OVERLAPPED*涓哄紓姝ュ彂閫 - if (!bWriteStat) - { - if (GetLastError() == ERROR_IO_PENDING) //濡傛灉涓插彛姝e湪鍐欏叆 - { - WaitForSingleObject(m_osWrite.hEvent, 1000); //绛夊緟鍐欏叆浜嬩欢1绉掗挓 - } - else - { - ClearCommError(hCom, &dwErrorFlags, &comStat); //娓呴櫎閫氳閿欒 - CloseHandle(m_osWrite.hEvent); //鍏抽棴骞堕噴鏀緃Event鍐呭瓨 - return 0; - } - } - return dwBytesWrite; - } -} - -std::string NahidaProject::SerialPort::Receive() -{ - HANDLE hCom = *(HANDLE*)pHandle; - std::string rec_str=""; - char buf[1024]; - if (this->synchronizeFlag) - { - //鍚屾鏂瑰紡 - DWORD wCount = 1024; //鎴愬姛璇诲彇鐨勬暟鎹瓧鑺傛暟 - BOOL bReadStat = ReadFile(hCom, //涓插彛鍙ユ焺 - buf, //鏁版嵁棣栧湴鍧 - wCount, //瑕佽鍙栫殑鏁版嵁鏈澶у瓧鑺傛暟 - &wCount, //DWORD*,鐢ㄦ潵鎺ユ敹杩斿洖鎴愬姛璇诲彇鐨勬暟鎹瓧鑺傛暟 - NULL); //NULL涓哄悓姝ュ彂閫侊紝OVERLAPPED*涓哄紓姝ュ彂閫 - for (int i = 0; i < 1024; i++) - { - if (buf[i] != -52) - rec_str += buf[i]; - else - break; - } - return rec_str; - } - else - { - //寮傛鏂瑰紡 - DWORD wCount = 1024; //鎴愬姛璇诲彇鐨勬暟鎹瓧鑺傛暟 - DWORD dwErrorFlags; //閿欒鏍囧織 - COMSTAT comStat; //閫氳鐘舵 - OVERLAPPED m_osRead; //寮傛杈撳叆杈撳嚭缁撴瀯浣 - - //鍒涘缓涓涓敤浜嶰VERLAPPED鐨勪簨浠跺鐞嗭紝涓嶄細鐪熸鐢ㄥ埌锛屼絾绯荤粺瑕佹眰杩欎箞鍋 - memset(&m_osRead, 0, sizeof(m_osRead)); - m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, "ReadEvent"); - - ClearCommError(hCom, &dwErrorFlags, &comStat); //娓呴櫎閫氳閿欒锛岃幏寰楄澶囧綋鍓嶇姸鎬 - if (!comStat.cbInQue)return 0; //濡傛灉杈撳叆缂撳啿鍖哄瓧鑺傛暟涓0锛屽垯杩斿洖false - //std::cout << comStat.cbInQue << std::endl; - BOOL bReadStat = ReadFile(hCom, //涓插彛鍙ユ焺 - buf, //鏁版嵁棣栧湴鍧 - wCount, //瑕佽鍙栫殑鏁版嵁鏈澶у瓧鑺傛暟 - &wCount, //DWORD*,鐢ㄦ潵鎺ユ敹杩斿洖鎴愬姛璇诲彇鐨勬暟鎹瓧鑺傛暟 - &m_osRead); //NULL涓哄悓姝ュ彂閫侊紝OVERLAPPED*涓哄紓姝ュ彂閫 - if (!bReadStat) - { - if (GetLastError() == ERROR_IO_PENDING) //濡傛灉涓插彛姝e湪璇诲彇涓 - { - //GetOverlappedResult鍑芥暟鐨勬渶鍚庝竴涓弬鏁拌涓篢RUE - //鍑芥暟浼氫竴鐩寸瓑寰咃紝鐩村埌璇绘搷浣滃畬鎴愭垨鐢变簬閿欒鑰岃繑鍥 - GetOverlappedResult(hCom, &m_osRead, &wCount, TRUE); - } - else - { - ClearCommError(hCom, &dwErrorFlags, &comStat); //娓呴櫎閫氳閿欒 - CloseHandle(m_osRead.hEvent); //鍏抽棴骞堕噴鏀緃Event鐨勫唴瀛 - return 0; - } - } - for (int i = 0;i<1024; i++) - { - if (buf[i]!=-52) - rec_str += buf[i]; - else - break; - } - return rec_str; - } -} - \ No newline at end of file diff --git a/NahidaProject.System/Sources/SerialPort.h b/NahidaProject.System/Sources/SerialPort.h deleted file mode 100644 index 209e3bf6063702e22015e17690186d6927785f63..0000000000000000000000000000000000000000 --- a/NahidaProject.System/Sources/SerialPort.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright (c) 2025 HeZongLun -NahidaProject is licensed under Mulan PSL v2. -You can use this software according to the terms and conditions of the Mulan -PSL v2. -You may obtain a copy of Mulan PSL v2 at: - http://license.coscl.org.cn/MulanPSL2 -THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -See the Mulan PSL v2 for more details. -*/ - -#ifndef SERIALPORT_H -#define SERIALPORT_H - -#include - -namespace NahidaProject { - class __declspec(dllexport) SerialPort { - public: - SerialPort(); - ~SerialPort(); - - bool OpenSerialPort(const char* portName, int bitPerSecond = 115200, char parity = 0, char dataBit = 8, char stopBit = 1, char synchronizeFlag = 0); - void CloseSerialPort(); - int Send(std::string data); - std::string Receive(); - - private: - int pHandle[16]; - char synchronizeFlag; - }; -} -#endif \ No newline at end of file diff --git a/NahidaProject.System/Sources/WindowsService.cpp b/NahidaProject.System/Sources/WindowsService.cpp deleted file mode 100644 index 699ea7fd8680e0f28e82c12405246419da4452fa..0000000000000000000000000000000000000000 --- a/NahidaProject.System/Sources/WindowsService.cpp +++ /dev/null @@ -1,231 +0,0 @@ -#include "WindowsService.h" - -NahidaProject::WindowsService* NahidaProject::WindowsService::instance; - -NahidaProject::WindowsService::WindowsService(std::string _name, bool _canPauseContinue) : - name(_name), canPauseContinue(_canPauseContinue) { - Wname = const_cast(name.c_str()); - - status = { 0 }; - statusHandle = NULL; - - stopEvent = INVALID_HANDLE_VALUE; - pauseEvent = INVALID_HANDLE_VALUE; - continueEvent = INVALID_HANDLE_VALUE; -} - -int NahidaProject::WindowsService::Run() { - instance = this; - - SERVICE_TABLE_ENTRY serviceTable[] = { { Wname, (LPSERVICE_MAIN_FUNCTION)ServiceMain},{ NULL, NULL } }; - - if (StartServiceCtrlDispatcher(serviceTable) == FALSE) { - DWORD serviceDispatchError = GetLastError(); - if (serviceDispatchError == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { - OnFailedRegistration(); - } - else { - return serviceDispatchError; - } - } - - return 0; -} - -void WINAPI NahidaProject::WindowsService::ServiceMain() { - // Register our service control handler with the SCM - instance->statusHandle = RegisterServiceCtrlHandler(instance->Wname, instance->ControlHandler); - - if (instance->statusHandle == NULL) { - return; - } - - instance->Startup(); - - // Start a thread that will perform the main task of the service - HANDLE hThread = CreateThread(NULL, 0, WorkerThread, NULL, 0, NULL); - - // Wait until our worker thread exits signaling that the service needs to stop - WaitForSingleObject(hThread, INFINITE); - - instance->Exit(); -} - -void WINAPI NahidaProject::WindowsService::ControlHandler(DWORD CtrlCode) -{ - switch (CtrlCode) { - case SERVICE_CONTROL_STOP: - if (instance->status.dwCurrentState == SERVICE_PAUSED) { - instance->ControlStopOnPause(); - break; - } - - if (instance->status.dwCurrentState != SERVICE_RUNNING) { break; } - instance->ControlStop(); - break; - - case SERVICE_CONTROL_PAUSE: - if (instance->status.dwCurrentState != SERVICE_RUNNING) { break; } - instance->ControlPause(); - break; - - case SERVICE_CONTROL_CONTINUE: - if (instance->status.dwCurrentState != SERVICE_PAUSED) { break; } - instance->ControlContinue(); - break; - - case SERVICE_CONTROL_SHUTDOWN: - if (instance->status.dwCurrentState != SERVICE_RUNNING) { break; } - instance->ControlStop(); - break; - - case SERVICE_CONTROL_INTERROGATE: // Deprecated, but you never know... let's just handle it. - SetServiceStatus(instance->statusHandle, &instance->status); - break; - - default: - break; - } -} - -DWORD WINAPI NahidaProject::WindowsService::WorkerThread(LPVOID lpParam) { - return instance->Worker(lpParam); -} - -void NahidaProject::WindowsService::Startup() { - ZeroMemory(&status, sizeof(status)); - status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - SetAcceptedControls(false); - status.dwServiceSpecificExitCode = 0; - SetState(SERVICE_START_PENDING); - - OnStartup(); - - stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - pauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - continueEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - if (stopEvent == NULL) { - OnError(); - return; - } - - SetAcceptedControls(true); - - SetState(SERVICE_RUNNING); -} - -void NahidaProject::WindowsService::Exit() { - OnExit(); - CloseHandle(stopEvent); - CloseHandle(pauseEvent); - CloseHandle(continueEvent); - CloseHandle(workerPaused); - CloseHandle(workerContinued); - SetState(SERVICE_STOPPED); -} - -void NahidaProject::WindowsService::OnError() { - SetAcceptedControls(false); - status.dwCurrentState = SERVICE_STOPPED; - status.dwWin32ExitCode = GetLastError(); - status.dwCheckPoint = 0; - - if (SetServiceStatus(statusHandle, &status) == FALSE) - { - std::string debugmsg = name + ": service_main: SetServiceStatus returned an error"; - OutputDebugString(debugmsg.c_str()); - } -} - -void NahidaProject::WindowsService::ControlStop() { - SetState(SERVICE_STOP_PENDING); - OnStop(); - SetAcceptedControls(false); - SetEvent(stopEvent); -} - -void NahidaProject::WindowsService::ControlPause() { - SetState(SERVICE_PAUSE_PENDING); - OnPause(); - SetEvent(pauseEvent); - WaitForSingleObject(workerPaused, INFINITE); - SetState(SERVICE_PAUSED); -} - -void NahidaProject::WindowsService::ControlContinue() { - SetState(SERVICE_CONTINUE_PENDING); - SetAcceptedControls(false); - ResetEvent(pauseEvent); - OnContinue(); - SetEvent(continueEvent); - WaitForSingleObject(workerContinued, INFINITE); - SetAcceptedControls(true); - ResetEvent(continueEvent); - SetState(SERVICE_RUNNING); -} - -void NahidaProject::WindowsService::ControlStopOnPause() { - SetAcceptedControls(false); - SetState(SERVICE_STOP_PENDING); - OnContinue(); - SetEvent(stopEvent); - SetEvent(continueEvent); -} - -void NahidaProject::WindowsService::SetState(DWORD state) { - status.dwCurrentState = state; - status.dwWin32ExitCode = 0; - status.dwCheckPoint = 0; - status.dwWaitHint = 0; - SetServiceStatus(statusHandle, &status); - if (SetServiceStatus(statusHandle, &status) == FALSE) { - std::string debugmsg = name + ": service_main: SetServiceStatus returned an error"; - OutputDebugString(debugmsg.c_str()); - } -} - -void NahidaProject::WindowsService::SetAcceptedControls(bool _in) { - if (_in) { - status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; - if (canPauseContinue) { - status.dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE; - } - } - else { - status.dwControlsAccepted = 0; - } - - if (SetServiceStatus(statusHandle, &status) == FALSE) { - std::string debugmsg = name + ": service_main: SetServiceStatus change accepted controls operation failed"; - OutputDebugString(debugmsg.c_str()); - } -} - -void NahidaProject::WindowsService::Bump() { - status.dwCheckPoint++; - if (SetServiceStatus(statusHandle, &status) == FALSE) { - std::string debugmsg = name + ": service_main: SetServiceStatus dwCheckPoint operation failed"; - OutputDebugString(debugmsg.c_str()); - } -} - -void NahidaProject::WindowsService::TestStartStop() { - std::cout << "START_PENDING" << std::endl; - OnStartup(); - - stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - pauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - continueEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - HANDLE hThread = CreateThread(NULL, 0, WorkerThread, NULL, 0, NULL); - std::cout << "RUNNING" << std::endl; - - std::cout << "Press enter to simulate SCM stop event..." << std::endl; - std::cin.ignore(); - - std::cout << "STOP_PENDING" << std::endl; - OnStop(); - SetEvent(stopEvent); - WaitForSingleObject(hThread, INFINITE); - std::cout << "STOPPED" << std::endl; -} \ No newline at end of file diff --git a/NahidaProject.System/Sources/WindowsService.h b/NahidaProject.System/Sources/WindowsService.h deleted file mode 100644 index faf1938a42c3fa8b2daed0be8c9b622d825e4371..0000000000000000000000000000000000000000 --- a/NahidaProject.System/Sources/WindowsService.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef WINDOWSSERVICE_H -#define WINDOWSSERVICE_H - -#include -#include -#include - -namespace NahidaProject { - class __declspec(dllexport) WindowsService { - private: - std::string name; - LPSTR Wname; - bool canPauseContinue; - - SERVICE_STATUS status; - SERVICE_STATUS_HANDLE statusHandle; - - HANDLE workerPaused; - HANDLE workerContinued; - - static void WINAPI ServiceMain(); - static void WINAPI ControlHandler(DWORD); - static DWORD WINAPI WorkerThread(LPVOID lpParam); - - // Set accepted controls - void SetAcceptedControls(bool _in); - - // Internal start/stop functions - void Startup(); - void Exit(); - void OnError(); - - // Service controller invoked start/stop functions - void ControlStop(); - void ControlPause(); - void ControlContinue(); - void ControlStopOnPause(); - - protected: - HANDLE stopEvent; - HANDLE pauseEvent; - HANDLE continueEvent; - - void SetState(DWORD state); - static WindowsService* instance; - virtual DWORD WINAPI Worker(LPVOID) { return ERROR_SUCCESS; } - - void ConfirmPause() { - SetEvent(workerPaused); - } - - void ConfirmContinue() { - SetEvent(workerContinued); - } - - virtual void OnStartup() { - - }; - - virtual void OnPause() { - - }; - - virtual void OnContinue() { - - }; - - virtual void OnStop() { - - }; - - virtual void OnExit() { - - }; - - virtual void OnFailedRegistration() { - TestStartStop(); - } - - void Bump(); - - public: - WindowsService(std::string _name, bool _canPauseContinue); - void TestStartStop(); - int Run(); - - }; -} - -#endif \ No newline at end of file diff --git a/NahidaProject.System/Tests/ModuleUnitTestFile.cpp b/NahidaProject.System/Tests/ModuleUnitTestFile.cpp deleted file mode 100644 index c7197ef8b16ab12d8b0af4b31bf6cce21198bd36..0000000000000000000000000000000000000000 --- a/NahidaProject.System/Tests/ModuleUnitTestFile.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "..\..\NahidaProject.UnitTest\Sources\NahidaUnitTest.h" - -#include "..\Sources\RegisterTable.h" - - -Test(RegisterTableTest) { - NahidaProject::RegisterTable reg("Software\\ExampleCache"); - reg.SetValue("Key1", "Value1"); - reg.SetValue("Key2", "Value2"); - AssertEqual(reg.GetValue("Key1"), "Value1"); - AssertEqual(reg.GetValue("Key2"), "Value2"); -} - - -Test(SpecialInformation) { - std::cout << "These module must run in special project templates. Please compile them in another project." << std::endl; -} - -int main() { - RunAllTestCase(); - return 0; -} \ No newline at end of file diff --git a/NahidaProject.Thread/Sources/EventBus.cpp b/NahidaProject.Thread/Sources/EventBus.cpp index 72d3761df4573bfc9126c315a209437e61dbc9ad..f67cdec067958d6c42d0da04314b11edff73cf84 100644 --- a/NahidaProject.Thread/Sources/EventBus.cpp +++ b/NahidaProject.Thread/Sources/EventBus.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "EventBus.h" bool NahidaProject::EventBus::EventBusTopic::operator==(const EventBusTopic& other) const { diff --git a/NahidaProject.Thread/Sources/EventBus.h b/NahidaProject.Thread/Sources/EventBus.h index 3bd8bdbcfa31da78306fc27bb88c79ddacb23f0a..98144eb547dd1f8e923c4f75129edc5e1d103cc4 100644 --- a/NahidaProject.Thread/Sources/EventBus.h +++ b/NahidaProject.Thread/Sources/EventBus.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #pragma once #include diff --git a/NahidaProject.Thread/Sources/SignalAndSlot.cpp b/NahidaProject.Thread/Sources/SignalAndSlot.cpp index 3d926e7a223e763e714c40c4883394de3af5cd67..9d01684ab64cce94e8395f4a9e732143d9e11530 100644 --- a/NahidaProject.Thread/Sources/SignalAndSlot.cpp +++ b/NahidaProject.Thread/Sources/SignalAndSlot.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "SignalAndSlot.h" inline void NahidaProject::SignalAndSlot::Connection::Disconnect() { diff --git a/NahidaProject.Thread/Sources/SignalAndSlot.h b/NahidaProject.Thread/Sources/SignalAndSlot.h index 9f2b2863a0aa0515462f06658fcd48ad460dd9ae..961f55897d1ea05429cf844e8fad221b22d2cd06 100644 --- a/NahidaProject.Thread/Sources/SignalAndSlot.h +++ b/NahidaProject.Thread/Sources/SignalAndSlot.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #ifndef SIGNALANDSLOT_H #define SIGNALANDSLOT_H diff --git a/NahidaProject.Thread/Sources/TaskTimer.cpp b/NahidaProject.Thread/Sources/TaskTimer.cpp index 82cf2dc26885ffca570dd46e480cbb77665f8829..aa025aaf5edf2309ae39d5f5537581728049904e 100644 --- a/NahidaProject.Thread/Sources/TaskTimer.cpp +++ b/NahidaProject.Thread/Sources/TaskTimer.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "TaskTimer.h" void NahidaProject::TaskTimer::SetTimeout(auto function, int delay) { diff --git a/NahidaProject.Thread/Sources/TaskTimer.h b/NahidaProject.Thread/Sources/TaskTimer.h index 4b467b14e4d1cd605af00907963a3f265ac14e17..a63ac0201704ece72633b04a771c3bb606eb251d 100644 --- a/NahidaProject.Thread/Sources/TaskTimer.h +++ b/NahidaProject.Thread/Sources/TaskTimer.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include #include #include diff --git a/NahidaProject.Thread/Sources/ThreadPool.cpp b/NahidaProject.Thread/Sources/ThreadPool.cpp index 04e400557c580bdff1aa03fc7d0797fd37b4e1de..cd31b45589aa180c42f071e863f2ec22d579b556 100644 --- a/NahidaProject.Thread/Sources/ThreadPool.cpp +++ b/NahidaProject.Thread/Sources/ThreadPool.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "ThreadPool.h" void NahidaProject::ThreadPool::Queue::ThreadPool::Start(size_t num_threads) { diff --git a/NahidaProject.Thread/Sources/ThreadPool.h b/NahidaProject.Thread/Sources/ThreadPool.h index 1edbed105a36506de14677d96ad67b7d17e6dea0..491a3b3b52c1f01345759b4d01a81e445b8f63c7 100644 --- a/NahidaProject.Thread/Sources/ThreadPool.h +++ b/NahidaProject.Thread/Sources/ThreadPool.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #pragma once #include diff --git a/NahidaProject.UnitTest/Sources/NahidaBenchmarkTest.cpp b/NahidaProject.UnitTest/Sources/NahidaBenchmarkTest.cpp index 7a200ac1040780b7426520a21801a1cbcc591e81..57624a1314ba1e1f049fe4c49e5a8a964548f697 100644 --- a/NahidaProject.UnitTest/Sources/NahidaBenchmarkTest.cpp +++ b/NahidaProject.UnitTest/Sources/NahidaBenchmarkTest.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "NahidaBenchmarkTest.h" std::string NahidaProject::NahidaBenchmarkTest::TimeConverter::UnitName(TimeUnit unit) { diff --git a/NahidaProject.UnitTest/Sources/NahidaBenchmarkTest.h b/NahidaProject.UnitTest/Sources/NahidaBenchmarkTest.h index 78011de3a5d6c19cd2624dc722318ec24104473f..d28e744302f7bfbdfadf68714fbb3f28c9a7ce95 100644 --- a/NahidaProject.UnitTest/Sources/NahidaBenchmarkTest.h +++ b/NahidaProject.UnitTest/Sources/NahidaBenchmarkTest.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #pragma once #include diff --git a/NahidaProject.UnitTest/Sources/NahidaMockTest.cpp b/NahidaProject.UnitTest/Sources/NahidaMockTest.cpp index cfd35d65c072e35bf19d341bc876069662af9d67..1c2e9e122a5362e841e1d7d338322de03de617b1 100644 --- a/NahidaProject.UnitTest/Sources/NahidaMockTest.cpp +++ b/NahidaProject.UnitTest/Sources/NahidaMockTest.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "NahidaMockTest.h" void NahidaProject::NahidaMockTest::Assertion::Fail(const std::string& message, std::source_location location) { diff --git a/NahidaProject.UnitTest/Sources/NahidaMockTest.h b/NahidaProject.UnitTest/Sources/NahidaMockTest.h index 2144bf70f6418e2cec78883504acc05680021ce3..4984c20f59143f25769a3ef9b563bc1a923ad797 100644 --- a/NahidaProject.UnitTest/Sources/NahidaMockTest.h +++ b/NahidaProject.UnitTest/Sources/NahidaMockTest.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #pragma once #include diff --git a/NahidaProject.UnitTest/Sources/NahidaUnitTest.cpp b/NahidaProject.UnitTest/Sources/NahidaUnitTest.cpp index 5bd9206564b3075e0f6e6f203b1ee1e8721621fc..827ce49eb4da14f7a9f898a33024de029f1463dd 100644 --- a/NahidaProject.UnitTest/Sources/NahidaUnitTest.cpp +++ b/NahidaProject.UnitTest/Sources/NahidaUnitTest.cpp @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #include "NahidaUnitTest.h" #include diff --git a/NahidaProject.UnitTest/Sources/NahidaUnitTest.h b/NahidaProject.UnitTest/Sources/NahidaUnitTest.h index 45db830f2da92f0965c461e4f61ee052fccbeb99..f7bb573791440d930d207fff6d7b82f2e8b90c03 100644 --- a/NahidaProject.UnitTest/Sources/NahidaUnitTest.h +++ b/NahidaProject.UnitTest/Sources/NahidaUnitTest.h @@ -1,3 +1,16 @@ +/* +Copyright (c) 2025 HeZongLun +NahidaProject is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +*/ + #pragma once #include diff --git a/README.md b/README.md index accfb878bdf23ae05a0b991793f2128f85352542..5146070a82e8b5981abb90b448eea2ea59659b3e 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,9 @@ NahidaProject 鍗佸垎灏忓阀锛屽嵈鍖呭惈浜嗗父鐢ㄧ殑妯″潡锛 |NahidaProject.Mathmatics |鏁板涓庣畻娉曟ā鍧 | |NahidaProject.Other |鍏朵粬妯″潡 | |NahidaProject.Serialization|搴忓垪鍖栨ā鍧 | -|NahidaProject.System |Windows 绯荤粺鐙湁鐨勬ā鍧 | |NahidaProject.Thread |涓庣嚎绋嬶紝娴佺▼鎺у埗鏈夊叧鐨勬ā鍧 | |NahidaProject.UnitTest |寰瀷鍗曞厓銆佸熀鍑嗐佹ā鎷熸祴璇曟ā鍧 | -鍙﹀锛屾垜浠繕鎻愪緵浜 NahidaProject 鐨 C# 瀹炵幇銆 - ## 鍙傝冩枃妗 - [寮鍙戞枃妗(https://gitee.com/hezonglun/nahida-project/tree/master/Documents) @@ -31,7 +28,7 @@ NahidaProject 鍗佸垎灏忓阀锛屽嵈鍖呭惈浜嗗父鐢ㄧ殑妯″潡锛 ### 甯冮殕杩囨护鍣ㄧ被 -[BloomFilter.h](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject-Generic/Sources/BloomFilter.h) 鎻愪緵甯冮殕杩囨护鍣ㄧ殑瀹炵幇銆 +[BloomFilter.h](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject.Generic/Sources/BloomFilter.h) 鎻愪緵甯冮殕杩囨护鍣ㄧ殑瀹炵幇銆 ```cpp #include "BloomFilter.h" @@ -44,10 +41,10 @@ int main(int argc, char** argv) { bf.Set("Object B"); bf.Set("Object C"); - std::cout << bf.Test("Object A") << std::endl; - std::cout << bf.Test("Object B") << std::endl; - std::cout << bf.Test("Object C") << std::endl; - std::cout << bf.Test("Object D") << std::endl; + std::cout << bf.Check("Object A") << std::endl; + std::cout << bf.Check("Object B") << std::endl; + std::cout << bf.Check("Object C") << std::endl; + std::cout << bf.Check("Object D") << std::endl; std::cout << bf.EstimateElementCount() << std::endl; @@ -60,7 +57,7 @@ int main(int argc, char** argv) { ``` ### 鏃ュ織绫 -**[Logger.h](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject-Generic/Sources/Logger.h)** 鏄竴涓紓姝ユ墽琛岀殑鏃ュ織缁勪欢銆 +**[Logger.h](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject.Generic/Sources/Logger.h)** 鏄竴涓紓姝ユ墽琛岀殑鏃ュ織缁勪欢銆 鍙互蹇熸彁渚涙棩蹇楁敮鎸併 @@ -95,21 +92,21 @@ int main(int argc, char** argv) { ### 鍗曞厓娴嬭瘯绫 -**[NahidaUnitTest.h](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject-UnitTest/Sources/NahidaUnitTest.h)** 鏄竴涓畝鍗曠殑鍗曞厓娴嬭瘯妗嗘灦锛孨ahidaProject 涓殑鎵鏈夌粍浠剁敤瀹冨啓鍗曞厓娴嬭瘯浠g爜銆 +**[NahidaUnitTest.h](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject.UnitTest/Sources/NahidaUnitTest.h)** 鏄竴涓畝鍗曠殑鍗曞厓娴嬭瘯妗嗘灦锛孨ahidaProject 涓殑鎵鏈夌粍浠剁敤瀹冨啓鍗曞厓娴嬭瘯浠g爜銆 ```cpp #include "NahidaTest.h" -TESTCASE(TestPoint1) { - JUDGE_EQUAL(1 + 1, 2); // 娴嬭瘯閫氳繃 +Test(TestPoint1) { + AssertEqual(1 + 1, 2); // 娴嬭瘯閫氳繃 } -TESTCASE(TestPoint2) { - JUDGE_EQUAL(1 - 1, 10086); // 娴嬭瘯澶辫触 +Test(TestPoint2) { + AssertEqual(1 - 1, 10086); // 娴嬭瘯澶辫触 } int main(int argc, char** argv) { - NahidaProject::NahidaTest::RunAllTests(); + RunAllTestCase(); return 0; } ``` @@ -118,26 +115,22 @@ int main(int argc, char** argv) { ## 鐩綍缁撴瀯璇存槑 -- NahidaProject-XXX +- NahidaProject.XXX NahidaProject 鍚勪釜妯″潡鐨勬簮浠g爜锛岀紪璇戜細鐢熸垚锛 - 鍙湁绗﹀彿閾炬帴鐨 LibNahidaProject-XXX.lib銆 + 鍙湁绗﹀彿閾炬帴鐨 NahidaProject.XXX.lib銆 - 鍖呭惈鍑芥暟瀹氫箟鐨 LibNahidaProject-XXX-IMPLEMENT.lib銆 + 鍖呭惈鍑芥暟瀹氫箟鐨 NahidaProject.XXX.IMPLEMENT.lib銆 - 鍖呭惈鍑芥暟瀹氫箟鐨 LibNahidaProject-XXX.dll銆 + 鍖呭惈鍑芥暟瀹氫箟鐨 NahidaProject.XXX.dll銆 - 鐢ㄤ簬娴嬭瘯鐨 LibNahidaProject-XXXTest.exe銆 + 鐢ㄤ簬娴嬭瘯鐨 NahidaProject.XXXTest.exe銆 - [Documents](https://gitee.com/hezonglun/nahida-project/tree/master/Documents) NahidaProject 鐨勪娇鐢ㄦ枃妗c - 鍏朵腑鐨 `PureDocument` 鏄函鏂囨。銆俙DocumentByDocusaurus` 鏄粡杩 Docusaurus 灏佽鐨勬枃妗c - -~~瀹為檯涓婄紪鍐欐枃妗g殑鎰忎箟涓嶅ぇ锛屾祴璇曠敤渚嬬湅涓閬嶅氨浼氱敤浜嗐倊~ - ## 缂栬瘧涓庡畨瑁 NahidaProject 涓殑浠g爜锛屽彲浠ョ洿鎺ュ紩鍏ヤ娇鐢ㄣ備絾鏄垜浠洿寤鸿缂栬瘧瀹夎銆 @@ -157,7 +150,7 @@ NahidaProject 涓殑浠g爜锛屽彲浠ョ洿鎺ュ紩鍏ヤ娇鐢ㄣ備絾鏄垜浠洿寤鸿缂 ### 缂栬瘧姝ラ - 浣跨敤 Microsoft Visual Studio Community 鐩存帴鎵撳紑鏂囦欢澶癸紝绛夊緟鍒濆鍖 CMake 椤圭洰銆 -- 瀵规瘡涓ā鍧楃敓鎴 LibNahidaProject-XXXTests.exe 浠ユ祴璇曞簱浠g爜鍜岀墿鏂欓厤缃病鏈夐棶棰樸 +- 瀵规瘡涓ā鍧楃敓鎴 NahidaProject.XXXTests.exe 浠ユ祴璇曞簱浠g爜鍜岀墿鏂欓厤缃病鏈夐棶棰樸 - 鍙抽敭椤圭洰鏍圭洰褰曪紝閫夋嫨鍒囨崲鍒 CMake 鐩爣瑙嗗浘锛岀敓鎴愭墍鏈夌紪璇戜骇鐗┿ - 缂栬瘧瀹屾垚鍚庯紝璇疯繍琛 `AutoInstallScript.ps1` 浠ヨ嚜鍔ㄥ惛鍙栨暎钀界殑缂栬瘧浜х墿銆 - 澶嶅埗 `NahidaProject-InstallDirectory` 鍒颁綘鍠滄鐨勮矾寰勪笅浣跨敤銆 @@ -168,6 +161,13 @@ NahidaProject 涓殑浠g爜锛屽彲浠ョ洿鎺ュ紩鍏ヤ娇鐢ㄣ備絾鏄垜浠洿寤鸿缂 ## 娣荤爾鍔犵摝 +### 闂鍙嶉 + +闂鍙嶉鏃讹紝璇锋彁渚涳細 + +* 浣犺绠楁満鎿嶄綔绯荤粺鍜岀紪璇戝伐鍏烽摼鐨勭増鏈彿銆 +* 浣犱负浜嗚В鍐宠繖涓棶棰橈紝浣滃嚭浜嗗摢浜涘姫鍔涖 + ### 鎿嶄綔娴佺▼ 杩欎篃璁告槸浣犲彲浠ュ弬涓庣殑绗竴涓湁鐢ㄧ殑 C++ 椤圭洰銆 @@ -185,7 +185,7 @@ NahidaProject 涓殑浠g爜锛屽彲浠ョ洿鎺ュ紩鍏ヤ娇鐢ㄣ備絾鏄垜浠洿寤鸿缂 - 鎺ㄩ佸埌浣犲悕涓嬬殑鏈粨搴撳垎鏀 - 鏂板缓 Pull Request锛岃姹傚悎骞躲 -寮鍙戝皬閿﹀泭锛氭渶濂界殑鏍锋湰鏄 [CowSay.cpp](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject-Other/Sources/CowSay.cpp) 鍜 [CowSay.h](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject-Other/Sources/CowSay.h) +寮鍙戝皬閿﹀泭锛氭渶濂界殑鏍锋湰鏄 [CowSay.cpp](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject.Other/Sources/CowSay.cpp) 鍜 [CowSay.h](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject.Other/Sources/CowSay.h) ### 璐$尞瑙勫畾 @@ -204,7 +204,7 @@ NahidaProject 涓殑浠g爜锛屽彲浠ョ洿鎺ュ紩鍏ヤ娇鐢ㄣ備絾鏄垜浠洿寤鸿缂 鈹 鈹斺攢Tests ---> 鏀剧疆鍗曞厓娴嬭瘯浠g爜 ``` -褰撶劧涔熶笉瑕佸繕浜嗗湪 [NahidaProject.cpp](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject-Generic/Sources/NahidaProject.cpp) 涓暀涓嬩綘鐨 Gitee ID銆 +褰撶劧涔熶笉瑕佸繕浜嗗湪 [NahidaProject.cpp](https://gitee.com/hezonglun/nahida-project/blob/master/NahidaProject.Generic/Sources/NahidaProject.cpp) 涓暀涓嬩綘鐨 Gitee ID銆 ## 寮鏀炬簮浠g爜璁稿彲涓庤鏄 @@ -212,4 +212,4 @@ NahidaProject 涓殑浠g爜锛屽彲浠ョ洿鎺ュ紩鍏ヤ娇鐢ㄣ備絾鏄垜浠洿寤鸿缂 ## 寮鏀炬簮浠g爜鐘舵 -[![HeZongLun/NahidaProject](https://gitee.com/hezonglun/nahida-project/widgets/widget_card.svg?colors=4183c4,ffffff,ffffff,e3e9ed,666666,9b9b9b)](https://gitee.com/hezonglun/nahida-project) +[![HeZongLun/NahidaProject](https://gitee.com/hezonglun/nahida-project/widgets/widget_card.svg?colors=eae9d7,2e2f29,272822,484a45,eae9d7,747571)](https://gitee.com/hezonglun/nahida-project)