Upload 2.0.2
[physicsfs] / lzma / CPP / 7zip / UI / Common / ExtractingFilePath.cpp
1 // ExtractingFilePath.cpp
2
3 #include "StdAfx.h"
4 #include "ExtractingFilePath.h"
5
6 static UString ReplaceIncorrectChars(const UString &s)
7 {
8   #ifdef _WIN32
9   UString res;
10   for (int i = 0; i < s.Length(); i++)
11   {
12     wchar_t c = s[i];
13     if (c < 0x20 || c == '*' || c == '?' || c == '<' || c == '>'  || c == '|' || c == ':' || c == '"')
14       c = '_';
15     res += c;
16   }
17   return res;
18   #else
19   return s;
20   #endif
21 }
22
23 #ifdef _WIN32
24 static const wchar_t *g_ReservedNames[] =
25 {
26   L"CON", L"PRN", L"AUX", L"NUL"
27 };
28
29 static bool CheckTail(const UString &name, int len)
30 {
31   int dotPos = name.Find(L'.');
32   if (dotPos < 0)
33     dotPos = name.Length();
34   UString s = name.Left(dotPos);
35   s.TrimRight();
36   return (s.Length() != len);
37 }
38
39 static bool CheckNameNum(const UString &name, const wchar_t *reservedName)
40 {
41   int len = MyStringLen(reservedName);
42   if (name.Length() <= len)
43     return true;
44   if (name.Left(len).CompareNoCase(reservedName) != 0)
45     return true;
46   wchar_t c = name[len];
47   if (c < L'0' || c > L'9')
48     return true;
49   return CheckTail(name, len + 1);
50 }
51
52 static bool IsSupportedName(const UString &name)
53 {
54   for (int i = 0; i < sizeof(g_ReservedNames) / sizeof(g_ReservedNames[0]); i++)
55   {
56     const wchar_t *reservedName = g_ReservedNames[i];
57     int len = MyStringLen(reservedName);
58     if (name.Length() < len)
59       continue;
60     if (name.Left(len).CompareNoCase(reservedName) != 0)
61       continue;
62     if (!CheckTail(name, len))
63       return false;
64   }
65   if (!CheckNameNum(name, L"COM"))
66     return false;
67   return CheckNameNum(name, L"LPT");
68 }
69 #endif
70
71 static UString GetCorrectFileName(const UString &path)
72 {
73   if (path == L".." || path == L".")
74     return UString();
75   return ReplaceIncorrectChars(path);
76 }
77
78 void MakeCorrectPath(UStringVector &pathParts)
79 {
80   for (int i = 0; i < pathParts.Size();)
81   {
82     UString &s = pathParts[i];
83     s = GetCorrectFileName(s);
84     if (s.IsEmpty())
85       pathParts.Delete(i);
86     else
87     {
88       #ifdef _WIN32
89       if (!IsSupportedName(s))
90         s = (UString)L"_" + s;
91       #endif
92       i++;
93     }
94   }
95 }
96