mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 17:15:00 -06:00
23.01
This commit is contained in:
@@ -2,82 +2,40 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../../C/Sort.h"
|
||||
|
||||
#include "../../../Common/Wildcard.h"
|
||||
#include "../../../Common/StringToInt.h"
|
||||
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
|
||||
#include "ExtractingFilePath.h"
|
||||
#include "ArchiveName.h"
|
||||
#include "ExtractingFilePath.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
|
||||
static UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
|
||||
{
|
||||
FString resultName = fi.Name;
|
||||
if (!fi.IsDir() && !keepName)
|
||||
{
|
||||
int dotPos = resultName.ReverseFind_Dot();
|
||||
if (dotPos > 0)
|
||||
{
|
||||
FString archiveName2 = resultName.Left((unsigned)dotPos);
|
||||
if (archiveName2.ReverseFind_Dot() < 0)
|
||||
resultName = archiveName2;
|
||||
}
|
||||
}
|
||||
return Get_Correct_FsFile_Name(fs2us(resultName));
|
||||
}
|
||||
|
||||
static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepName)
|
||||
{
|
||||
FString resultName ("Archive");
|
||||
if (fromPrev)
|
||||
{
|
||||
FString dirPrefix;
|
||||
if (NDir::GetOnlyDirPrefix(path, dirPrefix))
|
||||
{
|
||||
if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back()))
|
||||
{
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (NName::IsDriveRootPath_SuperAllowed(dirPrefix))
|
||||
resultName = dirPrefix[dirPrefix.Len() - 3]; // only letter
|
||||
else
|
||||
#endif
|
||||
{
|
||||
dirPrefix.DeleteBack();
|
||||
NFind::CFileInfo fi;
|
||||
if (fi.Find(dirPrefix))
|
||||
resultName = fi.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NFind::CFileInfo fi;
|
||||
if (fi.Find(path))
|
||||
{
|
||||
resultName = fi.Name;
|
||||
if (!fi.IsDir() && !keepName)
|
||||
{
|
||||
int dotPos = resultName.ReverseFind_Dot();
|
||||
if (dotPos > 0)
|
||||
{
|
||||
FString name2 = resultName.Left((unsigned)dotPos);
|
||||
if (name2.ReverseFind_Dot() < 0)
|
||||
resultName = name2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return resultName;
|
||||
}
|
||||
static const char *g_ArcExts =
|
||||
"7z"
|
||||
"\0" "zip"
|
||||
"\0" "tar"
|
||||
"\0" "wim"
|
||||
"\0";
|
||||
|
||||
static const char *g_HashExts =
|
||||
"sha256"
|
||||
"\0";
|
||||
|
||||
|
||||
UString CreateArchiveName(const UStringVector &paths, const NFind::CFileInfo *fi)
|
||||
UString CreateArchiveName(
|
||||
const UStringVector &paths,
|
||||
bool isHash,
|
||||
const NFind::CFileInfo *fi,
|
||||
UString &baseName)
|
||||
{
|
||||
bool keepName = false;
|
||||
bool keepName = isHash;
|
||||
/*
|
||||
if (paths.Size() == 1)
|
||||
{
|
||||
@@ -88,68 +46,131 @@ UString CreateArchiveName(const UStringVector &paths, const NFind::CFileInfo *fi
|
||||
}
|
||||
*/
|
||||
|
||||
UString name;
|
||||
if (fi)
|
||||
name = CreateArchiveName(*fi, keepName);
|
||||
else
|
||||
UString name ("Archive");
|
||||
NFind::CFileInfo fi3;
|
||||
if (paths.Size() > 1)
|
||||
fi = NULL;
|
||||
if (!fi && paths.Size() != 0)
|
||||
{
|
||||
if (paths.IsEmpty())
|
||||
return L"archive";
|
||||
bool fromPrev = (paths.Size() > 1);
|
||||
name = Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(paths.Front()), fromPrev, keepName)));
|
||||
const UString &path = paths.Front();
|
||||
if (paths.Size() == 1)
|
||||
{
|
||||
if (fi3.Find(us2fs(path)))
|
||||
fi = &fi3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we try to use name of parent folder
|
||||
FString dirPrefix;
|
||||
if (NDir::GetOnlyDirPrefix(us2fs(path), dirPrefix))
|
||||
{
|
||||
if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back()))
|
||||
{
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (NName::IsDriveRootPath_SuperAllowed(dirPrefix))
|
||||
{
|
||||
if (path != fs2us(dirPrefix))
|
||||
name = dirPrefix[dirPrefix.Len() - 3]; // only letter
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
dirPrefix.DeleteBack();
|
||||
if (!dirPrefix.IsEmpty())
|
||||
{
|
||||
const int slash = dirPrefix.ReverseFind_PathSepar();
|
||||
if (slash >= 0 && slash != (int)dirPrefix.Len() - 1)
|
||||
name = dirPrefix.Ptr(slash + 1);
|
||||
else if (fi3.Find(dirPrefix))
|
||||
name = fs2us(fi3.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UStringVector names;
|
||||
|
||||
if (fi)
|
||||
{
|
||||
name = fs2us(fi->Name);
|
||||
if (!fi->IsDir() && !keepName)
|
||||
{
|
||||
const int dotPos = name.Find(L'.');
|
||||
if (dotPos > 0 && name.Find(L'.', (unsigned)dotPos + 1) < 0)
|
||||
name.DeleteFrom((unsigned)dotPos);
|
||||
}
|
||||
}
|
||||
name = Get_Correct_FsFile_Name(name);
|
||||
|
||||
CRecordVector<UInt32> ids;
|
||||
bool simple_IsAllowed = true;
|
||||
// for (int y = 0; y < 10000; y++) // for debug
|
||||
{
|
||||
// ids.Clear();
|
||||
UString n;
|
||||
|
||||
FOR_VECTOR (i, paths)
|
||||
{
|
||||
NFind::CFileInfo fi2;
|
||||
const NFind::CFileInfo *fp;
|
||||
if (fi && paths.Size() == 1)
|
||||
fp = fi;
|
||||
else
|
||||
const UString &a = paths[i];
|
||||
const int slash = a.ReverseFind_PathSepar();
|
||||
// if (name.Len() >= a.Len() - slash + 1) continue;
|
||||
const wchar_t *s = a.Ptr(slash + 1);
|
||||
if (!IsPath1PrefixedByPath2(s, name))
|
||||
continue;
|
||||
s += name.Len();
|
||||
const char *exts = isHash ? g_HashExts : g_ArcExts;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!fi2.Find(us2fs(paths[i])))
|
||||
const char *ext = exts;
|
||||
const unsigned len = MyStringLen(ext);
|
||||
if (len == 0)
|
||||
break;
|
||||
exts += len + 1;
|
||||
n = s;
|
||||
if (n.Len() <= len)
|
||||
continue;
|
||||
fp = &fi2;
|
||||
}
|
||||
names.Add(fs2us(fp->Name));
|
||||
}
|
||||
}
|
||||
|
||||
UString postfix;
|
||||
UInt32 index = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// we don't want cases when we include archive to itself.
|
||||
// so we find first available name for archive
|
||||
const UString name2 = name + postfix;
|
||||
const UString name2_zip = name2 + L".zip";
|
||||
const UString name2_7z = name2 + L".7z";
|
||||
const UString name2_tar = name2 + L".tar";
|
||||
const UString name2_wim = name2 + L".wim";
|
||||
|
||||
unsigned i = 0;
|
||||
|
||||
for (i = 0; i < names.Size(); i++)
|
||||
{
|
||||
const UString &fname = names[i];
|
||||
if ( 0 == CompareFileNames(fname, name2_zip)
|
||||
|| 0 == CompareFileNames(fname, name2_7z)
|
||||
|| 0 == CompareFileNames(fname, name2_tar)
|
||||
|| 0 == CompareFileNames(fname, name2_wim))
|
||||
if (!StringsAreEqualNoCase_Ascii(n.RightPtr(len), ext))
|
||||
continue;
|
||||
n.DeleteFrom(n.Len() - len);
|
||||
if (n.Back() != '.')
|
||||
continue;
|
||||
n.DeleteBack();
|
||||
if (n.IsEmpty())
|
||||
{
|
||||
simple_IsAllowed = false;
|
||||
break;
|
||||
}
|
||||
if (n.Len() < 2)
|
||||
continue;
|
||||
if (n[0] != '_')
|
||||
continue;
|
||||
const wchar_t *end;
|
||||
const UInt32 v = ConvertStringToUInt32(n.Ptr(1), &end);
|
||||
if (*end != 0)
|
||||
continue;
|
||||
ids.Add(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == names.Size())
|
||||
break;
|
||||
index++;
|
||||
postfix = "_";
|
||||
postfix.Add_UInt32(index);
|
||||
}
|
||||
|
||||
name += postfix;
|
||||
|
||||
baseName = name;
|
||||
if (!simple_IsAllowed)
|
||||
{
|
||||
HeapSort(&ids.Front(), ids.Size());
|
||||
UInt32 v = 2;
|
||||
const unsigned num = ids.Size();
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
{
|
||||
const UInt32 id = ids[i];
|
||||
if (id > v)
|
||||
break;
|
||||
if (id == v)
|
||||
v = id + 1;
|
||||
}
|
||||
name += '_';
|
||||
name.Add_UInt32(v);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user