framerip/platform_utils.cpp

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