@@ -36,6 +36,25 @@ namespace clr
36
36
class Path
37
37
{
38
38
public:
39
+ #if !PLATFORM_UNIX
40
+ static const CHAR DirectorySeparatorChar = ' \\ ' ;
41
+ #else // PLATFORM_UNIX
42
+ static const CHAR DirectorySeparatorChar = ' /' ;
43
+ #endif
44
+
45
+ #if !PLATFORM_UNIX
46
+ static const CHAR PathSeparatorChar = ' ;' ;
47
+ #else // PLATFORM_UNIX
48
+ static const CHAR PathSeparatorChar = ' :' ;
49
+ #endif // !PLATFORM_UNIX
50
+
51
+ #if !PLATFORM_UNIX
52
+ static const CHAR VolumeSeparatorChar = ' :' ;
53
+ #else // PLATFORM_UNIX
54
+ static const CHAR VolumeSeparatorChar = ' /' ;
55
+ #endif // !PLATFORM_UNIX
56
+
57
+ public:
39
58
// -----------------------------------------------------------------------------------------
40
59
static inline bool
41
60
Exists (
@@ -54,36 +73,41 @@ namespace clr
54
73
return wcscmp (wzPath, LONG_FORMAT_PATH_PREFIX) == 0 ;
55
74
}
56
75
57
- // -----------------------------------------------------------------------------------------
58
- static inline bool
59
- HasUncPrefix (LPCWSTR wzPath)
60
- {
61
- _ASSERTE (!clr::str::IsNullOrEmpty (wzPath)); // Must check this first.
62
- return wzPath[0 ] != W (' \0 ' ) && wzPath[0 ] == W (' \\ ' )
63
- && wzPath[1 ] != W (' \0 ' ) && wzPath[1 ] == W (' \\ ' )
64
- && wzPath[2 ] != W (' \0 ' ) && wzPath[2 ] != W (' ?' );
65
- }
66
-
67
- // -----------------------------------------------------------------------------------------
68
- static inline bool
69
- HasDrivePrefix (LPCWSTR wzPath)
70
- {
71
- _ASSERTE (!clr::str::IsNullOrEmpty (wzPath)); // Must check this first.
72
- return wzPath[0 ] != W (' \0 ' )
73
- && wzPath[1 ] != W (' \0 ' ) && wzPath[1 ] == W (' :' )
74
- && ((wzPath[0 ] >= W (' a' ) && wzPath[0 ] <= W (' z' )) ||
75
- (wzPath[0 ] >= W (' A' ) && wzPath[0 ] <= W (' Z' )));
76
- }
77
-
78
76
// -----------------------------------------------------------------------------------------
79
77
// Returns true if wzPath represents a relative path.
80
78
static inline bool
81
79
IsRelative (LPCWSTR wzPath)
82
80
{
83
- _ASSERTE (!clr::str::IsNullOrEmpty (wzPath)); // Must check this first.
84
- return !HasLongFormatPrefix (wzPath)
85
- && !HasUncPrefix (wzPath)
86
- && (!HasDrivePrefix (wzPath) || wzPath[2 ] != W (' \\ ' ));
81
+ _ASSERTE (wzPath != nullptr );
82
+
83
+ // Similar to System.IO.Path.IsRelative()
84
+ #if PLATFORM_UNIX
85
+ if (wzPath[0 ] == VolumeSeparatorChar)
86
+ {
87
+ return false ;
88
+ }
89
+ #else
90
+ // Check for a paths like "C:\..." or "\\...". Additional notes:
91
+ // - "\\?\..." - long format paths are considered as absolute paths due to the "\\" prefix
92
+ // - "\..." - these paths are relative, as they depend on the current drive
93
+ // - "C:..." and not "C:\..." - these paths are relative, as they depend on the current directory for drive C
94
+ if (wzPath[0 ] != W (' \0 ' ) &&
95
+ wzPath[1 ] == VolumeSeparatorChar &&
96
+ wzPath[2 ] == DirectorySeparatorChar &&
97
+ (
98
+ (wzPath[0 ] >= W (' A' ) && wzPath[0 ] <= W (' Z' )) ||
99
+ (wzPath[0 ] >= W (' a' ) && wzPath[0 ] <= W (' z' ))
100
+ ))
101
+ {
102
+ return false ;
103
+ }
104
+ if (wzPath[0 ] == DirectorySeparatorChar && wzPath[1 ] == DirectorySeparatorChar)
105
+ {
106
+ return false ;
107
+ }
108
+ #endif
109
+
110
+ return true ;
87
111
}
88
112
89
113
// -----------------------------------------------------------------------------------------
@@ -105,7 +129,8 @@ namespace clr
105
129
size_t cchBuf = *pcchBuffer;
106
130
107
131
IfFailRet (StringCchCopyExW (wzBuf, cchBuf, wzPathLeft, &wzBuf, &cchBuf, STRSAFE_NULL_ON_FAILURE));
108
- IfFailRet (StringCchCatExW (wzBuf, cchBuf, wzBuf[-1 ] == W (' \\ ' ) ? W (" " ) : W (" \\ " ), &wzBuf, &cchBuf, STRSAFE_NULL_ON_FAILURE));
132
+ const WCHAR directorySeparatorWString[] = {DirectorySeparatorChar, W (' \0 ' )};
133
+ IfFailRet (StringCchCatExW (wzBuf, cchBuf, wzBuf[-1 ] == DirectorySeparatorChar ? W (" " ) : directorySeparatorWString, &wzBuf, &cchBuf, STRSAFE_NULL_ON_FAILURE));
109
134
IfFailRet (StringCchCatExW (wzBuf, cchBuf, wzPathRight, &wzBuf, &cchBuf, STRSAFE_NULL_ON_FAILURE));
110
135
111
136
return S_OK;
0 commit comments