// ArchiveName.cpp #include "StdAfx.h" #include "../../../../C/Sort.h" #include "../../../Common/Wildcard.h" #include "../../../Common/StringToInt.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/FileName.h" #include "ArchiveName.h" #include "ExtractingFilePath.h" using namespace NWindows; using namespace NFile; 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, bool isHash, const NFind::CFileInfo *fi, UString &baseName) { bool keepName = isHash; /* if (paths.Size() == 1) { const UString &name = paths[0]; if (name.Len() > 4) if (CompareFileNames(name.RightPtr(4), L".tar") == 0) keepName = true; } */ UString name ("Archive"); NFind::CFileInfo fi3; if (paths.Size() > 1) fi = NULL; if (!fi && paths.Size() != 0) { 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); } } } } } } 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 ids; bool simple_IsAllowed = true; // for (int y = 0; y < 10000; y++) // for debug { // ids.Clear(); UString n; FOR_VECTOR (i, paths) { 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 (;;) { const char *ext = exts; const unsigned len = MyStringLen(ext); if (len == 0) break; exts += len + 1; n = s; if (n.Len() <= len) continue; 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; } } } 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; }