|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
internal static partial class Interop
{
internal static partial class Sys
{
internal enum NodeType : int
{
DT_UNKNOWN = 0,
DT_FIFO = 1,
DT_CHR = 2,
DT_DIR = 4,
DT_BLK = 6,
DT_REG = 8,
DT_LNK = 10,
DT_SOCK = 12,
DT_WHT = 14
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct DirectoryEntry
{
internal byte* Name;
internal int NameLength;
internal NodeType InodeType;
internal ReadOnlySpan<char> GetName(Span<char> buffer)
{
Debug.Assert(Name != null, "should not have a null name");
ReadOnlySpan<byte> nameBytes = (NameLength == -1)
? MemoryMarshal.CreateReadOnlySpanFromNullTerminated(Name)
: new ReadOnlySpan<byte>(Name, NameLength);
Debug.Assert(nameBytes.Length > 0, "we shouldn't have gotten a garbage value from the OS");
ReadOnlySpan<char> result = !Encoding.UTF8.TryGetChars(nameBytes, buffer, out int charsWritten)
? Encoding.UTF8.GetString(nameBytes) // Fallback to allocation since this is a rare case
: buffer.Slice(0, charsWritten);
Debug.Assert(!result.Contains('\0'), "should not have embedded nulls");
return result;
}
}
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_OpenDir", StringMarshalling = StringMarshalling.Utf8, SetLastError = true)]
internal static partial IntPtr OpenDir(string path);
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_ReadDir")]
internal static unsafe partial int ReadDir(IntPtr dir, DirectoryEntry* outputEntry);
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_CloseDir", SetLastError = true)]
internal static partial int CloseDir(IntPtr dir);
}
}
|