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 11static 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 32static const wchar_t *g_ReservedNames[] = 33{ 34 L"CON", L"PRN", L"AUX", L"NUL" 35}; 36 37static 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 47static 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 60static 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 79static UString GetCorrectFileName(const UString &path) 80{ 81 if (path == L".." || path == L".") 82 return UString(); 83 return ReplaceIncorrectChars(path); 84} 85 86void 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 105UString 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 117UString 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 127UString 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