1 // ArchiveName.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../Common/Wildcard.h"
6
7 #include "../../../Windows/FileDir.h"
8 #include "../../../Windows/FileName.h"
9
10 #include "ExtractingFilePath.h"
11 #include "ArchiveName.h"
12
13 using namespace NWindows;
14 using namespace NFile;
15
CreateArchiveName(const NFind::CFileInfo & fi,bool keepName)16 static UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
17 {
18 FString resultName = fi.Name;
19 if (!fi.IsDir() && !keepName)
20 {
21 int dotPos = resultName.ReverseFind_Dot();
22 if (dotPos > 0)
23 {
24 FString archiveName2 = resultName.Left((unsigned)dotPos);
25 if (archiveName2.ReverseFind_Dot() < 0)
26 resultName = archiveName2;
27 }
28 }
29 return Get_Correct_FsFile_Name(fs2us(resultName));
30 }
31
CreateArchiveName2(const FString & path,bool fromPrev,bool keepName)32 static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepName)
33 {
34 FString resultName ("Archive");
35 if (fromPrev)
36 {
37 FString dirPrefix;
38 if (NDir::GetOnlyDirPrefix(path, dirPrefix))
39 {
40 if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back()))
41 {
42 #if defined(_WIN32) && !defined(UNDER_CE)
43 if (NName::IsDriveRootPath_SuperAllowed(dirPrefix))
44 resultName = dirPrefix[dirPrefix.Len() - 3]; // only letter
45 else
46 #endif
47 {
48 dirPrefix.DeleteBack();
49 NFind::CFileInfo fi;
50 if (fi.Find(dirPrefix))
51 resultName = fi.Name;
52 }
53 }
54 }
55 }
56 else
57 {
58 NFind::CFileInfo fi;
59 if (fi.Find(path))
60 {
61 resultName = fi.Name;
62 if (!fi.IsDir() && !keepName)
63 {
64 int dotPos = resultName.ReverseFind_Dot();
65 if (dotPos > 0)
66 {
67 FString name2 = resultName.Left((unsigned)dotPos);
68 if (name2.ReverseFind_Dot() < 0)
69 resultName = name2;
70 }
71 }
72 }
73 }
74 return resultName;
75 }
76
77
CreateArchiveName(const UStringVector & paths,const NFind::CFileInfo * fi)78 UString CreateArchiveName(const UStringVector &paths, const NFind::CFileInfo *fi)
79 {
80 bool keepName = false;
81 /*
82 if (paths.Size() == 1)
83 {
84 const UString &name = paths[0];
85 if (name.Len() > 4)
86 if (CompareFileNames(name.RightPtr(4), L".tar") == 0)
87 keepName = true;
88 }
89 */
90
91 UString name;
92 if (fi)
93 name = CreateArchiveName(*fi, keepName);
94 else
95 {
96 if (paths.IsEmpty())
97 return L"archive";
98 bool fromPrev = (paths.Size() > 1);
99 name = Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(paths.Front()), fromPrev, keepName)));
100 }
101
102 UStringVector names;
103
104 {
105 FOR_VECTOR (i, paths)
106 {
107 NFind::CFileInfo fi2;
108 const NFind::CFileInfo *fp;
109 if (fi && paths.Size() == 1)
110 fp = fi;
111 else
112 {
113 if (!fi2.Find(us2fs(paths[i])))
114 continue;
115 fp = &fi2;
116 }
117 names.Add(fs2us(fp->Name));
118 }
119 }
120
121 UString postfix;
122 UInt32 index = 1;
123
124 for (;;)
125 {
126 // we don't want cases when we include archive to itself.
127 // so we find first available name for archive
128 const UString name2 = name + postfix;
129 const UString name2_zip = name2 + L".zip";
130 const UString name2_7z = name2 + L".7z";
131 const UString name2_tar = name2 + L".tar";
132 const UString name2_wim = name2 + L".wim";
133
134 unsigned i = 0;
135
136 for (i = 0; i < names.Size(); i++)
137 {
138 const UString &fname = names[i];
139 if ( 0 == CompareFileNames(fname, name2_zip)
140 || 0 == CompareFileNames(fname, name2_7z)
141 || 0 == CompareFileNames(fname, name2_tar)
142 || 0 == CompareFileNames(fname, name2_wim))
143 break;
144 }
145
146 if (i == names.Size())
147 break;
148 index++;
149 postfix = "_";
150 postfix.Add_UInt32(index);
151 }
152
153 name += postfix;
154 return name;
155 }
156