diff --git a/UnitTests/Shell.cpp b/UnitTests/Shell.cpp index 63ee295c..fd7de51f 100644 --- a/UnitTests/Shell.cpp +++ b/UnitTests/Shell.cpp @@ -26,5 +26,39 @@ namespace UnitTests Assert::IsTrue(::PathCanonicalizeW(path, L"C:\\Windows\\Temp\\test\\..")); Assert::AreEqual(L"C:\\Windows\\Temp", path.c_str(), true); } + + TEST_METHOD(PathRemoveBackslashA) + { + string path; + + static const char normal_path[] = "C:\\Windows\\Temp\\test"; + path = normal_path; path += '\\'; ::PathRemoveBackslashA(path); + Assert::AreEqual(normal_path, path.c_str()); + path = normal_path; ::PathRemoveBackslashA(path); + Assert::AreEqual(normal_path, path.c_str()); + + static const char very_long_path[] = "C:\\Windows\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\test"; + path = very_long_path; path += '\\'; ::PathRemoveBackslashA(path); + Assert::AreEqual(very_long_path, path.c_str()); + path = very_long_path; ::PathRemoveBackslashA(path); + Assert::AreEqual(very_long_path, path.c_str()); + } + + TEST_METHOD(PathRemoveBackslashW) + { + wstring path; + + static const wchar_t normal_path[] = L"C:\\Windows\\Temp\\test"; + path = normal_path; path += L'\\'; ::PathRemoveBackslashW(path); + Assert::AreEqual(normal_path, path.c_str()); + path = normal_path; ::PathRemoveBackslashW(path); + Assert::AreEqual(normal_path, path.c_str()); + + static const wchar_t very_long_path[] = L"C:\\Windows\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\Temp\\test"; + path = very_long_path; path += L'\\'; ::PathRemoveBackslashW(path); + Assert::AreEqual(very_long_path, path.c_str()); + path = very_long_path; ::PathRemoveBackslashW(path); + Assert::AreEqual(very_long_path, path.c_str()); + } }; } diff --git a/include/WinStd/Shell.h b/include/WinStd/Shell.h index f3a5ba04..077b99b6 100644 --- a/include/WinStd/Shell.h +++ b/include/WinStd/Shell.h @@ -39,4 +39,50 @@ static BOOL PathCanonicalizeW(_Inout_ std::basic_string & return bResult; } +/// @copydoc PathRemoveBackslashW() +template +static void PathRemoveBackslashA(_Inout_ std::basic_string& sValue) +{ + char szBuffer[MAX_PATH + 1]; + size_t len = sValue.length(); + if (len < _countof(szBuffer)) { + memcpy(szBuffer, sValue.c_str(), len); + szBuffer[len] = 0; + PathRemoveBackslashA(szBuffer); + sValue.assign(szBuffer); + } + else { + std::unique_ptr buf(new char[len + 1]); + memcpy(buf.get(), sValue.c_str(), len); + buf[len] = 0; + PathRemoveBackslashA(buf.get()); + sValue.assign(buf.get()); + } +} + +/// +/// Removes the trailing backslash from a given path. +/// +/// \sa [PathRemoveBackslashW function](https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathremovebackslashw) +/// +template +static void PathRemoveBackslashW(_Inout_ std::basic_string& sValue) +{ + wchar_t szBuffer[MAX_PATH + 1]; + size_t len = sValue.length(); + if (len < _countof(szBuffer)) { + wmemcpy(szBuffer, sValue.c_str(), len); + szBuffer[len] = 0; + PathRemoveBackslashW(szBuffer); + sValue.assign(szBuffer); + } + else { + std::unique_ptr buf(new wchar_t[len + 1]); + wmemcpy(buf.get(), sValue.c_str(), len); + buf[len] = 0; + PathRemoveBackslashW(buf.get()); + sValue.assign(buf.get()); + } +} + /// @}