diff options
Diffstat (limited to 'src/libs/3rdparty/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.cpp')
-rw-r--r-- | src/libs/3rdparty/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.cpp | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.cpp new file mode 100644 index 000000000..852fd5adb --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/UI/Common/ExtractingFilePath.cpp @@ -0,0 +1,190 @@ +// ExtractingFilePath.cpp + +#include "StdAfx.h" + +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileName.h" + +#include "ExtractingFilePath.h" + +static UString ReplaceIncorrectChars(const UString &s, bool repaceColon) +{ + #ifdef _WIN32 + UString res; + bool beforeColon = true; + { + 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, '_'); + } + } + return res; + #else + return s; + #endif +} + +#ifdef _WIN32 + +static const wchar_t *g_ReservedNames[] = +{ + L"CON", L"PRN", L"AUX", L"NUL" +}; + +static bool CheckTail(const UString &name, unsigned len) +{ + int dotPos = name.Find(L'.'); + if (dotPos < 0) + dotPos = name.Len(); + UString s = name.Left(dotPos); + s.TrimRight(); + return s.Len() != len; +} + +static bool CheckNameNum(const UString &name, const wchar_t *reservedName) +{ + unsigned len = MyStringLen(reservedName); + if (name.Len() <= len) + return true; + if (MyStringCompareNoCase_N(name, reservedName, len) != 0) + return true; + wchar_t c = name[len]; + if (c < L'0' || c > L'9') + return true; + return CheckTail(name, len + 1); +} + +static bool IsSupportedName(const UString &name) +{ + for (unsigned i = 0; i < ARRAY_SIZE(g_ReservedNames); i++) + { + const wchar_t *reservedName = g_ReservedNames[i]; + unsigned len = MyStringLen(reservedName); + if (name.Len() < len) + continue; + if (MyStringCompareNoCase_N(name, reservedName, len) != 0) + continue; + if (!CheckTail(name, len)) + return false; + } + if (!CheckNameNum(name, L"COM")) + return false; + return CheckNameNum(name, L"LPT"); +} + +#endif + +static UString GetCorrectFileName(const UString &path, bool repaceColon) +{ + if (path == L".." || path == L".") + return UString(); + return ReplaceIncorrectChars(path, repaceColon); +} + +void MakeCorrectPath(bool isPathFromRoot, UStringVector &pathParts, bool replaceAltStreamColon) +{ + for (unsigned i = 0; i < pathParts.Size();) + { + UString &s = pathParts[i]; + #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 + { + #ifdef _WIN32 + if (!IsSupportedName(s)) + s = (UString)L"_" + s; + #endif + i++; + } + } +} + +UString MakePathNameFromParts(const UStringVector &parts) +{ + UString result; + FOR_VECTOR (i, parts) + { + if (i != 0) + result += WCHAR_PATH_SEPARATOR; + result += parts[i]; + } + 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, true); + #ifdef _WIN32 + if (!IsSupportedName(res)) + res = (UString)L"_" + res; + #endif + if (res.IsEmpty()) + res = k_EmptyReplaceName; + return res; +} + +UString GetCorrectFullFsPath(const UString &path) +{ + UStringVector parts; + SplitPathToParts(path, parts); + FOR_VECTOR (i, parts) + { + UString &s = parts[i]; + #ifdef _WIN32 + while (!s.IsEmpty() && (s.Back() == '.' || s.Back() == ' ')) + s.DeleteBack(); + if (!IsSupportedName(s)) + s.InsertAtFront(L'_'); + #endif + } + return MakePathNameFromParts(parts); +} |