1370b324cSopenharmony_ci// ArchiveName.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../../../C/Sort.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "../../../Common/Wildcard.h"
8370b324cSopenharmony_ci#include "../../../Common/StringToInt.h"
9370b324cSopenharmony_ci
10370b324cSopenharmony_ci#include "../../../Windows/FileDir.h"
11370b324cSopenharmony_ci#include "../../../Windows/FileName.h"
12370b324cSopenharmony_ci
13370b324cSopenharmony_ci#include "ArchiveName.h"
14370b324cSopenharmony_ci#include "ExtractingFilePath.h"
15370b324cSopenharmony_ci
16370b324cSopenharmony_ciusing namespace NWindows;
17370b324cSopenharmony_ciusing namespace NFile;
18370b324cSopenharmony_ci
19370b324cSopenharmony_ci
20370b324cSopenharmony_cistatic const char *g_ArcExts =
21370b324cSopenharmony_ci        "7z"
22370b324cSopenharmony_ci  "\0"  "zip"
23370b324cSopenharmony_ci  "\0"  "tar"
24370b324cSopenharmony_ci  "\0"  "wim"
25370b324cSopenharmony_ci  "\0";
26370b324cSopenharmony_ci
27370b324cSopenharmony_cistatic const char *g_HashExts =
28370b324cSopenharmony_ci  "sha256"
29370b324cSopenharmony_ci  "\0";
30370b324cSopenharmony_ci
31370b324cSopenharmony_ci
32370b324cSopenharmony_ciUString CreateArchiveName(
33370b324cSopenharmony_ci    const UStringVector &paths,
34370b324cSopenharmony_ci    bool isHash,
35370b324cSopenharmony_ci    const NFind::CFileInfo *fi,
36370b324cSopenharmony_ci    UString &baseName)
37370b324cSopenharmony_ci{
38370b324cSopenharmony_ci  bool keepName = isHash;
39370b324cSopenharmony_ci  /*
40370b324cSopenharmony_ci  if (paths.Size() == 1)
41370b324cSopenharmony_ci  {
42370b324cSopenharmony_ci    const UString &name = paths[0];
43370b324cSopenharmony_ci    if (name.Len() > 4)
44370b324cSopenharmony_ci      if (CompareFileNames(name.RightPtr(4), L".tar") == 0)
45370b324cSopenharmony_ci        keepName = true;
46370b324cSopenharmony_ci  }
47370b324cSopenharmony_ci  */
48370b324cSopenharmony_ci
49370b324cSopenharmony_ci  UString name ("Archive");
50370b324cSopenharmony_ci  NFind::CFileInfo fi3;
51370b324cSopenharmony_ci  if (paths.Size() > 1)
52370b324cSopenharmony_ci    fi = NULL;
53370b324cSopenharmony_ci  if (!fi && paths.Size() != 0)
54370b324cSopenharmony_ci  {
55370b324cSopenharmony_ci    const UString &path = paths.Front();
56370b324cSopenharmony_ci    if (paths.Size() == 1)
57370b324cSopenharmony_ci    {
58370b324cSopenharmony_ci      if (fi3.Find(us2fs(path)))
59370b324cSopenharmony_ci        fi = &fi3;
60370b324cSopenharmony_ci    }
61370b324cSopenharmony_ci    else
62370b324cSopenharmony_ci    {
63370b324cSopenharmony_ci      // we try to use name of parent folder
64370b324cSopenharmony_ci      FString dirPrefix;
65370b324cSopenharmony_ci      if (NDir::GetOnlyDirPrefix(us2fs(path), dirPrefix))
66370b324cSopenharmony_ci      {
67370b324cSopenharmony_ci        if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back()))
68370b324cSopenharmony_ci        {
69370b324cSopenharmony_ci         #if defined(_WIN32) && !defined(UNDER_CE)
70370b324cSopenharmony_ci          if (NName::IsDriveRootPath_SuperAllowed(dirPrefix))
71370b324cSopenharmony_ci          {
72370b324cSopenharmony_ci            if (path != fs2us(dirPrefix))
73370b324cSopenharmony_ci              name = dirPrefix[dirPrefix.Len() - 3]; // only letter
74370b324cSopenharmony_ci          }
75370b324cSopenharmony_ci          else
76370b324cSopenharmony_ci         #endif
77370b324cSopenharmony_ci          {
78370b324cSopenharmony_ci            dirPrefix.DeleteBack();
79370b324cSopenharmony_ci            if (!dirPrefix.IsEmpty())
80370b324cSopenharmony_ci            {
81370b324cSopenharmony_ci              const int slash = dirPrefix.ReverseFind_PathSepar();
82370b324cSopenharmony_ci              if (slash >= 0 && slash != (int)dirPrefix.Len() - 1)
83370b324cSopenharmony_ci                name = dirPrefix.Ptr(slash + 1);
84370b324cSopenharmony_ci              else if (fi3.Find(dirPrefix))
85370b324cSopenharmony_ci                name = fs2us(fi3.Name);
86370b324cSopenharmony_ci            }
87370b324cSopenharmony_ci          }
88370b324cSopenharmony_ci        }
89370b324cSopenharmony_ci      }
90370b324cSopenharmony_ci    }
91370b324cSopenharmony_ci  }
92370b324cSopenharmony_ci
93370b324cSopenharmony_ci  if (fi)
94370b324cSopenharmony_ci  {
95370b324cSopenharmony_ci    name = fs2us(fi->Name);
96370b324cSopenharmony_ci    if (!fi->IsDir() && !keepName)
97370b324cSopenharmony_ci    {
98370b324cSopenharmony_ci      const int dotPos = name.Find(L'.');
99370b324cSopenharmony_ci      if (dotPos > 0 && name.Find(L'.', (unsigned)dotPos + 1) < 0)
100370b324cSopenharmony_ci        name.DeleteFrom((unsigned)dotPos);
101370b324cSopenharmony_ci    }
102370b324cSopenharmony_ci  }
103370b324cSopenharmony_ci  name = Get_Correct_FsFile_Name(name);
104370b324cSopenharmony_ci
105370b324cSopenharmony_ci  CRecordVector<UInt32> ids;
106370b324cSopenharmony_ci  bool simple_IsAllowed = true;
107370b324cSopenharmony_ci  // for (int y = 0; y < 10000; y++) // for debug
108370b324cSopenharmony_ci  {
109370b324cSopenharmony_ci    // ids.Clear();
110370b324cSopenharmony_ci    UString n;
111370b324cSopenharmony_ci
112370b324cSopenharmony_ci    FOR_VECTOR (i, paths)
113370b324cSopenharmony_ci    {
114370b324cSopenharmony_ci      const UString &a = paths[i];
115370b324cSopenharmony_ci      const int slash = a.ReverseFind_PathSepar();
116370b324cSopenharmony_ci      // if (name.Len() >= a.Len() - slash + 1) continue;
117370b324cSopenharmony_ci      const wchar_t *s = a.Ptr(slash + 1);
118370b324cSopenharmony_ci      if (!IsPath1PrefixedByPath2(s, name))
119370b324cSopenharmony_ci        continue;
120370b324cSopenharmony_ci      s += name.Len();
121370b324cSopenharmony_ci      const char *exts = isHash ? g_HashExts : g_ArcExts;
122370b324cSopenharmony_ci
123370b324cSopenharmony_ci      for (;;)
124370b324cSopenharmony_ci      {
125370b324cSopenharmony_ci        const char *ext = exts;
126370b324cSopenharmony_ci        const unsigned len = MyStringLen(ext);
127370b324cSopenharmony_ci        if (len == 0)
128370b324cSopenharmony_ci          break;
129370b324cSopenharmony_ci        exts += len + 1;
130370b324cSopenharmony_ci        n = s;
131370b324cSopenharmony_ci        if (n.Len() <= len)
132370b324cSopenharmony_ci          continue;
133370b324cSopenharmony_ci        if (!StringsAreEqualNoCase_Ascii(n.RightPtr(len), ext))
134370b324cSopenharmony_ci          continue;
135370b324cSopenharmony_ci        n.DeleteFrom(n.Len() - len);
136370b324cSopenharmony_ci        if (n.Back() != '.')
137370b324cSopenharmony_ci          continue;
138370b324cSopenharmony_ci        n.DeleteBack();
139370b324cSopenharmony_ci        if (n.IsEmpty())
140370b324cSopenharmony_ci        {
141370b324cSopenharmony_ci          simple_IsAllowed = false;
142370b324cSopenharmony_ci          break;
143370b324cSopenharmony_ci        }
144370b324cSopenharmony_ci        if (n.Len() < 2)
145370b324cSopenharmony_ci          continue;
146370b324cSopenharmony_ci        if (n[0] != '_')
147370b324cSopenharmony_ci          continue;
148370b324cSopenharmony_ci        const wchar_t *end;
149370b324cSopenharmony_ci        const UInt32 v = ConvertStringToUInt32(n.Ptr(1), &end);
150370b324cSopenharmony_ci        if (*end != 0)
151370b324cSopenharmony_ci          continue;
152370b324cSopenharmony_ci        ids.Add(v);
153370b324cSopenharmony_ci        break;
154370b324cSopenharmony_ci      }
155370b324cSopenharmony_ci    }
156370b324cSopenharmony_ci  }
157370b324cSopenharmony_ci
158370b324cSopenharmony_ci  baseName = name;
159370b324cSopenharmony_ci  if (!simple_IsAllowed)
160370b324cSopenharmony_ci  {
161370b324cSopenharmony_ci    HeapSort(&ids.Front(), ids.Size());
162370b324cSopenharmony_ci    UInt32 v = 2;
163370b324cSopenharmony_ci    const unsigned num = ids.Size();
164370b324cSopenharmony_ci    for (unsigned i = 0; i < num; i++)
165370b324cSopenharmony_ci    {
166370b324cSopenharmony_ci      const UInt32 id = ids[i];
167370b324cSopenharmony_ci      if (id > v)
168370b324cSopenharmony_ci        break;
169370b324cSopenharmony_ci      if (id == v)
170370b324cSopenharmony_ci        v = id + 1;
171370b324cSopenharmony_ci    }
172370b324cSopenharmony_ci    name += '_';
173370b324cSopenharmony_ci    name.Add_UInt32(v);
174370b324cSopenharmony_ci  }
175370b324cSopenharmony_ci  return name;
176370b324cSopenharmony_ci}
177