1// ArchiveName.cpp 2 3#include "StdAfx.h" 4 5#include "../../../../C/Sort.h" 6 7#include "../../../Common/Wildcard.h" 8#include "../../../Common/StringToInt.h" 9 10#include "../../../Windows/FileDir.h" 11#include "../../../Windows/FileName.h" 12 13#include "ArchiveName.h" 14#include "ExtractingFilePath.h" 15 16using namespace NWindows; 17using namespace NFile; 18 19 20static const char *g_ArcExts = 21 "7z" 22 "\0" "zip" 23 "\0" "tar" 24 "\0" "wim" 25 "\0"; 26 27static const char *g_HashExts = 28 "sha256" 29 "\0"; 30 31 32UString CreateArchiveName( 33 const UStringVector &paths, 34 bool isHash, 35 const NFind::CFileInfo *fi, 36 UString &baseName) 37{ 38 bool keepName = isHash; 39 /* 40 if (paths.Size() == 1) 41 { 42 const UString &name = paths[0]; 43 if (name.Len() > 4) 44 if (CompareFileNames(name.RightPtr(4), L".tar") == 0) 45 keepName = true; 46 } 47 */ 48 49 UString name ("Archive"); 50 NFind::CFileInfo fi3; 51 if (paths.Size() > 1) 52 fi = NULL; 53 if (!fi && paths.Size() != 0) 54 { 55 const UString &path = paths.Front(); 56 if (paths.Size() == 1) 57 { 58 if (fi3.Find(us2fs(path))) 59 fi = &fi3; 60 } 61 else 62 { 63 // we try to use name of parent folder 64 FString dirPrefix; 65 if (NDir::GetOnlyDirPrefix(us2fs(path), dirPrefix)) 66 { 67 if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back())) 68 { 69 #if defined(_WIN32) && !defined(UNDER_CE) 70 if (NName::IsDriveRootPath_SuperAllowed(dirPrefix)) 71 { 72 if (path != fs2us(dirPrefix)) 73 name = dirPrefix[dirPrefix.Len() - 3]; // only letter 74 } 75 else 76 #endif 77 { 78 dirPrefix.DeleteBack(); 79 if (!dirPrefix.IsEmpty()) 80 { 81 const int slash = dirPrefix.ReverseFind_PathSepar(); 82 if (slash >= 0 && slash != (int)dirPrefix.Len() - 1) 83 name = dirPrefix.Ptr(slash + 1); 84 else if (fi3.Find(dirPrefix)) 85 name = fs2us(fi3.Name); 86 } 87 } 88 } 89 } 90 } 91 } 92 93 if (fi) 94 { 95 name = fs2us(fi->Name); 96 if (!fi->IsDir() && !keepName) 97 { 98 const int dotPos = name.Find(L'.'); 99 if (dotPos > 0 && name.Find(L'.', (unsigned)dotPos + 1) < 0) 100 name.DeleteFrom((unsigned)dotPos); 101 } 102 } 103 name = Get_Correct_FsFile_Name(name); 104 105 CRecordVector<UInt32> ids; 106 bool simple_IsAllowed = true; 107 // for (int y = 0; y < 10000; y++) // for debug 108 { 109 // ids.Clear(); 110 UString n; 111 112 FOR_VECTOR (i, paths) 113 { 114 const UString &a = paths[i]; 115 const int slash = a.ReverseFind_PathSepar(); 116 // if (name.Len() >= a.Len() - slash + 1) continue; 117 const wchar_t *s = a.Ptr(slash + 1); 118 if (!IsPath1PrefixedByPath2(s, name)) 119 continue; 120 s += name.Len(); 121 const char *exts = isHash ? g_HashExts : g_ArcExts; 122 123 for (;;) 124 { 125 const char *ext = exts; 126 const unsigned len = MyStringLen(ext); 127 if (len == 0) 128 break; 129 exts += len + 1; 130 n = s; 131 if (n.Len() <= len) 132 continue; 133 if (!StringsAreEqualNoCase_Ascii(n.RightPtr(len), ext)) 134 continue; 135 n.DeleteFrom(n.Len() - len); 136 if (n.Back() != '.') 137 continue; 138 n.DeleteBack(); 139 if (n.IsEmpty()) 140 { 141 simple_IsAllowed = false; 142 break; 143 } 144 if (n.Len() < 2) 145 continue; 146 if (n[0] != '_') 147 continue; 148 const wchar_t *end; 149 const UInt32 v = ConvertStringToUInt32(n.Ptr(1), &end); 150 if (*end != 0) 151 continue; 152 ids.Add(v); 153 break; 154 } 155 } 156 } 157 158 baseName = name; 159 if (!simple_IsAllowed) 160 { 161 HeapSort(&ids.Front(), ids.Size()); 162 UInt32 v = 2; 163 const unsigned num = ids.Size(); 164 for (unsigned i = 0; i < num; i++) 165 { 166 const UInt32 id = ids[i]; 167 if (id > v) 168 break; 169 if (id == v) 170 v = id + 1; 171 } 172 name += '_'; 173 name.Add_UInt32(v); 174 } 175 return name; 176} 177