Home | History | Annotate | Download | only in Common
      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 
     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 
     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 
     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 
     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 
     79 static UString GetCorrectFileName(const UString &path)
     80 {
     81   if (path == L".." || path == L".")
     82     return UString();
     83   return ReplaceIncorrectChars(path);
     84 }
     85 
     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 
    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 
    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 
    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