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