160 lines
3.4 KiB
C++
160 lines
3.4 KiB
C++
#include "of_path.h"
|
|
#include "of_str.h"
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#elif defined(__clang__) && defined(__APPLE__)
|
|
#include <mach-o/dyld.h>
|
|
#include <unistd.h>
|
|
#else
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#ifndef PATH_MAX
|
|
#define PATH_MAX 256
|
|
#endif
|
|
|
|
namespace fs = std::filesystem;
|
|
namespace ofen {
|
|
COfPath::COfPath()
|
|
{
|
|
}
|
|
|
|
COfPath::~COfPath()
|
|
{
|
|
}
|
|
|
|
bool COfPath::is_same_path(const ofString& pa, const ofString& pb)
|
|
{
|
|
return normalize(pa) == normalize(pb);
|
|
}
|
|
|
|
ofString COfPath::normalize(const ofString& path)
|
|
{
|
|
ofString normalized = COfStr::replace(path, ofT("\\"), ofT("/"));
|
|
if (!normalized.empty() && normalized.back() == ofT('/')) {
|
|
normalized.pop_back();
|
|
}
|
|
return normalized;
|
|
}
|
|
ofString COfPath::get_full_path()
|
|
{
|
|
ofString path;
|
|
#ifdef _WIN32
|
|
ofChar buffer[MAX_PATH];
|
|
DWORD length = GetModuleFileName(NULL, buffer, MAX_PATH);
|
|
if (length == 0) {
|
|
return ofT("");
|
|
}
|
|
return ofString(buffer, length);
|
|
#elif defined(__clang__) && defined(__APPLE__)
|
|
uint32_t size = 0;
|
|
_NSGetExecutablePath(NULL, &size); // 获取路径缓冲区的大小
|
|
std::vector<ofChar> buffer(size); // 创建缓冲区
|
|
if (_NSGetExecutablePath(buffer.data(), &size) != 0) {
|
|
return ofT("");
|
|
}
|
|
return ofString(buffer.data());
|
|
#else
|
|
ofChar buffer[PATH_MAX];
|
|
ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1);
|
|
if (len == -1) {
|
|
return ofT("");
|
|
}
|
|
buffer[len] = ofT('\0'); // 确保字符串以null终止
|
|
return ofString(buffer);
|
|
#endif
|
|
}
|
|
|
|
ofString COfPath::get_home()
|
|
{
|
|
#if defined(_WIN32)
|
|
ofChar* value = nullptr;
|
|
std::size_t len = 0;
|
|
#ifdef UNICODE_OFSTR
|
|
auto err = _wdupenv_s(&value, &len, ofT("USERPROFILE"));
|
|
#else
|
|
auto err = _dupenv_s(&value, &len, "USERPROFILE");
|
|
#endif
|
|
if (err == 0 && value != nullptr) {
|
|
ofString ret(value);
|
|
free(value);
|
|
return ret;
|
|
} else {
|
|
return ofT("");
|
|
}
|
|
#else
|
|
ofChar* homedir = getenv("HOME");
|
|
if (homedir) {
|
|
return ofString(homedir);
|
|
}
|
|
return ofT("");
|
|
#endif
|
|
}
|
|
|
|
ofString COfPath::get_config_dir(const ofString& sub_dir, bool create)
|
|
{
|
|
fs::path userHome = fs::path(get_home());
|
|
userHome.append(".config");
|
|
userHome.append(sub_dir);
|
|
if (create) {
|
|
if (!fs::exists(userHome)) {
|
|
fs::create_directories(userHome);
|
|
}
|
|
}
|
|
#ifdef UNICODE_OFSTR
|
|
return ofString(userHome.wstring());
|
|
#else
|
|
return ofString(userHome.string());
|
|
#endif
|
|
}
|
|
|
|
ofString COfPath::get_full(const ofString& path, const ofString& sub_file_path)
|
|
{
|
|
fs::path p(path);
|
|
p.append(sub_file_path);
|
|
#ifdef UNICODE_OFSTR
|
|
return ofString(p.wstring());
|
|
#else
|
|
return ofString(p.string());
|
|
#endif
|
|
}
|
|
|
|
bool COfPath::exist(const ofString& path)
|
|
{
|
|
fs::path p(path);
|
|
return fs::exists(p);
|
|
}
|
|
|
|
bool COfPath::write(const ofString& path, const char* data, int len)
|
|
{
|
|
std::ofstream file(path, std::ios::binary);
|
|
if (!file.is_open()) {
|
|
return false;
|
|
}
|
|
file.write(data, len);
|
|
file.close();
|
|
return true;
|
|
}
|
|
|
|
ofString COfPath::to_full(const ofString& path)
|
|
{
|
|
fs::path base;
|
|
if (fs::path(path).is_relative()) {
|
|
base = fs::current_path();
|
|
base.append(path);
|
|
} else {
|
|
base = fs::path(path);
|
|
}
|
|
fs::path ret = fs::absolute(base);
|
|
#ifdef UNICODE_OFSTR
|
|
return ofString(ret.wstring());
|
|
#else
|
|
return ofString(ret.string());
|
|
#endif
|
|
}
|
|
|
|
} // namespace ofen
|