summaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/3rdparty/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.cpp')
-rw-r--r--src/libs/3rdparty/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.cpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/libs/3rdparty/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/src/libs/3rdparty/7zip/win/CPP/7zip/UI/Common/ExtractingFilePath.cpp
new file mode 100644
index 000000000..852fd5adb
--- /dev/null
+++ b/src/libs/3rdparty/7zip/win/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);
+}