diff --git a/.gitea/workflows/BuildRelease.yaml b/.gitea/workflows/BuildRelease.yaml index 6062a6d..223daf5 100644 --- a/.gitea/workflows/BuildRelease.yaml +++ b/.gitea/workflows/BuildRelease.yaml @@ -35,6 +35,8 @@ jobs: mv build/Release/EHS_Dyn.dll bin mv build/Release/StrToHash.exe bin mv build/Release/zlib1.dll bin + mv build/Release/libcrypto-3-x64.dll bin + mv build/Release/libssl-3-x64.dll bin mkdir lib mv build/Release/EHS_Stc.lib lib mv build/Release/EHS_Dyn.lib lib @@ -65,7 +67,7 @@ jobs: - name: Installing Dependencies run: | - sudo pacman -S --noconfirm doxygen zip alsa-lib libxcb xcb-util-cursor pipewire + sudo pacman -S --noconfirm doxygen ninja zip libxcb xcb-util-cursor pipewire - name: Generating Documentation run: | @@ -74,7 +76,7 @@ jobs: - name: Building/Compiling/Installing Project run: | cd ${{ gitea.workspace }} - cmake -DCMAKE_BUILD_TYPE=Release -DLINUX_WINDOW_SYSTEM:STRING=XCB . + cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLINUX_WINDOW_SYSTEM:STRING=XCB . cmake --build . --config Release cmake --install . @@ -110,7 +112,7 @@ jobs: uses: actions/checkout@v3 - name: Installing Dependencies - run: sudo apt install -y doxygen zip libasound2-dev libxcb1-dev libxcb-xinput-dev libxcb-cursor-dev libpipewire-0.3-dev + run: sudo apt install -y doxygen ninja-build zip libxcb1-dev libxcb-xinput-dev libxcb-cursor-dev libpipewire-0.3-dev - name: Generating Documentation run: | @@ -119,7 +121,7 @@ jobs: - name: Building/Compiling/Installing Project run: | cd ${{ gitea.workspace }} - cmake -DCMAKE_BUILD_TYPE=Release -DLINUX_WINDOW_SYSTEM:STRING=XCB . + cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLINUX_WINDOW_SYSTEM:STRING=XCB . cmake --build . --config Release cmake --install . diff --git a/Assembly.def b/Assembly.def new file mode 100644 index 0000000..6207d84 --- /dev/null +++ b/Assembly.def @@ -0,0 +1,26 @@ +LIBRARY EHS_Dyn +EXPORTS + ?GenerateSeed_u64@HRNG@ehs@@SA_KXZ + ?Generate_u64@HRNG@ehs@@SA_K_K0@Z + ?Generate_u64@HRNG@ehs@@SA_KXZ + ?GenerateSeed_s64@HRNG@ehs@@SA_JXZ + ?Generate_s64@HRNG@ehs@@SA_J_J0@Z + ?Generate_s64@HRNG@ehs@@SA_JXZ + ?GenerateSeed_u32@HRNG@ehs@@SAIXZ + ?Generate_u32@HRNG@ehs@@SAIII@Z + ?Generate_u32@HRNG@ehs@@SAIXZ + ?GenerateSeed_s32@HRNG@ehs@@SAHXZ + ?Generate_s32@HRNG@ehs@@SAHHH@Z + ?Generate_s32@HRNG@ehs@@SAHXZ + ?GenerateSeed_u16@HRNG@ehs@@SAIXZ + ?Generate_u16@HRNG@ehs@@SAGGG@Z + ?Generate_u16@HRNG@ehs@@SAGXZ + ?GenerateSeed_s16@HRNG@ehs@@SAFXZ + ?Generate_s16@HRNG@ehs@@SAFFF@Z + ?Generate_s16@HRNG@ehs@@SAFXZ + ?GenerateSeed_u8@HRNG@ehs@@SAEXZ + ?Generate_u8@HRNG@ehs@@SAEEE@Z + ?Generate_u8@HRNG@ehs@@SAEXZ + ?GenerateSeed_s8@HRNG@ehs@@SACXZ + ?Generate_s8@HRNG@ehs@@SACCC@Z + ?Generate_s8@HRNG@ehs@@SACXZ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e3eda96..7d710b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.25.1) +cmake_minimum_required(VERSION 3.30.4) set(IS_OS_WINDOWS FALSE) set(IS_OS_LINUX FALSE) @@ -11,6 +11,8 @@ set(IS_ARCH_ARM FALSE) project(EHS CXX C) +set(CMAKE_VERBOSE_MAKEFILE ON) + if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") set(IS_OS_WINDOWS TRUE) set(USER_HOME_DIRECTORY "$ENV{USERPROFILE}") @@ -51,6 +53,7 @@ set(EHS_SOURCES src/Color3.cpp include/ehs/Color3.h src/Version.cpp include/ehs/Version.h src/Base64.cpp include/ehs/Base64.h + src/SHA256.cpp include/ehs/SHA256.h src/Data.cpp include/ehs/Data.h src/Range.cpp include/ehs/Range.h src/Util.cpp include/ehs/Util.h @@ -97,6 +100,8 @@ set(EHS_SOURCES include/ehs/system/OS.h include/ehs/system/Semaphore.h include/ehs/system/System.h + include/ehs/system/AVX2.h + include/ehs/system/AVX512.h src/json/Json.cpp include/ehs/json/Json.h src/json/JsonBase.cpp include/ehs/json/JsonBase.h @@ -196,6 +201,8 @@ set(EHS_SOURCES src/io/socket/ehc/NetUtils.cpp include/ehs/io/socket/BaseICMP.h src/io/socket/BaseICMP.cpp include/ehs/io/socket/ICMP.h + src/io/socket/QueryVar.cpp include/ehs/io/socket/QueryVar.h + src/io/socket/HeaderVar.cpp include/ehs/io/socket/HeaderVar.h ) if (IS_OS_WINDOWS) @@ -215,6 +222,7 @@ if (IS_OS_WINDOWS) src/system/CPU_MSVC_AMD64.asm src/HRNG_MSVC.asm src/Math_MSVC_AMD64.asm src/io/Directory_W32.cpp include/ehs/io/Directory_W32.h include/ehs/io/socket/ICMP_W32.h src/io/socket/ICMP_W32.cpp + src/system/AVX2_MSVC_AMD64.asm src/system/AVX512_MSVC_AMD64.asm ) elseif (IS_OS_LINUX) @@ -236,7 +244,7 @@ elseif (IS_OS_LINUX) include/ehs/io/socket/ICMP_LNX.h src/io/socket/ICMP_LNX.cpp ) - #set(LINUX_WINDOW_SYSTEM "Wayland" CACHE STRING "Linux Window System") + set(LINUX_WINDOW_SYSTEM "XCB" CACHE STRING "Linux Window System") if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland") add_compile_definitions(EHS_WS_WAYLAND) @@ -252,17 +260,14 @@ elseif (IS_OS_LINUX) endif () if (IS_ARCH_AMD64) - list(APPEND EHS_SOURCES src/system/CPU_GCC_AMD64.asm src/HRNG_GCC.asm src/Math_GCC_AMD64.asm) + list(APPEND EHS_SOURCES src/system/CPU_GCC_AMD64.asm src/HRNG_GCC.asm src/Math_GCC_AMD64.asm src/system/AVX2_GCC_AMD64.asm src/system/AVX512_GCC_AMD64.asm) elseif (IS_ARCH_ARM64) - list(APPEND EHS_SOURCES src/system/CPU_ARM64.cpp src/HRNG_ARM64.cpp src/Math_GCC_ARM64.s) + list(APPEND EHS_SOURCES src/system/CPU_ARM64.cpp src/system/CPU_GCC_AARCH64.s src/HRNG_ARM64.cpp src/Math_GCC_ARM64.s src/system/AVX2_AARCH64.cpp src/system/AVX512_AARCH64.cpp) endif () endif() -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") -#message("${CMAKE_CXX_FLAGS}") - add_library(EHS_Stc STATIC ${EHS_SOURCES}) -add_library(EHS_Dyn SHARED ${EHS_SOURCES}) +add_library(EHS_Dyn SHARED ${EHS_SOURCES} Assembly.def) add_executable(StrToHash src/StrToHash.cpp) target_compile_definitions(EHS_Dyn PRIVATE EHS_LIB_EXPORT) @@ -323,6 +328,6 @@ elseif (IS_OS_LINUX) target_link_libraries(StrToHash xcb xcb-cursor xcb-xfixes xcb-xinput) endif () - target_link_libraries(EHS_Dyn z asound pipewire-0.3) - target_link_libraries(StrToHash z asound EHS_Stc) + target_link_libraries(EHS_Dyn z pipewire-0.3) + target_link_libraries(StrToHash z EHS_Stc) endif () \ No newline at end of file diff --git a/README.md b/README.md index 29c74fc..3b3c283 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ This project does not fully follow the C++ standard. - Asynchronous Task System - URI Parsing - USB (WIP) +- Base64 +- SHA256 ### Supported Architectures - AMD64 diff --git a/include/ehs/Base64.h b/include/ehs/Base64.h index 71fcf35..ee0f0c9 100644 --- a/include/ehs/Base64.h +++ b/include/ehs/Base64.h @@ -8,17 +8,26 @@ namespace ehs class EHS_LIB_IO Base64 { private: - static const char ascii[]; + static constexpr UInt_8 asciiUrl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + static constexpr UInt_8 ascii[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; public: + static Str_8 EncodeURL(const Str_8 &input); + static Str_8 Encode(const Str_8 &input); - + + static Str_8 DecodeURL(const Str_8 &input); + static Str_8 Decode(const Str_8 &input); private: - static char Find(char c); - - static bool IsBase64(char c); + static UInt_8 FindURL(const UInt_8 &c); + + static UInt_8 Find(const UInt_8 &c); + + static bool IsBase64URL(const UInt_8 &c); + + static bool IsBase64(const UInt_8 &c); }; } \ No newline at end of file diff --git a/include/ehs/HRNG.h b/include/ehs/HRNG.h index 3a0a203..f95e38a 100644 --- a/include/ehs/HRNG.h +++ b/include/ehs/HRNG.h @@ -5,7 +5,7 @@ namespace ehs { - class EHS_LIB_IO HRNG + class HRNG { public: static UInt_64 GenerateSeed_u64(); diff --git a/include/ehs/Log.h b/include/ehs/Log.h index 7eccf5a..4ff37f3 100644 --- a/include/ehs/Log.h +++ b/include/ehs/Log.h @@ -63,7 +63,7 @@ namespace ehs /// @param [in] tags The tags to associate this log with. /// @param [in] code The unique code to use. /// @param [in] msg Detailed information about what happened. - Log(LogType type, const std::initializer_list &tags, UInt_64 code, Str_8 msg); + Log(LogType type, const Str_8 &tags, UInt_64 code, Str_8 msg); /// Initializes members with the given information. /// @param [in] tags The tags to associate this log with. @@ -134,20 +134,20 @@ namespace ehs #ifndef EHS_LOG_INT #ifdef EHS_DEBUG - #define EHS_LOG_INT(type, code, msg) ehs::Log::Raise({type, {ehs::GetAcronym_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg}) + #define EHS_LOG_INT(type, code, msg) ehs::Log::Raise(ehs::Log(type, ehs::Str_8(ehs::GetAcronym_8()) + ", " + EHS_FILE + ", " + EHS_FUNC + ", " + ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE), code, msg)) #else - #define EHS_LOG_INT(type, code, msg) ehs::Log::Raise({type, {ehs::GetAcronym_8(), EHS_FUNC}, code, msg}) + #define EHS_LOG_INT(type, code, msg) ehs::Log::Raise(ehs::Log(type, ehs::Str_8(ehs::GetAcronym_8()) + ", " + EHS_FUNC, code, msg)) #endif #endif #ifndef EHS_LOG #ifdef EHS_DEBUG - #define EHS_LOG(type, code, msg) ehs::Log::Raise({type, {ehs::GetAppName_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg}) + #define EHS_LOG(type, code, msg) ehs::Log::Raise(ehs::Log(type, ehs::Str_8(ehs::GetAppName_8()) + ", " + EHS_FILE + ", " + EHS_FUNC + ", " + ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE), code, msg)) #else - #define EHS_LOG(type, code, msg) ehs::Log::Raise({type, {ehs::GetAppName_8(), EHS_FUNC}, code, msg}) + #define EHS_LOG(type, code, msg) ehs::Log::Raise(ehs::Log(type, ehs::Str_8(ehs::GetAppName_8()) + ", " + EHS_FUNC, code, msg)) #endif #endif #ifndef EHS_LOG_SUCCESS -#define EHS_LOG_SUCCESS() ehs::Log::Raise({}) + #define EHS_LOG_SUCCESS() ehs::Log::Raise({}) #endif \ No newline at end of file diff --git a/include/ehs/SHA256.h b/include/ehs/SHA256.h new file mode 100644 index 0000000..b5d9a46 --- /dev/null +++ b/include/ehs/SHA256.h @@ -0,0 +1,59 @@ +#pragma once +#include "Types.h" + +namespace ehs +{ + class EHS_LIB_IO SHA256 + { + private: + static UInt_32 ROTR(UInt_32 x, UInt_32 n); + + static UInt_32 CH(UInt_32 x, UInt_32 y, UInt_32 z); + + static UInt_32 MAJ(UInt_32 x, UInt_32 y, UInt_32 z); + + static UInt_32 EP0(UInt_32 x); + + static UInt_32 EP1(UInt_32 x); + + static UInt_32 SIG0(UInt_32 x); + + static UInt_32 SIG1(UInt_32 x); + + static constexpr UInt_32 k[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 + }; + + UInt_32 state[8]; + UInt_64 bitLen; + Byte data[64]; + UInt_64 dataLen; + + public: + SHA256(); + + SHA256(SHA256 &&other) noexcept; + + SHA256(const SHA256 &other); + + SHA256 &operator=(SHA256 &&other) noexcept; + + SHA256 &operator=(const SHA256 &other); + + void Update(const Byte *data, UInt_64 len); + + void Final(Byte hash[32]); + + void Hash(const Byte *data, UInt_64 len, Byte hash[32]); + + private: + void Transform(const Byte data[64]); + }; +} diff --git a/include/ehs/Str.h b/include/ehs/Str.h index e1dfb8a..bd651bb 100644 --- a/include/ehs/Str.h +++ b/include/ehs/Str.h @@ -48,8 +48,11 @@ namespace ehs /// @param [in] str The C-style string. /// @param [in] size The size of the given C-style string. Str(const T* const str, const N size) - : size((size) ? size : Len(str)), data(nullptr) + : size(size), data(nullptr) { + if (!size) + return; + data = new T[this->size + 1]; Util::Copy(data, str, Size(true)); @@ -914,10 +917,10 @@ namespace ehs } /// Splits a string into a Vector with the given separator. - /// @param [in] ide The given string as the separator. + /// @param [in] delimeter The given string as the separator. /// @param [in] max The max amount of times to split the string. /// @returns The resulting string object. - Vector, N> Split(const Str& ide, const N max = 0) const + Vector, N> Split(const Str& delimeter, const N max = 0) const { Vector, N> result(0, 5); @@ -925,9 +928,9 @@ namespace ehs for (N i = 0, c = 0; i < size; ++i) { - if (data[i] == ide[c]) + if (data[i] == delimeter[c]) { - if (++c == ide.Size()) + if (++c == delimeter.Size()) { N r = i - (c - 1) - b; if (!r) @@ -955,17 +958,17 @@ namespace ehs } /// Removes all instances of the ide. - /// @param [in] ide The string to look for. + /// @param [in] delimeter The string to look for. /// @returns The resulting string object. - Str RemoveAll(const Str& ide) const + Str RemoveAll(const Str& delimeter) const { Str result(size); for (N i = 0, b = 0, c = 0; i < size; ++i) { - if (data[i] == ide[c]) + if (data[i] == delimeter[c]) { - if (++c == ide.Size()) + if (++c == delimeter.Size()) c = 0; } else @@ -984,18 +987,18 @@ namespace ehs } /// Replaces all instances of ide with the replacer. - /// @param [in] ide The string to look for. + /// @param [in] delimeter The string to look for. /// @param [in] replacer The string placed. /// @returns The resulting string object. - Str ReplaceAll(const Str& ide, const Str& replacer) const + Str ReplaceAll(const Str& delimeter, const Str& replacer) const { Str result; for (N i = 0, b = 0; i < size; ++i) { - if (data[i] == ide[b]) + if (data[i] == delimeter[b]) { - if (++b == ide.Size()) + if (++b == delimeter.Size()) { result.Push(replacer); b = 0; @@ -1011,20 +1014,20 @@ namespace ehs } /// Finds the first instance of the given string object. - /// @param [in] ide The string to look for. + /// @param [in] delimeter The string to look for. /// @param [out] index The index of the string found. Can be a nullptr. /// @param [in] pattern The search pattern for optimization. /// @param [in] result What index to return where the first instance is found. /// @returns The index where the instance was found with the result varying from the result parameter. - bool Find(const Str &ide, N* const index = nullptr, const SearchPattern pattern = SearchPattern::LEFT_RIGHT, const IndexResult result = IndexResult::BEGINNING) const + bool Find(const Str &delimeter, N* const index = nullptr, const SearchPattern pattern = SearchPattern::LEFT_RIGHT, const IndexResult result = IndexResult::BEGINNING) const { if (pattern == SearchPattern::LEFT_RIGHT) { for (N i = 0, c = 0; i < size; ++i) { - if (data[i] == ide[c]) + if (data[i] == delimeter[c]) { - if (++c == ide.Size()) + if (++c == delimeter.Size()) { if (result == IndexResult::BEGINNING) { @@ -1046,16 +1049,16 @@ namespace ehs } else if (pattern == SearchPattern::RIGHT_LEFT) { - for (N i = size, c = ide.Size(); i > 0; --i) + for (N i = size, c = delimeter.Size(); i > 0; --i) { - if (data[i - 1] == ide[c - 1]) + if (data[i - 1] == delimeter[c - 1]) { if (--c == 0) { if (result == IndexResult::BEGINNING) { if (index) - *index = i - (ide.Size() - 1); + *index = i - (delimeter.Size() - 1); return true; } @@ -1075,18 +1078,18 @@ namespace ehs } /// Checks if the current string contains the given ide. - /// @param [in] ide The given ide to check for. + /// @param [in] delimeter The given ide to check for. /// @param [in] pattern The search pattern to use. /// @returns True if the current string does contain the ide. - bool Contains(const Str& ide, const SearchPattern pattern = SearchPattern::LEFT_RIGHT) const + bool Contains(const Str& delimeter, const SearchPattern pattern = SearchPattern::LEFT_RIGHT) const { if (pattern == SearchPattern::LEFT_RIGHT) { for (N i = 0, c = 0; i < size; ++i) { - if (data[i] == ide[c]) + if (data[i] == delimeter[c]) { - if (++c == ide.Size()) + if (++c == delimeter.Size()) { return true; } @@ -1095,9 +1098,9 @@ namespace ehs } else if (pattern == SearchPattern::RIGHT_LEFT) { - for (N i = size, c = ide.Size(); i > 0; --i) + for (N i = size, c = delimeter.Size(); i > 0; --i) { - if (data[i - 1] == ide[c - 1]) + if (data[i - 1] == delimeter[c - 1]) { if (--c == 0) { @@ -1110,6 +1113,54 @@ namespace ehs return false; } + Vector ParseArgs() const + { + Vector args; + T *quoteStart = nullptr; + T *spaceStart = nullptr; + + for (T *i = data; i <= data + size; ++i) + { + if (*i == '\"' && !spaceStart) + { + if (quoteStart) + { + args.Push(Str(quoteStart, i - quoteStart)); + quoteStart = nullptr; + } + else + { + if (i + 1 < &data[size - 1]) + quoteStart = i + 1; + else + args.Push({}); + } + } + else if (*i == ' ' && !quoteStart) + { + if (spaceStart) + { + args.Push(Str(spaceStart, i - spaceStart)); + spaceStart = i + 1; + } + else + { + if (i + 1 < &data[size - 1]) + spaceStart = i + 1; + else + args.Push({}); + } + } + } + + if (quoteStart) + args.Push(Str(quoteStart, &data[size - 1] - (quoteStart - 1))); + else if (spaceStart) + args.Push(Str(spaceStart, &data[size - 1] - (spaceStart - 1))); + + return args; + } + /// Checks if the string represents a number. Must not have any alphabetical characters. /// @returns The result. bool IsNum() const diff --git a/include/ehs/Vector.h b/include/ehs/Vector.h index 7f66afb..06aa50f 100644 --- a/include/ehs/Vector.h +++ b/include/ehs/Vector.h @@ -392,7 +392,7 @@ namespace ehs { if (stride) { - rawSize = (this->size + size()) / stride * stride; + rawSize = (this->size + size) / stride * stride; if ((this->size + size) % stride) rawSize += stride; } @@ -403,7 +403,7 @@ namespace ehs T* result = new T[rawSize]; - for (N i = 0; i < size; ++i) + for (N i = 0; i < this->size; ++i) result[i] = std::move(data[i]); delete[] data; diff --git a/include/ehs/io/audio/AudioDevice_PW.h b/include/ehs/io/audio/AudioDevice_PW.h index f94bddd..b366d05 100644 --- a/include/ehs/io/audio/AudioDevice_PW.h +++ b/include/ehs/io/audio/AudioDevice_PW.h @@ -25,6 +25,7 @@ namespace ehs pw_core *core; pw_stream *input; pw_stream *output; + spa_hook paramsHook; static void RegistryEventGlobal(void *data, UInt_32 id, UInt_32 permissions, const char *type, UInt_32 version, const spa_dict *props); diff --git a/include/ehs/io/socket/BaseTCP.h b/include/ehs/io/socket/BaseTCP.h index b5e521f..3908ac5 100644 --- a/include/ehs/io/socket/BaseTCP.h +++ b/include/ehs/io/socket/BaseTCP.h @@ -24,9 +24,9 @@ namespace ehs bool connected; public: - static const UInt_16 HTTPS_Port = 443; - static const UInt_16 HTTP_Port = 80; - static const UInt_16 MaxHeaderSize = 8192; + static constexpr UInt_16 HTTPS_Port = 443; + static constexpr UInt_16 HTTP_Port = 80; + static constexpr UInt_16 MaxHeaderSize = 8192; virtual ~BaseTCP() = default; @@ -55,7 +55,7 @@ namespace ehs /// @param [in] address The ip address to bind to. /// @param [in] port The port to bind to. /// @note Used for servers. - virtual void Bind(const Str_8& address, UInt_16 port) = 0; + virtual void Bind(Str_8 address, const UInt_16 &port) = 0; /// Listens for new incoming connections. /// @note Used for servers. @@ -63,13 +63,13 @@ namespace ehs /// Accepts the new incoming connection. /// @note Used for servers. - virtual BaseTCP* Accept() = 0; + virtual BaseTCP *Accept() = 0; /// Connects to a server at the specified address and port. /// @param [in] address The ip address to connect to. /// @param [in] port The port to connect to. /// @note Used for clients. - virtual void Connect(const Str_8& address, UInt_16 port) = 0; + virtual void Connect(Str_8 address, const UInt_16 &port) = 0; /// Sends data to the connected endpoint. /// @param [in] buffer The data to send to the endpoint. @@ -150,6 +150,8 @@ namespace ehs virtual bool IsIPv6Only() const = 0; + virtual void SetReuse(const bool &enabled) = 0; + /// Retrieves whether or not this socket was initialized. /// @returns The result. virtual bool IsValid() const = 0; diff --git a/include/ehs/io/socket/HeaderVar.h b/include/ehs/io/socket/HeaderVar.h new file mode 100644 index 0000000..ade976a --- /dev/null +++ b/include/ehs/io/socket/HeaderVar.h @@ -0,0 +1,45 @@ +#pragma once + +#include "ehs/Str.h" + +namespace ehs +{ + class HeaderVar + { + private: + UInt_64 id; + Str_8 name; + Str_8 value; + + public: + HeaderVar(); + + HeaderVar(Str_8 name, Str_8 value); + + HeaderVar(HeaderVar &&other) noexcept; + + HeaderVar(const HeaderVar &other); + + HeaderVar &operator=(HeaderVar &&other) noexcept; + + HeaderVar &operator=(const HeaderVar &other); + + bool operator==(const HeaderVar &other) const; + + bool operator!=(const HeaderVar &other) const; + + bool operator==(const UInt_64 &otherId) const; + + bool operator!=(const UInt_64 &otherId) const; + + UInt_64 GetId() const; + + Str_8 GetName() const; + + Str_8 GetValue() const; + + void SetValue(Str_8 value); + + Str_8 ToStr() const; + }; +} diff --git a/include/ehs/io/socket/QueryVar.h b/include/ehs/io/socket/QueryVar.h new file mode 100644 index 0000000..a420097 --- /dev/null +++ b/include/ehs/io/socket/QueryVar.h @@ -0,0 +1,45 @@ +#pragma once + +#include "ehs/Str.h" + +namespace ehs +{ + class QueryVar + { + private: + UInt_64 id; + Str_8 name; + Str_8 value; + + public: + QueryVar(); + + QueryVar(Str_8 name, Str_8 value); + + QueryVar(QueryVar &&other) noexcept; + + QueryVar(const QueryVar &other); + + QueryVar &operator=(QueryVar &&other) noexcept; + + QueryVar &operator=(const QueryVar &other); + + bool operator==(const QueryVar &other) const; + + bool operator!=(const QueryVar &other) const; + + bool operator==(const UInt_64 &otherId) const; + + bool operator!=(const UInt_64 &otherId) const; + + UInt_64 GetId() const; + + Str_8 GetName() const; + + Str_8 GetValue() const; + + void SetValue(Str_8 value); + + Str_8 ToStr() const; + }; +} \ No newline at end of file diff --git a/include/ehs/io/socket/Request.h b/include/ehs/io/socket/Request.h index f97e10a..902a6ed 100644 --- a/include/ehs/io/socket/Request.h +++ b/include/ehs/io/socket/Request.h @@ -5,6 +5,8 @@ #include "ehs/Str.h" #include "ehs/json/Json.h" #include "Socket.h" +#include "QueryVar.h" +#include "HeaderVar.h" namespace ehs { @@ -21,8 +23,8 @@ namespace ehs private: Verb verb; Str_8 rsrc; - Vector queries; - Vector header; + Vector queries; + Vector header; ContentType cType; Str_8 body; @@ -33,25 +35,34 @@ namespace ehs /// Initializes this request with a given verb and URI resource. /// @param [in] verb The type of request to make. /// @param [in] rsrc The URI endpoint to make the request at. - Request(const Verb verb, const Str_8& rsrc); + Request(const Verb &verb, Str_8 rsrc); /// Initializes this request with the raw request data. /// @param [in] data The C-style string of the request. /// @param [in] size The size of the given C-style string. - Request(const char* data, const UInt_64 size); + Request(const char *data, const UInt_64 &size); /// Initializes this request with the raw request data. /// @param [in] data The string of the request. - Request(const Str_8& data); + Request(const Str_8 &data); + + /// Moves members from another object of the same type. + /// @param [in] other The object to move from. + Request(Request &&other) noexcept; /// Copies members from another object of the same type. - /// @param [in] req The object to copy from. - Request(const Request& req) = default; + /// @param [in] other The object to copy from. + Request(const Request &other); + + /// Moves members from another object of the same type. + /// @param [in] other The object to move from. + /// @returns The request that has been assigned to. + Request& operator=(Request &&other) noexcept; /// Copies members from another object of the same type. - /// @param [in] req The object to copy from. + /// @param [in] other The object to copy from. /// @returns The request that has been assigned to. - Request& operator=(const Request& req); + Request& operator=(const Request &other); /// Retrieves the verb for the request. /// @returns The result. @@ -59,7 +70,7 @@ namespace ehs /// Sets the content type for the body. /// @param [in] cType The content type to use. - void SetContentType(const ContentType cType); + void SetContentType(const ContentType &cType); /// Retrieves the content type for the body. /// @returns The result. @@ -67,75 +78,145 @@ namespace ehs /// Sets the URI resource. /// @param [in] rsrc The resource. - void SetResource(const Str_8& rsrc); + void SetResource(Str_8 rsrc); /// Retrieves the URI resource. /// @returns The result. Str_8 GetResource() const; - /// Adds a query variable to the URI. - /// @param [in] var The variable identifier. - /// @param [in] value The value of the variable. - void AddQuery(const Str_8& var, const Str_8& value); + /// Checks whether a header variable exists using the id. + /// @param [in] id The variable id to look for. + /// @returns True if the variable exists. False otherwise. + bool HasQueryVar(const UInt_64 &id) const; - /// Retrieves a query variable from the URI. - /// @param [in] var The variable identifier to look for. - /// @returns The value of the query variable. Empty if it was not found. - Str_8 GetQuery(const Str_8& var); + /// Checks whether a header variable exists using the name. + /// @param [in] name The variable name to look for. + /// @returns True if the variable exists. False otherwise. + bool HasQueryVar(const Str_8 &name) const; + + /// Adds a header variable. + /// @param [in] var The variable to add to the header. + /// @returns False if the given variable name already exists. True otherwise. + bool AddQueryVar(QueryVar var); + + /// Removes a header variable using the id. + /// @param [in] id The variable id to look for. + /// @returns True if the variable was found. False otherwise. + bool RemoveQueryVar(const UInt_64 &id); + + /// Removes a header variable using the name. + /// @param [in] name The variable name to look for. + /// @returns True if the variable was found. False otherwise. + bool RemoveQueryVar(const Str_8 &name); + + /// Retrieves a header variable using the id. + /// @param [in] id The variable id to look for. + /// @returns The variable object if found. Nullptr otherwise. + QueryVar *GetQueryVar(const UInt_64 &id) const; + + /// Retrieves a header variable using the name. + /// @param [in] name The variable name to look for. + /// @returns The variable object if found. Nullptr otherwise. + QueryVar *GetQueryVar(const Str_8& name) const; + + /// Retrieves a header variable value using the id. + /// @param [in] id The variable id to look for. + /// @returns The variable's value if found. Empty otherwise. + Str_8 GetQueryValue(const UInt_64 &id) const; + + /// Retrieves a header variable value using the name. + /// @param [in] name The variable name to look for. + /// @returns The variable's value if found. Empty otherwise. + Str_8 GetQueryValue(const Str_8& name) const; /// Retrieves all the query variables from the URI in a vector object. /// @returns The result. - Vector GetQueries() const; + Vector GetQueries() const; /// A helper method to automatically add the required header variables for basic authentication. /// @param [in] id The username or id. /// @param [in] secret The secret given by an API. - void BasicAuth(const Str_8& id, const Str_8& secret); + void BasicAuth(const Str_8 &id, const Str_8 &secret); /// A helper method to automatically add the required header variables for bearer authentication. /// @param [in] token The token given by an API. - void BearerAuth(const Str_8& token); + void BearerAuth(const Str_8 &token); /// A helper method to automatically add the required header variables for bearer authentication. /// @param [in] token The token given by an API. /// @param [in] clientId The client id given by an API. - void BearerAuth(const Str_8& token, const Str_8& clientId); + void BearerAuth(const Str_8 &token, const Str_8 &clientId); /// A helper method to automatically add the required header variables for bot authentication. /// @param [in] token The token given by an API. - void BotAuth(const Str_8& token); + void BotAuth(const Str_8 &token); + + /// Checks whether a header variable exists using the id. + /// @param [in] id The variable id to look for. + /// @returns True if the variable exists. False otherwise. + bool HasHeaderVar(const UInt_64 &id) const; + + /// Checks whether a header variable exists using the name. + /// @param [in] name The variable name to look for. + /// @returns True if the variable exists. False otherwise. + bool HasHeaderVar(const Str_8 &name) const; /// Adds a header variable. - /// @param [in] var The variable identifier. - /// @param [in] value The value of the variable. - void AddToHeader(const Str_8& var, const Str_8& value); + /// @param [in] var The variable to add to the header. + /// @returns False if the given variable name already exists. True otherwise. + bool AddHeaderVar(HeaderVar var); - /// Retrieves a header variable. - /// @param [in] var The variable identifier to look for. - /// @returns The value of the header variable. Empty if it was not found. - Str_8 GetHeader(const Str_8& var) const; + /// Removes a header variable using the id. + /// @param [in] id The variable id to look for. + /// @returns True if the variable was found. False otherwise. + bool RemoveHeaderVar(const UInt_64 &id); + + /// Removes a header variable using the name. + /// @param [in] name The variable name to look for. + /// @returns True if the variable was found. False otherwise. + bool RemoveHeaderVar(const Str_8 &name); + + /// Retrieves a header variable using the id. + /// @param [in] id The variable id to look for. + /// @returns The variable object if found. Nullptr otherwise. + HeaderVar *GetHeaderVar(const UInt_64 &id) const; + + /// Retrieves a header variable using the name. + /// @param [in] name The variable name to look for. + /// @returns The variable object if found. Nullptr otherwise. + HeaderVar *GetHeaderVar(const Str_8& name) const; + + /// Retrieves a header variable value using the id. + /// @param [in] id The variable id to look for. + /// @returns The variable's value if found. Empty otherwise. + Str_8 GetHeaderValue(const UInt_64 &id) const; + + /// Retrieves a header variable value using the name. + /// @param [in] name The variable name to look for. + /// @returns The variable's value if found. Empty otherwise. + Str_8 GetHeaderValue(const Str_8& name) const; /// Retrieves all the header variables in a vector object. /// @returns The result. - Vector GetHeader() const; + Vector GetHeader() const; /// Adds a body variable. /// @param [in] var The variable identifier. /// @param [in] value The value of the variable. - void AddToBody(const Str_8& var, const Str_8& value); + void AddToBody(const Str_8 &var, const Str_8 &value); /// Adds a value to the body. /// @param [in] data The value to add. - void AddToBody(const Str_8& data); + void AddToBody(const Str_8 &data); /// Sets the entire body. /// @param [in] body The body to use. - void SetBody(const Str_8& body); + void SetBody(const Str_8 &body); /// Retrieves a body variable. /// @param [in] var The variable identifier to look for. /// @returns The value of the body variable. Empty if it was not found. - Str_8 GetVar(const Str_8& var) const; + Str_8 GetVar(const Str_8 &var) const; /// Retrieves the entire body. /// @returns The result. @@ -152,13 +233,13 @@ namespace ehs bool IsValid() const; private: - static Str_8 VerbToStr(const Verb verb); + static Str_8 VerbToStr(const Verb &verb); - static Str_8 ContentTypeToStr(const ContentType cType); + static Str_8 ContentTypeToStr(const ContentType &cType); - static ContentType StrToContentType(const Str_8& value); + static ContentType StrToContentType(const Str_8 &value); - void ReadData(const Str_8& data); + void ReadData(const Str_8 &data); }; } \ No newline at end of file diff --git a/include/ehs/io/socket/Response.h b/include/ehs/io/socket/Response.h index 5735ba4..d76ea1e 100644 --- a/include/ehs/io/socket/Response.h +++ b/include/ehs/io/socket/Response.h @@ -5,6 +5,7 @@ #include "ehs/Str.h" #include "ehs/json/Json.h" #include "Socket.h" +#include "HeaderVar.h" namespace ehs { @@ -14,7 +15,7 @@ namespace ehs UInt_32 code; Str_8 server; ContentType cType; - Vector header; + Vector header; Str_8 body; public: @@ -24,29 +25,38 @@ namespace ehs /// Initializes this response with a given code and server identifier. /// @param [in] code The code to give. /// @param [in] server The server identifier. - Response(const UInt_32 code, const Str_8& server); + Response(const UInt_32 &code, Str_8 server); /// Initializes this response with the raw response data. /// @param [in] data The C-style string of the response. /// @param [in] size The size of the given C-style string. - Response(const char* data, const UInt_64 size); + Response(const char *data, const UInt_64 &size); /// Initializes this response with the raw response data. /// @param [in] data The string of the response. - Response(const Str_8& data); + Response(const Str_8 &data); + + /// Moves members from another object of the same type. + /// @param [in] other The object to move from. + Response(Response &&other) noexcept; /// Copies members from another object of the same type. - /// @param [in] res The object to copy from. - Response(const Response& res) = default; + /// @param [in] other The object to copy from. + Response(const Response &other); + + /// Moves members from another object of the same type. + /// @param [in] other The object to move from. + /// @returns The response that has been assigned to. + Response &operator=(Response &&other) noexcept; /// Copies members from another object of the same type. /// @param [in] res The object to copy from. /// @returns The response that has been assigned to. - Response& operator=(const Response& res); + Response& operator=(const Response &other); /// Sets the response code to send to the endpoint. /// @param [in] code The code for success, error or info. - void SetCode(const UInt_32 code); + void SetCode(const UInt_32 &code); /// Retrieves the response code. /// @returns The result. @@ -54,7 +64,7 @@ namespace ehs /// Sets the server identifier. /// @param [in] server The server identifier to use. - void SetServer(const Str_8& server); + void SetServer(Str_8 server); /// Retrieves the server identifier. /// @returns The result. @@ -62,25 +72,60 @@ namespace ehs /// Sets the content type for the body. /// @param [in] cType The content type to use. - void SetContentType(const ContentType cType); + void SetContentType(const ContentType &cType); /// Retrieves the content type for the body. /// @returns The result. ContentType GetContentType() const; - /// Adds a header variable. - /// @param [in] var The variable identifier. - /// @param [in] value The value of the variable. - void AddToHeader(const Str_8& var, const Str_8& value); + /// Checks whether a header variable exists using the id. + /// @param [in] id The variable id to look for. + /// @returns True if the variable exists. False otherwise. + bool HasHeaderVar(const UInt_64 &id) const; - /// Retrieves a header variable. - /// @param [in] var The variable identifier to look for. - /// @returns The value of the header variable. Empty if it was not found. - Str_8 GetHeader(const Str_8& var) const; + /// Checks whether a header variable exists using the name. + /// @param [in] name The variable name to look for. + /// @returns True if the variable exists. False otherwise. + bool HasHeaderVar(const Str_8 &name) const; + + /// Adds a header variable. + /// @param [in] var The variable to add to the header. + /// @returns False if the given variable name already exists. True otherwise. + bool AddHeaderVar(HeaderVar var); + + /// Removes a header variable using the id. + /// @param [in] id The variable id to look for. + /// @returns True if the variable was found. False otherwise. + bool RemoveHeaderVar(const UInt_64 &id); + + /// Removes a header variable using the name. + /// @param [in] name The variable name to look for. + /// @returns True if the variable was found. False otherwise. + bool RemoveHeaderVar(const Str_8 &name); + + /// Retrieves a header variable using the id. + /// @param [in] id The variable id to look for. + /// @returns The variable object if found. Nullptr otherwise. + HeaderVar *GetHeaderVar(const UInt_64 &id) const; + + /// Retrieves a header variable using the name. + /// @param [in] name The variable name to look for. + /// @returns The variable object if found. Nullptr otherwise. + HeaderVar *GetHeaderVar(const Str_8& name) const; + + /// Retrieves a header variable value using the id. + /// @param [in] id The variable id to look for. + /// @returns The variable's value if found. Empty otherwise. + Str_8 GetHeaderValue(const UInt_64 &id) const; + + /// Retrieves a header variable value using the name. + /// @param [in] name The variable name to look for. + /// @returns The variable's value if found. Empty otherwise. + Str_8 GetHeaderValue(const Str_8& name) const; /// Retrieves all the header variables in a vector object. /// @returns The result. - Vector GetHeader() const; + Vector GetHeader() const; /// Adds a body variable. /// @param [in] var The variable identifier. @@ -115,13 +160,13 @@ namespace ehs bool IsValid() const; private: - static Str_8 CodeToStr(const UInt_32 code); + static Str_8 CodeToStr(const UInt_32 &code); - static Str_8 ContentTypeToStr(const ContentType cType); + static Str_8 ContentTypeToStr(const ContentType &cType); - static ContentType StrToContentType(const Str_8& value); + static ContentType StrToContentType(const Str_8 &value); - void ReadData(const Str_8& data); + void ReadData(const Str_8 &data); }; } \ No newline at end of file diff --git a/include/ehs/io/socket/SSL.h b/include/ehs/io/socket/SSL.h index ff6b528..bae197d 100644 --- a/include/ehs/io/socket/SSL.h +++ b/include/ehs/io/socket/SSL.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "ehs/EHS.h" #include "ehs/Str.h" #include "TCP.h" @@ -15,15 +17,18 @@ namespace ehs class EHS_LIB_IO SSL : public TCP { private: + bool server; SSL_CTX* ctx; ::SSL* sslHdl; + X509 *cert; + EVP_PKEY* pkey; public: ~SSL() override; SSL(); - SSL(const IP type); + SSL(const IP &type, const bool &server); SSL(TCP&& tcp) noexcept; @@ -37,19 +42,19 @@ namespace ehs void Release() override; - void Bind(const Str_8& address, unsigned short port) override; + void Listen() override; SSL* Accept() override; - void Connect(const Str_8& address, const UInt_16 port) override; + void Connect(Str_8 address, const UInt_16 &port) override; - UInt_64 Send(const Byte* const buffer, const UInt_32 size) override; + UInt_64 Send(const Byte* buffer, const UInt_32 size) override; - UInt_64 Receive(Byte* const buffer, const UInt_32 size) override; + UInt_64 Receive(Byte* buffer, const UInt_32 size) override; - void UseCertificate(const Byte* data, const UInt_64 size); + void UseCertificate(const Char_8* data, const UInt_32 &size); - void UsePrivateKey(const Byte* data, const UInt_64 size); + void UsePrivateKey(const Char_8* data, const UInt_32 &size); bool IsValid(); }; diff --git a/include/ehs/io/socket/Socket.h b/include/ehs/io/socket/Socket.h index 3d9561a..7d2d8e3 100644 --- a/include/ehs/io/socket/Socket.h +++ b/include/ehs/io/socket/Socket.h @@ -40,7 +40,9 @@ namespace ehs APP_XML, TEXT_PLAIN, TEXT_HTML, + TEXT_CSS, TEXT_XML, + IMG_X_ICON, NONE }; diff --git a/include/ehs/io/socket/TCP_BSD.h b/include/ehs/io/socket/TCP_BSD.h index 09ae2eb..81f4de7 100644 --- a/include/ehs/io/socket/TCP_BSD.h +++ b/include/ehs/io/socket/TCP_BSD.h @@ -46,7 +46,7 @@ namespace ehs /// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. /// @param [in] port The port to bind to. /// @note Requires the port given to be forwarded if this is called. - void Bind(const Str_8& address, UInt_16 port) override; + void Bind(Str_8 address, const UInt_16 &port) override; /// Listens for incoming connections. Used for servers or PtP. void Listen() override; @@ -58,7 +58,7 @@ namespace ehs /// Connects to a TCP Socket that listens for incoming connections. Used for clients or PtP. /// @param address The address of the listening TCP socket. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. /// @param port The port of the listening TCP socket. - void Connect(const Str_8& address, UInt_16 port) override; + void Connect(Str_8 address, const UInt_16 &port) override; /// Sends data in a C-style array with raw functionality. Meaning no internal help outside of native functions besides error checking. /// @param [in] buffer The C-style array to send. @@ -84,15 +84,17 @@ namespace ehs bool IsIPv6Only() const override; + void SetReuse(const bool &value) override; + bool IsValid() const override; private: - void Bind_v6(const Str_8& address, UInt_16 port); + void Bind_v6(const Str_8 &address, const UInt_16 &port) const; - void Bind_v4(const Str_8& address, UInt_16 port); + void Bind_v4(const Str_8 &address, const UInt_16 &port) const; - void Connect_v6(const Str_8& address, UInt_16 port); + void Connect_v6(const Str_8 &address, const UInt_16 &port); - void Connect_v4(const Str_8& address, UInt_16 port); + void Connect_v4(const Str_8 &address, const UInt_16 &port); }; } \ No newline at end of file diff --git a/include/ehs/io/socket/TCP_W32.h b/include/ehs/io/socket/TCP_W32.h index 09ae2eb..94594da 100644 --- a/include/ehs/io/socket/TCP_W32.h +++ b/include/ehs/io/socket/TCP_W32.h @@ -46,7 +46,7 @@ namespace ehs /// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. /// @param [in] port The port to bind to. /// @note Requires the port given to be forwarded if this is called. - void Bind(const Str_8& address, UInt_16 port) override; + void Bind(Str_8 address, const UInt_16 &port) override; /// Listens for incoming connections. Used for servers or PtP. void Listen() override; @@ -58,7 +58,7 @@ namespace ehs /// Connects to a TCP Socket that listens for incoming connections. Used for clients or PtP. /// @param address The address of the listening TCP socket. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. /// @param port The port of the listening TCP socket. - void Connect(const Str_8& address, UInt_16 port) override; + void Connect(Str_8 address, const UInt_16 &port) override; /// Sends data in a C-style array with raw functionality. Meaning no internal help outside of native functions besides error checking. /// @param [in] buffer The C-style array to send. @@ -84,12 +84,14 @@ namespace ehs bool IsIPv6Only() const override; + void SetReuse(const bool &value) override; + bool IsValid() const override; private: - void Bind_v6(const Str_8& address, UInt_16 port); + void Bind_v6(const Str_8& address, const UInt_16 &port); - void Bind_v4(const Str_8& address, UInt_16 port); + void Bind_v4(const Str_8& address, const UInt_16 &port); void Connect_v6(const Str_8& address, UInt_16 port); diff --git a/include/ehs/system/AVX2.h b/include/ehs/system/AVX2.h new file mode 100644 index 0000000..9ea0a5d --- /dev/null +++ b/include/ehs/system/AVX2.h @@ -0,0 +1,36 @@ +#pragma once + +#include "ehs/Types.h" + +namespace ehs +{ + class EHS_LIB_IO AVX2 + { + public: + /// Compares two unaligned 4 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 4 elements are equal. False otherwise. + static bool CompareUnaligned(const UInt_64 *a, const UInt_64 *b); + + /// Compares two unaligned 4 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 4 elements are equal. False otherwise. + static bool CompareUnaligned(const SInt_64 *a, const SInt_64 *b); + + /// Compares two aligned 4 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 4 elements are equal. False otherwise. + /// @note The parameters "a", and "b" must have alignas(32). + static bool CompareAligned(const UInt_64 *a, const UInt_64 *b); + + /// Compares two aligned 4 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 4 elements are equal. False otherwise. + /// @note The parameters "a", and "b" must have alignas(32). + static bool CompareAligned(const SInt_64 *a, const SInt_64 *b); + }; +} diff --git a/include/ehs/system/AVX512.h b/include/ehs/system/AVX512.h new file mode 100644 index 0000000..7dcb53f --- /dev/null +++ b/include/ehs/system/AVX512.h @@ -0,0 +1,36 @@ +#pragma once + +#include "ehs/Types.h" + +namespace ehs +{ + class EHS_LIB_IO AVX512 + { + public: + /// Compares two unaligned 8 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 8 elements are equal. False otherwise. + static bool CompareUnaligned(const UInt_64 *a, const UInt_64 *b); + + /// Compares two unaligned 8 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 8 elements are equal. False otherwise. + static bool CompareUnaligned(const SInt_64 *a, const SInt_64 *b); + + /// Compares two aligned 8 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 8 elements are equal. False otherwise. + /// @note The parameters "a", and "b" must have alignas(32). + static bool CompareAligned(const UInt_64 *a, const UInt_64 *b); + + /// Compares two aligned 8 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 8 elements are equal. False otherwise. + /// @note The parameters "a", and "b" must have alignas(32). + static bool CompareAligned(const SInt_64 *a, const SInt_64 *b); + }; +} diff --git a/include/ehs/system/Architecture.h b/include/ehs/system/Architecture.h index da29911..0db9b45 100644 --- a/include/ehs/system/Architecture.h +++ b/include/ehs/system/Architecture.h @@ -6,7 +6,7 @@ #define EHS_64_BIT #elif defined(_M_ARM64) || defined(__aarch64__) #define EHS_LITTLE_ENDIAN - #define EHS_ARCH_ARM64 + #define EHS_ARCH_AARCH64 #define EHS_64_BIT #else #error Unsupported architecture. diff --git a/include/ehs/system/BaseSystem.h b/include/ehs/system/BaseSystem.h index c3e54ab..713af91 100644 --- a/include/ehs/system/BaseSystem.h +++ b/include/ehs/system/BaseSystem.h @@ -8,7 +8,7 @@ namespace ehs class EHS_LIB_IO BaseSystem { public: - static void OpenURI(const Str_8& uri); + static void OpenURI(Str_8 uri); static Str_8 OpenFileDialog(const Str_8 &dir, const Str_8 &filters); diff --git a/include/ehs/system/CPU.h b/include/ehs/system/CPU.h index e512fca..59d7dc5 100644 --- a/include/ehs/system/CPU.h +++ b/include/ehs/system/CPU.h @@ -38,6 +38,70 @@ namespace ehs #endif public: + static const bool hasFPU; + static const bool hasVME; + static const bool hasDE; + static const bool hasPSE; + static const bool hasTSC; + static const bool hasMSR; + static const bool hasPAE; + static const bool hasMCE; + static const bool hasCX8; + static const bool hasAPIC; + static const bool hasSEP; + static const bool hasMTRR; + static const bool hasPGE; + static const bool hasMCA; + static const bool hasCMOV; + static const bool hasPSE_36; + static const bool hasPSN; + static const bool hasCLFSH; + static const bool hasDS; + static const bool hasACPI; + static const bool hasMMX; + static const bool hasFXSR; + static const bool hasSSE; + static const bool hasSSE2; + static const bool hasSS; + static const bool hasHTT; + static const bool hasTM; + static const bool hasIA64; + static const bool hasPBE; + static const bool hasSSE3; + static const bool hasPCLMULQDQ; + static const bool hasDTES64; + static const bool hasMONITOR; + static const bool hasVMX; + static const bool hasSMX; + static const bool hasEST; + static const bool hasTM2; + static const bool hasSSSE3; + static const bool hasCNXT_ID; + static const bool hasSDBG; + static const bool hasFMA; + static const bool hasCX16; + static const bool hasXTPR; + static const bool hasPDCM; + static const bool hasPCID; + static const bool hasDCA; + static const bool hasSSE4_1; + static const bool hasSSE4_2; + static const bool hasX2APIC; + static const bool hasMOVBE; + static const bool hasPOPCNT; + static const bool hasTSC_DEADLINE; + static const bool hasAES; + static const bool hasXSAVE; + static const bool hasOSXSAVE; + static const bool hasAVX; + static const bool hasF16C; + static const bool hasRDRND; + static const bool hasHYPERVISOR; + static const bool hasAVX2; + static const bool hasAVX512F; + static const bool hasRDSEED; + static const bool hasADX; + static Architecture GetArchitecture(); static UInt_8 PointerSize(); @@ -68,153 +132,157 @@ namespace ehs static UInt_8 GetExtFamilyId(); - static UInt_32 GetFeatureBits_1(); - - static bool HasFPU(); - - static bool HasVME(); - - static bool HasDE(); - - static bool HasPSE(); - - static bool HasTSC(); - - static bool HasMSR(); - - static bool HasPAE(); - - static bool HasMCE(); - - static bool HasCX8(); - - static bool HasAPIC(); - - static bool HasSEP(); - - static bool HasMTRR(); - - static bool HasPGE(); - - static bool HasMCA(); - - static bool HasCMOV(); - - static bool HasPAT(); - - static bool HasPSE_36(); - - static bool HasPSN(); - - static bool HasCLFSH(); - - static bool HasDS(); - - static bool HasACPI(); - - static bool HasMMX(); - - static bool HasFXSR(); - - static bool HasSSE(); - - static bool HasSSE2(); - - static bool HasSS(); - - static bool HasHTT(); - - static bool HasTM(); - - static bool HasIA64(); - - static bool HasPBE(); - - static UInt_32 GetFeatureBits_2(); - - static bool HasSSE3(); - - static bool HasPCLMULQDQ(); - - static bool HasDTES64(); - - static bool HasMONITOR(); - - static bool HasDS_CPL(); - - static bool HasVMX(); - - static bool HasSMX(); - - static bool HasEST(); - - static bool HasTM2(); - - static bool HasSSSE3(); - - static bool HasCNXT_ID(); - - static bool HasSDBG(); - - static bool HasFMA(); - - static bool HasCX16(); - - static bool HasXTPR(); - - static bool HasPDCM(); - - static bool HasPCID(); - - static bool HasDCA(); - - static bool HasSSE4_1(); - - static bool HasSSE4_2(); - - static bool HasX2APIC(); - - static bool HasMOVBE(); - - static bool HasPOPCNT(); - - static bool HasTSC_DEADLINE(); - - static bool HasAES(); - - static bool HasXSAVE(); - - static bool HasOSXSAVE(); - - static bool HasAVX(); - - static bool HasF16C(); - - static bool HasRDRND(); - - static bool HasHYPERVISOR(); - - static UInt_32 GetExtFeatureBits_1(); - - static bool HasAVX2(); - - static bool HasRDSEED(); - - static bool HasADX(); - - static UInt_32 GetExtFeatureBits_2(); - - static UInt_32 GetExtFeatureBits_3(); - - /// Retrieves the CPU brand as a null-terminated ASCII string. - /// @param[out] input A 48 byte character array representing the brand. + /// Retrieves the CPU brand as a null-terminated ASCII string. + /// @param[out] input A 48 byte character array representing the brand. static void GetBrand(Char_8* input); static UInt_8 GetCacheLineSize(); + static UInt_32 GetFeatureBits_1(); + + static UInt_32 GetFeatureBits_2(); + + static UInt_32 GetExtFeatureBits_1(); + + static UInt_32 GetExtFeatureBits_2(); + + static UInt_32 GetExtFeatureBits_3(); + + private: + static bool RetrieveFPU(); + + static bool RetrieveVME(); + + static bool RetrieveDE(); + + static bool RetrievePSE(); + + static bool RetrieveTSC(); + + static bool RetrieveMSR(); + + static bool RetrievePAE(); + + static bool RetrieveMCE(); + + static bool RetrieveCX8(); + + static bool RetrieveAPIC(); + + static bool RetrieveSEP(); + + static bool RetrieveMTRR(); + + static bool RetrievePGE(); + + static bool RetrieveMCA(); + + static bool RetrieveCMOV(); + + static bool RetrievePAT(); + + static bool RetrievePSE_36(); + + static bool RetrievePSN(); + + static bool RetrieveCLFSH(); + + static bool RetrieveDS(); + + static bool RetrieveACPI(); + + static bool RetrieveMMX(); + + static bool RetrieveFXSR(); + + static bool RetrieveSSE(); + + static bool RetrieveSSE2(); + + static bool RetrieveSS(); + + static bool RetrieveHTT(); + + static bool RetrieveTM(); + + static bool RetrieveIA64(); + + static bool RetrievePBE(); + + static bool RetrieveSSE3(); + + static bool RetrievePCLMULQDQ(); + + static bool RetrieveDTES64(); + + static bool RetrieveMONITOR(); + + static bool RetrieveDS_CPL(); + + static bool RetrieveVMX(); + + static bool RetrieveSMX(); + + static bool RetrieveEST(); + + static bool RetrieveTM2(); + + static bool RetrieveSSSE3(); + + static bool RetrieveCNXT_ID(); + + static bool RetrieveSDBG(); + + static bool RetrieveFMA(); + + static bool RetrieveCX16(); + + static bool RetrieveXTPR(); + + static bool RetrievePDCM(); + + static bool RetrievePCID(); + + static bool RetrieveDCA(); + + static bool RetrieveSSE4_1(); + + static bool RetrieveSSE4_2(); + + static bool RetrieveX2APIC(); + + static bool RetrieveMOVBE(); + + static bool RetrievePOPCNT(); + + static bool RetrieveTSC_DEADLINE(); + + static bool RetrieveAES(); + + static bool RetrieveXSAVE(); + + static bool RetrieveOSXSAVE(); + + static bool RetrieveAVX(); + + static bool RetrieveF16C(); + + static bool RetrieveRDRND(); + + static bool RetrieveHYPERVISOR(); + + static bool RetrieveAVX2(); + + static bool RetrieveAVX512F(); + + static bool RetrieveRDSEED(); + + static bool RetrieveADX(); + //static Str_8 ToStr(); - private: + static UInt_64 RetrieveFreq_AARCH64(); + static UInt_64 RetrieveTSC_Freq(); static UInt_64 CalculateTSC_Freq(); diff --git a/include/ehs/system/System_LNX.h b/include/ehs/system/System_LNX.h index 144019c..c468697 100644 --- a/include/ehs/system/System_LNX.h +++ b/include/ehs/system/System_LNX.h @@ -8,7 +8,7 @@ namespace ehs class EHS_LIB_IO System : public BaseSystem { public: - static void OpenURI(const Str_8& uri); + static void OpenURI(Str_8 uri); static Str_8 OpenFileDialog(const Str_8 &dir, const Str_8 &filters); diff --git a/include/ehs/system/System_W32.h b/include/ehs/system/System_W32.h index 148aa20..9e814d0 100644 --- a/include/ehs/system/System_W32.h +++ b/include/ehs/system/System_W32.h @@ -7,6 +7,6 @@ namespace ehs class EHS_LIB_IO System : public BaseSystem { public: - static void OpenURI(const Str_8& uri); + static void OpenURI(Str_8 uri); }; } \ No newline at end of file diff --git a/src/Base64.cpp b/src/Base64.cpp index 0e07821..8235cbd 100644 --- a/src/Base64.cpp +++ b/src/Base64.cpp @@ -2,8 +2,36 @@ namespace ehs { - const char Base64::ascii[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - + Str_8 Base64::EncodeURL(const Str_8 &input) + { + UInt_64 input_length = input.Size(); + + // Calculate the output length + UInt_64 output_length = (input_length * 4 + 2) / 3; + + // Allocate memory for the output + Str_8 result(output_length); + + // Loop through the input and fill the output + for (int i = 0, j = 0; i < input_length;) { + + // Take first byte and shift right by 2 bits + UInt_32 octet_a = (UInt_8)input[i++]; + UInt_32 octet_b = i < input_length ? (UInt_8)input[i++] : 0; + UInt_32 octet_c = i < input_length ? (UInt_8)input[i++] : 0; + + UInt_32 triple = (octet_a << 16) + (octet_b << 8) + octet_c; + + // Encode the 24-bits into four 6-bits integers + result[j++] = asciiUrl[(triple >> 3 * 6) & 0x3F]; + result[j++] = asciiUrl[(triple >> 2 * 6) & 0x3F]; + result[j++] = asciiUrl[(triple >> 1 * 6) & 0x3F]; + result[j++] = asciiUrl[(triple >> 0 * 6) & 0x3F]; + } + + return result; + } + Str_8 Base64::Encode(const Str_8 &input) { UInt_64 input_length = input.Size(); @@ -18,9 +46,9 @@ namespace ehs for (int i = 0, j = 0; i < input_length;) { // Take first byte and shift right by 2 bits - UInt_32 octet_a = i < input_length ? input[i++] : 0; - UInt_32 octet_b = i < input_length ? input[i++] : 0; - UInt_32 octet_c = i < input_length ? input[i++] : 0; + UInt_32 octet_a = i < input_length ? (UInt_8)input[i++] : 0; + UInt_32 octet_b = i < input_length ? (UInt_8)input[i++] : 0; + UInt_32 octet_c = i < input_length ? (UInt_8)input[i++] : 0; UInt_32 triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; @@ -41,64 +69,152 @@ namespace ehs return result; } - - Str_8 Base64::Decode(const Str_8 &input) + + Str_8 Base64::DecodeURL(const Str_8 &input) { - UInt_64 in_len = input.Size(); - int i = 0; - int j = 0; - int in_ = 0; - char char_array_4[4], char_array_3[3]; - Str_8 ret; + Str_8 result(input.Size() * 3 / 4); - while (in_len-- && ( input[in_] != '=') && IsBase64(input[in_])) + UInt_64 remaining = input.Size(); + UInt_64 offsetIn = 0; + UInt_64 offsetOut = 0; + UInt_8 quartet[4]; + + while (remaining) { - char_array_4[i++] = input[in_]; in_++; - - if (i ==4) + if (remaining >= 4) { - for (i = 0; i <4; i++) - char_array_4[i] = Find(char_array_4[i]); + for (UInt_8 i = 0; i < 4; ++i) + { + if (!IsBase64URL(input[offsetIn + i])) + return {}; - char_array_3[0] = ( char_array_4[0] << 2 ) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + quartet[i] = FindURL(input[offsetIn + i]); + if (quartet[i] == EHS_UINT_8_MAX) + return {}; + } - for (i = 0; (i < 3); i++) - ret += char_array_3[i]; + result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[0] << 2) | (((UInt_8*)&quartet)[1] >> 4)); + result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[1] << 4) | (((UInt_8*)&quartet)[2] >> 2)); + result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[2] << 6) | ((UInt_8*)&quartet)[3]); - i = 0; + offsetIn += 4; + remaining -= 4; + } + else + { + for (UInt_8 i = 0; i < 4; ++i) + { + if (i < remaining) + { + if (!IsBase64URL(input[offsetIn + i])) + return {}; + + quartet[i] = FindURL(input[offsetIn + i]); + if (quartet[i] == EHS_UINT_8_MAX) + return {}; + } + else + quartet[i] = 0; + } + + result[offsetOut++] = (Char_8)((quartet[0] << 2) | (quartet[1] >> 4)); + + if (remaining == 3) + result[offsetOut++] = (Char_8)((quartet[1] << 4) | (quartet[2] >> 2)); + + offsetIn += remaining; + remaining = 0; } } - if (i) + return result; + } + + Str_8 Base64::Decode(const Str_8 &input) + { + Str_8 result(input.Size() * 3 / 4); + + UInt_64 remaining = input.Size(); + UInt_64 offsetIn = 0; + UInt_64 offsetOut = 0; + UInt_8 quartet[4]; + + while (remaining) { - for (j = 0; j < i; j++) - char_array_4[j] = Find(char_array_4[j]); + if (remaining >= 4) + { + for (UInt_8 i = 0; i < 4; ++i) + { + if (!IsBase64(input[offsetIn + i])) + return {}; - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + quartet[i] = Find(input[offsetIn + i]); + if (quartet[i] == EHS_UINT_8_MAX) + return {}; + } - for (j = 0; (j < i - 1); j++) - ret += char_array_3[j]; + result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[0] << 2) | (((UInt_8*)&quartet)[1] >> 4)); + result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[1] << 4) | (((UInt_8*)&quartet)[2] >> 2)); + result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[2] << 6) | ((UInt_8*)&quartet)[3]); + + offsetIn += 4; + remaining -= 4; + } + else + { + for (UInt_8 i = 0; i < 4; ++i) + { + if (i < remaining) + { + if (!IsBase64(input[offsetIn + i])) + return {}; + + quartet[i] = Find(input[offsetIn + i]); + if (quartet[i] == EHS_UINT_8_MAX) + return {}; + } + else + quartet[i] = 0; + } + + result[offsetOut++] = (Char_8)((quartet[0] << 2) | (quartet[1] >> 4)); + + if (remaining == 3) + result[offsetOut++] = (Char_8)((quartet[1] << 4) | (quartet[2] >> 2)); + + offsetIn += remaining; + remaining = 0; + } } - return ret; + return result; } - - char Base64::Find(const char c) + + UInt_8 Base64::FindURL(const UInt_8 &c) { - for (char i = 0; i < (char)sizeof(ascii); ++i) - { + for (UInt_8 i = 0; i < (UInt_8)sizeof(asciiUrl) - 1; ++i) + if (asciiUrl[i] == c) + return i; + + return EHS_UINT_8_MAX;; + } + + UInt_8 Base64::Find(const UInt_8 &c) + { + for (UInt_8 i = 0; i < (UInt_8)sizeof(ascii) - 1; ++i) if (ascii[i] == c) return i; - } return EHS_SINT_8_MAX; } - - bool Base64::IsBase64(const char c) + + bool Base64::IsBase64URL(const UInt_8 &c) { - return (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123) || (c == '+') || (c == '/'); + return (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123) || c == '-' || c == '_'; + } + + bool Base64::IsBase64(const UInt_8 &c) + { + return (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123) || c == '+' || c == '/'; } } \ No newline at end of file diff --git a/src/Log.cpp b/src/Log.cpp index 3436f87..bc3f5bf 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -75,12 +75,12 @@ namespace ehs { } - Log::Log(LogType type, const std::initializer_list &tags, const UInt_64 code, Str_8 msg) - : type(type), tags(tags.size()), code(code), msg((Str_8&&)msg) + Log::Log(LogType type, const Str_8 &tags, const UInt_64 code, Str_8 msg) + : type(type), code(code), msg((Str_8&&)msg) { - UInt_64 i = 0; - for (auto v = tags.begin(); v != tags.end(); ++v) - this->tags[i++] = *v; + const Vector tmpTags = tags.Split(", "); + + this->tags = Array(&tmpTags[0], tmpTags.Size()); } Log::Log(LogType type, Array tags, const UInt_64 code, Str_8 msg) diff --git a/src/Math.cpp b/src/Math.cpp index 790a04e..c876fef 100644 --- a/src/Math.cpp +++ b/src/Math.cpp @@ -36,9 +36,9 @@ namespace ehs double Math::Sqrt(const double from) { #if defined(EHS_ARCH_X64) - if (CPU::HasAVX()) + if (CPU::hasAVX) return Sqrt_AVX(from); - else if (CPU::HasSSE()) + else if (CPU::hasSSE) return Sqrt_SSE2(from); double temp = 0.0; @@ -51,7 +51,7 @@ namespace ehs } return result; - #elif defined(EHS_ARCH_ARM64) + #elif defined(EHS_ARCH_AARCH64) return Sqrt_VFP4(from); #endif } @@ -59,9 +59,9 @@ namespace ehs float Math::Sqrt(const float from) { #if defined(EHS_ARCH_X64) - if (CPU::HasAVX()) + if (CPU::hasAVX) return Sqrt_AVX(from); - else if (CPU::HasSSE()) + else if (CPU::hasSSE) return Sqrt_SSE(from); float temp = 0.0f; @@ -74,7 +74,7 @@ namespace ehs } return result; - #elif defined(EHS_ARCH_ARM64) + #elif defined(EHS_ARCH_AARCH64) return Sqrt_VFP4(from); #endif } diff --git a/src/SHA256.cpp b/src/SHA256.cpp new file mode 100644 index 0000000..4fb52ff --- /dev/null +++ b/src/SHA256.cpp @@ -0,0 +1,209 @@ +#include "ehs/SHA256.h" + +#include "ehs/Util.h" + +namespace ehs +{ + UInt_32 SHA256::ROTR(const UInt_32 x, const UInt_32 n) + { + return (x >> n) | (x << (32 - n)); + } + + UInt_32 SHA256::CH(const UInt_32 x, const UInt_32 y, const UInt_32 z) + { + return (x & y) ^ (~x & z); + } + + UInt_32 SHA256::MAJ(const UInt_32 x, const UInt_32 y, const UInt_32 z) + { + return (x & y) ^ (x & z) ^ (y & z); + } + + UInt_32 SHA256::EP0(const UInt_32 x) + { + return ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22); + } + + UInt_32 SHA256::EP1(const UInt_32 x) + { + return ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25); + } + + UInt_32 SHA256::SIG0(const UInt_32 x) + { + return ROTR(x, 7) ^ ROTR(x, 18) ^ (x >> 3); + } + + UInt_32 SHA256::SIG1(const UInt_32 x) + { + return ROTR(x,17) ^ ROTR(x, 19) ^ (x >> 10); + } + + SHA256::SHA256() + : state{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}, + bitLen(0), data{}, dataLen(0) + { + } + + SHA256::SHA256(SHA256&& other) noexcept + : state{}, bitLen(0), data{}, dataLen(0) + { + Util::Copy(state, other.state, sizeof(state) / sizeof(UInt_32)); + bitLen = other.bitLen; + Util::Copy(data, other.data, sizeof(data)); + dataLen = other.dataLen; + + Util::Zero(other.state, sizeof(state) / sizeof(UInt_32)); + other.bitLen = 0; + Util::Zero(other.data, sizeof(data)); + other.dataLen = 0; + } + + SHA256::SHA256(const SHA256& other) + : state{}, bitLen(0), data{}, dataLen(0) + { + Util::Copy(state, other.state, sizeof(state) / sizeof(UInt_32)); + bitLen = other.bitLen; + Util::Copy(data, other.data, sizeof(data)); + dataLen = other.dataLen; + } + + SHA256& SHA256::operator=(SHA256&& other) noexcept + { + if (this == &other) + return *this; + + Util::Copy(state, other.state, sizeof(state) / sizeof(UInt_32)); + bitLen = other.bitLen; + Util::Copy(data, other.data, sizeof(data)); + dataLen = other.dataLen; + + Util::Zero(other.state, sizeof(state) / sizeof(UInt_32)); + other.bitLen = 0; + Util::Zero(other.data, sizeof(data)); + other.dataLen = 0; + + return *this; + } + + SHA256& SHA256::operator=(const SHA256& other) + { + if (this == &other) + return *this; + + Util::Copy(state, other.state, sizeof(state) / sizeof(UInt_32)); + bitLen = other.bitLen; + Util::Copy(data, other.data, sizeof(data)); + dataLen = other.dataLen; + + return *this; + } + + void SHA256::Update(const Byte* data, const UInt_64 len) + { + for(UInt_64 i = 0; i < len; ++i) + { + this->data[dataLen++] = data[i]; + + if(dataLen == 64) + { + Transform(this->data); + bitLen += 512; + dataLen = 0; + } + } + } + + void SHA256::Final(Byte hash[32]) + { + UInt_32 i = dataLen; + + /* Pad */ + data[i++] = 0x80; + if(i > 56) + { + while(i < 64) + data[i++] = 0x00; + + Transform(data); + + i = 0; + } + + while(i < 56) + data[i++] = 0x00; + + /* Length in bits */ + bitLen += dataLen * 8ULL; + data[63] = bitLen; + data[62] = bitLen >> 8; + data[61] = bitLen >> 16; + data[60] = bitLen >> 24; + data[59] = bitLen >> 32; + data[58] = bitLen >> 40; + data[57] = bitLen >> 48; + data[56] = bitLen >> 56; + Transform(data); + + /* big‑endian output */ + for(i = 0; i < 4; ++i) { + hash[i] = (state[0] >> (24 - i * 8)) & 0xff; + hash[i + 4] = (state[1] >> (24 - i * 8)) & 0xff; + hash[i + 8] = (state[2] >> (24 - i * 8)) & 0xff; + hash[i + 12] = (state[3] >> (24 - i * 8)) & 0xff; + hash[i + 16] = (state[4] >> (24 - i * 8)) & 0xff; + hash[i + 20] = (state[5] >> (24 - i * 8)) & 0xff; + hash[i + 24] = (state[6] >> (24 - i * 8)) & 0xff; + hash[i + 28] = (state[7] >> (24 - i * 8)) & 0xff; + } + } + + void SHA256::Hash(const Byte* data, const UInt_64 len, Byte hash[32]) + { + Update(data, len); + Final(hash); + } + + void SHA256::Transform(const Byte data[64]) + { + UInt_32 m[64]; + UInt_32 a = state[0]; + UInt_32 b = state[1]; + UInt_32 c = state[2]; + UInt_32 d = state[3]; + UInt_32 e = state[4]; + UInt_32 f = state[5]; + UInt_32 g = state[6]; + UInt_32 h = state[7]; + UInt_32 i, t1, t2; + + for (i = 0; i < 16; ++i) + m[i] = (UInt_32)data[i * 4] << 24 | (UInt_32)data[i * 4 + 1] << 16 | (UInt_32)data[i * 4 + 2] << 8 | (UInt_32)data[i * 4 + 3]; + + for (; i < 64; ++i) + m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; + + for(i = 0; i < 64; ++i) + { + t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; + t2 = EP0(a) + MAJ(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + } +} diff --git a/src/Util.cpp b/src/Util.cpp index 6274956..dcbbe4c 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -1,5 +1,9 @@ #include "ehs/Util.h" +#include "ehs/system/CPU.h" +#include "ehs/system/AVX2.h" +#include "ehs/system/AVX512.h" + namespace ehs { bool Util::Compare(const void* const a, const void* const b, const UInt_64 size) @@ -118,4 +122,4 @@ namespace ehs remainder = size - i; } } -} \ No newline at end of file +} diff --git a/src/io/Console.cpp b/src/io/Console.cpp index 85b088c..ffdf552 100644 --- a/src/io/Console.cpp +++ b/src/io/Console.cpp @@ -693,7 +693,7 @@ namespace ehs Vector Console::GetArgs_32(const UInt_64 bufferSize) { #if defined(EHS_OS_WINDOWS) - return UTF::To_32(GetCommandLineW()).Split(U" "); + return UTF::To_32(GetCommandLineW()).ParseArgs(); #elif defined(EHS_OS_LINUX) File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN); Array data = cmdFile.ReadArray(bufferSize); @@ -725,7 +725,7 @@ namespace ehs Vector Console::GetArgs_16(const UInt_64 bufferSize) { #if defined(EHS_OS_WINDOWS) - return Str_16(GetCommandLineW()).Split(L" "); + return Str_16(GetCommandLineW()).ParseArgs(); #elif defined(EHS_OS_LINUX) File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN); Array data = cmdFile.ReadArray(bufferSize); @@ -755,7 +755,7 @@ namespace ehs Vector Console::GetArgs_8(const UInt_64 bufferSize) { #if defined(EHS_OS_WINDOWS) - return UTF::To_8(GetCommandLineW()).Split(" "); + return UTF::To_8(GetCommandLineW()).ParseArgs(); #elif defined(EHS_OS_LINUX) File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN); Array data = cmdFile.ReadArray(bufferSize); diff --git a/src/io/audio/AudioDevice_PW.cpp b/src/io/audio/AudioDevice_PW.cpp index 9e1071e..efbadec 100644 --- a/src/io/audio/AudioDevice_PW.cpp +++ b/src/io/audio/AudioDevice_PW.cpp @@ -93,13 +93,13 @@ namespace ehs } AudioDevice::AudioDevice() - : id(0), loop(nullptr), context(nullptr), core(nullptr), input(nullptr), output(nullptr) + : id(0), loop(nullptr), context(nullptr), core(nullptr), input(nullptr), output(nullptr), paramsHook{} { } AudioDevice::AudioDevice(AudioDevice&& device) noexcept : BaseAudioDevice(device), id(device.id), name((Str_8 &&)device.name), loop(device.loop), - context(device.context), core(device.core), input(device.input), output(device.output) + context(device.context), core(device.core), input(device.input), output(device.output), paramsHook(device.paramsHook) { device.id = 0; device.loop = nullptr; @@ -107,11 +107,12 @@ namespace ehs device.core = nullptr; device.input = nullptr; device.output = nullptr; + device.paramsHook = {}; } AudioDevice::AudioDevice(const AudioDevice& device) : BaseAudioDevice(device), id(device.id), name(device.name), loop(nullptr), context(nullptr), core(nullptr), - input(nullptr), output(nullptr) + input(nullptr), output(nullptr), paramsHook{} { } @@ -129,6 +130,7 @@ namespace ehs core = device.core; input = device.input; output = device.output; + paramsHook = device.paramsHook; device.id = 0; device.loop = nullptr; @@ -136,6 +138,7 @@ namespace ehs device.core = nullptr; device.input = nullptr; device.output = nullptr; + device.paramsHook = {}; return *this; } @@ -154,6 +157,7 @@ namespace ehs core = nullptr; input = nullptr; output = nullptr; + paramsHook = {}; return *this; } @@ -206,14 +210,18 @@ namespace ehs return; } - pw_stream_connect( - output, + SInt_32 err = pw_stream_connect( + input, PW_DIRECTION_INPUT, id, (pw_stream_flags)(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS), pod, 1 ); + if (err) + { + EHS_LOG_INT(LogType::ERR, 2, "Failed to connect input stream for audio device."); + } } if (GetType() == AudioDeviceType::OUTPUT || GetType() == AudioDeviceType::ALL) @@ -225,7 +233,7 @@ namespace ehs return; } - pw_stream_connect( + SInt_32 err = pw_stream_connect( output, PW_DIRECTION_OUTPUT, id, @@ -233,6 +241,10 @@ namespace ehs pod, 1 ); + if (err) + { + EHS_LOG_INT(LogType::ERR, 2, "Failed to connect output stream for audio device."); + } } static constexpr pw_stream_events streamEvents = { @@ -240,8 +252,17 @@ namespace ehs .param_changed = OnParamChanged }; - spa_hook streamListener = {}; - pw_stream_add_listener(output, &streamListener, &streamEvents, this); + pw_stream_add_listener(output, ¶msHook, &streamEvents, this); + + while (pw_stream_get_state(output, nullptr) == PW_STREAM_STATE_CONNECTING) + { + SInt_32 err = pw_loop_iterate(loop, 0); + if (err < 0) + { + EHS_LOG_INT(LogType::ERR, 3, "Failed to update audio with error #" + Str_8::FromNum(err) + "."); + return; + } + } EHS_LOG_SUCCESS(); } @@ -283,7 +304,15 @@ namespace ehs return 0; } - pw_loop_iterate(loop, 0); + if (!data || !size) + return 0; + + SInt_32 err = pw_loop_iterate(loop, 0); + if (err < 0) + { + EHS_LOG_INT(LogType::ERR, 1, "Failed to update audio with error #" + Str_8::FromNum(err) + "."); + return 0; + } if (pw_stream_get_state(output, nullptr) != PW_STREAM_STATE_STREAMING) return 0; diff --git a/src/io/socket/BaseTCP.cpp b/src/io/socket/BaseTCP.cpp index 61320e3..2866781 100644 --- a/src/io/socket/BaseTCP.cpp +++ b/src/io/socket/BaseTCP.cpp @@ -108,7 +108,7 @@ namespace ehs if (!IsValid()) return; - req.AddToHeader("Host", remoteHostName); + req.AddHeaderVar({"Host", remoteHostName}); SendStr(req.FormResult()); } @@ -124,10 +124,10 @@ namespace ehs Response response(header); - Str_8 encoding = response.GetHeader("Transfer-Encoding"); + Str_8 encoding = response.GetHeaderValue("Transfer-Encoding"); if (!encoding.Size()) { - int bodySize = response.GetHeader("content-length").ToDecimal(); + int bodySize = response.GetHeaderValue("content-length").ToDecimal(); if (!bodySize) return response; @@ -163,10 +163,10 @@ namespace ehs if (request.GetVerb() == Verb::GET) return request; - Str_8 encoding = request.GetHeader("Transfer-Encoding"); + Str_8 encoding = request.GetHeaderValue("Transfer-Encoding"); if (!encoding.Size()) { - int bodySize = request.GetHeader("Content-Length").ToDecimal(); + int bodySize = request.GetHeaderValue("Content-Length").ToDecimal(); if (!bodySize) return request; diff --git a/src/io/socket/HeaderVar.cpp b/src/io/socket/HeaderVar.cpp new file mode 100644 index 0000000..732bc82 --- /dev/null +++ b/src/io/socket/HeaderVar.cpp @@ -0,0 +1,96 @@ +#include "ehs/io/socket/HeaderVar.h" + +namespace ehs +{ + HeaderVar::HeaderVar() + : id(0) + { + } + + HeaderVar::HeaderVar(Str_8 name, Str_8 value) + : id(name.Hash_64()), name((Str_8 &&)name), value((Str_8 &&)value) + { + } + + HeaderVar::HeaderVar(HeaderVar&& other) noexcept + : id(other.id), name((Str_8 &&)other.name), value((Str_8 &&)other.value) + { + other.id = 0; + } + + HeaderVar::HeaderVar(const HeaderVar& other) + : id(other.id), name(other.name), value(other.value) + { + } + + HeaderVar& HeaderVar::operator=(HeaderVar&& other) noexcept + { + if (this == &other) + return *this; + + id = other.id; + name = (Str_8 &&)other.name; + value = (Str_8 &&)other.value; + + other.id = 0; + + return *this; + } + + HeaderVar& HeaderVar::operator=(const HeaderVar& other) + { + if (this == &other) + return *this; + + id = other.id; + name = other.name; + value = other.value; + + return *this; + } + + bool HeaderVar::operator==(const HeaderVar& other) const + { + return id == other.id; + } + + bool HeaderVar::operator!=(const HeaderVar& other) const + { + return id != other.id; + } + + bool HeaderVar::operator==(const UInt_64& otherId) const + { + return id == otherId; + } + + bool HeaderVar::operator!=(const UInt_64& otherId) const + { + return id != otherId; + } + + UInt_64 HeaderVar::GetId() const + { + return id; + } + + Str_8 HeaderVar::GetName() const + { + return name; + } + + Str_8 HeaderVar::GetValue() const + { + return value; + } + + void HeaderVar::SetValue(Str_8 value) + { + this->value = (Str_8 &&)value; + } + + Str_8 HeaderVar::ToStr() const + { + return name + ": " + value; + } +} diff --git a/src/io/socket/QueryVar.cpp b/src/io/socket/QueryVar.cpp new file mode 100644 index 0000000..7947b79 --- /dev/null +++ b/src/io/socket/QueryVar.cpp @@ -0,0 +1,96 @@ +#include "ehs/io/socket/QueryVar.h" + +namespace ehs +{ + QueryVar::QueryVar() + : id(0) + { + } + + QueryVar::QueryVar(Str_8 name, Str_8 value) + : id(name.Hash_64()), name((Str_8 &&)name), value((Str_8 &&)value) + { + } + + QueryVar::QueryVar(QueryVar&& other) noexcept + : id(other.id), name((Str_8 &&)other.name), value((Str_8 &&)other.value) + { + other.id = 0; + } + + QueryVar::QueryVar(const QueryVar& other) + : id(other.id), name(other.name), value(other.value) + { + } + + QueryVar& QueryVar::operator=(QueryVar&& other) noexcept + { + if (this == &other) + return *this; + + id = other.id; + name = (Str_8 &&)other.name; + value = (Str_8 &&)other.value; + + other.id = 0; + + return *this; + } + + QueryVar& QueryVar::operator=(const QueryVar& other) + { + if (this == &other) + return *this; + + id = other.id; + name = other.name; + value = other.value; + + return *this; + } + + bool QueryVar::operator==(const QueryVar& other) const + { + return id == other.id; + } + + bool QueryVar::operator!=(const QueryVar& other) const + { + return id != other.id; + } + + bool QueryVar::operator==(const UInt_64& otherId) const + { + return id == otherId; + } + + bool QueryVar::operator!=(const UInt_64& otherId) const + { + return id != otherId; + } + + UInt_64 QueryVar::GetId() const + { + return id; + } + + Str_8 QueryVar::GetName() const + { + return name; + } + + Str_8 QueryVar::GetValue() const + { + return value; + } + + void QueryVar::SetValue(Str_8 value) + { + this->value = (Str_8 &&)value; + } + + Str_8 QueryVar::ToStr() const + { + return name + "=" + value; + } +} diff --git a/src/io/socket/Request.cpp b/src/io/socket/Request.cpp index c61c7eb..6949a25 100644 --- a/src/io/socket/Request.cpp +++ b/src/io/socket/Request.cpp @@ -4,38 +4,70 @@ namespace ehs { Request::Request() - : verb(Verb::GET), cType(ContentType::NONE) + : verb(Verb::POST), cType(ContentType::NONE) { } - Request::Request(const Verb verb, const Str_8& rsrc) - : verb(verb), rsrc(rsrc), cType(ContentType::NONE) + Request::Request(const Verb &verb, Str_8 rsrc) + : verb(verb), rsrc((Str_8 &&)rsrc), cType(ContentType::NONE) { } - Request::Request(const char* data, const UInt_64 size) + Request::Request(const char *data, const UInt_64 &size) : verb(Verb::POST), cType(ContentType::NONE) { ReadData(Str_8(data, size)); } - Request::Request(const Str_8& data) + Request::Request(const Str_8 &data) : verb(Verb::POST), cType(ContentType::NONE) { ReadData(data); } - - Request& Request::operator=(const Request &req) + + Request::Request(Request&& other) noexcept + : verb(other.verb), rsrc((Str_8 &&)other.rsrc), queries((Vector &&)other.queries), + header((Vector &&)other.header), cType(other.cType), body((Str_8 &&)other.body) { - if (this == &req) + other.verb = Verb::POST; + other.cType = ContentType::NONE; + } + + Request::Request(const Request& other) + : verb(other.verb), rsrc(other.rsrc), queries(other.queries), header(other.header), cType(other.cType), + body(other.body) + { + } + + Request& Request::operator=(Request&& other) noexcept + { + if (this == &other) + return *this; + + verb = other.verb; + rsrc = (Str_8 &&)other.rsrc; + queries = (Vector &&)other.queries; + header = (Vector &&)other.header; + cType = other.cType; + body = (Str_8 &&)other.body; + + other.verb = Verb::POST; + other.cType = ContentType::NONE; + + return* this; + } + + Request& Request::operator=(const Request &other) + { + if (this == &other) return *this; - verb = req.verb; - rsrc = req.rsrc; - queries = req.queries; - header = req.header; - cType = req.cType; - body = req.body; + verb = other.verb; + rsrc = other.rsrc; + queries = other.queries; + header = other.header; + cType = other.cType; + body = other.body; return* this; } @@ -45,7 +77,7 @@ namespace ehs return verb; } - void Request::SetContentType(const ContentType cType) + void Request::SetContentType(const ContentType &cType) { if (body.Size()) body.Resize(0); @@ -58,9 +90,9 @@ namespace ehs return cType; } - void Request::SetResource(const Str_8& rsrc) + void Request::SetResource(Str_8 rsrc) { - this->rsrc = rsrc; + this->rsrc = (Str_8 &&)rsrc; } Str_8 Request::GetResource() const @@ -68,69 +100,179 @@ namespace ehs return rsrc; } - void Request::AddQuery(const Str_8& var, const Str_8& value) + bool Request::HasQueryVar(const UInt_64& id) const { - queries.Push(var + "=" + value); + for (UInt_64 i = 0; i < queries.Size(); ++i) + if (queries[i] == id) + return true; + + return false; } - Str_8 Request::GetQuery(const Str_8& var) + bool Request::HasQueryVar(const Str_8& name) const + { + return HasQueryVar(name.Hash_64()); + } + + bool Request::AddQueryVar(QueryVar var) + { + if (HasQueryVar(var.GetId())) + return false; + + queries.Push((QueryVar &&)var); + + return true; + } + + bool Request::RemoveQueryVar(const UInt_64& id) { for (UInt_64 i = 0; i < queries.Size(); ++i) { - Vector data = queries[i].Split("="); + if (queries[i] != id) + continue; - if (data[0] == var) - return data[1]; + queries.Swap(i, queries.End()); + queries.Pop(); + + return true; } - return ""; + return false; } - Vector Request::GetQueries() const + bool Request::RemoveQueryVar(const Str_8& name) + { + return RemoveQueryVar(name.Hash_64()); + } + + QueryVar *Request::GetQueryVar(const UInt_64& id) const + { + for (UInt_64 i = 0; i < queries.Size(); ++i) + if (queries[i] == id) + return &queries[i]; + + return nullptr; + } + + QueryVar *Request::GetQueryVar(const Str_8& name) const + { + return GetQueryVar(name.Hash_64()); + } + + Str_8 Request::GetQueryValue(const UInt_64& id) const + { + for (UInt_64 i = 0; i < queries.Size(); ++i) + if (queries[i] == id) + return queries[i].GetValue(); + + return {}; + } + + Str_8 Request::GetQueryValue(const Str_8& name) const + { + return GetQueryValue(name.Hash_64()); + } + + Vector Request::GetQueries() const { return queries; } void Request::BasicAuth(const Str_8& id, const Str_8& secret) { - AddToHeader("Authorization", Str_8("Basic ") + Base64::Encode(id + ":" + secret)); + AddHeaderVar({"Authorization", Str_8("Basic ") + Base64::Encode(id + ":" + secret)}); } void Request::BearerAuth(const Str_8& token) { - AddToHeader("Authorization", "Bearer " + token); + AddHeaderVar({"Authorization", "Bearer " + token}); } void Request::BearerAuth(const Str_8& token, const Str_8& clientId) { - AddToHeader("Authorization", "Bearer " + token); - AddToHeader("Client-Id", clientId); + AddHeaderVar({"Authorization", "Bearer " + token}); + AddHeaderVar({"Client-Id", clientId}); } void Request::BotAuth(const Str_8& token) { - AddToHeader("Authorization", "Bot " + token); - } - - void Request::AddToHeader(const Str_8& var, const Str_8& value) - { - header.Push(var + ": " + value); + AddHeaderVar({"Authorization", "Bot " + token}); } - Str_8 Request::GetHeader(const Str_8& var) const + bool Request::HasHeaderVar(const UInt_64& id) const + { + for (UInt_64 i = 0; i < header.Size(); ++i) + if (header[i] == id) + return true; + + return false; + } + + bool Request::HasHeaderVar(const Str_8& name) const + { + return HasHeaderVar(name.Hash_64()); + } + + bool Request::AddHeaderVar(HeaderVar var) + { + if (HasHeaderVar(var.GetId())) + return false; + + header.Push((HeaderVar &&)var); + + return true; + } + + bool Request::RemoveHeaderVar(const UInt_64 &id) { for (UInt_64 i = 0; i < header.Size(); ++i) { - Vector data = header[i].Split(": "); + if (header[i] != id) + continue; - if (data[0] == var) - return data[1]; + header.Swap(i, header.End()); + header.Pop(); + + return true; } - return ""; + return false; } - - Vector Request::GetHeader() const + + bool Request::RemoveHeaderVar(const Str_8 &name) + { + return RemoveHeaderVar(name.Hash_64()); + } + + HeaderVar *Request::GetHeaderVar(const UInt_64 &id) const + { + for (UInt_64 i = 0; i < header.Size(); ++i) + if (header[i] == id) + return &header[i]; + + return nullptr; + } + + HeaderVar *Request::GetHeaderVar(const Str_8 &name) const + { + return GetHeaderVar(name.Hash_64()); + } + + Str_8 Request::GetHeaderValue(const UInt_64 &id) const + { + for (UInt_64 i = 0; i < header.Size(); ++i) + if (header[i] == id) + return header[i].GetValue(); + + return {}; + } + + Str_8 Request::GetHeaderValue(const Str_8 &name) const + { + return GetHeaderValue(name.Hash_64()); + } + + Vector Request::GetHeader() const { return header; } @@ -200,16 +342,20 @@ namespace ehs Str_8 result = VerbToStr(verb) + " " + rsrc; if (queries.Size()) - result += "?" + queries[0]; + result += "?" + queries[0].ToStr(); for (UInt_64 i = 1; i < queries.Size(); ++i) - result += "&" + queries[i]; + result += "&" + queries[i].ToStr(); result += " HTTP/1.1\r\n"; for (UInt_64 i = 0; i < header.Size(); ++i) { - result += header[i] + "\r\n"; + if (header[i] == 11245195881701120957ull || header[i] == 6556302699635904946ull || + header[i] == 13347276190653935221ull) // Content-Length, Server, and Content-Type in order from left to right. + continue; + + result += header[i].ToStr() + "\r\n"; } result += "Content-Type: " + ContentTypeToStr(cType) + "\r\n"; @@ -227,7 +373,7 @@ namespace ehs return rsrc.Size() || queries.Size() || header.Size() || body.Size(); } - Str_8 Request::VerbToStr(const Verb verb) + Str_8 Request::VerbToStr(const Verb &verb) { switch (verb) { @@ -244,7 +390,7 @@ namespace ehs } } - Str_8 Request::ContentTypeToStr(const ContentType cType) + Str_8 Request::ContentTypeToStr(const ContentType &cType) { switch (cType) { @@ -262,14 +408,18 @@ namespace ehs return "text/plain"; case ContentType::TEXT_HTML: return "text/html"; + case ContentType::TEXT_CSS: + return "text/css"; case ContentType::TEXT_XML: return "text/xml"; + case ContentType::IMG_X_ICON: + return "image/x-icon"; default: return ""; } } - ContentType Request::StrToContentType(const Str_8& value) + ContentType Request::StrToContentType(const Str_8 &value) { if (value == "multipart/form-data") return ContentType::APP_MULTIPART_FORMDATA; @@ -285,13 +435,17 @@ namespace ehs return ContentType::TEXT_PLAIN; else if (value == "text/html") return ContentType::TEXT_HTML; + else if (value == "text/css") + return ContentType::TEXT_CSS; else if (value == "text/xml") return ContentType::TEXT_XML; + else if (value == "image/x-icon") + return ContentType::IMG_X_ICON; else return ContentType::NONE; } - void Request::ReadData(const Str_8& data) + void Request::ReadData(const Str_8 &data) { Vector lines = data.Split("\r\n"); Vector meta = lines[0].Split(" "); @@ -308,7 +462,14 @@ namespace ehs { rsrc = meta[1].Sub(0, queryIndex); cType = ContentType::APP_FORMURLENCODED; - queries = meta[1].Sub(queryIndex + 1).Split("&"); + + Vector strQueries = meta[1].Sub(queryIndex + 1).Split("&"); + for (UInt_64 i = 0; i < strQueries.Size(); ++i) + { + const Vector queryVar = strQueries[i].Split("="); + + queries.Push({queryVar[0], queryVar[1]}); + } } else { @@ -331,7 +492,9 @@ namespace ehs if (var[0] == "Content-Length") continue; - header.Push(lines[i]); + Vector headerVar = lines[i].Split(": "); + + header.Push({headerVar[0], headerVar[1]}); } } } \ No newline at end of file diff --git a/src/io/socket/Response.cpp b/src/io/socket/Response.cpp index c5065dd..bf7bc3f 100644 --- a/src/io/socket/Response.cpp +++ b/src/io/socket/Response.cpp @@ -2,43 +2,73 @@ namespace ehs { - Response::Response(const UInt_32 code, const Str_8& server) - : code(code), server(server), cType(ContentType::NONE) - { - } - - Response::Response(const char* data, const UInt_64 size) - : code(0), cType(ContentType::NONE) - { - ReadData(Str_8(data, size)); - } - - Response::Response(const Str_8& data) - : code(0), cType(ContentType::NONE) - { - ReadData(data); - } - Response::Response() : code(0), cType(ContentType::NONE) { } - Response& Response::operator=(const Response& res) + Response::Response(const UInt_32 &code, Str_8 server) + : code(code), server((Str_8 &&)server), cType(ContentType::NONE) { - if (this == &res) - return *this; + } - code = res.code; - server = res.server; - cType = res.cType; - header = res.header; - body = res.body; + Response::Response(const char *data, const UInt_64 &size) + : code(0), cType(ContentType::NONE) + { + ReadData(Str_8(data, size)); + } + + Response::Response(const Str_8 &data) + : code(0), cType(ContentType::NONE) + { + ReadData(data); + } + + Response::Response(Response&& other) noexcept + : code(other.code), server((Str_8 &&)other.server), cType(other.cType), header((Vector &&)other.header), + body((Str_8 &&)other.body) + { + other.code = 0; + other.cType = ContentType::NONE; + } + + Response::Response(const Response &other) + : code(other.code), server(other.server), cType(other.cType), header(other.header), body(other.body) + { + } + + Response& Response::operator=(Response&& other) noexcept + { + if (this == &other) + return *this; + + code = other.code; + server = (Str_8 &&)other.server; + cType = other.cType; + header = (Vector &&)other.header; + body = (Str_8 &&)other.body; + + other.code = 0; + other.cType = ContentType::NONE; return *this; } - void Response::SetCode(const UInt_32 code) + Response& Response::operator=(const Response& other) + { + if (this == &other) + return *this; + + code = other.code; + server = other.server; + cType = other.cType; + header = other.header; + body = other.body; + + return *this; + } + + void Response::SetCode(const UInt_32 &code) { this->code = code; } @@ -48,9 +78,9 @@ namespace ehs return code; } - void Response::SetServer(const Str_8& server) + void Response::SetServer(Str_8 server) { - this->server = server; + this->server = (Str_8 &&)server; } Str_8 Response::GetServer() const @@ -58,7 +88,7 @@ namespace ehs return server; } - void Response::SetContentType(const ContentType cType) + void Response::SetContentType(const ContentType &cType) { this->cType = cType; } @@ -68,27 +98,80 @@ namespace ehs return cType; } - void Response::AddToHeader(const Str_8& var, const Str_8& value) + bool Response::HasHeaderVar(const UInt_64& id) const { - header.Push(var + ": " + value); + for (UInt_64 i = 0; i < header.Size(); ++i) + if (header[i] == id) + return true; + + return false; } - Str_8 Response::GetHeader(const Str_8& var) const + bool Response::HasHeaderVar(const Str_8& name) const { - Str_8 lIdentity = var.GetLower(); + return HasHeaderVar(name.Hash_64()); + } + bool Response::AddHeaderVar(HeaderVar var) + { + if (HasHeaderVar(var.GetId())) + return false; + + header.Push((HeaderVar &&)var); + + return true; + } + + bool Response::RemoveHeaderVar(const UInt_64& id) + { for (UInt_64 i = 0; i < header.Size(); ++i) { - Vector data = header[i].Split(": "); + if (header[i] != id) + continue; - if (data[0].GetLower() == lIdentity) - return data[1]; + header.Swap(i, header.End()); + header.Pop(); + + return true; } - return ""; + return false; } - Vector Response::GetHeader() const + bool Response::RemoveHeaderVar(const Str_8& name) + { + return RemoveHeaderVar(name.Hash_64()); + } + + HeaderVar* Response::GetHeaderVar(const UInt_64 &id) const + { + for (UInt_64 i = 0; i < header.Size(); ++i) + if (header[i] == id) + return &header[i]; + + return nullptr; + } + + HeaderVar *Response::GetHeaderVar(const Str_8 &name) const + { + return GetHeaderVar(name.Hash_64()); + } + + Str_8 Response::GetHeaderValue(const UInt_64& id) const + { + for (UInt_64 i = 0; i < header.Size(); ++i) + if (header[i] == id) + return header[i].GetValue(); + + return {}; + } + + Str_8 Response::GetHeaderValue(const Str_8& name) const + { + return GetHeaderValue(name.Hash_64()); + } + + Vector Response::GetHeader() const { return header; } @@ -159,14 +242,11 @@ namespace ehs for (UInt_64 i = 0; i < header.Size(); ++i) { - if (header[i].Find("Content-Length", nullptr, SearchPattern::LEFT_RIGHT, IndexResult::ENDING)) - continue; - else if (header[i].Find("Server", nullptr, SearchPattern::LEFT_RIGHT, IndexResult::ENDING)) - continue; - else if (header[i].Find("Content-Type", nullptr, SearchPattern::LEFT_RIGHT, IndexResult::ENDING)) + if (header[i] == 11245195881701120957ull || header[i] == 6556302699635904946ull || + header[i] == 13347276190653935221ull) // Content-Length, Server, and Content-Type in order from left to right. continue; - result += header[i] + "\r\n"; + result += header[i].ToStr() + "\r\n"; } result += "Content-Type: " + ContentTypeToStr(cType) + "\r\nContent-Length: " + Str_8::FromNum(body.Size()) + "\r\n\r\n" + body; @@ -179,7 +259,7 @@ namespace ehs return server.Size() || header.Size() || body.Size(); } - Str_8 Response::CodeToStr(const UInt_32 code) + Str_8 Response::CodeToStr(const UInt_32 &code) { if (code == 100) return "Continue"; @@ -323,7 +403,7 @@ namespace ehs return "Unused Status Code"; } - Str_8 Response::ContentTypeToStr(const ContentType cType) + Str_8 Response::ContentTypeToStr(const ContentType &cType) { switch (cType) { @@ -341,14 +421,18 @@ namespace ehs return "text/plain"; case ContentType::TEXT_HTML: return "text/html"; + case ContentType::TEXT_CSS: + return "text/css"; case ContentType::TEXT_XML: return "text/xml"; + case ContentType::IMG_X_ICON: + return "image/x-icon"; default: return ""; } } - ContentType Response::StrToContentType(const Str_8& value) + ContentType Response::StrToContentType(const Str_8 &value) { if (value == "multipart/form-data") return ContentType::APP_MULTIPART_FORMDATA; @@ -364,13 +448,17 @@ namespace ehs return ContentType::TEXT_PLAIN; else if (value == "text/html") return ContentType::TEXT_HTML; + else if (value == "text/css") + return ContentType::TEXT_CSS; else if (value == "text/xml") return ContentType::TEXT_XML; + else if (value == "image/x-icon") + return ContentType::IMG_X_ICON; else return ContentType::NONE; } - void Response::ReadData(const Str_8& data) + void Response::ReadData(const Str_8 &data) { Vector lines = data.Split("\r\n"); Vector meta = lines[0].Split(" "); @@ -384,12 +472,12 @@ namespace ehs Vector var = lines[i].Split(": "); - if (var[0].GetLower() == "server") + if (var[0] == "Server") { server = var[1]; continue; } - else if (var[0].GetLower() == "content-type") + else if (var[0] == "Content-Type") { Vector ctData = var[1].Split(";"); @@ -397,7 +485,9 @@ namespace ehs continue; } - header.Push(lines[i]); + Vector headerVar = lines[i].Split(": "); + + header.Push({headerVar[0], headerVar[1]}); } } } \ No newline at end of file diff --git a/src/io/socket/SSL.cpp b/src/io/socket/SSL.cpp index 87de809..3e57eac 100644 --- a/src/io/socket/SSL.cpp +++ b/src/io/socket/SSL.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include namespace ehs { @@ -12,6 +14,11 @@ namespace ehs if (!IsValid()) return; + EVP_PKEY_free(pkey); + + X509_free(cert); + + if (sslHdl) { if (connection) @@ -25,28 +32,28 @@ namespace ehs } SSL::SSL() - : ctx(nullptr), sslHdl(nullptr) + : server(false), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr) { } - SSL::SSL(const IP type) - : TCP(type), ctx(nullptr), sslHdl(nullptr) + SSL::SSL(const IP &type, const bool &server) + : TCP(type), server(server), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr) { SSL::Initialize(); } SSL::SSL(TCP&& tcp) noexcept - : TCP(std::move(tcp)), ctx(nullptr), sslHdl(nullptr) + : TCP(std::move(tcp)), server(false), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr) { } SSL::SSL(const TCP& tcp) - : TCP(tcp), ctx(nullptr), sslHdl(nullptr) + : TCP(tcp), server(false), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr) { } SSL::SSL(const SSL& ssl) - : TCP(ssl), ctx(nullptr), sslHdl(nullptr) + : TCP(ssl), server(ssl.server), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr) { } @@ -57,8 +64,11 @@ namespace ehs TCP::operator=(ssl); + server = ssl.server; ctx = nullptr; sslHdl = nullptr; + cert = nullptr; + pkey = nullptr; return *this; } @@ -71,6 +81,40 @@ namespace ehs return; SSL_library_init(); + OpenSSL_add_ssl_algorithms(); + SSL_load_error_strings(); + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, nullptr); + OSSL_PROVIDER_load(nullptr, "default"); + + SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); + + if (server) + { + ctx = SSL_CTX_new(TLS_server_method()); + if (!ctx) + { + UInt_32 code = ERR_get_error(); + EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr)); + } + + SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!MD5"); + SSL_CTX_set_ciphersuites(ctx, + "TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:" + "TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256" + ); + } + else + { + ctx = SSL_CTX_new(TLS_client_method()); + if (!ctx) + { + UInt_32 code = ERR_get_error(); + EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr)); + } + + SSL_CTX_set_default_verify_paths(ctx); + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, nullptr); + } } void SSL::Release() @@ -80,6 +124,12 @@ namespace ehs if (!IsValid()) return; + EVP_PKEY_free(pkey); + pkey = nullptr; + + X509_free(cert); + cert = nullptr; + if (sslHdl) { if (connection) @@ -97,34 +147,37 @@ namespace ehs } } - void SSL::Bind(const Str_8& address, unsigned short port) + void SSL::Listen() { - if (bound) - return; + sslHdl = SSL_new(ctx); + SSL_set_fd(sslHdl, hdl); - OpenSSL_add_all_algorithms(); - SSL_load_error_strings(); - ctx = SSL_CTX_new(SSLv23_server_method()); + TCP::Listen(); - sslHdl = SSL_new(ctx); - SSL_set_fd(sslHdl, hdl); - - TCP::Bind(address, port); + EHS_LOG_SUCCESS(); } - SSL* SSL::Accept() + SSL* SSL::Accept() { if (!bound) return nullptr; TCP* tcp = TCP::Accept(); + if (!tcp) + return nullptr; SSL* client = new SSL(std::move(*tcp)); delete tcp; - client->ctx = nullptr; - client->sslHdl = SSL_new(ctx); + client->sslHdl = SSL_new(this->ctx); + if (!client->sslHdl) + { + UInt_32 code = ERR_get_error(); + EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr)); + return nullptr; + } + SSL_set_fd(client->sslHdl, client->hdl); int err = SSL_accept(client->sslHdl); @@ -134,21 +187,29 @@ namespace ehs return {}; } + EHS_LOG_SUCCESS(); + return client; } - void SSL::Connect(const Str_8& address, const UInt_16 port) + void SSL::Connect(Str_8 address, const UInt_16 &port) { - if (bound) - return; - TCP::Connect(address, port); - OpenSSL_add_all_algorithms(); - SSL_load_error_strings(); - ctx = SSL_CTX_new(SSLv23_client_method()); + sslHdl = SSL_new(ctx); SSL_set_fd(sslHdl, hdl); - SSL_connect(sslHdl); + + SSL_set_tlsext_host_name(sslHdl, &address[0]); + + SInt_32 rc = SSL_connect(sslHdl); + if (rc != 1) + { + EHS_LOG_INT(LogType::ERR, 1, "Failed to connect with error #" + Str_8::FromNum(SSL_get_error(sslHdl, rc)) + "."); + + return; + } + + EHS_LOG_SUCCESS(); } UInt_64 SSL::Send(const Byte* const buffer, const UInt_32 size) @@ -157,8 +218,12 @@ namespace ehs if (written <= 0) { int code = SSL_get_error(sslHdl, written); - ERR_print_errors_fp(stderr); - EHS_LOG_INT(LogType::ERR, 0, "Failed to send data with error #" + Str_8::FromNum(code) + "."); + if (code != SSL_ERROR_WANT_WRITE) + { + ERR_print_errors_fp(stderr); + EHS_LOG_INT(LogType::ERR, 0, "Failed to send data with error #" + Str_8::FromNum(code) + "."); + } + return 0; } @@ -171,48 +236,46 @@ namespace ehs if (received <= 0) { int code = SSL_get_error(sslHdl, received); - ERR_print_errors_fp(stderr); - EHS_LOG_INT(LogType::ERR, 0, "Failed to receive data with error #" + Str_8::FromNum(code) + "."); + if (code != SSL_ERROR_WANT_READ) + { + ERR_print_errors_fp(stderr); + EHS_LOG_INT(LogType::ERR, 0, "Failed to receive data with error #" + Str_8::FromNum(code) + "."); + } + return 0; } return received; } - void SSL::UseCertificate(const Byte* data, const UInt_64 size) + void SSL::UseCertificate(const Char_8* data, const UInt_32 &size) { - X509 *cert = d2i_X509(nullptr, &data, (long)size); - if (!cert) - { - EHS_LOG_INT(LogType::ERR, 0, "Invalid certificate."); - return; - } + BIO* certBio = BIO_new_mem_buf(data, (int)size); + X509 *cert = PEM_read_bio_X509(certBio, nullptr, nullptr, nullptr); - if (SSL_CTX_use_certificate(ctx, cert) != 1) - { - EHS_LOG_INT(LogType::ERR, 1, "Failed to use certificate."); - return; - } + if (!SSL_CTX_use_certificate(ctx, cert)) + { + UInt_32 code = ERR_get_error(); + EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr)); + return; + } - X509_free(cert); + BIO_free(certBio); } - void SSL::UsePrivateKey(const Byte* data, const UInt_64 size) + void SSL::UsePrivateKey(const Char_8* data, const UInt_32 &size) { - EVP_PKEY *key = d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &data, (long)size); - if (!key) - { - EHS_LOG_INT(LogType::ERR, 0, "Invalid private key."); - return; - } + BIO* keyBio = BIO_new_mem_buf(data, (int)size); + EVP_PKEY* pkey = PEM_read_bio_PrivateKey(keyBio, nullptr, nullptr, nullptr); - if (SSL_CTX_use_PrivateKey(ctx, key) != 1) - { - EHS_LOG_INT(LogType::ERR, 1, "Failed to use private key."); - return; - } + if (!SSL_CTX_use_PrivateKey(ctx, pkey)) + { + UInt_32 code = ERR_get_error(); + EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr)); + return; + } - EVP_PKEY_free(key); + BIO_free(keyBio); } bool SSL::IsValid() diff --git a/src/io/socket/TCP_BSD.cpp b/src/io/socket/TCP_BSD.cpp index 4bfed25..b68ad29 100644 --- a/src/io/socket/TCP_BSD.cpp +++ b/src/io/socket/TCP_BSD.cpp @@ -114,7 +114,7 @@ namespace ehs hdl = EHS_INVALID_SOCKET; } - void TCP::Bind(const Str_8& address, UInt_16 port) + void TCP::Bind(Str_8 address, const UInt_16 &port) { if (!IsValid() || bound || connection) return; @@ -124,7 +124,7 @@ namespace ehs else if (ip == IP::V4) Bind_v4(address, port); - this->localAddr = address; + this->localAddr = (Str_8 &&)address; this->localPort = port; bound = true; @@ -207,26 +207,26 @@ namespace ehs return client; } - void TCP::Connect(const Str_8& address, const UInt_16 port) + void TCP::Connect(Str_8 address, const UInt_16 &port) { if (connection || !IsValid() || listening) return; - remoteHostName = address; + remoteHostName = (Str_8 &&)address; remotePort = port; if (ip == IP::V6) { if (IsIPv6Only()) - remoteAddr = DNS::Resolve(IP::V6, address); + remoteAddr = DNS::Resolve(IP::V6, remoteHostName); else - remoteAddr = DNS::Resolve(address); + remoteAddr = DNS::Resolve(remoteHostName); Connect_v6(remoteAddr, port); } else if (ip == IP::V4) { - remoteAddr = DNS::Resolve(IP::V4, address); + remoteAddr = DNS::Resolve(IP::V4, remoteHostName); Connect_v4(remoteAddr, port); } @@ -385,12 +385,30 @@ namespace ehs return result; } + void TCP::SetReuse(const bool &value) + { + if (!IsValid()) + { + EHS_LOG_INT(LogType::WARN, 1, "Attempted to set address and port reuse while socket is not initialized."); + return; + } + + const int result = (int)value; + if (setsockopt(hdl, SOL_SOCKET, SO_REUSEPORT, &result, sizeof(int)) == -1) + { + EHS_LOG_INT(LogType::ERR, 2, "Failed to set address and port reuse with error #" + Str_8::FromNum(errno) + "."); + return; + } + + EHS_LOG_SUCCESS(); + } + bool TCP::IsValid() const { return hdl != EHS_INVALID_SOCKET; } - void TCP::Bind_v6(const Str_8& address, UInt_16 port) + void TCP::Bind_v6(const Str_8& address, const UInt_16 &port) const { sockaddr_in6 result = {}; result.sin6_family = AF_INET6; @@ -426,7 +444,7 @@ namespace ehs } } - void TCP::Bind_v4(const Str_8& address, UInt_16 port) + void TCP::Bind_v4(const Str_8& address, const UInt_16 &port) const { sockaddr_in result = {}; result.sin_family = AF_INET; @@ -461,7 +479,7 @@ namespace ehs } } - void TCP::Connect_v6(const Str_8& address, UInt_16 port) + void TCP::Connect_v6(const Str_8 &address, const UInt_16 &port) { sockaddr_in6 result = {}; result.sin6_family = AF_INET6; @@ -498,7 +516,7 @@ namespace ehs } } - void TCP::Connect_v4(const Str_8& address, UInt_16 port) + void TCP::Connect_v4(const Str_8 &address, const UInt_16 &port) { sockaddr_in result = {}; result.sin_family = AF_INET; diff --git a/src/io/socket/TCP_W32.cpp b/src/io/socket/TCP_W32.cpp index e2b2344..7b19d51 100644 --- a/src/io/socket/TCP_W32.cpp +++ b/src/io/socket/TCP_W32.cpp @@ -137,7 +137,7 @@ namespace ehs connected = false; } - void TCP::Bind(const Str_8& address, UInt_16 port) + void TCP::Bind(Str_8 address, const UInt_16 &port) { if (!IsValid() || bound || connection) return; @@ -147,7 +147,7 @@ namespace ehs else if (ip == IP::V4) Bind_v4(address, port); - this->localAddr = address; + this->localAddr = (Str_8 &&)address; this->localPort = port; bound = true; @@ -236,26 +236,26 @@ namespace ehs return client; } - void TCP::Connect(const Str_8& address, const UInt_16 port) + void TCP::Connect(Str_8 address, const UInt_16 &port) { if (connection || !IsValid() || listening) return; - remoteHostName = address; + remoteHostName = (Str_8 &&)address; remotePort = port; if (ip == IP::V6) { if (IsIPv6Only()) - remoteAddr = DNS::Resolve(IP::V6, address); + remoteAddr = DNS::Resolve(IP::V6, remoteHostName); else - remoteAddr = DNS::Resolve(address); + remoteAddr = DNS::Resolve(remoteHostName); Connect_v6(remoteAddr, port); } else if (ip == IP::V4) { - remoteAddr = DNS::Resolve(IP::V4, address); + remoteAddr = DNS::Resolve(IP::V4, remoteHostName); Connect_v4(remoteAddr, port); } @@ -406,6 +406,10 @@ namespace ehs return result; } + void TCP::SetReuse(const bool &value) + { + } + bool TCP::IsValid() const { return hdl != EHS_INVALID_SOCKET; diff --git a/src/io/socket/rest/Spotify.cpp b/src/io/socket/rest/Spotify.cpp index 479aded..492efb4 100644 --- a/src/io/socket/rest/Spotify.cpp +++ b/src/io/socket/rest/Spotify.cpp @@ -81,7 +81,7 @@ namespace ehs authReq.SetContentType(ContentType::APP_FORMURLENCODED); authReq.BasicAuth(clientId, secret); authReq.AddToBody("grant_type", "authorization_code"); - authReq.AddToBody("code", cbReq.GetQuery("code")); + authReq.AddToBody("code", cbReq.GetQueryValue("code")); authReq.AddToBody("redirect_uri", rURI); accounts.SendReq(authReq); @@ -134,7 +134,7 @@ namespace ehs StartConnection(); Request req(Verb::PUT, "/v1/me/player/volume"); - req.AddQuery("volume_percent", Str_8::FromNum(level)); + req.AddQueryVar({"volume_percent", Str_8::FromNum(level)}); req.BearerAuth(token); client.SendReq(req); @@ -206,7 +206,7 @@ namespace ehs } Request req(Verb::PUT, "/v1/me/player/repeat"); - req.AddQuery("state", result); + req.AddQueryVar({"state", result}); req.BearerAuth(token); client.SendReq(req); @@ -226,7 +226,7 @@ namespace ehs StartConnection(); Request req(Verb::PUT, "/v1/me/player/repeat"); - req.AddQuery("state", state ? "true" : "false"); + req.AddQueryVar({"state", state ? "true" : "false"}); req.BearerAuth(token); client.SendReq(req); @@ -258,10 +258,10 @@ namespace ehs q += "+track%3A" + name.ReplaceAll(" ", "+"); - req.AddQuery("q", q); - req.AddQuery("type", "track"); - req.AddQuery("limit", "1"); - req.AddQuery("offset", "0"); + req.AddQueryVar({"q", q}); + req.AddQueryVar({"type", "track"}); + req.AddQueryVar({"limit", "1"}); + req.AddQueryVar({"offset", "0"}); req.BearerAuth(token); client.SendReq(req); @@ -454,7 +454,7 @@ namespace ehs StartConnection(); Request req(Verb::POST, "/v1/me/player/queue"); - req.AddQuery("uri", "spotify:track:" + id); + req.AddQueryVar({"uri", "spotify:track:" + id}); req.BearerAuth(token); client.SendReq(req); @@ -505,8 +505,8 @@ namespace ehs StartConnection(); Request req(Verb::POST, "/v1/playlists/" + playlistId + "/tracks"); - req.AddQuery("position", Str_8::FromNum(pos)); - req.AddQuery("uris", "spotify:track:" + trackId); + req.AddQueryVar({"position", Str_8::FromNum(pos)}); + req.AddQueryVar({"uris", "spotify:track:" + trackId}); req.BearerAuth(token); client.SendReq(req); @@ -564,7 +564,7 @@ namespace ehs StartConnection(); Request req(Verb::PUT, "/v1/me/player/seek"); - req.AddQuery("position_ms", Str_8::FromNum(pos)); + req.AddQueryVar({"position_ms", Str_8::FromNum(pos)}); req.BearerAuth(token); client.SendReq(req); diff --git a/src/io/socket/rest/Twitch.cpp b/src/io/socket/rest/Twitch.cpp index e29a112..1d84f1c 100644 --- a/src/io/socket/rest/Twitch.cpp +++ b/src/io/socket/rest/Twitch.cpp @@ -78,7 +78,7 @@ namespace ehs authReq.SetContentType(ContentType::APP_FORMURLENCODED); authReq.AddToBody("client_id", clientId); authReq.AddToBody("client_secret", secret); - authReq.AddToBody("code", cbReq.GetQuery("code")); + authReq.AddToBody("code", cbReq.GetQueryValue("code")); authReq.AddToBody("grant_type", "authorization_code"); authReq.AddToBody("redirect_uri", redURI); diff --git a/src/system/AVX2_AARCH64.cpp b/src/system/AVX2_AARCH64.cpp new file mode 100644 index 0000000..654853b --- /dev/null +++ b/src/system/AVX2_AARCH64.cpp @@ -0,0 +1,24 @@ +#include "ehs/system/AVX2.h" + +namespace ehs +{ + bool AVX2::CompareUnaligned(const UInt_64* a, const UInt_64* b) + { + return false; + } + + bool AVX2::CompareUnaligned(const SInt_64* a, const SInt_64* b) + { + return false; + } + + bool AVX2::CompareAligned(const UInt_64* a, const UInt_64* b) + { + return false; + } + + bool AVX2::CompareAligned(const SInt_64* a, const SInt_64* b) + { + return false; + } +} \ No newline at end of file diff --git a/src/system/AVX2_GCC_AMD64.asm b/src/system/AVX2_GCC_AMD64.asm new file mode 100644 index 0000000..2db1829 --- /dev/null +++ b/src/system/AVX2_GCC_AMD64.asm @@ -0,0 +1,49 @@ +global _ZN3ehs4AVX216CompareUnalignedEPKmS2_ +global _ZN3ehs4AVX216CompareUnalignedEPKlS2_ +global _ZN3ehs4AVX214CompareAlignedEPKmS2_ +global _ZN3ehs4AVX214CompareAlignedEPKlS2_ + +section .text + _ZN3ehs4AVX216CompareUnalignedEPKmS2_: + VMOVDQU YMM0, [RDI] + VMOVDQU YMM1, [RSI] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET + + _ZN3ehs4AVX216CompareUnalignedEPKlS2_: + VMOVDQU YMM0, [RDI] + VMOVDQU YMM1, [RSI] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET + + _ZN3ehs4AVX214CompareAlignedEPKmS2_: + VMOVDQA YMM0, [RDI] + VMOVDQA YMM1, [RSI] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET + + _ZN3ehs4AVX214CompareAlignedEPKlS2_: + VMOVDQA YMM0, [RDI] + VMOVDQA YMM1, [RSI] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET \ No newline at end of file diff --git a/src/system/AVX2_MSVC_AMD64.asm b/src/system/AVX2_MSVC_AMD64.asm new file mode 100644 index 0000000..93cd8d8 --- /dev/null +++ b/src/system/AVX2_MSVC_AMD64.asm @@ -0,0 +1,49 @@ +global ?CompareUnaligned@AVX2@ehs@@SA_NPEBK0@Z +global ?CompareUnaligned@AVX2@ehs@@SA_NPEBJ0@Z +global ?CompareAligned@AVX2@ehs@@SA_NPEBK0@Z +global ?CompareAligned@AVX2@ehs@@SA_NPEBJ0@Z + +section .text + ?CompareUnaligned@AVX2@ehs@@SA_NPEBK0@Z: + VMOVDQU YMM0, [RCX] + VMOVDQU YMM1, [RDX] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET + + ?CompareUnaligned@AVX2@ehs@@SA_NPEBJ0@Z: + VMOVDQU YMM0, [RCX] + VMOVDQU YMM1, [RDX] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET + + ?CompareAligned@AVX2@ehs@@SA_NPEBK0@Z: + VMOVDQA YMM0, [RCX] + VMOVDQA YMM1, [RDX] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET + + ?CompareAligned@AVX2@ehs@@SA_NPEBJ0@Z: + VMOVDQA YMM0, [RCX] + VMOVDQA YMM1, [RDX] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET \ No newline at end of file diff --git a/src/system/AVX512_AARCH64.cpp b/src/system/AVX512_AARCH64.cpp new file mode 100644 index 0000000..46890be --- /dev/null +++ b/src/system/AVX512_AARCH64.cpp @@ -0,0 +1,24 @@ +#include "ehs/system/AVX512.h" + +namespace ehs +{ + bool AVX512::CompareUnaligned(const UInt_64* a, const UInt_64* b) + { + return false; + } + + bool AVX512::CompareUnaligned(const SInt_64* a, const SInt_64* b) + { + return false; + } + + bool AVX512::CompareAligned(const UInt_64* a, const UInt_64* b) + { + return false; + } + + bool AVX512::CompareAligned(const SInt_64* a, const SInt_64* b) + { + return false; + } +} \ No newline at end of file diff --git a/src/system/AVX512_GCC_AMD64.asm b/src/system/AVX512_GCC_AMD64.asm new file mode 100644 index 0000000..6a3c698 --- /dev/null +++ b/src/system/AVX512_GCC_AMD64.asm @@ -0,0 +1,49 @@ +global _ZN3ehs6AVX51216CompareUnalignedEPKmS2_ +global _ZN3ehs6AVX51216CompareUnalignedEPKlS2_ +global _ZN3ehs6AVX51214CompareAlignedEPKmS2_ +global _ZN3ehs6AVX51214CompareAlignedEPKlS2_ + +section .text + _ZN3ehs6AVX51216CompareUnalignedEPKmS2_: + VMOVDQU64 ZMM0, [RDI] + VMOVDQU64 ZMM1, [RSI] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET + + _ZN3ehs6AVX51216CompareUnalignedEPKlS2_: + VMOVDQU64 ZMM0, [RDI] + VMOVDQU64 ZMM1, [RSI] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET + + _ZN3ehs6AVX51214CompareAlignedEPKmS2_: + VMOVDQA64 ZMM0, [RDI] + VMOVDQA64 ZMM1, [RSI] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET + + _ZN3ehs6AVX51214CompareAlignedEPKlS2_: + VMOVDQA64 ZMM0, [RDI] + VMOVDQA64 ZMM1, [RSI] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET \ No newline at end of file diff --git a/src/system/AVX512_MSVC_AMD64.asm b/src/system/AVX512_MSVC_AMD64.asm new file mode 100644 index 0000000..49321cb --- /dev/null +++ b/src/system/AVX512_MSVC_AMD64.asm @@ -0,0 +1,49 @@ +global ?CompareUnaligned@AVX512@ehs@@SA_NPEBK0@Z +global ?CompareUnaligned@AVX512@ehs@@SA_NPEBJ0@Z +global ?CompareAligned@AVX512@ehs@@SA_NPEBK0@Z +global ?CompareAligned@AVX512@ehs@@SA_NPEBJ0@Z + +section .text + ?CompareUnaligned@AVX512@ehs@@SA_NPEBK0@Z: + VMOVDQU64 ZMM0, [RCX] + VMOVDQU64 ZMM1, [RDX] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET + + ?CompareUnaligned@AVX512@ehs@@SA_NPEBJ0@Z: + VMOVDQU64 ZMM0, [RCX] + VMOVDQU64 ZMM1, [RDX] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET + + ?CompareAligned@AVX512@ehs@@SA_NPEBK0@Z: + VMOVDQA64 ZMM0, [RCX] + VMOVDQA64 ZMM1, [RDX] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET + + ?CompareAligned@AVX512@ehs@@SA_NPEBJ0@Z: + VMOVDQA64 ZMM0, [RCX] + VMOVDQA64 ZMM1, [RDX] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET \ No newline at end of file diff --git a/src/system/BaseSystem.cpp b/src/system/BaseSystem.cpp index c963082..2bcd747 100644 --- a/src/system/BaseSystem.cpp +++ b/src/system/BaseSystem.cpp @@ -2,7 +2,7 @@ namespace ehs { - void BaseSystem::OpenURI(const Str_8& uri) + void BaseSystem::OpenURI(Str_8 uri) { } diff --git a/src/system/CPU.cpp b/src/system/CPU.cpp index ccab72e..9f23fde 100644 --- a/src/system/CPU.cpp +++ b/src/system/CPU.cpp @@ -10,11 +10,75 @@ namespace ehs UInt_64 CPU::TSC_Freq = 0; #endif + const bool CPU::hasFPU = RetrieveFPU(); + const bool CPU::hasVME = RetrieveVME(); + const bool CPU::hasDE = RetrieveDE(); + const bool CPU::hasPSE = RetrievePSE(); + const bool CPU::hasTSC = RetrieveTSC(); + const bool CPU::hasMSR = RetrieveMSR(); + const bool CPU::hasPAE = RetrievePAE(); + const bool CPU::hasMCE = RetrieveMCE(); + const bool CPU::hasCX8 = RetrieveCX8(); + const bool CPU::hasAPIC = RetrieveAPIC(); + const bool CPU::hasSEP = RetrieveSEP(); + const bool CPU::hasMTRR = RetrieveMTRR(); + const bool CPU::hasPGE = RetrievePGE(); + const bool CPU::hasMCA = RetrieveMCA(); + const bool CPU::hasCMOV = RetrieveCMOV(); + const bool CPU::hasPSE_36 = RetrievePSE_36(); + const bool CPU::hasPSN = RetrievePSN(); + const bool CPU::hasCLFSH = RetrieveCLFSH(); + const bool CPU::hasDS = RetrieveDS(); + const bool CPU::hasACPI = RetrieveACPI(); + const bool CPU::hasMMX = RetrieveMMX(); + const bool CPU::hasFXSR = RetrieveFXSR(); + const bool CPU::hasSSE = RetrieveSSE(); + const bool CPU::hasSSE2 = RetrieveSSE2(); + const bool CPU::hasSS = RetrieveSS(); + const bool CPU::hasHTT = RetrieveHTT(); + const bool CPU::hasTM = RetrieveTM(); + const bool CPU::hasIA64 = RetrieveIA64(); + const bool CPU::hasPBE = RetrievePBE(); + const bool CPU::hasSSE3 = RetrieveSSE3(); + const bool CPU::hasPCLMULQDQ = RetrievePCLMULQDQ(); + const bool CPU::hasDTES64 = RetrieveDTES64(); + const bool CPU::hasMONITOR = RetrieveMONITOR(); + const bool CPU::hasVMX = RetrieveVMX(); + const bool CPU::hasSMX = RetrieveSMX(); + const bool CPU::hasEST = RetrieveEST(); + const bool CPU::hasTM2 = RetrieveTM2(); + const bool CPU::hasSSSE3 = RetrieveSSSE3(); + const bool CPU::hasCNXT_ID = RetrieveCNXT_ID(); + const bool CPU::hasSDBG = RetrieveSDBG(); + const bool CPU::hasFMA = RetrieveFMA(); + const bool CPU::hasCX16 = RetrieveCX16(); + const bool CPU::hasXTPR = RetrieveXTPR(); + const bool CPU::hasPDCM = RetrievePDCM(); + const bool CPU::hasPCID = RetrievePCID(); + const bool CPU::hasDCA = RetrieveDCA(); + const bool CPU::hasSSE4_1 = RetrieveSSE4_1(); + const bool CPU::hasSSE4_2 = RetrieveSSE4_2(); + const bool CPU::hasX2APIC = RetrieveX2APIC(); + const bool CPU::hasMOVBE = RetrieveMOVBE(); + const bool CPU::hasPOPCNT = RetrievePOPCNT(); + const bool CPU::hasTSC_DEADLINE = RetrieveTSC_DEADLINE(); + const bool CPU::hasAES = RetrieveAES(); + const bool CPU::hasXSAVE = RetrieveXSAVE(); + const bool CPU::hasOSXSAVE = RetrieveOSXSAVE(); + const bool CPU::hasAVX = RetrieveAVX(); + const bool CPU::hasF16C = RetrieveF16C(); + const bool CPU::hasRDRND = RetrieveRDRND(); + const bool CPU::hasHYPERVISOR = RetrieveHYPERVISOR(); + const bool CPU::hasAVX2 = RetrieveAVX2(); + const bool CPU::hasAVX512F = RetrieveAVX512F(); + const bool CPU::hasRDSEED = RetrieveRDSEED(); + const bool CPU::hasADX = RetrieveADX(); + Architecture CPU::GetArchitecture() { #if defined(EHS_ARCH_X64) return Architecture::X64; - #elif defined(EHS_ARCH_ARM64) + #elif defined(EHS_ARCH_AARCH64) return Architecture::ARM64; #else return Architecture::UNKNOWN; @@ -49,13 +113,19 @@ namespace ehs return frequency.QuadPart; #elif defined(EHS_OS_LINUX) - if (!TSC_Freq) - TSC_Freq = RetrieveTSC_Freq(); + #if defined(EHS_ARCH_X64) + if (!TSC_Freq) + TSC_Freq = RetrieveTSC_Freq(); - return TSC_Freq; + return TSC_Freq; + #elif defined(EHS_ARCH_AARCH64) + return RetrieveFreq_AARCH64(); + #else + return 0; + #endif + #else + return 0; #endif - - return 0; } UInt_64 CPU::GetTSC() @@ -69,7 +139,7 @@ namespace ehs TSC tsc; RDTSCP(&tsc); - #if defined(EHS_ARCH_X64) + #if defined(EHS_ARCH_X64) || defined(EHS_ARCH_AARCH64) UInt_64 result = 0; #if defined(EHS_LITTLE_ENDIAN) @@ -119,324 +189,589 @@ namespace ehs return (UInt_8)(GetInfoBits() >> 20); } - bool CPU::HasFPU() + bool CPU::RetrieveFPU() { - return GetFeatureBits_1() & 0b00000000000000000000000000000001; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000000001; + #else + return false; + #endif } - bool CPU::HasVME() + bool CPU::RetrieveVME() { - return GetFeatureBits_1() & 0b00000000000000000000000000000010; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000000010; + #else + return false; + #endif } - bool CPU::HasDE() + bool CPU::RetrieveDE() { - return GetFeatureBits_1() & 0b00000000000000000000000000000100; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000000100; + #else + return false; + #endif } - bool CPU::HasPSE() + bool CPU::RetrievePSE() { - return GetFeatureBits_1() & 0b00000000000000000000000000001000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000001000; + #else + return false; + #endif } - bool CPU::HasTSC() + bool CPU::RetrieveTSC() { - return GetFeatureBits_1() & 0b00000000000000000000000000010000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000010000; + #else + return false; + #endif } - bool CPU::HasMSR() + bool CPU::RetrieveMSR() { - return GetFeatureBits_1() & 0b00000000000000000000000000100000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000100000; + #else + return false; + #endif } - bool CPU::HasPAE() + bool CPU::RetrievePAE() { - return GetFeatureBits_1() & 0b00000000000000000000000001000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000001000000; + #else + return false; + #endif } - bool CPU::HasMCE() + bool CPU::RetrieveMCE() { - return GetFeatureBits_1() & 0b00000000000000000000000010000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000010000000; + #else + return false; + #endif } - bool CPU::HasCX8() + bool CPU::RetrieveCX8() { - return GetFeatureBits_1() & 0b00000000000000000000000100000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000100000000; + #else + return false; + #endif } - bool CPU::HasAPIC() + bool CPU::RetrieveAPIC() { - return GetFeatureBits_1() & 0b00000000000000000000001000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000001000000000; + #else + return false; + #endif } - bool CPU::HasSEP() + bool CPU::RetrieveSEP() { - return GetFeatureBits_1() & 0b00000000000000000000100000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000100000000000; + #else + return false; + #endif } - bool CPU::HasMTRR() + bool CPU::RetrieveMTRR() { - return GetFeatureBits_1() & 0b00000000000000000001000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000001000000000000; + #else + return false; + #endif } - bool CPU::HasPGE() + bool CPU::RetrievePGE() { - return GetFeatureBits_1() & 0b00000000000000000010000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000010000000000000; + #else + return false; + #endif } - bool CPU::HasMCA() + bool CPU::RetrieveMCA() { - return GetFeatureBits_1() & 0b00000000000000000100000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000100000000000000; + #else + return false; + #endif } - bool CPU::HasCMOV() + bool CPU::RetrieveCMOV() { - return GetFeatureBits_1() & 0b00000000000000001000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000001000000000000000; + #else + return false; + #endif } - bool CPU::HasPAT() + bool CPU::RetrievePAT() { - return GetFeatureBits_1() & 0b00000000000000010000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000010000000000000000; + #else + return false; + #endif } - bool CPU::HasPSE_36() + bool CPU::RetrievePSE_36() { - return GetFeatureBits_1() & 0b00000000000000100000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000100000000000000000; + #else + return false; + #endif } - bool CPU::HasPSN() + bool CPU::RetrievePSN() { - return GetFeatureBits_1() & 0b00000000000001000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000001000000000000000000; + #else + return false; + #endif } - bool CPU::HasCLFSH() + bool CPU::RetrieveCLFSH() { - return GetFeatureBits_1() & 0b00000000000010000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000010000000000000000000; + #else + return false; + #endif } - bool CPU::HasDS() + bool CPU::RetrieveDS() { - return GetFeatureBits_1() & 0b00000000001000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000001000000000000000000000; + #else + return false; + #endif } - bool CPU::HasACPI() + bool CPU::RetrieveACPI() { - return GetFeatureBits_1() & 0b00000000010000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000010000000000000000000000; + #else + return false; + #endif } - bool CPU::HasMMX() + bool CPU::RetrieveMMX() { - return GetFeatureBits_1() & 0b00000000100000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000100000000000000000000000; + #else + return false; + #endif } - bool CPU::HasFXSR() + bool CPU::RetrieveFXSR() { - return GetFeatureBits_1() & 0b00000001000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000001000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasSSE() + bool CPU::RetrieveSSE() { - return GetFeatureBits_1() & 0b00000010000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000010000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasSSE2() + bool CPU::RetrieveSSE2() { - return GetFeatureBits_1() & 0b00000100000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000100000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasSS() + bool CPU::RetrieveSS() { - return GetFeatureBits_1() & 0b00001000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00001000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasHTT() + bool CPU::RetrieveHTT() { - return GetFeatureBits_1() & 0b00010000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00010000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasTM() + bool CPU::RetrieveTM() { - return GetFeatureBits_1() & 0b00100000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00100000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasIA64() + bool CPU::RetrieveIA64() { - return GetFeatureBits_1() & 0b01000000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b01000000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasPBE() + bool CPU::RetrievePBE() { - return GetFeatureBits_1() & 0b10000000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b10000000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasSSE3() + bool CPU::RetrieveSSE3() { - return GetFeatureBits_2() & 0b00000000000000000000000000000001; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000000001; + #else + return false; + #endif } - bool CPU::HasPCLMULQDQ() + bool CPU::RetrievePCLMULQDQ() { - return GetFeatureBits_2() & 0b00000000000000000000000000000010; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000000010; + #else + return false; + #endif } - bool CPU::HasDTES64() + bool CPU::RetrieveDTES64() { - return GetFeatureBits_2() & 0b00000000000000000000000000000100; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000000100; + #else + return false; + #endif } - bool CPU::HasMONITOR() + bool CPU::RetrieveMONITOR() { - return GetFeatureBits_2() & 0b00000000000000000000000000001000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000001000; + #else + return false; + #endif } - bool CPU::HasDS_CPL() + bool CPU::RetrieveDS_CPL() { - return GetFeatureBits_2() & 0b00000000000000000000000000010000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000010000; + #else + return false; + #endif } - bool CPU::HasVMX() + bool CPU::RetrieveVMX() { - return GetFeatureBits_2() & 0b00000000000000000000000000100000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000100000; + #else + return false; + #endif } - bool CPU::HasSMX() + bool CPU::RetrieveSMX() { - return GetFeatureBits_2() & 0b00000000000000000000000001000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000001000000; + #else + return false; + #endif } - bool CPU::HasEST() + bool CPU::RetrieveEST() { - return GetFeatureBits_2() & 0b00000000000000000000000010000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000010000000; + #else + return false; + #endif } - bool CPU::HasTM2() + bool CPU::RetrieveTM2() { - return GetFeatureBits_2() & 0b00000000000000000000000100000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000100000000; + #else + return false; + #endif } - bool CPU::HasSSSE3() + bool CPU::RetrieveSSSE3() { - return GetFeatureBits_2() & 0b00000000000000000000001000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000001000000000; + #else + return false; + #endif } - bool CPU::HasCNXT_ID() + bool CPU::RetrieveCNXT_ID() { - return GetFeatureBits_2() & 0b00000000000000000000010000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000010000000000; + #else + return false; + #endif } - bool CPU::HasSDBG() + bool CPU::RetrieveSDBG() { - return GetFeatureBits_2() & 0b00000000000000000000100000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000100000000000; + #else + return false; + #endif } - bool CPU::HasFMA() + bool CPU::RetrieveFMA() { - return GetFeatureBits_2() & 0b00000000000000000001000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000001000000000000; + #else + return false; + #endif } - bool CPU::HasCX16() + bool CPU::RetrieveCX16() { - return GetFeatureBits_2() & 0b00000000000000000010000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000010000000000000; + #else + return false; + #endif } - bool CPU::HasXTPR() + bool CPU::RetrieveXTPR() { - return GetFeatureBits_2() & 0b00000000000000000100000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000100000000000000; + #else + return false; + #endif } - bool CPU::HasPDCM() + bool CPU::RetrievePDCM() { - return GetFeatureBits_2() & 0b00000000000000001000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000001000000000000000; + #else + return false; + #endif } - bool CPU::HasPCID() + bool CPU::RetrievePCID() { - return GetFeatureBits_2() & 0b00000000000000100000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000100000000000000000; + #else + return false; + #endif } - bool CPU::HasDCA() + bool CPU::RetrieveDCA() { - return GetFeatureBits_2() & 0b00000000000001000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000001000000000000000000; + #else + return false; + #endif } - bool CPU::HasSSE4_1() + bool CPU::RetrieveSSE4_1() { - return GetFeatureBits_2() & 0b00000000000010000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000010000000000000000000; + #else + return false; + #endif } - bool CPU::HasSSE4_2() + bool CPU::RetrieveSSE4_2() { - return GetFeatureBits_2() & 0b00000000000100000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000100000000000000000000; + #else + return false; + #endif } - bool CPU::HasX2APIC() + bool CPU::RetrieveX2APIC() { - return GetFeatureBits_2() & 0b00000000001000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000001000000000000000000000; + #else + return false; + #endif } - bool CPU::HasMOVBE() + bool CPU::RetrieveMOVBE() { - return GetFeatureBits_2() & 0b00000000010000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000010000000000000000000000; + #else + return false; + #endif } - bool CPU::HasPOPCNT() + bool CPU::RetrievePOPCNT() { - return GetFeatureBits_2() & 0b00000000100000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000100000000000000000000000; + #else + return false; + #endif } - bool CPU::HasTSC_DEADLINE() + bool CPU::RetrieveTSC_DEADLINE() { - return GetFeatureBits_2() & 0b00000001000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000001000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasAES() + bool CPU::RetrieveAES() { - return GetFeatureBits_2() & 0b00000010000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000010000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasXSAVE() + bool CPU::RetrieveXSAVE() { - return GetFeatureBits_2() & 0b00000100000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000100000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasOSXSAVE() + bool CPU::RetrieveOSXSAVE() { - return GetFeatureBits_2() & 0b00001000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00001000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasAVX() + bool CPU::RetrieveAVX() { - return GetFeatureBits_2() & 0b00010000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00010000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasF16C() + bool CPU::RetrieveF16C() { - return GetFeatureBits_2() & 0b00100000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00100000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasRDRND() + bool CPU::RetrieveRDRND() { - return GetFeatureBits_2() & 0b01000000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b01000000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasHYPERVISOR() + bool CPU::RetrieveHYPERVISOR() { - return GetFeatureBits_2() & 0b10000000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b10000000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasAVX2() + bool CPU::RetrieveAVX2() { - return GetExtFeatureBits_1() & 0b00000000000000000000000000100000; + #ifdef EHS_ARCH_X64 + return GetExtFeatureBits_1() & 0b00000000000000000000000000100000; + #else + return false; + #endif } - bool CPU::HasRDSEED() + bool CPU::RetrieveAVX512F() { - return GetExtFeatureBits_1() & 0b00000000000001000000000000000000; + #ifdef EHS_ARCH_X64 + return GetExtFeatureBits_1() & 0b00000000000000010000000000000000; + #else + return false; + #endif } - bool CPU::HasADX() + bool CPU::RetrieveRDSEED() { - return GetExtFeatureBits_1() & 0b00000000000010000000000000000000; + #ifdef EHS_ARCH_X64 + return GetExtFeatureBits_1() & 0b00000000000001000000000000000000; + #else + return false; + #endif + } + + bool CPU::RetrieveADX() + { + #ifdef EHS_ARCH_X64 + return GetExtFeatureBits_1() & 0b00000000000010000000000000000000; + #else + return false; + #endif } /* diff --git a/src/system/CPU_ARM64.cpp b/src/system/CPU_ARM64.cpp index ba140bf..33b6561 100644 --- a/src/system/CPU_ARM64.cpp +++ b/src/system/CPU_ARM64.cpp @@ -2,10 +2,6 @@ namespace ehs { - void CPU::RDTSCP(TSC* tsc) - { - } - void CPU::GetManufacturer(Char_8* input) { } diff --git a/src/system/CPU_GCC_AARCH64.s b/src/system/CPU_GCC_AARCH64.s new file mode 100644 index 0000000..367a064 --- /dev/null +++ b/src/system/CPU_GCC_AARCH64.s @@ -0,0 +1,14 @@ +.global _ZN3ehs3CPU6RDTSCPEPNS_3TSCE +.global _ZN3ehs3CPU20RetrieveFreq_AARCH64Ev + +.section .text + _ZN3ehs3CPU6RDTSCPEPNS_3TSCE: + MRS X2, CNTVCT_EL0 + EOR W1, W1, W1 + STR W1, [X0] + STR X2, [X0, #4] + RET + + _ZN3ehs3CPU20RetrieveFreq_AARCH64Ev: + MRS X0, CNTFRQ_EL0 + RET diff --git a/src/system/System_LNX.cpp b/src/system/System_LNX.cpp index dfaff88..016c2ab 100644 --- a/src/system/System_LNX.cpp +++ b/src/system/System_LNX.cpp @@ -13,13 +13,17 @@ namespace ehs system("xdg-open \"" + *uri + "\""); + delete uri; + return 0; } - void System::OpenURI(const Str_8& uri) + void System::OpenURI(Str_8 uri) { + Str_8 *arg = new Str_8((Str_8&&)uri); + Thread xdg; - xdg.Start(XDG_Thread, (void*)&uri); + xdg.Start(XDG_Thread, arg); xdg.Detach(); } diff --git a/src/system/System_W32.cpp b/src/system/System_W32.cpp index 1029f1d..ccc0b18 100644 --- a/src/system/System_W32.cpp +++ b/src/system/System_W32.cpp @@ -4,7 +4,7 @@ namespace ehs { - void System::OpenURI(const Str_8& uri) + void System::OpenURI(Str_8 uri) { ShellExecuteA(nullptr, "open", uri, nullptr, nullptr, SW_SHOW); }