/* * mptPathString.cpp * ----------------- * Purpose: Wrapper class around the platform-native representation of path names. Should be the only type that is used to store path names. * Notes : Currently none. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "mptPathString.h" #include "mpt/path/os_path_long.hpp" #include #if MPT_OS_WINDOWS #include #endif #if MPT_OS_WINDOWS #include #endif OPENMPT_NAMESPACE_BEGIN namespace mpt { #if MPT_OS_WINDOWS #if !MPT_OS_WINDOWS_WINRT int PathCompareNoCase(const PathString & a, const PathString & b) { return lstrcmpi(a.AsNative().c_str(), b.AsNative().c_str()); } #endif // !MPT_OS_WINDOWS_WINRT #endif // MPT_OS_WINDOWS #if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS // Convert an absolute path to a path that's relative to "&relativeTo". mpt::PathString AbsolutePathToRelative(const mpt::PathString &path, const mpt::PathString &relativeTo) { using namespace path_literals; using char_type = RawPathString::value_type; mpt::PathString result = path; if(path.empty() || relativeTo.empty()) { return result; } if(!_tcsncicmp(relativeTo.AsNative().c_str(), path.AsNative().c_str(), relativeTo.AsNative().length())) { // Path is OpenMPT's directory or a sub directory ("C:\OpenMPT\Somepath" => ".\Somepath") result = mpt::PathString::FromNative(L(".\\")); // ".\" result += mpt::PathString::FromNative(path.AsNative().substr(relativeTo.AsNative().length())); } else if(!_tcsncicmp(relativeTo.AsNative().c_str(), path.AsNative().c_str(), 2)) { // Path is on the same drive as OpenMPT ("C:\Somepath" => "\Somepath") result = mpt::PathString::FromNative(path.AsNative().substr(2)); } return result; } // Convert a path that is relative to "&relativeTo" to an absolute path. mpt::PathString RelativePathToAbsolute(const mpt::PathString &path, const mpt::PathString &relativeTo) { using namespace path_literals; using char_type = RawPathString::value_type; mpt::PathString result = path; if(path.empty() || relativeTo.empty()) { return result; } if(path.length() >= 2 && path.AsNative()[0] == L('\\') && path.AsNative()[1] == L('\\')) { // Network / UNC paths return result; } if(path.length() >= 1 && path.AsNative()[0] == L('\\')) { // Path is on the same drive as relativeTo ("\Somepath\" => "C:\Somepath\") result = mpt::PathString::FromNative(relativeTo.AsNative().substr(0, 2)); result += mpt::PathString(path); } else if(path.length() >= 2 && path.AsNative().substr(0, 2) == L(".\\")) { // Path is in relativeTo or a sub directory (".\Somepath\" => "C:\OpenMPT\Somepath\") result = relativeTo; // "C:\OpenMPT\" result += mpt::PathString::FromNative(path.AsNative().substr(2)); } else if(path.length() < 3 || path.AsNative()[1] != L(':') || path.AsNative()[2] != L('\\')) { // Any other path not starting with drive letter result = relativeTo; // "C:\OpenMPT\" result += mpt::PathString(path); } return result; } #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS #if MPT_OS_WINDOWS #if !(MPT_WINRT_BEFORE(MPT_WIN_10)) mpt::PathString GetAbsolutePath(const mpt::PathString &path) { DWORD size = GetFullPathName(path.AsNative().c_str(), 0, nullptr, nullptr); if(size == 0) { return path; } std::vector fullPathName(size, TEXT('\0')); if(GetFullPathName(path.AsNative().c_str(), size, fullPathName.data(), nullptr) == 0) { return path; } return mpt::PathString::FromNative(fullPathName.data()); } #endif #endif // MPT_OS_WINDOWS } // namespace mpt #if defined(MODPLUG_TRACKER) mpt::ustring SanitizePathComponent(mpt::ustring str) { return mpt::PathString::FromUnicode(str).AsSanitizedComponent().ToUnicode(); } #if defined(MPT_WITH_MFC) CString SanitizePathComponent(CString str) { return mpt::PathString::FromCString(str).AsSanitizedComponent().ToCString(); } #endif // MPT_WITH_MFC #endif // MODPLUG_TRACKER OPENMPT_NAMESPACE_END