/* * vislib::sys::Path::Concatenate */ vislib::StringW vislib::sys::Path::Concatenate(const StringW& lhs, const StringW& rhs, const bool canonicalise) { StringW retval(lhs); if (lhs.EndsWith(SEPARATOR_W) && rhs.StartsWith(SEPARATOR_W)) { retval.Append(rhs.PeekBuffer() + 1); } else if (!lhs.EndsWith(SEPARATOR_W) && !rhs.StartsWith(SEPARATOR_W)) { retval.Append(SEPARATOR_W); retval.Append(rhs); } else { retval.Append(rhs); } return canonicalise ? Path::Canonicalise(retval) : retval; }
/* * vislib::sys::Path::GetUserHomeDirectoryW */ vislib::StringW vislib::sys::Path::GetUserHomeDirectoryW(void) { #ifdef _WIN32 StringW retval; if (FAILED(::SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, retval.AllocateBuffer(MAX_PATH)))) { throw SystemException(ERROR_NOT_FOUND, __FILE__, __LINE__); } if (!retval.EndsWith(SEPARATOR_W)) { retval += SEPARATOR_W; } return retval; #else /* _WIN32 */ return StringW(GetUserHomeDirectoryA()); #endif /* _WIN32 */ }
/* * vislib::sys::Path::PurgeDirectory */ void vislib::sys::Path::PurgeDirectory(const StringW& path, bool recursive) { StringW fullpath = Resolve(path); if (!fullpath.EndsWith(SEPARATOR_W)) fullpath += SEPARATOR_W; DirectoryIteratorW iter(fullpath); while (iter.HasNext()) { DirectoryEntryW entry = iter.Next(); if (entry.Type == DirectoryEntryW::FILE) { vislib::sys::File::Delete(fullpath + entry.Path); } else if (entry.Type == DirectoryEntryW::DIRECTORY) { if (recursive) { DeleteDirectory(fullpath + entry.Path, true); } } else { ASSERT(false); // DirectoryEntry is something unknown to this // implementation. Check DirectoryIterator for // changes. } } }
/* * vislib::sys::Path::DeleteDirectory */ void vislib::sys::Path::DeleteDirectory(const StringA& path, bool recursive) { if (!File::Exists(path)) return; // we don't delete non-existing stuff StringA fullPath = Resolve(path); if (!fullPath.EndsWith(SEPARATOR_A)) fullPath += SEPARATOR_A; if (recursive) { // remove files and directory PurgeDirectory(fullPath, true); } #ifdef _WIN32 if (RemoveDirectoryA(fullPath) == 0) { #else /* _WIN32 */ if (rmdir(fullPath) != 0) { #endif /* _WIN32 */ throw vislib::sys::SystemException(__FILE__, __LINE__); } } /* * vislib::sys::Path::DeleteDirectory */ void vislib::sys::Path::DeleteDirectory(const StringW& path, bool recursive) { #ifdef _WIN32 if (!File::Exists(path)) return; // we don't delete non-existing stuff StringW fullPath = Resolve(path); if (!fullPath.EndsWith(SEPARATOR_W)) fullPath += SEPARATOR_W; if (recursive) { // remove files and directory PurgeDirectory(fullPath, true); } if (RemoveDirectoryW(fullPath) == 0) { throw vislib::sys::SystemException(__FILE__, __LINE__); } #else /* _WIN32 */ // linux is stupid DeleteDirectory(W2A(path), recursive); #endif /* _WIN32 */ } /* * vislib::sys::Path::FindExecutablePath */ vislib::StringA vislib::sys::Path::FindExecutablePath( const vislib::StringA& filename) { #ifdef _WIN32 bool found = false; DWORD bufSize = MAX_PATH; char *buffer = new char[bufSize]; // first try: "SearchPath" DWORD rv = ::SearchPathA(NULL, filename.PeekBuffer(), NULL, bufSize, buffer, NULL); if (rv > 0) { found = true; if (rv + 1 > bufSize) { bufSize = rv + 1; delete[] buffer; buffer = new char[bufSize]; rv = ::SearchPathA(NULL, filename.PeekBuffer(), NULL, bufSize, buffer, NULL); if (rv == 0) { // failed found = false; } } } if (!found) { // second try: "AssocQueryString" // NOTE: // AssocQueryString does not work as specified! It is not possible to ask // for the size of the string buffer holding the value returned. Therefore // this implementation increases the buffersize until the returned strings // no longer grow. DWORD bufLen = MAX_PATH; HRESULT hr; bufSize = MAX_PATH; do { hr = ::AssocQueryStringA(ASSOCF_INIT_BYEXENAME, ASSOCSTR_EXECUTABLE, filename.PeekBuffer(), NULL, buffer, &bufSize); if ((hr != E_POINTER) && (hr != S_OK)) { // error break; } if (bufSize == bufLen) { bufLen += MAX_PATH; bufSize = bufLen; delete[] buffer; buffer = new char[bufSize]; } else { found = true; } } while (bufSize == bufLen); } if (found) { vislib::StringA retval(buffer); delete[] buffer; return retval; } else { return ""; } #else /* _WIN32 */ // Note: // Do not use "Console::Run" or "Process" methods because they might use // this method to determine the full path of their binaries. So we avoid // calling cycles by just using "popen" directly vislib::StringA cmd("which "); vislib::StringA ret; cmd += filename; cmd += " 2> /dev/null"; const int bufferSize = 1024; char buffer[bufferSize]; FILE *which = ::popen(cmd.PeekBuffer(), "r"); if (which == NULL) { return ""; } while (!::feof(which)) { ret += fgets(buffer, bufferSize, which); } ::pclose(which); vislib::StringA::Size end = ret.Find('\n'); if (end != vislib::StringA::INVALID_POS) { ret.Truncate(end); } if (ret.EndsWith(filename)) { return ret; } else { return ""; } #endif /* _WIN32 */ }