97 lines
2.8 KiB
C#
97 lines
2.8 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;
|
|
}
|
|
}
|
|
} |