| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- // 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.Text;
- using System.Runtime.InteropServices;
- namespace System.IO
- {
- /// <summary>Contains internal path helpers that are shared between many projects.</summary>
- internal static partial class PathInternal
- {
- internal const char DirectorySeparatorChar = '/';
- internal const char AltDirectorySeparatorChar = '/';
- internal const char VolumeSeparatorChar = '/';
- internal const char PathSeparator = ':';
- internal const string DirectorySeparatorCharAsString = "/";
- // There is only one invalid path character in Unix
- private const char InvalidPathChar = '\0';
- internal const string ParentDirectoryPrefix = @"../";
- internal static int GetRootLength(ReadOnlySpan<char> path)
- {
- return path.Length > 0 && IsDirectorySeparator(path[0]) ? 1 : 0;
- }
- internal static bool IsDirectorySeparator(char c)
- {
- // The alternate directory separator char is the same as the directory separator,
- // so we only need to check one.
- Debug.Assert(DirectorySeparatorChar == AltDirectorySeparatorChar);
- return c == DirectorySeparatorChar;
- }
- /// <summary>
- /// Normalize separators in the given path. Compresses forward slash runs.
- /// </summary>
- internal static string NormalizeDirectorySeparators(string path)
- {
- if (string.IsNullOrEmpty(path))
- return path;
- // Make a pass to see if we need to normalize so we can potentially skip allocating
- bool normalized = true;
- for (int i = 0; i < path.Length; i++)
- {
- if (IsDirectorySeparator(path[i])
- && (i + 1 < path.Length && IsDirectorySeparator(path[i + 1])))
- {
- normalized = false;
- break;
- }
- }
- if (normalized)
- return path;
- StringBuilder builder = new StringBuilder(path.Length);
- for (int i = 0; i < path.Length; i++)
- {
- char current = path[i];
- // Skip if we have another separator following
- if (IsDirectorySeparator(current)
- && (i + 1 < path.Length && IsDirectorySeparator(path[i + 1])))
- continue;
- builder.Append(current);
- }
- return builder.ToString();
- }
- internal static bool IsPartiallyQualified(ReadOnlySpan<char> path)
- {
- // This is much simpler than Windows where paths can be rooted, but not fully qualified (such as Drive Relative)
- // As long as the path is rooted in Unix it doesn't use the current directory and therefore is fully qualified.
- return !Path.IsPathRooted(path);
- }
- /// <summary>
- /// Returns true if the path is effectively empty for the current OS.
- /// For unix, this is empty or null. For Windows, this is empty, null, or
- /// just spaces ((char)32).
- /// </summary>
- internal static bool IsEffectivelyEmpty(string path)
- {
- return string.IsNullOrEmpty(path);
- }
- internal static bool IsEffectivelyEmpty(ReadOnlySpan<char> path)
- {
- return path.IsEmpty;
- }
- }
- }
|