Files
DotNetAlpm/Alpm/FileList.cs
2020-04-30 20:42:46 -04:00

95 lines
2.7 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Foodsoft.Alpm
{
public struct FileList : IReadOnlyList<File>
{
private readonly SafePackageHandle _handle;
private readonly IntPtr _ptr;
internal FileList(SafePackageHandle handle, IntPtr ptr)
{
_handle = handle;
_ptr = ptr;
}
public File? Contains(string path)
{
return _handle.UseHandle(_ptr, ptr =>
{
var foundPtr = alpm.alpm_filelist_contains(ptr, path);
return foundPtr != IntPtr.Zero ? new File(foundPtr) : (File?) null;
});
}
public IEnumerator<File> GetEnumerator()
{
var release = false;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
_handle.DangerousAddRef(ref release);
if (!release) throw new ObjectDisposedException(_handle.GetType().FullName);
var arrayPtr = FileArray(_ptr, out var count);
for (var i = 0; i < count; ++i) yield return new File(FilePtr(arrayPtr, i));
}
finally
{
if (release)
_handle.DangerousRelease();
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public int Count => _handle.UseHandle(_ptr, FileCount);
public File this[int index]
{
get
{
return _handle.UseHandle(_ptr, ptr =>
{
var arrayPtr = FileArray(ptr, out var count);
if (index >= count || index < 0)
throw new ArgumentOutOfRangeException(nameof(index), index, $"Exceeds size {count}");
return new File(FilePtr(arrayPtr, index));
});
}
}
[StructLayout(LayoutKind.Sequential)]
private readonly unsafe struct NativeFileList
{
internal readonly UIntPtr count;
internal readonly File.NativeFile* files;
}
private static unsafe IntPtr FilePtr(IntPtr array, int i)
{
return (IntPtr) ((File.NativeFile*) array + i);
}
private static unsafe IntPtr FileArray(IntPtr ptr, out int count)
{
var list = (NativeFileList*) ptr;
count = (int) list->count;
return (IntPtr) list->files;
}
private static unsafe int FileCount(IntPtr ptr)
{
var list = (NativeFileList*) ptr;
return (int) list->count;
}
}
}