mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 17:15:00 -06:00
191 lines
4.0 KiB
C++
191 lines
4.0 KiB
C++
// 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);
|
|
}
|