diff options
Diffstat (limited to 'CPP/7zip/UI/Common/ExtractingFilePath.cpp')
-rw-r--r--[-rwxr-xr-x] | CPP/7zip/UI/Common/ExtractingFilePath.cpp | 110 |
1 files changed, 79 insertions, 31 deletions
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp index 25494d0e..37e15013 100755..100644 --- a/CPP/7zip/UI/Common/ExtractingFilePath.cpp +++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp @@ -2,26 +2,44 @@ #include "StdAfx.h" -#include "../../../../C/Types.h" +#include "../../../Common/Wildcard.h" -#include "Common/Wildcard.h" +#include "../../../Windows/FileName.h" #include "ExtractingFilePath.h" -static UString ReplaceIncorrectChars(const UString &s) +static UString ReplaceIncorrectChars(const UString &s, bool repaceColon) { #ifdef _WIN32 UString res; - for (int i = 0; i < s.Length(); i++) + bool beforeColon = true; { - wchar_t c = s[i]; - if (c < 0x20 || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c == ':' || c == '"') - c = '_'; - res += c; + for (unsigned i = 0; i < s.Len(); i++) + { + wchar_t c = s[i]; + if (beforeColon) + if (c == '*' || c == '?' || c < 0x20 || c == '<' || c == '>' || c == '|' || c == '"') + c = '_'; + if (c == ':') + { + if (repaceColon) + c = '_'; + else + beforeColon = false; + } + res += c; + } + } + if (beforeColon) + { + for (int i = res.Len() - 1; i >= 0; i--) + { + wchar_t c = res[i]; + if (c != '.' && c != ' ') + break; + res.ReplaceOneCharAtPos(i, '_'); + } } - res.TrimRight(); - while (!res.IsEmpty() && res.Back() == '.') - res.DeleteBack(); return res; #else return s; @@ -29,27 +47,28 @@ static UString ReplaceIncorrectChars(const UString &s) } #ifdef _WIN32 + static const wchar_t *g_ReservedNames[] = { L"CON", L"PRN", L"AUX", L"NUL" }; -static bool CheckTail(const UString &name, int len) +static bool CheckTail(const UString &name, unsigned len) { int dotPos = name.Find(L'.'); if (dotPos < 0) - dotPos = name.Length(); + dotPos = name.Len(); UString s = name.Left(dotPos); s.TrimRight(); - return (s.Length() != len); + return s.Len() != len; } static bool CheckNameNum(const UString &name, const wchar_t *reservedName) { - int len = MyStringLen(reservedName); - if (name.Length() <= len) + unsigned len = MyStringLen(reservedName); + if (name.Len() <= len) return true; - if (name.Left(len).CompareNoCase(reservedName) != 0) + if (MyStringCompareNoCase_N(name, reservedName, len) != 0) return true; wchar_t c = name[len]; if (c < L'0' || c > L'9') @@ -59,13 +78,13 @@ static bool CheckNameNum(const UString &name, const wchar_t *reservedName) static bool IsSupportedName(const UString &name) { - for (int i = 0; i < sizeof(g_ReservedNames) / sizeof(g_ReservedNames[0]); i++) + for (unsigned i = 0; i < ARRAY_SIZE(g_ReservedNames); i++) { const wchar_t *reservedName = g_ReservedNames[i]; - int len = MyStringLen(reservedName); - if (name.Length() < len) + unsigned len = MyStringLen(reservedName); + if (name.Len() < len) continue; - if (name.Left(len).CompareNoCase(reservedName) != 0) + if (MyStringCompareNoCase_N(name, reservedName, len) != 0) continue; if (!CheckTail(name, len)) return false; @@ -74,21 +93,34 @@ static bool IsSupportedName(const UString &name) return false; return CheckNameNum(name, L"LPT"); } + #endif -static UString GetCorrectFileName(const UString &path) +static UString GetCorrectFileName(const UString &path, bool repaceColon) { if (path == L".." || path == L".") return UString(); - return ReplaceIncorrectChars(path); + return ReplaceIncorrectChars(path, repaceColon); } -void MakeCorrectPath(UStringVector &pathParts) +void MakeCorrectPath(bool isPathFromRoot, UStringVector &pathParts, bool replaceAltStreamColon) { - for (int i = 0; i < pathParts.Size();) + for (unsigned i = 0; i < pathParts.Size();) { UString &s = pathParts[i]; - s = GetCorrectFileName(s); + #ifdef _WIN32 + bool needReplaceColon = (replaceAltStreamColon || i != pathParts.Size() - 1); + if (i == 0 && isPathFromRoot && NWindows::NFile::NName::IsDrivePath(s)) + { + UString s2 = s[0]; + s2 += L'_'; + s2 += GetCorrectFileName(s.Ptr(2), needReplaceColon); + s = s2; + } + else + s = GetCorrectFileName(s, needReplaceColon); + #endif + if (s.IsEmpty()) pathParts.Delete(i); else @@ -105,7 +137,7 @@ void MakeCorrectPath(UStringVector &pathParts) UString MakePathNameFromParts(const UStringVector &parts) { UString result; - for (int i = 0; i < parts.Size(); i++) + FOR_VECTOR (i, parts) { if (i != 0) result += WCHAR_PATH_SEPARATOR; @@ -114,13 +146,29 @@ UString MakePathNameFromParts(const UStringVector &parts) return result; } +static const wchar_t *k_EmptyReplaceName = L"[]"; + +void Correct_IfEmptyLastPart(UStringVector &parts) +{ + if (parts.IsEmpty()) + parts.Add(k_EmptyReplaceName); + else + { + UString &s = parts.Back(); + if (s.IsEmpty()) + s = k_EmptyReplaceName; + } +} + UString GetCorrectFsPath(const UString &path) { - UString res = GetCorrectFileName(path); + UString res = GetCorrectFileName(path, true); #ifdef _WIN32 if (!IsSupportedName(res)) res = (UString)L"_" + res; #endif + if (res.IsEmpty()) + res = k_EmptyReplaceName; return res; } @@ -128,14 +176,14 @@ UString GetCorrectFullFsPath(const UString &path) { UStringVector parts; SplitPathToParts(path, parts); - for (int i = 0; i < parts.Size(); i++) + FOR_VECTOR (i, parts) { UString &s = parts[i]; #ifdef _WIN32 - while (!s.IsEmpty() && s.Back() == '.') + while (!s.IsEmpty() && (s.Back() == '.' || s.Back() == ' ')) s.DeleteBack(); if (!IsSupportedName(s)) - s = (UString)L"_" + s; + s.InsertAtFront(L'_'); #endif } return MakePathNameFromParts(parts); |