diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..e58d809 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,18 @@ +Checks: 'readability-identifier-naming' + +CheckOptions: + - key: readability-identifier-naming.MethodCase + value: PascalCase + + - key: readability-identifier-naming.StructMemberCase + value: lower_case + + - key: readability-identifier-naming.PrivateMemberCase + value: camelCase + - key: readability-identifier-naming.PrivateMemberPrefix + value: m_ + + - key: readability-identifier-naming.ClassCase + value: PascalCase + - key: readability-identifier-naming.StructCase + value: PascalCase \ No newline at end of file diff --git a/.clangd b/.clangd index c8865a6..d2ee80f 100644 --- a/.clangd +++ b/.clangd @@ -1,3 +1,3 @@ -Index: - PathExclude: - - .*/EmbeddedResources\.cpp \ No newline at end of file +CompileFlags: + Add: [-Wno-missing-field-initializers, -Wno-missing-designated-field-initializers] + \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 36a129a..77f1190 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -3,24 +3,13 @@ "configurations": [ { "name": "Debug (Linux)", - "type": "cppdbg", + "type": "lldb", "request": "launch", "program": "${command:cmake.launchTargetPath}", "args": [ "dummy" ], - "stopAtEntry": false, "cwd": "${workspaceFolder}/", - "environment": [], - "externalConsole": false, - "MIMode": "gdb", - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } - ], "preLaunchTask": "CMake Build" } ] diff --git a/.vscode/settings.json b/.vscode/settings.json index 0a73760..b28d6ef 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,9 @@ { "editor.formatOnSave": true, + "C_Cpp.codeAnalysis.runAutomatically": "onSave", + "C_Cpp.codeAnalysis.clangTidy.enabled": true, + "C_Cpp.codeAnalysis.clangTidy.useBuildPath": false, + "C_Cpp.codeAnalysis.clangTidy.config": "", "C_Cpp.clang_format_fallbackStyle": "Microsoft", - "cmake.copyCompileCommands": "${workspaceFolder}/compile_commands.json" + "cmake.copyCompileCommands": "${workspaceFolder}/compile_commands.json", } \ No newline at end of file diff --git a/Src/IACore/CMakeLists.txt b/Src/IACore/CMakeLists.txt index d79e45a..40d56b0 100644 --- a/Src/IACore/CMakeLists.txt +++ b/Src/IACore/CMakeLists.txt @@ -13,9 +13,12 @@ set(SRC_FILES "imp/cpp/SocketOps.cpp" "imp/cpp/StringOps.cpp" "imp/cpp/ProcessOps.cpp" - "imp/cpp/HttpClient.cpp" "imp/cpp/StreamReader.cpp" "imp/cpp/StreamWriter.cpp" + + "imp/cpp/Http/Common.cpp" + "imp/cpp/Http/Client.cpp" + "imp/cpp/Http/Server.cpp" ) add_library(IACore STATIC ${SRC_FILES}) diff --git a/Src/IACore/imp/cpp/AsyncOps.cpp b/Src/IACore/imp/cpp/AsyncOps.cpp index c3ba984..134f146 100644 --- a/Src/IACore/imp/cpp/AsyncOps.cpp +++ b/Src/IACore/imp/cpp/AsyncOps.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/imp/cpp/DataOps.cpp b/Src/IACore/imp/cpp/DataOps.cpp index 04dfd1d..66c4b67 100644 --- a/Src/IACore/imp/cpp/DataOps.cpp +++ b/Src/IACore/imp/cpp/DataOps.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -272,7 +272,7 @@ namespace IACore return CompressionType::None; } - Expected, String> DataOps::ZlibInflate(IN Span data) + EXPECT(Vector) DataOps::ZlibInflate(IN Span data) { z_stream zs{}; zs.zalloc = Z_NULL; @@ -323,7 +323,7 @@ namespace IACore return outBuffer; } - Expected, String> DataOps::ZlibDeflate(IN Span data) + EXPECT(Vector) DataOps::ZlibDeflate(IN Span data) { z_stream zs{}; zs.zalloc = Z_NULL; @@ -357,7 +357,7 @@ namespace IACore return outBuffer; } - Expected, String> DataOps::ZstdInflate(IN Span data) + EXPECT(Vector) DataOps::ZstdInflate(IN Span data) { unsigned long long const contentSize = ZSTD_getFrameContentSize(data.data(), data.size()); @@ -412,7 +412,7 @@ namespace IACore return outBuffer; } - Expected, String> DataOps::ZstdDeflate(IN Span data) + EXPECT(Vector) DataOps::ZstdDeflate(IN Span data) { size_t const maxDstSize = ZSTD_compressBound(data.size()); @@ -428,7 +428,7 @@ namespace IACore return outBuffer; } - Expected, String> DataOps::GZipDeflate(IN Span data) + EXPECT(Vector) DataOps::GZipDeflate(IN Span data) { z_stream zs{}; zs.zalloc = Z_NULL; @@ -465,7 +465,7 @@ namespace IACore return outBuffer; } - Expected, String> DataOps::GZipInflate(IN Span data) + EXPECT(Vector) DataOps::GZipInflate(IN Span data) { return ZlibInflate(data); } diff --git a/Src/IACore/imp/cpp/FileOps.cpp b/Src/IACore/imp/cpp/FileOps.cpp index 03aa2f2..5046907 100644 --- a/Src/IACore/imp/cpp/FileOps.cpp +++ b/Src/IACore/imp/cpp/FileOps.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ namespace IACore #endif } - Expected FileOps::MapSharedMemory(IN CONST String &name, IN SIZE_T size, IN BOOL isOwner) + EXPECT(PUINT8) FileOps::MapSharedMemory(IN CONST String &name, IN SIZE_T size, IN BOOL isOwner) { #if IA_PLATFORM_WINDOWS int wchars_num = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), -1, NULL, 0); @@ -112,7 +112,7 @@ namespace IACore #endif } - Expected FileOps::MapFile(IN CONST FilePath &path, OUT SIZE_T &size) + EXPECT(PCUINT8) FileOps::MapFile(IN CONST FilePath &path, OUT SIZE_T &size) { #if IA_PLATFORM_WINDOWS @@ -182,21 +182,21 @@ namespace IACore #endif } - Expected FileOps::StreamToFile(IN CONST FilePath &path, IN BOOL overwrite) + EXPECT(StreamWriter) FileOps::StreamToFile(IN CONST FilePath &path, IN BOOL overwrite) { if (!overwrite && FileSystem::exists(path)) return MakeUnexpected(std::format("File aready exists: {}", path.string().c_str())); return StreamWriter(path); } - Expected FileOps::StreamFromFile(IN CONST FilePath &path) + EXPECT(StreamReader) FileOps::StreamFromFile(IN CONST FilePath &path) { if (!FileSystem::exists(path)) return MakeUnexpected(std::format("File does not exist: {}", path.string().c_str())); return StreamReader(path); } - Expected FileOps::ReadTextFile(IN CONST FilePath &path) + EXPECT(String) FileOps::ReadTextFile(IN CONST FilePath &path) { const auto f = fopen(path.string().c_str(), "r"); if (!f) @@ -210,7 +210,7 @@ namespace IACore return result; } - Expected, String> FileOps::ReadBinaryFile(IN CONST FilePath &path) + EXPECT(Vector) FileOps::ReadBinaryFile(IN CONST FilePath &path) { const auto f = fopen(path.string().c_str(), "rb"); if (!f) @@ -224,8 +224,7 @@ namespace IACore return result; } - Expected FileOps::WriteTextFile(IN CONST FilePath &path, IN CONST String &contents, - IN BOOL overwrite) + EXPECT(SIZE_T) FileOps::WriteTextFile(IN CONST FilePath &path, IN CONST String &contents, IN BOOL overwrite) { const char *mode = overwrite ? "w" : "wx"; const auto f = fopen(path.string().c_str(), mode); @@ -240,8 +239,7 @@ namespace IACore return result; } - Expected FileOps::WriteBinaryFile(IN CONST FilePath &path, IN Span contents, - IN BOOL overwrite) + EXPECT(SIZE_T) FileOps::WriteBinaryFile(IN CONST FilePath &path, IN Span contents, IN BOOL overwrite) { const char *mode = overwrite ? "w" : "wx"; const auto f = fopen(path.string().c_str(), mode); @@ -281,8 +279,8 @@ namespace IACore namespace IACore { - Expected FileOps::NativeOpenFile(IN CONST FilePath &path, IN EFileAccess access, - IN EFileMode mode, IN UINT32 permissions) + EXPECT(NativeFileHandle) + FileOps::NativeOpenFile(IN CONST FilePath &path, IN EFileAccess access, IN EFileMode mode, IN UINT32 permissions) { #if IA_PLATFORM_WINDOWS DWORD dwAccess = 0; @@ -414,7 +412,7 @@ namespace IACore return *this; } - Expected FileOps::MemoryMappedRegion::Map(NativeFileHandle handle, UINT64 offset, SIZE_T size) + EXPECT(VOID) FileOps::MemoryMappedRegion::Map(NativeFileHandle handle, UINT64 offset, SIZE_T size) { Unmap(); diff --git a/Src/IACore/imp/cpp/Http/Client.cpp b/Src/IACore/imp/cpp/Http/Client.cpp new file mode 100644 index 0000000..89e3ad4 --- /dev/null +++ b/Src/IACore/imp/cpp/Http/Client.cpp @@ -0,0 +1,139 @@ +// IACore-OSS; The Core Library for All IA Open Source Projects +// Copyright (C) 2026 IAS (ias@iasoft.dev) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +namespace IACore +{ + EXPECT(UniquePtr) HttpClient::Create(IN CONST String &host) + { + return MakeUniqueProtected(httplib::Client(host)); + } + + httplib::Headers BuildHeaders(IN Span headers, IN PCCHAR defaultContentType) + { + httplib::Headers out; + bool hasContentType = false; + + for (const auto &h : headers) + { + out.emplace(h.first, h.second); + + if (h.first == HttpClient::HeaderTypeToString(HttpClient::EHeaderType::CONTENT_TYPE)) + hasContentType = true; + } + + if (!hasContentType && defaultContentType) + out.emplace("Content-Type", defaultContentType); + return out; + } + + HttpClient::HttpClient(IN httplib::Client &&client) + : m_client(IA_MOVE(client)), m_lastResponseCode(EResponseCode::INTERNAL_SERVER_ERROR) + { + m_client.enable_server_certificate_verification(true); + } + + HttpClient::~HttpClient() + { + } + + VOID HttpClient::EnableCertificateVerfication() + { + m_client.enable_server_certificate_verification(true); + } + + VOID HttpClient::DisableCertificateVerfication() + { + m_client.enable_server_certificate_verification(false); + } + + String HttpClient::PreprocessResponse(IN CONST String &response) + { + const auto responseBytes = Span{(PCUINT8) response.data(), response.size()}; + const auto compression = DataOps::DetectCompression(responseBytes); + switch (compression) + { + case DataOps::CompressionType::Gzip: { + const auto data = DataOps::GZipInflate(responseBytes); + if (!data) + return response; + return String((PCCHAR) data->data(), data->size()); + } + + case DataOps::CompressionType::Zlib: { + const auto data = DataOps::ZlibInflate(responseBytes); + if (!data) + return response; + return String((PCCHAR) data->data(), data->size()); + } + + case DataOps::CompressionType::None: + default: + break; + } + return response; + } + + EXPECT(String) + HttpClient::RawGet(IN CONST String &path, IN Span headers, IN PCCHAR defaultContentType) + { + auto httpHeaders = BuildHeaders(headers, defaultContentType); + + auto res = m_client.Get((!path.empty() && path[0] != '/') ? ('/' + path).c_str() : path.c_str(), httpHeaders); + + if (res) + { + m_lastResponseCode = static_cast(res->status); + if (res->status >= 200 && res->status < 300) + return PreprocessResponse(res->body); + else + return MakeUnexpected(std::format("HTTP Error {} : {}", res->status, res->body)); + } + + return MakeUnexpected(std::format("Network Error: {}", httplib::to_string(res.error()))); + } + + EXPECT(String) + HttpClient::RawPost(IN CONST String &path, IN Span headers, IN CONST String &body, + IN PCCHAR defaultContentType) + { + auto httpHeaders = BuildHeaders(headers, defaultContentType); + + String contentType = defaultContentType; + if (httpHeaders.count("Content-Type")) + { + const auto t = httpHeaders.find("Content-Type"); + contentType = t->second; + httpHeaders.erase(t); + } + + m_client.set_keep_alive(true); + auto res = m_client.Post((!path.empty() && path[0] != '/') ? ('/' + path).c_str() : path.c_str(), httpHeaders, + body, contentType.c_str()); + + if (res) + { + m_lastResponseCode = static_cast(res->status); + if (res->status >= 200 && res->status < 300) + return PreprocessResponse(res->body); + else + return MakeUnexpected(std::format("HTTP Error {} : {}", res->status, res->body)); + } + + return MakeUnexpected(std::format("Network Error: {}", httplib::to_string(res.error()))); + } +} // namespace IACore diff --git a/Src/IACore/imp/cpp/Http/Common.cpp b/Src/IACore/imp/cpp/Http/Common.cpp new file mode 100644 index 0000000..e313f91 --- /dev/null +++ b/Src/IACore/imp/cpp/Http/Common.cpp @@ -0,0 +1,124 @@ +// IACore-OSS; The Core Library for All IA Open Source Projects +// Copyright (C) 2026 IAS (ias@iasoft.dev) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +namespace IACore +{ + String HttpCommon::UrlEncode(IN CONST String &value) + { + std::stringstream escaped; + escaped.fill('0'); + escaped << std::hex << std::uppercase; + + for (char c : value) + { + if (std::isalnum(static_cast(c)) || c == '-' || c == '_' || c == '.' || c == '~') + escaped << c; + else + escaped << '%' << std::setw(2) << static_cast(static_cast(c)); + } + + return escaped.str(); + } + + String HttpCommon::UrlDecode(IN CONST String &value) + { + String result; + result.reserve(value.length()); + + for (size_t i = 0; i < value.length(); ++i) + { + if (value[i] == '%' && i + 2 < value.length()) + { + std::string hexStr = value.substr(i + 1, 2); + char decodedChar = static_cast(std::strtol(hexStr.c_str(), nullptr, 16)); + result += decodedChar; + i += 2; + } + else if (value[i] == '+') + result += ' '; + else + result += value[i]; + } + + return result; + } + + String HttpCommon::HeaderTypeToString(IN EHeaderType type) + { + switch (type) + { + case EHeaderType::ACCEPT: + return "Accept"; + case EHeaderType::ACCEPT_CHARSET: + return "Accept-Charset"; + case EHeaderType::ACCEPT_ENCODING: + return "Accept-Encoding"; + case EHeaderType::ACCEPT_LANGUAGE: + return "Accept-Language"; + case EHeaderType::AUTHORIZATION: + return "Authorization"; + case EHeaderType::CACHE_CONTROL: + return "Cache-Control"; + case EHeaderType::CONNECTION: + return "Connection"; + case EHeaderType::CONTENT_LENGTH: + return "Content-Length"; + case EHeaderType::CONTENT_TYPE: + return "Content-Type"; + case EHeaderType::COOKIE: + return "Cookie"; + case EHeaderType::DATE: + return "Date"; + case EHeaderType::EXPECT: + return "Expect"; + case EHeaderType::HOST: + return "Host"; + case EHeaderType::IF_MATCH: + return "If-Match"; + case EHeaderType::IF_MODIFIED_SINCE: + return "If-Modified-Since"; + case EHeaderType::IF_NONE_MATCH: + return "If-None-Match"; + case EHeaderType::ORIGIN: + return "Origin"; + case EHeaderType::PRAGMA: + return "Pragma"; + case EHeaderType::PROXY_AUTHORIZATION: + return "Proxy-Authorization"; + case EHeaderType::RANGE: + return "Range"; + case EHeaderType::REFERER: + return "Referer"; + case EHeaderType::TE: + return "TE"; + case EHeaderType::UPGRADE: + return "Upgrade"; + case EHeaderType::USER_AGENT: + return "User-Agent"; + case EHeaderType::VIA: + return "Via"; + case EHeaderType::WARNING: + return "Warning"; + } + return ""; + } + + BOOL HttpCommon::IsSuccessResponseCode(IN EResponseCode code) + { + return (INT32) code >= 200 && (INT32) code < 300; + } +} // namespace IACore \ No newline at end of file diff --git a/Src/IACore/imp/cpp/Http/Server.cpp b/Src/IACore/imp/cpp/Http/Server.cpp new file mode 100644 index 0000000..30f6ffe --- /dev/null +++ b/Src/IACore/imp/cpp/Http/Server.cpp @@ -0,0 +1,21 @@ +// IACore-OSS; The Core Library for All IA Open Source Projects +// Copyright (C) 2026 IAS (ias@iasoft.dev) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +namespace IACore +{ + +} \ No newline at end of file diff --git a/Src/IACore/imp/cpp/HttpClient.cpp b/Src/IACore/imp/cpp/HttpClient.cpp deleted file mode 100644 index 1305d25..0000000 --- a/Src/IACore/imp/cpp/HttpClient.cpp +++ /dev/null @@ -1,238 +0,0 @@ -// IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#include - -namespace IACore -{ - httplib::Headers BuildHeaders(IN Span headers, IN PCCHAR defaultContentType) - { - httplib::Headers out; - bool hasContentType = false; - - for (const auto &h : headers) - { - out.emplace(h.first, h.second); - - if (h.first == HttpClient::HeaderTypeToString(HttpClient::EHeaderType::CONTENT_TYPE)) - hasContentType = true; - } - - if (!hasContentType && defaultContentType) - out.emplace("Content-Type", defaultContentType); - return out; - } - - HttpClient::HttpClient(IN CONST String &host) - : m_client(new httplib::Client(host)), m_lastResponseCode(EResponseCode::INTERNAL_SERVER_ERROR) - { - } - - HttpClient::~HttpClient() - { - if (m_client) - delete static_cast(m_client); - } - - String HttpClient::PreprocessResponse(IN CONST String &response) - { - const auto responseBytes = Span{(PCUINT8) response.data(), response.size()}; - const auto compression = DataOps::DetectCompression(responseBytes); - switch (compression) - { - case DataOps::CompressionType::Gzip: { - const auto data = DataOps::GZipInflate(responseBytes); - if (!data) - return response; - return String((PCCHAR) data->data(), data->size()); - } - - case DataOps::CompressionType::Zlib: { - const auto data = DataOps::ZlibInflate(responseBytes); - if (!data) - return response; - return String((PCCHAR) data->data(), data->size()); - } - - case DataOps::CompressionType::None: - default: - break; - } - return response; - } - - Expected HttpClient::RawGet(IN CONST String &path, IN Span headers, - IN PCCHAR defaultContentType) - { - auto httpHeaders = BuildHeaders(headers, defaultContentType); - - static_cast(m_client)->enable_server_certificate_verification(false); - auto res = static_cast(m_client)->Get( - (!path.empty() && path[0] != '/') ? ('/' + path).c_str() : path.c_str(), httpHeaders); - - if (res) - { - m_lastResponseCode = static_cast(res->status); - if (res->status >= 200 && res->status < 300) - return PreprocessResponse(res->body); - else - return MakeUnexpected(std::format("HTTP Error {} : {}", res->status, res->body)); - } - - return MakeUnexpected(std::format("Network Error: {}", httplib::to_string(res.error()))); - } - - Expected HttpClient::RawPost(IN CONST String &path, IN Span headers, - IN CONST String &body, IN PCCHAR defaultContentType) - { - auto httpHeaders = BuildHeaders(headers, defaultContentType); - - String contentType = defaultContentType; - if (httpHeaders.count("Content-Type")) - { - const auto t = httpHeaders.find("Content-Type"); - contentType = t->second; - httpHeaders.erase(t); - } - - static_cast(m_client)->set_keep_alive(true); - static_cast(m_client)->enable_server_certificate_verification(false); - auto res = static_cast(m_client)->Post( - (!path.empty() && path[0] != '/') ? ('/' + path).c_str() : path.c_str(), httpHeaders, body, - contentType.c_str()); - - if (res) - { - m_lastResponseCode = static_cast(res->status); - if (res->status >= 200 && res->status < 300) - return PreprocessResponse(res->body); - else - return MakeUnexpected(std::format("HTTP Error {} : {}", res->status, res->body)); - } - - return MakeUnexpected(std::format("Network Error: {}", httplib::to_string(res.error()))); - } -} // namespace IACore - -namespace IACore -{ - String HttpClient::UrlEncode(IN CONST String &value) - { - std::stringstream escaped; - escaped.fill('0'); - escaped << std::hex << std::uppercase; - - for (char c : value) - { - if (std::isalnum(static_cast(c)) || c == '-' || c == '_' || c == '.' || c == '~') - escaped << c; - else - escaped << '%' << std::setw(2) << static_cast(static_cast(c)); - } - - return escaped.str(); - } - - String HttpClient::UrlDecode(IN CONST String &value) - { - String result; - result.reserve(value.length()); - - for (size_t i = 0; i < value.length(); ++i) - { - if (value[i] == '%' && i + 2 < value.length()) - { - std::string hexStr = value.substr(i + 1, 2); - char decodedChar = static_cast(std::strtol(hexStr.c_str(), nullptr, 16)); - result += decodedChar; - i += 2; - } - else if (value[i] == '+') - result += ' '; - else - result += value[i]; - } - - return result; - } - - String HttpClient::HeaderTypeToString(IN EHeaderType type) - { - switch (type) - { - case EHeaderType::ACCEPT: - return "Accept"; - case EHeaderType::ACCEPT_CHARSET: - return "Accept-Charset"; - case EHeaderType::ACCEPT_ENCODING: - return "Accept-Encoding"; - case EHeaderType::ACCEPT_LANGUAGE: - return "Accept-Language"; - case EHeaderType::AUTHORIZATION: - return "Authorization"; - case EHeaderType::CACHE_CONTROL: - return "Cache-Control"; - case EHeaderType::CONNECTION: - return "Connection"; - case EHeaderType::CONTENT_LENGTH: - return "Content-Length"; - case EHeaderType::CONTENT_TYPE: - return "Content-Type"; - case EHeaderType::COOKIE: - return "Cookie"; - case EHeaderType::DATE: - return "Date"; - case EHeaderType::EXPECT: - return "Expect"; - case EHeaderType::HOST: - return "Host"; - case EHeaderType::IF_MATCH: - return "If-Match"; - case EHeaderType::IF_MODIFIED_SINCE: - return "If-Modified-Since"; - case EHeaderType::IF_NONE_MATCH: - return "If-None-Match"; - case EHeaderType::ORIGIN: - return "Origin"; - case EHeaderType::PRAGMA: - return "Pragma"; - case EHeaderType::PROXY_AUTHORIZATION: - return "Proxy-Authorization"; - case EHeaderType::RANGE: - return "Range"; - case EHeaderType::REFERER: - return "Referer"; - case EHeaderType::TE: - return "TE"; - case EHeaderType::UPGRADE: - return "Upgrade"; - case EHeaderType::USER_AGENT: - return "User-Agent"; - case EHeaderType::VIA: - return "Via"; - case EHeaderType::WARNING: - return "Warning"; - } - return ""; - } - - BOOL HttpClient::IsSuccessResponseCode(IN EResponseCode code) - { - return (INT32) code >= 200 && (INT32) code < 300; - } -} // namespace IACore \ No newline at end of file diff --git a/Src/IACore/imp/cpp/IACore.cpp b/Src/IACore/imp/cpp/IACore.cpp index 145203b..6bea1e8 100644 --- a/Src/IACore/imp/cpp/IACore.cpp +++ b/Src/IACore/imp/cpp/IACore.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/imp/cpp/IPC.cpp b/Src/IACore/imp/cpp/IPC.cpp index edccf32..800823b 100644 --- a/Src/IACore/imp/cpp/IPC.cpp +++ b/Src/IACore/imp/cpp/IPC.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -83,7 +83,7 @@ namespace IACore SocketOps::Close(m_socket); // SocketOps gracefully handles INVALID_SOCKET } - Expected IPC_Node::Connect(IN PCCHAR connectionString) + EXPECT(VOID) IPC_Node::Connect(IN PCCHAR connectionString) { auto desc = IPC_ConnectionDescriptor::Deserialize(connectionString); m_shmName = desc.SharedMemPath; @@ -287,8 +287,7 @@ namespace IACore } } - Expected IPC_Manager::SpawnNode(IN CONST FilePath &executablePath, - IN UINT32 sharedMemorySize) + EXPECT(NativeProcessID) IPC_Manager::SpawnNode(IN CONST FilePath &executablePath, IN UINT32 sharedMemorySize) { auto session = std::make_unique(); @@ -364,7 +363,7 @@ namespace IACore puts(std::format(__CC_MAGENTA "[Node:{}:STDOUT|STDERR]: {}" __CC_DEFAULT, sid, line).c_str()); #endif }, - [sid](IN Expected result) { + [sid](IN EXPECT(INT32) result) { UNUSED(sid); UNUSED(result); #if __IA_DEBUG diff --git a/Src/IACore/imp/cpp/JSON.cpp b/Src/IACore/imp/cpp/JSON.cpp index 303d33b..5e0e5b3 100644 --- a/Src/IACore/imp/cpp/JSON.cpp +++ b/Src/IACore/imp/cpp/JSON.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ namespace IACore { - Expected JSON::Parse(IN CONST String &json) + EXPECT(nlohmann::json) JSON::Parse(IN CONST String &json) { const auto parseResult = nlohmann::json::parse(json, nullptr, false, true); if (parseResult.is_discarded()) @@ -25,8 +25,7 @@ namespace IACore return parseResult; } - Expected, simdjson::dom::object>, String> JSON::ParseReadOnly( - IN CONST String &json) + EXPECT(Pair, simdjson::dom::object>) JSON::ParseReadOnly(IN CONST String &json) { auto parser = std::make_shared(); diff --git a/Src/IACore/imp/cpp/Logger.cpp b/Src/IACore/imp/cpp/Logger.cpp index 9fd3472..1a0601c 100644 --- a/Src/IACore/imp/cpp/Logger.cpp +++ b/Src/IACore/imp/cpp/Logger.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/imp/cpp/Platform.cpp b/Src/IACore/imp/cpp/Platform.cpp index dbf1d50..33a07d1 100644 --- a/Src/IACore/imp/cpp/Platform.cpp +++ b/Src/IACore/imp/cpp/Platform.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/imp/cpp/ProcessOps.cpp b/Src/IACore/imp/cpp/ProcessOps.cpp index 5638991..33113bc 100644 --- a/Src/IACore/imp/cpp/ProcessOps.cpp +++ b/Src/IACore/imp/cpp/ProcessOps.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -42,8 +42,10 @@ namespace IACore #endif } - Expected ProcessOps::SpawnProcessSync(IN CONST String &command, IN CONST String &args, - IN Function onOutputLineCallback) + EXPECT(INT32) + + ProcessOps::SpawnProcessSync(IN CONST String &command, IN CONST String &args, + IN Function onOutputLineCallback) { Atomic id; #if IA_PLATFORM_WINDOWS @@ -55,7 +57,7 @@ namespace IACore SharedPtr ProcessOps::SpawnProcessAsync(IN CONST String &command, IN CONST String &args, IN Function onOutputLineCallback, - IN Function)> onFinishCallback) + IN Function onFinishCallback) { SharedPtr handle = std::make_shared(); handle->IsRunning = true; @@ -108,19 +110,20 @@ namespace IACore namespace IACore { #if IA_PLATFORM_WINDOWS - Expected ProcessOps::SpawnProcessWindows(IN CONST String &command, IN CONST String &args, - IN Function onOutputLineCallback, - OUT Atomic &id) + EXPECT(INT32) + + ProcessOps::SpawnProcessWindows(IN CONST String &command, IN CONST String &args, + IN Function onOutputLineCallback, OUT Atomic &id) { SECURITY_ATTRIBUTES saAttr = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; // Allow inheritance HANDLE hRead = NULL, hWrite = NULL; if (!CreatePipe(&hRead, &hWrite, &saAttr, 0)) - return tl::make_unexpected("Failed to create pipe"); + return MakeUnexpected("Failed to create pipe"); // Ensure the read handle to the pipe for STDOUT is NOT inherited if (!SetHandleInformation(hRead, HANDLE_FLAG_INHERIT, 0)) - return tl::make_unexpected("Failed to secure pipe handles"); + return MakeUnexpected("Failed to secure pipe handles"); STARTUPINFOA si = {sizeof(STARTUPINFOA)}; si.dwFlags |= STARTF_USESTDHANDLES; @@ -141,7 +144,7 @@ namespace IACore if (!success) { CloseHandle(hRead); - return tl::make_unexpected(String("CreateProcess failed: ") + std::to_string(GetLastError())); + return MakeUnexpected(String("CreateProcess failed: ") + std::to_string(GetLastError())); } id.store(pi.dwProcessId); @@ -172,19 +175,20 @@ namespace IACore #endif #if IA_PLATFORM_UNIX - Expected ProcessOps::SpawnProcessPosix(IN CONST String &command, IN CONST String &args, - IN Function onOutputLineCallback, - OUT Atomic &id) + EXPECT(INT32) + + ProcessOps::SpawnProcessPosix(IN CONST String &command, IN CONST String &args, + IN Function onOutputLineCallback, OUT Atomic &id) { int pipefd[2]; if (pipe(pipefd) == -1) - return tl::make_unexpected("Failed to create pipe"); + return MakeUnexpected("Failed to create pipe"); pid_t pid = fork(); if (pid == -1) { - return tl::make_unexpected("Failed to fork process"); + return MakeUnexpected("Failed to fork process"); } else if (pid == 0) { diff --git a/Src/IACore/imp/cpp/SIMD.cpp b/Src/IACore/imp/cpp/SIMD.cpp index b3a2078..d098ae1 100644 --- a/Src/IACore/imp/cpp/SIMD.cpp +++ b/Src/IACore/imp/cpp/SIMD.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/imp/cpp/SocketOps.cpp b/Src/IACore/imp/cpp/SocketOps.cpp index 63f4909..c5c5743 100644 --- a/Src/IACore/imp/cpp/SocketOps.cpp +++ b/Src/IACore/imp/cpp/SocketOps.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/imp/cpp/StreamReader.cpp b/Src/IACore/imp/cpp/StreamReader.cpp index 23d0a29..1e7444a 100644 --- a/Src/IACore/imp/cpp/StreamReader.cpp +++ b/Src/IACore/imp/cpp/StreamReader.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/imp/cpp/StreamWriter.cpp b/Src/IACore/imp/cpp/StreamWriter.cpp index 1552773..a27df44 100644 --- a/Src/IACore/imp/cpp/StreamWriter.cpp +++ b/Src/IACore/imp/cpp/StreamWriter.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/imp/cpp/StringOps.cpp b/Src/IACore/imp/cpp/StringOps.cpp index abf83a3..adf69f8 100644 --- a/Src/IACore/imp/cpp/StringOps.cpp +++ b/Src/IACore/imp/cpp/StringOps.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/imp/cpp/XML.cpp b/Src/IACore/imp/cpp/XML.cpp index d69ee2e..2b69724 100644 --- a/Src/IACore/imp/cpp/XML.cpp +++ b/Src/IACore/imp/cpp/XML.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ namespace IACore { - Expected XML::ParseFromString(IN CONST String &data) + EXPECT(XML::Document) XML::ParseFromString(IN CONST String &data) { Document doc; const auto parseResult = doc.load_string(data.data()); @@ -26,7 +26,7 @@ namespace IACore return IA_MOVE(doc); } - Expected XML::ParseFromFile(IN CONST FilePath &path) + EXPECT(XML::Document) XML::ParseFromFile(IN CONST FilePath &path) { Document doc; const auto parseResult = doc.load_file(path.string().c_str()); diff --git a/Src/IACore/inc/IACore/ADT/RingBuffer.hpp b/Src/IACore/inc/IACore/ADT/RingBuffer.hpp index 94b1e48..3c0d32e 100644 --- a/Src/IACore/inc/IACore/ADT/RingBuffer.hpp +++ b/Src/IACore/inc/IACore/ADT/RingBuffer.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/inc/IACore/AsyncOps.hpp b/Src/IACore/inc/IACore/AsyncOps.hpp index c92edb3..d210591 100644 --- a/Src/IACore/inc/IACore/AsyncOps.hpp +++ b/Src/IACore/inc/IACore/AsyncOps.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/inc/IACore/DataOps.hpp b/Src/IACore/inc/IACore/DataOps.hpp index 0bf68ef..0267dc5 100644 --- a/Src/IACore/inc/IACore/DataOps.hpp +++ b/Src/IACore/inc/IACore/DataOps.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -40,13 +40,13 @@ namespace IACore STATIC CompressionType DetectCompression(IN Span data); - STATIC Expected, String> GZipInflate(IN Span data); - STATIC Expected, String> GZipDeflate(IN Span data); + STATIC EXPECT(Vector) GZipInflate(IN Span data); + STATIC EXPECT(Vector) GZipDeflate(IN Span data); - STATIC Expected, String> ZlibInflate(IN Span data); - STATIC Expected, String> ZlibDeflate(IN Span data); + STATIC EXPECT(Vector) ZlibInflate(IN Span data); + STATIC EXPECT(Vector) ZlibDeflate(IN Span data); - STATIC Expected, String> ZstdInflate(IN Span data); - STATIC Expected, String> ZstdDeflate(IN Span data); + STATIC EXPECT(Vector) ZstdInflate(IN Span data); + STATIC EXPECT(Vector) ZstdDeflate(IN Span data); }; } // namespace IACore \ No newline at end of file diff --git a/Src/IACore/inc/IACore/DynamicLib.hpp b/Src/IACore/inc/IACore/DynamicLib.hpp index d50659e..f189aa4 100644 --- a/Src/IACore/inc/IACore/DynamicLib.hpp +++ b/Src/IACore/inc/IACore/DynamicLib.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -61,7 +61,7 @@ namespace IACore // Automatically detects extension (.dll/.so) if not provided NO_DISCARD("Check for load errors") - STATIC tl::expected Load(CONST String &searchPath, CONST String &name) + STATIC tl::EXPECT(DynamicLib) Load(CONST String &searchPath, CONST String &name) { namespace fs = std::filesystem; @@ -84,7 +84,7 @@ namespace IACore HMODULE h = LoadLibraryA(fullPath.string().c_str()); if (!h) { - return tl::make_unexpected(GetWindowsError()); + return MakeUnexpected(GetWindowsError()); } lib.m_handle = CAST(h, PVOID); #else @@ -94,7 +94,7 @@ namespace IACore { // dlerror returns a string describing the last error const char *err = dlerror(); - return tl::make_unexpected(String(err ? err : "Unknown dlopen error")); + return MakeUnexpected(String(err ? err : "Unknown dlopen error")); } lib.m_handle = h; #endif @@ -104,35 +104,35 @@ namespace IACore NO_DISCARD("Check if symbol exists") - tl::expected GetSymbol(CONST String &name) CONST + tl::EXPECT(PVOID) GetSymbol(CONST String &name) CONST { if (!m_handle) - return tl::make_unexpected(String("Library not loaded")); + return MakeUnexpected(String("Library not loaded")); PVOID sym = nullptr; #if IA_PLATFORM_WINDOWS sym = CAST(GetProcAddress(CAST(m_handle, HMODULE), name.c_str()), PVOID); if (!sym) - return tl::make_unexpected(GetWindowsError()); + return MakeUnexpected(GetWindowsError()); #else // Clear any previous error dlerror(); sym = dlsym(m_handle, name.c_str()); const char *err = dlerror(); if (err) - return tl::make_unexpected(String(err)); + return MakeUnexpected(String(err)); #endif return sym; } // Template helper for casting - template tl::expected GetFunction(CONST String &name) CONST + template tl::EXPECT(FuncT) GetFunction(CONST String &name) CONST { auto res = GetSymbol(name); if (!res) - return tl::make_unexpected(res.error()); + return MakeUnexpected(res.error()); return REINTERPRET(*res, FuncT); } diff --git a/Src/IACore/inc/IACore/Environment.hpp b/Src/IACore/inc/IACore/Environment.hpp index d9dae26..2eb5052 100644 --- a/Src/IACore/inc/IACore/Environment.hpp +++ b/Src/IACore/inc/IACore/Environment.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/inc/IACore/FileOps.hpp b/Src/IACore/inc/IACore/FileOps.hpp index b302d0b..a0e6ce6 100644 --- a/Src/IACore/inc/IACore/FileOps.hpp +++ b/Src/IACore/inc/IACore/FileOps.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -49,8 +49,8 @@ namespace IACore TRUNCATE_EXISTING // Opens existing and clears it }; - STATIC Expected NativeOpenFile(IN CONST FilePath &path, IN EFileAccess access, - IN EFileMode mode, IN UINT32 permissions = 0644); + STATIC EXPECT(NativeFileHandle) NativeOpenFile(IN CONST FilePath &path, IN EFileAccess access, + IN EFileMode mode, IN UINT32 permissions = 0644); STATIC VOID NativeCloseFile(IN NativeFileHandle handle); public: @@ -58,21 +58,21 @@ namespace IACore public: STATIC VOID UnmapFile(IN PCUINT8 mappedPtr); - STATIC Expected MapFile(IN CONST FilePath &path, OUT SIZE_T &size); + STATIC EXPECT(PCUINT8) MapFile(IN CONST FilePath &path, OUT SIZE_T &size); // @param `isOwner` TRUE to allocate/truncate. FALSE to just open. - STATIC Expected MapSharedMemory(IN CONST String &name, IN SIZE_T size, IN BOOL isOwner); + STATIC EXPECT(PUINT8) MapSharedMemory(IN CONST String &name, IN SIZE_T size, IN BOOL isOwner); STATIC VOID UnlinkSharedMemory(IN CONST String &name); - STATIC Expected StreamFromFile(IN CONST FilePath &path); - STATIC Expected StreamToFile(IN CONST FilePath &path, IN BOOL overwrite = false); + STATIC EXPECT(StreamReader) StreamFromFile(IN CONST FilePath &path); + STATIC EXPECT(StreamWriter) StreamToFile(IN CONST FilePath &path, IN BOOL overwrite = false); - STATIC Expected ReadTextFile(IN CONST FilePath &path); - STATIC Expected, String> ReadBinaryFile(IN CONST FilePath &path); - STATIC Expected WriteTextFile(IN CONST FilePath &path, IN CONST String &contents, - IN BOOL overwrite = false); - STATIC Expected WriteBinaryFile(IN CONST FilePath &path, IN Span contents, - IN BOOL overwrite = false); + STATIC EXPECT(String) ReadTextFile(IN CONST FilePath &path); + STATIC EXPECT(Vector) ReadBinaryFile(IN CONST FilePath &path); + STATIC EXPECT(SIZE_T) + WriteTextFile(IN CONST FilePath &path, IN CONST String &contents, IN BOOL overwrite = false); + STATIC EXPECT(SIZE_T) + WriteBinaryFile(IN CONST FilePath &path, IN Span contents, IN BOOL overwrite = false); private: STATIC UnorderedMap> s_mappedFiles; @@ -90,7 +90,7 @@ namespace IACore MemoryMappedRegion(MemoryMappedRegion &&other) NOEXCEPT; MemoryMappedRegion &operator=(MemoryMappedRegion &&other) NOEXCEPT; - Expected Map(NativeFileHandle handle, UINT64 offset, SIZE_T size); + EXPECT(VOID) Map(NativeFileHandle handle, UINT64 offset, SIZE_T size); VOID Unmap(); VOID Flush(); diff --git a/Src/IACore/inc/IACore/Http/Client.hpp b/Src/IACore/inc/IACore/Http/Client.hpp new file mode 100644 index 0000000..6e6dcd8 --- /dev/null +++ b/Src/IACore/inc/IACore/Http/Client.hpp @@ -0,0 +1,90 @@ +// IACore-OSS; The Core Library for All IA Open Source Projects +// Copyright (C) 2026 IAS (ias@iasoft.dev) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +namespace IACore +{ + class HttpClient : public HttpCommon + { + public: + STATIC EXPECT(UniquePtr) Create(IN CONST String &host); + + ~HttpClient(); + + public: + EXPECT(String) + RawGet(IN CONST String &path, IN Span headers, + IN PCCHAR defaultContentType = "application/x-www-form-urlencoded"); + EXPECT(String) + RawPost(IN CONST String &path, IN Span headers, IN CONST String &body, + IN PCCHAR defaultContentType = "application/x-www-form-urlencoded"); + + template + EXPECT(_response_type) + JsonGet(IN CONST String &path, IN Span headers); + + template + EXPECT(_response_type) + JsonPost(IN CONST String &path, IN Span headers, IN CONST _payload_type &body); + + // Certificate verfication is enabled by default + VOID EnableCertificateVerfication(); + VOID DisableCertificateVerfication(); + + public: + EResponseCode LastResponseCode() + { + return m_lastResponseCode; + } + + private: + httplib::Client m_client; + EResponseCode m_lastResponseCode; + + private: + String PreprocessResponse(IN CONST String &response); + + protected: + HttpClient(IN httplib::Client &&client); + }; + + template + EXPECT(_response_type) + HttpClient::JsonGet(IN CONST String &path, IN Span headers) + { + const auto rawResponse = RawGet(path, headers, "application/json"); + if (!rawResponse) + return MakeUnexpected(rawResponse.error()); + if (LastResponseCode() != EResponseCode::OK) + return MakeUnexpected(std::format("Server responded with code {}", (INT32) LastResponseCode())); + return JSON::ParseToStruct<_response_type>(*rawResponse); + } + + template + EXPECT(_response_type) + HttpClient::JsonPost(IN CONST String &path, IN Span headers, IN CONST _payload_type &body) + { + const auto encodedBody = IA_TRY(JSON::EncodeStruct(body)); + const auto rawResponse = RawPost(path, headers, encodedBody, "application/json"); + if (!rawResponse) + return MakeUnexpected(rawResponse.error()); + if (LastResponseCode() != EResponseCode::OK) + return MakeUnexpected(std::format("Server responded with code {}", (INT32) LastResponseCode())); + return JSON::ParseToStruct<_response_type>(*rawResponse); + } +} // namespace IACore \ No newline at end of file diff --git a/Src/IACore/inc/IACore/HttpClient.hpp b/Src/IACore/inc/IACore/Http/Common.hpp similarity index 62% rename from Src/IACore/inc/IACore/HttpClient.hpp rename to Src/IACore/inc/IACore/Http/Common.hpp index 20dfee0..09e761f 100644 --- a/Src/IACore/inc/IACore/HttpClient.hpp +++ b/Src/IACore/inc/IACore/Http/Common.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,9 +17,11 @@ #include +#include + namespace IACore { - class HttpClient + class HttpCommon { public: enum class EHeaderType @@ -129,24 +131,6 @@ namespace IACore using Header = KeyValuePair; - public: - HttpClient(IN CONST String &host); - ~HttpClient(); - - public: - Expected RawGet(IN CONST String &path, IN Span headers, - IN PCCHAR defaultContentType = "application/x-www-form-urlencoded"); - Expected RawPost(IN CONST String &path, IN Span headers, IN CONST String &body, - IN PCCHAR defaultContentType = "application/x-www-form-urlencoded"); - - template - Expected<_response_type, String> JsonGet(IN CONST String &path, IN Span headers); - - template - Expected<_response_type, String> JsonPost(IN CONST String &path, IN Span headers, - IN CONST _payload_type &body); - - public: STATIC String UrlEncode(IN CONST String &value); STATIC String UrlDecode(IN CONST String &value); @@ -157,50 +141,16 @@ namespace IACore STATIC BOOL IsSuccessResponseCode(IN EResponseCode code); - public: - EResponseCode LastResponseCode() - { - return m_lastResponseCode; - } - - private: - PVOID m_client{}; - EResponseCode m_lastResponseCode; - - private: - String PreprocessResponse(IN CONST String &response); + protected: + HttpCommon() = default; }; - template - Expected<_response_type, String> HttpClient::JsonGet(IN CONST String &path, IN Span headers) - { - const auto rawResponse = RawGet(path, headers, "application/json"); - if (!rawResponse) - return MakeUnexpected(rawResponse.error()); - if (LastResponseCode() != EResponseCode::OK) - return MakeUnexpected(std::format("Server responded with code {}", (INT32) LastResponseCode())); - return JSON::ParseToStruct<_response_type>(*rawResponse); - } - - template - Expected<_response_type, String> HttpClient::JsonPost(IN CONST String &path, IN Span headers, - IN CONST _payload_type &body) - { - const auto encodedBody = IA_TRY(JSON::EncodeStruct(body)); - const auto rawResponse = RawPost(path, headers, encodedBody, "application/json"); - if (!rawResponse) - return MakeUnexpected(rawResponse.error()); - if (LastResponseCode() != EResponseCode::OK) - return MakeUnexpected(std::format("Server responded with code {}", (INT32) LastResponseCode())); - return JSON::ParseToStruct<_response_type>(*rawResponse); - } - - HttpClient::Header HttpClient::CreateHeader(IN EHeaderType key, IN CONST String &value) + HttpCommon::Header HttpCommon::CreateHeader(IN EHeaderType key, IN CONST String &value) { return std::make_pair(HeaderTypeToString(key), value); } - HttpClient::Header HttpClient::CreateHeader(IN CONST String &key, IN CONST String &value) + HttpCommon::Header HttpCommon::CreateHeader(IN CONST String &key, IN CONST String &value) { return std::make_pair(key, value); } diff --git a/Src/IACore/inc/IACore/Http/Server.hpp b/Src/IACore/inc/IACore/Http/Server.hpp new file mode 100644 index 0000000..79548dc --- /dev/null +++ b/Src/IACore/inc/IACore/Http/Server.hpp @@ -0,0 +1,27 @@ +// IACore-OSS; The Core Library for All IA Open Source Projects +// Copyright (C) 2026 IAS (ias@iasoft.dev) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +namespace IACore +{ + class HttpServer : public HttpCommon + { + public: + HttpServer(IN CONST String &host, IN UINT32 port); + }; +} // namespace IACore \ No newline at end of file diff --git a/Src/IACore/inc/IACore/IACore.hpp b/Src/IACore/inc/IACore/IACore.hpp index 5b806ae..509a46d 100644 --- a/Src/IACore/inc/IACore/IACore.hpp +++ b/Src/IACore/inc/IACore/IACore.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ # include # define IACORE_MAIN() \ - Expected _app_entry(IN CONST Vector &args); \ + EXPECT(INT32) _app_entry(IN CONST Vector &args); \ int main(int argc, char *argv[]) \ { \ int exitCode = 0; \ @@ -44,7 +44,7 @@ IACore::Terminate(); \ return exitCode; \ } \ - Expected _app_entry(IN CONST Vector &args) + EXPECT(INT32) _app_entry(IN CONST Vector &args) namespace IACore { diff --git a/Src/IACore/inc/IACore/IATest.hpp b/Src/IACore/inc/IACore/IATest.hpp index 2e6eb21..9a5be8c 100644 --- a/Src/IACore/inc/IACore/IATest.hpp +++ b/Src/IACore/inc/IACore/IATest.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -73,17 +73,11 @@ namespace ia::iatest template std::string ToString(CONST T &value) { if constexpr (std::is_arithmetic_v) - { return std::to_string(value); - } else if constexpr (std::is_same_v || std::is_same_v) - { return std::string("\"") + value + "\""; - } else - { - return "{Object}"; // Fallback for complex types - } + return "{Object}"; } template std::string ToString(T *value) @@ -311,10 +305,8 @@ namespace ia::iatest printf(__CC_CYAN "[IATest] Discovered %zu Test Blocks\n\n" __CC_DEFAULT, entries.size()); for (auto &entry : entries) - { entry(r); - } - // The destructor of 'r' will automatically print the summary + return 0; } }; diff --git a/Src/IACore/inc/IACore/IPC.hpp b/Src/IACore/inc/IACore/IPC.hpp index 0f87297..34b2964 100644 --- a/Src/IACore/inc/IACore/IPC.hpp +++ b/Src/IACore/inc/IACore/IPC.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -75,7 +75,7 @@ namespace IACore // When Manager spawns a node, `connectionString` is passed // as the first command line argument - Expected Connect(IN PCCHAR connectionString); + EXPECT(VOID) Connect(IN PCCHAR connectionString); VOID Update(); @@ -129,8 +129,8 @@ namespace IACore VOID Update(); - Expected SpawnNode(IN CONST FilePath &executablePath, - IN UINT32 sharedMemorySize = DEFAULT_NODE_SHARED_MEMORY_SIZE); + EXPECT(NativeProcessID) + SpawnNode(IN CONST FilePath &executablePath, IN UINT32 sharedMemorySize = DEFAULT_NODE_SHARED_MEMORY_SIZE); BOOL WaitTillNodeIsOnline(IN NativeProcessID node); VOID ShutdownNode(IN NativeProcessID node); diff --git a/Src/IACore/inc/IACore/JSON.hpp b/Src/IACore/inc/IACore/JSON.hpp index 21f8a6c..342576f 100644 --- a/Src/IACore/inc/IACore/JSON.hpp +++ b/Src/IACore/inc/IACore/JSON.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,16 +29,16 @@ namespace IACore STATIC CONSTEXPR AUTO GLAZE_JSON_OPTS = glz::opts{.error_on_unknown_keys = false}; public: - STATIC Expected Parse(IN CONST String &json); - STATIC Expected, simdjson::dom::object>, String> ParseReadOnly( - IN CONST String &json); - template STATIC Expected<_object_type, String> ParseToStruct(IN CONST String &json); - + STATIC EXPECT(nlohmann::json) Parse(IN CONST String &json); + STATIC EXPECT(Pair, simdjson::dom::object>) + ParseReadOnly(IN CONST String &json); STATIC String Encode(IN nlohmann::json data); - template STATIC Expected EncodeStruct(IN CONST _object_type &data); + + template STATIC EXPECT(_object_type) ParseToStruct(IN CONST String &json); + template STATIC EXPECT(String) EncodeStruct(IN CONST _object_type &data); }; - template Expected<_object_type, String> JSON::ParseToStruct(IN CONST String &json) + template EXPECT(_object_type) JSON::ParseToStruct(IN CONST String &json) { _object_type result{}; const auto parseError = glz::read_json(result, json); @@ -47,7 +47,7 @@ namespace IACore return result; } - template Expected JSON::EncodeStruct(IN CONST _object_type &data) + template EXPECT(String) JSON::EncodeStruct(IN CONST _object_type &data) { String result; const auto encodeError = glz::write_json(data, result); diff --git a/Src/IACore/inc/IACore/Logger.hpp b/Src/IACore/inc/IACore/Logger.hpp index 7b2d320..445ccf7 100644 --- a/Src/IACore/inc/IACore/Logger.hpp +++ b/Src/IACore/inc/IACore/Logger.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/inc/IACore/PCH.hpp b/Src/IACore/inc/IACore/PCH.hpp index a4cdbaf..6615904 100644 --- a/Src/IACore/inc/IACore/PCH.hpp +++ b/Src/IACore/inc/IACore/PCH.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -339,7 +339,7 @@ auto _ia_res = (expr); \ if (!_ia_res) \ { \ - return tl::make_unexpected(std::move(_ia_res.error())); \ + return MakeUnexpected(std::move(_ia_res.error())); \ } \ } @@ -348,7 +348,7 @@ auto _ia_res = (expr); \ if (!_ia_res) \ { \ - return tl::make_unexpected(std::move(_ia_res.error())); \ + return MakeUnexpected(std::move(_ia_res.error())); \ } \ std::move(*_ia_res); \ }) @@ -358,7 +358,7 @@ auto _ia_res = (expr); \ if (!_ia_res) \ { \ - return tl::make_unexpected(std::move(_ia_res.error())); \ + return MakeUnexpected(std::move(_ia_res.error())); \ } \ UNUSED(*_ia_res); \ } @@ -595,7 +595,7 @@ template inline SharedPtr MakeSharedProtected(A return MakeShared(std::forward(args)...); } -template inline SharedPtr MakeUniqueProtected(Args &&...args) +template inline UniquePtr MakeUniqueProtected(Args &&...args) { struct make_unique_enabler : public T { @@ -610,7 +610,9 @@ template inline SharedPtr MakeUniqueProtected(A template using Expected = tl::expected<_expected_type, _unexpected_type>; ALIAS_FUNCTION(MakeUnexpected, tl::make_unexpected); -# define EXPECT(type) Expected + +# define EXPECT(...) Expected<__VA_ARGS__, String> +# define UNEXPECTED(...) MakeUnexpected(std::format(__VA_ARGS__)) using String = std::string; using StringView = std::string_view; diff --git a/Src/IACore/inc/IACore/Platform.hpp b/Src/IACore/inc/IACore/Platform.hpp index 79792c9..6ca7d20 100644 --- a/Src/IACore/inc/IACore/Platform.hpp +++ b/Src/IACore/inc/IACore/Platform.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/inc/IACore/ProcessOps.hpp b/Src/IACore/inc/IACore/ProcessOps.hpp index 9f721f2..a03d8b9 100644 --- a/Src/IACore/inc/IACore/ProcessOps.hpp +++ b/Src/IACore/inc/IACore/ProcessOps.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -48,20 +48,20 @@ namespace IACore public: STATIC NativeProcessID GetCurrentProcessID(); - STATIC Expected SpawnProcessSync(IN CONST String &command, IN CONST String &args, - IN Function onOutputLineCallback); + STATIC EXPECT(INT32) SpawnProcessSync(IN CONST String &command, IN CONST String &args, + IN Function onOutputLineCallback); STATIC SharedPtr SpawnProcessAsync(IN CONST String &command, IN CONST String &args, IN Function onOutputLineCallback, - IN Function)> onFinishCallback); + IN Function onFinishCallback); STATIC VOID TerminateProcess(IN CONST SharedPtr &handle); private: - STATIC Expected SpawnProcessWindows(IN CONST String &command, IN CONST String &args, - IN Function onOutputLineCallback, - OUT Atomic &id); - STATIC Expected SpawnProcessPosix(IN CONST String &command, IN CONST String &args, - IN Function onOutputLineCallback, - OUT Atomic &id); + STATIC EXPECT(INT32) + SpawnProcessWindows(IN CONST String &command, IN CONST String &args, + IN Function onOutputLineCallback, OUT Atomic &id); + STATIC EXPECT(INT32) + SpawnProcessPosix(IN CONST String &command, IN CONST String &args, + IN Function onOutputLineCallback, OUT Atomic &id); }; } // namespace IACore \ No newline at end of file diff --git a/Src/IACore/inc/IACore/SIMD.hpp b/Src/IACore/inc/IACore/SIMD.hpp index 115113b..550fb82 100644 --- a/Src/IACore/inc/IACore/SIMD.hpp +++ b/Src/IACore/inc/IACore/SIMD.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/inc/IACore/SocketOps.hpp b/Src/IACore/inc/IACore/SocketOps.hpp index ddec94b..f25203d 100644 --- a/Src/IACore/inc/IACore/SocketOps.hpp +++ b/Src/IACore/inc/IACore/SocketOps.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/inc/IACore/StreamReader.hpp b/Src/IACore/inc/IACore/StreamReader.hpp index abd4865..638d693 100644 --- a/Src/IACore/inc/IACore/StreamReader.hpp +++ b/Src/IACore/inc/IACore/StreamReader.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,8 +29,8 @@ namespace IACore }; public: - INLINE Expected Read(IN PVOID buffer, IN SIZE_T size); - template NO_DISCARD("Check for EOF") Expected Read(); + INLINE EXPECT(VOID) Read(IN PVOID buffer, IN SIZE_T size); + template NO_DISCARD("Check for EOF") EXPECT(T) Read(); VOID Skip(SIZE_T amount) { @@ -76,7 +76,7 @@ namespace IACore CONST EStorageType m_storageType; }; - Expected StreamReader::Read(IN PVOID buffer, IN SIZE_T size) + EXPECT(VOID) StreamReader::Read(IN PVOID buffer, IN SIZE_T size) { if B_UNLIKELY ((m_cursor + size > m_dataSize)) return MakeUnexpected(String("Unexpected EOF while reading")); @@ -87,7 +87,7 @@ namespace IACore return {}; } - template NO_DISCARD("Check for EOF") Expected StreamReader::Read() + template NO_DISCARD("Check for EOF") EXPECT(T) StreamReader::Read() { constexpr SIZE_T size = sizeof(T); diff --git a/Src/IACore/inc/IACore/StreamWriter.hpp b/Src/IACore/inc/IACore/StreamWriter.hpp index 2375396..df45ece 100644 --- a/Src/IACore/inc/IACore/StreamWriter.hpp +++ b/Src/IACore/inc/IACore/StreamWriter.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/inc/IACore/StringOps.hpp b/Src/IACore/inc/IACore/StringOps.hpp index c57cb2e..21762ae 100644 --- a/Src/IACore/inc/IACore/StringOps.hpp +++ b/Src/IACore/inc/IACore/StringOps.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Src/IACore/inc/IACore/Utils.hpp b/Src/IACore/inc/IACore/Utils.hpp index f5a9d0c..92a5be1 100644 --- a/Src/IACore/inc/IACore/Utils.hpp +++ b/Src/IACore/inc/IACore/Utils.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -39,11 +39,11 @@ namespace IACore return res; } - INLINE STATIC tl::expected, String> HexStringToBinary(CONST StringView &hex) + INLINE STATIC EXPECT(Vector) HexStringToBinary(CONST StringView &hex) { if (hex.size() % 2 != 0) { - return tl::make_unexpected(String("Hex string must have even length")); + return MakeUnexpected(String("Hex string must have even length")); } Vector out; @@ -69,7 +69,7 @@ namespace IACore if (h == -1 || l == -1) { - return tl::make_unexpected(String("Invalid hex character found")); + return MakeUnexpected(String("Invalid hex character found")); } out.push_back(CAST((h << 4) | l, UINT8)); diff --git a/Src/IACore/inc/IACore/XML.hpp b/Src/IACore/inc/IACore/XML.hpp index 1ba92a7..c1ceb3c 100644 --- a/Src/IACore/inc/IACore/XML.hpp +++ b/Src/IACore/inc/IACore/XML.hpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -28,8 +28,8 @@ namespace IACore using Document = pugi::xml_document; public: - STATIC Expected ParseFromString(IN CONST String &data); - STATIC Expected ParseFromFile(IN CONST FilePath &path); + STATIC EXPECT(Document) ParseFromString(IN CONST String &data); + STATIC EXPECT(Document) ParseFromFile(IN CONST FilePath &path); STATIC String SerializeToString(IN CONST Node &node, IN BOOL escape = false); STATIC String SerializeToString(IN CONST Document &doc, IN BOOL escape = false); diff --git a/Tests/Unit/CCompile.c b/Tests/Unit/CCompile.c index 17c65d4..ae28683 100644 --- a/Tests/Unit/CCompile.c +++ b/Tests/Unit/CCompile.c @@ -1,16 +1,16 @@ -// IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) -// +// IACore-OSS; The Core Library for All IA Open Source Projects +// Copyright (C) 2026 IAS (ias@iasoft.dev) +// // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -24,7 +24,8 @@ #error "TRUE macro is broken in C mode" #endif -int main(void) { +int main(void) +{ IA_VERSION_TYPE version = IA_MAKE_VERSION(1, 0, 0); IA_ASSERT(version > 0); @@ -32,8 +33,8 @@ int main(void) { UNUSED(version); int32_t myNumber = 10; - - (void)myNumber; + + (void)myNumber; return 0; } diff --git a/Tests/Unit/DataOps.cpp b/Tests/Unit/DataOps.cpp index 71129d0..7029758 100644 --- a/Tests/Unit/DataOps.cpp +++ b/Tests/Unit/DataOps.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Tests/Unit/Environment.cpp b/Tests/Unit/Environment.cpp index fb56e39..4294f6c 100644 --- a/Tests/Unit/Environment.cpp +++ b/Tests/Unit/Environment.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Tests/Unit/Main.cpp b/Tests/Unit/Main.cpp index 6f67532..a2d3bd8 100644 --- a/Tests/Unit/Main.cpp +++ b/Tests/Unit/Main.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Tests/Unit/ProcessOps.cpp b/Tests/Unit/ProcessOps.cpp index 17751ac..af263f2 100644 --- a/Tests/Unit/ProcessOps.cpp +++ b/Tests/Unit/ProcessOps.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Tests/Unit/RingBuffer.cpp b/Tests/Unit/RingBuffer.cpp index b7eb0bb..5c57555 100644 --- a/Tests/Unit/RingBuffer.cpp +++ b/Tests/Unit/RingBuffer.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Tests/Unit/SIMD/FloatVec4.cpp b/Tests/Unit/SIMD/FloatVec4.cpp index 98dd795..b3e2c26 100644 --- a/Tests/Unit/SIMD/FloatVec4.cpp +++ b/Tests/Unit/SIMD/FloatVec4.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Tests/Unit/SIMD/IntVec4.cpp b/Tests/Unit/SIMD/IntVec4.cpp index 072dd91..db230e0 100644 --- a/Tests/Unit/SIMD/IntVec4.cpp +++ b/Tests/Unit/SIMD/IntVec4.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // limitations under the License. // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) #include #include diff --git a/Tests/Unit/StreamReader.cpp b/Tests/Unit/StreamReader.cpp index 7ee8f7d..b4f38c4 100644 --- a/Tests/Unit/StreamReader.cpp +++ b/Tests/Unit/StreamReader.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Tests/Unit/Utils.cpp b/Tests/Unit/Utils.cpp index 904d853..ae7b358 100644 --- a/Tests/Unit/Utils.cpp +++ b/Tests/Unit/Utils.cpp @@ -1,5 +1,5 @@ // IACore-OSS; The Core Library for All IA Open Source Projects -// Copyright (C) 2025 IAS (ias@iasoft.dev) +// Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License.