Utils
This commit is contained in:
@ -4,6 +4,7 @@ set(SRC_FILES
|
|||||||
"imp/cpp/FileOps.cpp"
|
"imp/cpp/FileOps.cpp"
|
||||||
"imp/cpp/AsyncOps.cpp"
|
"imp/cpp/AsyncOps.cpp"
|
||||||
"imp/cpp/SocketOps.cpp"
|
"imp/cpp/SocketOps.cpp"
|
||||||
|
"imp/cpp/StringOps.cpp"
|
||||||
"imp/cpp/ProcessOps.cpp"
|
"imp/cpp/ProcessOps.cpp"
|
||||||
"imp/cpp/StreamReader.cpp"
|
"imp/cpp/StreamReader.cpp"
|
||||||
"imp/cpp/StreamWriter.cpp"
|
"imp/cpp/StreamWriter.cpp"
|
||||||
|
|||||||
@ -179,4 +179,20 @@ namespace IACore
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilePath FileOps::NormalizeExecutablePath(IN CONST FilePath &path)
|
||||||
|
{
|
||||||
|
#if IA_PLATFORM_WINDOWS
|
||||||
|
return path;
|
||||||
|
#elif IA_PLATFORM_UNIX
|
||||||
|
String result(path);
|
||||||
|
if (path.extension() == ".exe")
|
||||||
|
result.resize(result.size() - 4);
|
||||||
|
if (!path.is_absolute() && !path.string().starts_with("./"))
|
||||||
|
result = "./" + result;
|
||||||
|
return FilePath(result);
|
||||||
|
#else
|
||||||
|
# error "unreachable. previous checks must have stopped compilation beforehand .unsupported platform."
|
||||||
|
#endif
|
||||||
|
}
|
||||||
} // namespace IACore
|
} // namespace IACore
|
||||||
@ -15,10 +15,56 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include <IACore/IACore.hpp>
|
#include <IACore/IACore.hpp>
|
||||||
|
#include <IACore/Logger.hpp>
|
||||||
|
|
||||||
#include <mimalloc-new-delete.h>
|
#include <mimalloc-new-delete.h>
|
||||||
|
|
||||||
namespace IACore
|
namespace IACore
|
||||||
{
|
{
|
||||||
|
HRTimePoint g_startTime{};
|
||||||
|
std::thread::id g_mainThreadID{};
|
||||||
|
|
||||||
}
|
VOID Initialize()
|
||||||
|
{
|
||||||
|
g_mainThreadID = std::this_thread::get_id();
|
||||||
|
g_startTime = HRClock::now();
|
||||||
|
Logger::Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID Terminate()
|
||||||
|
{
|
||||||
|
Logger::Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT64 GetTicksCount()
|
||||||
|
{
|
||||||
|
return std::chrono::duration_cast<std::chrono::milliseconds>(HRClock::now() - g_startTime).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
FLOAT64 GetSecondsCount()
|
||||||
|
{
|
||||||
|
return (HRClock::now() - g_startTime).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 GetRandom(IN UINT32 seed)
|
||||||
|
{
|
||||||
|
srand(seed);
|
||||||
|
return (UINT32) GetRandom(0, UINT32_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
INT64 GetRandom(IN INT64 min, IN INT64 max)
|
||||||
|
{
|
||||||
|
const auto t = static_cast<FLOAT32>(rand()) / static_cast<FLOAT32>(RAND_MAX);
|
||||||
|
return min + (max - min) * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID Sleep(IN UINT64 milliseconds)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL IsMainThread()
|
||||||
|
{
|
||||||
|
return std::this_thread::get_id() == g_mainThreadID;
|
||||||
|
}
|
||||||
|
} // namespace IACore
|
||||||
@ -15,17 +15,16 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include <IACore/Logger.hpp>
|
#include <IACore/Logger.hpp>
|
||||||
|
#include <IACore/IACore.hpp>
|
||||||
#include <IACore/FileOps.hpp>
|
#include <IACore/FileOps.hpp>
|
||||||
|
|
||||||
namespace IACore
|
namespace IACore
|
||||||
{
|
{
|
||||||
Logger::ELogLevel Logger::s_logLevel{Logger::ELogLevel::WARN};
|
Logger::ELogLevel Logger::s_logLevel{Logger::ELogLevel::WARN};
|
||||||
HRTimePoint Logger::s_startTime{};
|
|
||||||
std::ofstream Logger::s_logFile{};
|
std::ofstream Logger::s_logFile{};
|
||||||
|
|
||||||
VOID Logger::Initialize()
|
VOID Logger::Initialize()
|
||||||
{
|
{
|
||||||
s_startTime = HRClock::now();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID Logger::Terminate()
|
VOID Logger::Terminate()
|
||||||
@ -55,9 +54,7 @@ namespace IACore
|
|||||||
|
|
||||||
VOID Logger::LogInternal(IN PCCHAR prefix, IN PCCHAR tag, IN String &&msg)
|
VOID Logger::LogInternal(IN PCCHAR prefix, IN PCCHAR tag, IN String &&msg)
|
||||||
{
|
{
|
||||||
std::chrono::duration<double> elapsed = HRClock::now() - s_startTime;
|
const auto outLine = std::format("[{:>8.3f}]: [{}]: {}", GetSecondsCount(), tag, msg);
|
||||||
double timestamp = elapsed.count();
|
|
||||||
const auto outLine = std::format("[{:>8.3f}]: [{}]: {}", timestamp, tag, msg);
|
|
||||||
std::cout << prefix << outLine << "\033[39m\n";
|
std::cout << prefix << outLine << "\033[39m\n";
|
||||||
if (s_logFile)
|
if (s_logFile)
|
||||||
{
|
{
|
||||||
|
|||||||
101
Src/IACore/imp/cpp/StringOps.cpp
Normal file
101
Src/IACore/imp/cpp/StringOps.cpp
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// IACore-OSS; The Core Library for All IA Open Source Projects
|
||||||
|
// Copyright (C) 2025 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <IACore/StringOps.hpp>
|
||||||
|
|
||||||
|
namespace IACore
|
||||||
|
{
|
||||||
|
CONST String BASE64_CHAR_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
String StringOps::EncodeBase64(IN Span<CONST UINT8> data)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
result.reserve(((data.size() + 2) / 3) * 4);
|
||||||
|
for (size_t i = 0; i < data.size(); i += 3)
|
||||||
|
{
|
||||||
|
uint32_t value = 0;
|
||||||
|
INT32 num_bytes = 0;
|
||||||
|
for (INT32 j = 0; j < 3 && (i + j) < data.size(); ++j)
|
||||||
|
{
|
||||||
|
value = (value << 8) | data[i + j];
|
||||||
|
num_bytes++;
|
||||||
|
}
|
||||||
|
for (INT32 j = 0; j < num_bytes + 1; ++j)
|
||||||
|
{
|
||||||
|
if (j < 4)
|
||||||
|
{
|
||||||
|
result += BASE64_CHAR_TABLE[(value >> (6 * (3 - j))) & 0x3F];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (num_bytes < 3)
|
||||||
|
{
|
||||||
|
for (INT32 j = 0; j < (3 - num_bytes); ++j)
|
||||||
|
{
|
||||||
|
result += '=';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<UINT8> StringOps::DecodeBase64(IN CONST String &data)
|
||||||
|
{
|
||||||
|
Vector<UINT8> result;
|
||||||
|
|
||||||
|
CONST AUTO isBase64 = [](UINT8 c) { return (isalnum(c) || (c == '+') || (c == '/')); };
|
||||||
|
|
||||||
|
INT32 in_len = data.size();
|
||||||
|
INT32 i = 0, j = 0, in_ = 0;
|
||||||
|
UINT8 tmpBuf0[4], tmpBuf1[3];
|
||||||
|
|
||||||
|
while (in_len-- && (data[in_] != '=') && isBase64(data[in_]))
|
||||||
|
{
|
||||||
|
tmpBuf0[i++] = data[in_];
|
||||||
|
in_++;
|
||||||
|
if (i == 4)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
tmpBuf0[i] = BASE64_CHAR_TABLE.find(tmpBuf0[i]);
|
||||||
|
|
||||||
|
tmpBuf1[0] = (tmpBuf0[0] << 2) + ((tmpBuf0[1] & 0x30) >> 4);
|
||||||
|
tmpBuf1[1] = ((tmpBuf0[1] & 0xf) << 4) + ((tmpBuf0[2] & 0x3c) >> 2);
|
||||||
|
tmpBuf1[2] = ((tmpBuf0[2] & 0x3) << 6) + tmpBuf0[3];
|
||||||
|
|
||||||
|
for (i = 0; (i < 3); i++)
|
||||||
|
result.push_back(tmpBuf1[i]);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
for (j = i; j < 4; j++)
|
||||||
|
tmpBuf0[j] = 0;
|
||||||
|
|
||||||
|
for (j = 0; j < 4; j++)
|
||||||
|
tmpBuf0[j] = BASE64_CHAR_TABLE.find(tmpBuf0[j]);
|
||||||
|
|
||||||
|
tmpBuf1[0] = (tmpBuf0[0] << 2) + ((tmpBuf0[1] & 0x30) >> 4);
|
||||||
|
tmpBuf1[1] = ((tmpBuf0[1] & 0xf) << 4) + ((tmpBuf0[2] & 0x3c) >> 2);
|
||||||
|
tmpBuf1[2] = ((tmpBuf0[2] & 0x3) << 6) + tmpBuf0[3];
|
||||||
|
|
||||||
|
for (j = 0; (j < i - 1); j++)
|
||||||
|
result.push_back(tmpBuf1[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} // namespace IACore
|
||||||
@ -23,6 +23,9 @@ namespace IACore
|
|||||||
{
|
{
|
||||||
class FileOps
|
class FileOps
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
STATIC FilePath NormalizeExecutablePath(IN CONST FilePath &path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC VOID UnmapFile(IN PCUINT8 mappedPtr);
|
STATIC VOID UnmapFile(IN PCUINT8 mappedPtr);
|
||||||
STATIC Expected<PCUINT8, String> MapFile(IN CONST FilePath &path, OUT SIZE_T &size);
|
STATIC Expected<PCUINT8, String> MapFile(IN CONST FilePath &path, OUT SIZE_T &size);
|
||||||
@ -32,8 +35,10 @@ namespace IACore
|
|||||||
|
|
||||||
STATIC Expected<String, String> ReadTextFile(IN CONST FilePath &path);
|
STATIC Expected<String, String> ReadTextFile(IN CONST FilePath &path);
|
||||||
STATIC Expected<Vector<UINT8>, String> ReadBinaryFile(IN CONST FilePath &path);
|
STATIC Expected<Vector<UINT8>, String> ReadBinaryFile(IN CONST FilePath &path);
|
||||||
STATIC Expected<SIZE_T, String> WriteTextFile(IN CONST FilePath &path, IN CONST String &contents, IN BOOL overwrite = false);
|
STATIC Expected<SIZE_T, String> WriteTextFile(IN CONST FilePath &path, IN CONST String &contents,
|
||||||
STATIC Expected<SIZE_T, String> WriteBinaryFile(IN CONST FilePath &path, IN Span<UINT8> contents, IN BOOL overwrite = false);
|
IN BOOL overwrite = false);
|
||||||
|
STATIC Expected<SIZE_T, String> WriteBinaryFile(IN CONST FilePath &path, IN Span<UINT8> contents,
|
||||||
|
IN BOOL overwrite = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
STATIC UnorderedMap<PCUINT8, Tuple<PVOID, PVOID, PVOID>> s_mappedFiles;
|
STATIC UnorderedMap<PCUINT8, Tuple<PVOID, PVOID, PVOID>> s_mappedFiles;
|
||||||
|
|||||||
@ -22,6 +22,19 @@
|
|||||||
|
|
||||||
namespace IACore
|
namespace IACore
|
||||||
{
|
{
|
||||||
|
// Must be called from main thread
|
||||||
|
VOID Initialize();
|
||||||
|
// Must be called from same thread as Initialize
|
||||||
|
VOID Terminate();
|
||||||
|
|
||||||
|
UINT64 GetTicksCount();
|
||||||
|
FLOAT64 GetSecondsCount();
|
||||||
|
|
||||||
|
UINT32 GetRandom(IN UINT32 seed);
|
||||||
|
INT64 GetRandom(IN INT64 min, IN INT64 max);
|
||||||
|
|
||||||
|
BOOL IsMainThread();
|
||||||
|
VOID Sleep(IN UINT64 milliseconds);
|
||||||
} // namespace IACore
|
} // namespace IACore
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -32,9 +32,6 @@ namespace IACore
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC VOID Initialize();
|
|
||||||
STATIC VOID Terminate();
|
|
||||||
|
|
||||||
STATIC BOOL EnableLoggingToDisk(IN PCCHAR filePath);
|
STATIC BOOL EnableLoggingToDisk(IN PCCHAR filePath);
|
||||||
STATIC VOID SetLogLevel(IN ELogLevel logLevel);
|
STATIC VOID SetLogLevel(IN ELogLevel logLevel);
|
||||||
|
|
||||||
@ -109,7 +106,12 @@ namespace IACore
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
STATIC ELogLevel s_logLevel;
|
STATIC ELogLevel s_logLevel;
|
||||||
STATIC HRTimePoint s_startTime;
|
|
||||||
STATIC std::ofstream s_logFile;
|
STATIC std::ofstream s_logFile;
|
||||||
|
|
||||||
|
STATIC VOID Initialize();
|
||||||
|
STATIC VOID Terminate();
|
||||||
|
|
||||||
|
friend VOID Initialize();
|
||||||
|
friend VOID Terminate();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
29
Src/IACore/inc/IACore/StringOps.hpp
Normal file
29
Src/IACore/inc/IACore/StringOps.hpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// IACore-OSS; The Core Library for All IA Open Source Projects
|
||||||
|
// Copyright (C) 2025 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <IACore/PCH.hpp>
|
||||||
|
|
||||||
|
namespace IACore
|
||||||
|
{
|
||||||
|
class StringOps
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
STATIC String EncodeBase64(IN Span<CONST UINT8> data);
|
||||||
|
STATIC Vector<UINT8> DecodeBase64(IN CONST String& data);
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -20,7 +20,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
def main(args: list[str]):
|
def main(args: list[str]):
|
||||||
os.system("cmake -S. -B./Build/Linux -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug")
|
os.system("cmake -S. -B./Build -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug")
|
||||||
os.system("cmake --build ./Build/Linux")
|
os.system("cmake --build ./Build")
|
||||||
|
|
||||||
main(sys.argv)
|
main(sys.argv)
|
||||||
|
|||||||
Reference in New Issue
Block a user