xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Rar/RarVol.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // RarVol.h
2 
3 #ifndef ZIP7_INC_ARCHIVE_RAR_VOL_H
4 #define ZIP7_INC_ARCHIVE_RAR_VOL_H
5 
6 #include "../../../Common/StringConvert.h"
7 
8 #include "RarHeader.h"
9 
10 namespace NArchive {
11 namespace NRar {
12 
IsDigit(wchar_t c)13 inline bool IsDigit(wchar_t c)
14 {
15   return c >= L'0' && c <= L'9';
16 }
17 
18 class CVolumeName
19 {
20   bool _needChangeForNext;
21   UString _before;
22   UString _changed;
23   UString _after;
24 public:
CVolumeName()25   CVolumeName(): _needChangeForNext(true) {}
26 
27   bool InitName(const UString &name, bool newStyle = true)
28   {
29     _needChangeForNext = true;
30     _after.Empty();
31     UString base (name);
32     const int dotPos = name.ReverseFind_Dot();
33 
34     if (dotPos >= 0)
35     {
36       const UString ext (name.Ptr(dotPos + 1));
37       if (ext.IsEqualTo_Ascii_NoCase("rar"))
38       {
39         _after = name.Ptr(dotPos);
40         base.DeleteFrom(dotPos);
41       }
42       else if (ext.IsEqualTo_Ascii_NoCase("exe"))
43       {
44         _after = ".rar";
45         base.DeleteFrom(dotPos);
46       }
47       else if (!newStyle)
48       {
49         if (ext.IsEqualTo_Ascii_NoCase("000") ||
50             ext.IsEqualTo_Ascii_NoCase("001") ||
51             ext.IsEqualTo_Ascii_NoCase("r00") ||
52             ext.IsEqualTo_Ascii_NoCase("r01"))
53         {
54           _changed = ext;
55           _before.SetFrom(name.Ptr(), (unsigned)dotPos + 1);
56           return true;
57         }
58       }
59     }
60 
61     if (newStyle)
62     {
63       unsigned k = base.Len();
64 
65       for (; k != 0; k--)
66         if (IsDigit(base[k - 1]))
67           break;
68 
69       unsigned i = k;
70 
71       for (; i != 0; i--)
72         if (!IsDigit(base[i - 1]))
73           break;
74 
75       if (i != k)
76       {
77         _before.SetFrom(base.Ptr(), i);
78         _changed.SetFrom(base.Ptr(i), k - i);
79         _after.Insert(0, base.Ptr(k));
80         return true;
81       }
82     }
83 
84     _after.Empty();
85     _before = base;
86     _before.Add_Dot();
87     _changed = "r00";
88     _needChangeForNext = false;
89     return true;
90   }
91 
92   /*
93   void MakeBeforeFirstName()
94   {
95     unsigned len = _changed.Len();
96     _changed.Empty();
97     for (unsigned i = 0; i < len; i++)
98       _changed += L'0';
99   }
100   */
101 
GetNextName()102   UString GetNextName()
103   {
104     if (_needChangeForNext)
105     {
106       unsigned i = _changed.Len();
107       if (i == 0)
108         return UString();
109       for (;;)
110       {
111         wchar_t c = _changed[--i];
112         if (c == L'9')
113         {
114           c = L'0';
115           _changed.ReplaceOneCharAtPos(i, c);
116           if (i == 0)
117           {
118             _changed.InsertAtFront(L'1');
119             break;
120           }
121           continue;
122         }
123         c++;
124         _changed.ReplaceOneCharAtPos(i, c);
125         break;
126       }
127     }
128 
129     _needChangeForNext = true;
130     return _before + _changed + _after;
131   }
132 };
133 
134 }}
135 
136 #endif
137