#include "of_path.h" #include #include #ifdef _WIN32 #include #elif defined(__clang__) && defined(__APPLE__) #include #include #else #include #endif #ifndef PATH_MAX #define PATH_MAX 256 #endif namespace fs = std::filesystem; namespace ofen { COfPath::COfPath() { } COfPath::~COfPath() { } bool COfPath::isSamePath(const ofString& pa, const ofString& pb) { return normalizePath(pa) == normalizePath(pb); } ofString COfPath::normalizePath(const ofString& path) { ofString normalized = replaceStr(path, ofT("\\"), ofT("/")); if (!normalized.empty() && normalized.back() == ofT('/')) { normalized.pop_back(); } return normalized; } ofString COfPath::replaceStr(const ofString& str, const ofString& from, const ofString& to) { if (from.empty()) { return str; } ofString result = str; size_t startPos = 0; while ((startPos = result.find(from, startPos)) != ofString::npos) { result.replace(startPos, from.length(), to); startPos += to.length(); } return result; } ofString COfPath::getFullRunPath() { 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 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::getHome() { #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::getConfigDir(const ofString& sub_dir, bool create) { fs::path userHome = fs::path(getHome()); 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::getFull(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::isExist(const ofString& path) { fs::path p(path); return fs::exists(p); } bool COfPath::writeBin(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; } } // namespace ofen