1 // ExtractingFilePath.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../../C/Types.h"
6
7 #include "Common/Wildcard.h"
8
9 #include "ExtractingFilePath.h"
10
ReplaceIncorrectChars(const UString & s)11 static UString ReplaceIncorrectChars(const UString &s)
12 {
13 #ifdef _WIN32
14 UString res;
15 for (int i = 0; i < s.Length(); i++)
16 {
17 wchar_t c = s[i];
18 if (c < 0x20 || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c == ':' || c == '"')
19 c = '_';
20 res += c;
21 }
22 res.TrimRight();
23 while (!res.IsEmpty() && res[res.Length() - 1] == '.')
24 res.Delete(res.Length() - 1);
25 return res;
26 #else
27 return s;
28 #endif
29 }
30
31 #ifdef _WIN32
32 static const wchar_t *g_ReservedNames[] =
33 {
34 L"CON", L"PRN", L"AUX", L"NUL"
35 };
36
CheckTail(const UString & name,int len)37 static bool CheckTail(const UString &name, int len)
38 {
39 int dotPos = name.Find(L'.');
40 if (dotPos < 0)
41 dotPos = name.Length();
42 UString s = name.Left(dotPos);
43 s.TrimRight();
44 return (s.Length() != len);
45 }
46
CheckNameNum(const UString & name,const wchar_t * reservedName)47 static bool CheckNameNum(const UString &name, const wchar_t *reservedName)
48 {
49 int len = MyStringLen(reservedName);
50 if (name.Length() <= len)
51 return true;
52 if (name.Left(len).CompareNoCase(reservedName) != 0)
53 return true;
54 wchar_t c = name[len];
55 if (c < L'0' || c > L'9')
56 return true;
57 return CheckTail(name, len + 1);
58 }
59
IsSupportedName(const UString & name)60 static bool IsSupportedName(const UString &name)
61 {
62 for (int i = 0; i < sizeof(g_ReservedNames) / sizeof(g_ReservedNames[0]); i++)
63 {
64 const wchar_t *reservedName = g_ReservedNames[i];
65 int len = MyStringLen(reservedName);
66 if (name.Length() < len)
67 continue;
68 if (name.Left(len).CompareNoCase(reservedName) != 0)
69 continue;
70 if (!CheckTail(name, len))
71 return false;
72 }
73 if (!CheckNameNum(name, L"COM"))
74 return false;
75 return CheckNameNum(name, L"LPT");
76 }
77 #endif
78
GetCorrectFileName(const UString & path)79 static UString GetCorrectFileName(const UString &path)
80 {
81 if (path == L".." || path == L".")
82 return UString();
83 return ReplaceIncorrectChars(path);
84 }
85
MakeCorrectPath(UStringVector & pathParts)86 void MakeCorrectPath(UStringVector &pathParts)
87 {
88 for (int i = 0; i < pathParts.Size();)
89 {
90 UString &s = pathParts[i];
91 s = GetCorrectFileName(s);
92 if (s.IsEmpty())
93 pathParts.Delete(i);
94 else
95 {
96 #ifdef _WIN32
97 if (!IsSupportedName(s))
98 s = (UString)L"_" + s;
99 #endif
100 i++;
101 }
102 }
103 }
104
MakePathNameFromParts(const UStringVector & parts)105 UString MakePathNameFromParts(const UStringVector &parts)
106 {
107 UString result;
108 for (int i = 0; i < parts.Size(); i++)
109 {
110 if (i != 0)
111 result += WCHAR_PATH_SEPARATOR;
112 result += parts[i];
113 }
114 return result;
115 }
116
GetCorrectFsPath(const UString & path)117 UString GetCorrectFsPath(const UString &path)
118 {
119 UString res = GetCorrectFileName(path);
120 #ifdef _WIN32
121 if (!IsSupportedName(res))
122 res = (UString)L"_" + res;
123 #endif
124 return res;
125 }
126
GetCorrectFullFsPath(const UString & path)127 UString GetCorrectFullFsPath(const UString &path)
128 {
129 UStringVector parts;
130 SplitPathToParts(path, parts);
131 for (int i = 0; i < parts.Size(); i++)
132 {
133 UString &s = parts[i];
134 #ifdef _WIN32
135 while (!s.IsEmpty() && s[s.Length() - 1] == '.')
136 s.Delete(s.Length() - 1);
137 if (!IsSupportedName(s))
138 s = (UString)L"_" + s;
139 #endif
140 }
141 return MakePathNameFromParts(parts);
142 }
143