diff options
Diffstat (limited to 'src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs')
-rw-r--r-- | src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs b/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs new file mode 100644 index 0000000000..fec2218844 --- /dev/null +++ b/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs @@ -0,0 +1,89 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace System.IO +{ + /// <summary>Contains internal path helpers that are shared between many projects.</summary> + internal static partial class PathInternal + { + /// <summary> + /// Returns true if the path uses the extended syntax (\\?\) + /// </summary> + internal static bool IsExtended(StringBuffer path) + { + // While paths like "//?/C:/" will work, they're treated the same as "\\.\" paths. + // Skipping of normalization will *only* occur if back slashes ('\') are used. + return path.Length >= DevicePrefixLength + && path[0] == '\\' + && (path[1] == '\\' || path[1] == '?') + && path[2] == '?' + && path[3] == '\\'; + } + + /// <summary> + /// Gets the length of the root of the path (drive, share, etc.). + /// </summary> + internal unsafe static uint GetRootLength(StringBuffer path) + { + if (path.Length == 0) return 0; + return GetRootLength(path.CharPointer, path.Length); + } + + /// <summary> + /// Returns true if the path uses any of the DOS device path syntaxes. ("\\.\", "\\?\", or "\??\") + /// </summary> + internal static bool IsDevice(StringBuffer path) + { + // If the path begins with any two separators is will be recognized and normalized and prepped with + // "\??\" for internal usage correctly. "\??\" is recognized and handled, "/??/" is not. + return IsExtended(path) + || + ( + path.Length >= DevicePrefixLength + && IsDirectorySeparator(path[0]) + && IsDirectorySeparator(path[1]) + && (path[2] == '.' || path[2] == '?') + && IsDirectorySeparator(path[3]) + ); + } + + /// <summary> + /// Returns true if the path specified is relative to the current drive or working directory. + /// Returns false if the path is fixed to a specific drive or UNC path. This method does no + /// validation of the path (URIs will be returned as relative as a result). + /// </summary> + /// <remarks> + /// Handles paths that use the alternate directory separator. It is a frequent mistake to + /// assume that rooted paths (Path.IsPathRooted) are not relative. This isn't the case. + /// "C:a" is drive relative- meaning that it will be resolved against the current directory + /// for C: (rooted, but relative). "C:\a" is rooted and not relative (the current directory + /// will not be used to modify the path). + /// </remarks> + internal static bool IsPartiallyQualified(StringBuffer path) + { + if (path.Length < 2) + { + // It isn't fixed, it must be relative. There is no way to specify a fixed + // path with one character (or less). + return true; + } + + if (IsDirectorySeparator(path[0])) + { + // There is no valid way to specify a relative path with two initial slashes or + // \? as ? isn't valid for drive relative paths and \??\ is equivalent to \\?\ + return !(path[1] == '?' || IsDirectorySeparator(path[1])); + } + + // The only way to specify a fixed path that doesn't begin with two slashes + // is the drive, colon, slash format- i.e. C:\ + return !((path.Length >= 3) + && (path[1] == Path.VolumeSeparatorChar) + && IsDirectorySeparator(path[2])); + } + } +} |