aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/UI/Common/ArchiveName.cpp
blob: b7250249e510a38ec74d3d2d7f85e488d9f26ec6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// ArchiveName.cpp

#include "StdAfx.h"

#include "../../../Common/Wildcard.h"

#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"

#include "ExtractingFilePath.h"
#include "ArchiveName.h"

using namespace NWindows;
using namespace NFile;

static UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
{
  FString resultName = fi.Name;
  if (!fi.IsDir() && !keepName)
  {
    int dotPos = resultName.ReverseFind_Dot();
    if (dotPos > 0)
    {
      FString archiveName2 = resultName.Left(dotPos);
      if (archiveName2.ReverseFind_Dot() < 0)
        resultName = archiveName2;
    }
  }
  return Get_Correct_FsFile_Name(fs2us(resultName));
}

static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepName)
{
  FString resultName ("Archive");
  if (fromPrev)
  {
    FString dirPrefix;
    if (NDir::GetOnlyDirPrefix(path, dirPrefix))
    {
      if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back()))
      {
        #if defined(_WIN32) && !defined(UNDER_CE)
        if (NName::IsDriveRootPath_SuperAllowed(dirPrefix))
          resultName = dirPrefix[dirPrefix.Len() - 3]; // only letter
        else
        #endif
        {
          dirPrefix.DeleteBack();
          NFind::CFileInfo fi;
          if (fi.Find(dirPrefix))
            resultName = fi.Name;
        }
      }
    }
  }
  else
  {
    NFind::CFileInfo fi;
    if (fi.Find(path))
    {
      resultName = fi.Name;
      if (!fi.IsDir() && !keepName)
      {
        int dotPos = resultName.ReverseFind_Dot();
        if (dotPos > 0)
        {
          FString name2 = resultName.Left(dotPos);
          if (name2.ReverseFind_Dot() < 0)
            resultName = name2;
        }
      }
    }
  }
  return resultName;
}


UString CreateArchiveName(const UStringVector &paths, const NFind::CFileInfo *fi)
{
  bool keepName = false;
  /*
  if (paths.Size() == 1)
  {
    const UString &name = paths[0];
    if (name.Len() > 4)
      if (CompareFileNames(name.RightPtr(4), L".tar") == 0)
        keepName = true;
  }
  */

  UString name;
  if (fi)
    name = CreateArchiveName(*fi, keepName);
  else
  {
    if (paths.IsEmpty())
      return L"archive";
    bool fromPrev = (paths.Size() > 1);
    name = Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(paths.Front()), fromPrev, keepName)));
  }

  UString postfix;
  UInt32 index = 1;
  
  for (;;)
  {
    // we don't want cases when we include archive to itself.
    // so we find first available name for archive
    const UString name2 = name + postfix;
    const UString name2_zip = name2 + L".zip";
    const UString name2_7z = name2 + L".7z";
    const UString name2_tar = name2 + L".tar";
    const UString name2_wim = name2 + L".wim";
    
    unsigned i = 0;
    
    for (i = 0; i < paths.Size(); i++)
    {
      const UString &fn = paths[i];
      NFind::CFileInfo fi2;

      const NFind::CFileInfo *fp;
      if (fi && paths.Size() == 1)
        fp = fi;
      else
      {
        if (!fi2.Find(us2fs(fn)))
          continue;
        fp = &fi2;
      }
      const UString fname = fs2us(fp->Name);
      if (   0 == CompareFileNames(fname, name2_zip)
          || 0 == CompareFileNames(fname, name2_7z)
          || 0 == CompareFileNames(fname, name2_tar)
          || 0 == CompareFileNames(fname, name2_wim))
        break;
    }
    
    if (i == paths.Size())
      break;
    index++;
    postfix = "_";
    postfix.Add_UInt32(index);
  }
  
  name += postfix;
  return name;
}