93 lines
2.7 KiB
C++
93 lines
2.7 KiB
C++
#include "platform_utils.h"
|
|
|
|
#include <cstring>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
|
|
// ── Windows ──────────────────────────────────────────────────────────────────
|
|
#if defined(_WIN32)
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
# define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#include <windows.h>
|
|
#include <wchar.h>
|
|
|
|
namespace platform {
|
|
|
|
char pathSeparator() { return '\\'; }
|
|
|
|
bool directoryExists(const std::string& path)
|
|
{
|
|
const int wlen = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, nullptr, 0);
|
|
if (wlen <= 0) return false;
|
|
std::wstring wpath(static_cast<size_t>(wlen - 1), L'\0');
|
|
MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, &wpath[0], wlen);
|
|
|
|
const DWORD attrs = GetFileAttributesW(wpath.c_str());
|
|
return attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY);
|
|
}
|
|
|
|
bool createTempDirectory(const std::string& prefix, std::string& outPath)
|
|
{
|
|
wchar_t tempBase[MAX_PATH + 1];
|
|
if (GetTempPathW(MAX_PATH, tempBase) == 0) return false;
|
|
|
|
std::wstring wPrefix(prefix.begin(), prefix.end());
|
|
|
|
wchar_t tempFile[MAX_PATH + 1];
|
|
if (GetTempFileNameW(tempBase, wPrefix.c_str(), 0, tempFile) == 0) return false;
|
|
|
|
DeleteFileW(tempFile);
|
|
if (!CreateDirectoryW(tempFile, nullptr)) return false;
|
|
|
|
const int len = WideCharToMultiByte(CP_UTF8, 0, tempFile, -1, nullptr, 0, nullptr, nullptr);
|
|
if (len <= 0) return false;
|
|
outPath.resize(static_cast<size_t>(len - 1));
|
|
WideCharToMultiByte(CP_UTF8, 0, tempFile, -1, &outPath[0], len, nullptr, nullptr);
|
|
return true;
|
|
}
|
|
|
|
} // namespace platform
|
|
|
|
// ── POSIX (macOS + Linux) ─────────────────────────────────────────────────
|
|
#else
|
|
|
|
#include <cerrno>
|
|
#include <cstdlib>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
namespace platform {
|
|
|
|
char pathSeparator() { return '/'; }
|
|
|
|
bool directoryExists(const std::string& path)
|
|
{
|
|
struct stat st{};
|
|
return stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
|
|
}
|
|
|
|
bool createTempDirectory(const std::string& prefix, std::string& outPath)
|
|
{
|
|
const char* tmpEnv = std::getenv("TMPDIR");
|
|
std::string base = (tmpEnv && *tmpEnv) ? tmpEnv : "/tmp";
|
|
|
|
if (!base.empty() && base.back() == '/')
|
|
base.pop_back();
|
|
|
|
// mkdtemp needs a mutable char*. In C++17, std::string::data() is
|
|
// non-const and the buffer is null-terminated, so we can use it directly
|
|
// without a separate std::vector<char> copy.
|
|
std::string tmpl = base + "/" + prefix + "XXXXXX";
|
|
|
|
if (mkdtemp(tmpl.data()) == nullptr) return false;
|
|
|
|
outPath = tmpl;
|
|
return true;
|
|
}
|
|
|
|
} // namespace platform
|
|
|
|
#endif
|