This commit is contained in:
Igor Pavlov
2014-11-23 00:00:00 +00:00
committed by Kornel Lesiński
parent 83f8ddcc5b
commit f08f4dcc3c
1158 changed files with 76451 additions and 35082 deletions

110
CPP/7zip/UI/Common/ExtractingFilePath.cpp Executable file → Normal file
View File

@@ -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);