1
0
Fork 0
netddi/System/IO/Paths.cs
2025-01-29 23:53:57 +01:00

113 lines
2.1 KiB
C#

#if !(LINUX || MACOS || WINDOWS)
#define TARGET_ANY
#endif
#if TARGET_ANY || LINUX
#define TARGET_LINUX
#endif
#if TARGET_ANY || MACOS
#define TARGET_MACOS
#endif
#if TARGET_ANY || WINDOWS
#define TARGET_WINDOWS
#endif
using System.Buffers;
using CommunityToolkit.HighPerformance.Buffers;
namespace System.IO;
public static class PathEx
{
public static string ExpandPath(string path)
{
#if TARGET_ANY
if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
{
#endif
#if TARGET_LINUX || TARGET_MACOS
return ExpandPathUnixImpl(path);
#endif
#if TARGET_ANY
}
else if (OperatingSystem.IsWindows())
{
#endif
#if TARGET_WINDOWS
return ExpandPathWindowsImpl(path);
#endif
#if TARGET_ANY
}
else
{
throw new PlatformNotSupportedException();
}
#endif
}
#if TARGET_LINUX || TARGET_MACOS
private static string ExpandPathUnixImpl(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
return path;
}
var reader = new SequenceReader<char>(new(path.AsMemory()));
if (!reader.TryReadTo(out ReadOnlySpan<char> read, '$'))
{
return path;
}
using ArrayPoolBufferWriter<char> result = new();
while (true)
{
result.Write(read);
int skip = 0;
if (reader.UnreadSpan[0] == '{' && reader.UnreadSpan.IndexOf('}') is not -1 and int s)
{
read = reader.UnreadSpan[1..s];
skip = s + 1;
}
else
{
var propertyReader = new SequenceReader<char>(reader.UnreadSequence);
while (!propertyReader.End && propertyReader.UnreadSpan[0] is char c && (c == '_' || char.IsAsciiLetterOrDigit(c)))
{
propertyReader.Advance(1);
}
read = reader.UnreadSpan[..(int)propertyReader.Consumed];
skip = read.Length;
}
if (skip != 0 && Environment.GetEnvironmentVariable(read.ToString()) is { } env)
{
result.Write(env);
reader.Advance(skip);
}
else
{
result.Write(['$']);
}
if (!reader.TryReadTo(out read, '$'))
{
break;
}
}
result.Write(reader.UnreadSpan);
return result.WrittenSpan.ToString();
}
#endif
#if TARGET_WINDOWS
private static string ExpandPathWindowsImpl(string path)
{
return Environment.ExpandEnvironmentVariables(path);
}
#endif
}