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(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(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 UString postfix;
103 UInt32 index = 1;
104
105 for (;;)
106 {
107 // we don't want cases when we include archive to itself.
108 // so we find first available name for archive
109 const UString name2 = name + postfix;
110 const UString name2_zip = name2 + L".zip";
111 const UString name2_7z = name2 + L".7z";
112 const UString name2_tar = name2 + L".tar";
113 const UString name2_wim = name2 + L".wim";
114
115 unsigned i = 0;
116
117 for (i = 0; i < paths.Size(); i++)
118 {
119 const UString &fn = paths[i];
120 NFind::CFileInfo fi2;
121
122 const NFind::CFileInfo *fp;
123 if (fi && paths.Size() == 1)
124 fp = fi;
125 else
126 {
127 if (!fi2.Find(us2fs(fn)))
128 continue;
129 fp = &fi2;
130 }
131 const UString fname = fs2us(fp->Name);
132 if ( 0 == CompareFileNames(fname, name2_zip)
133 || 0 == CompareFileNames(fname, name2_7z)
134 || 0 == CompareFileNames(fname, name2_tar)
135 || 0 == CompareFileNames(fname, name2_wim))
136 break;
137 }
138
139 if (i == paths.Size())
140 break;
141 index++;
142 postfix = "_";
143 postfix.Add_UInt32(index);
144 }
145
146 name += postfix;
147 return name;
148 }
149