xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Common/ArchiveName.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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