Files
DotNetAlpm/ReadOnlyCollectionWrapper`2.cs
2020-04-27 12:34:56 -04:00

47 lines
1.5 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Foodsoft.Alpm
{
internal class ReadOnlyCollectionWrapper<TImpl, TElement> : IReadOnlyCollection<TElement> where TImpl : struct,
IReadOnlyItemsAccessor<TElement>
{
private TImpl _impl;
private SafeAlpmHandle SafeAlpmHandle => _impl.SafeAlpmHandle;
public ReadOnlyCollectionWrapper(TImpl impl)
{
_impl = impl;
}
private static unsafe IntPtr ListNext(IntPtr list) => ((alpm_list_t*) list)->next;
private static unsafe IntPtr ListData(IntPtr list) => ((alpm_list_t*) list)->data;
public IEnumerator<TElement> GetEnumerator()
{
var safeAlpmHandle = _impl.SafeAlpmHandle;
var release = false;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
safeAlpmHandle.DangerousAddRef(ref release);
if (!release) throw new ObjectDisposedException(_impl.GetType().FullName);
for (var list = _impl.GetItems(); list != IntPtr.Zero; list = ListNext(list))
{
yield return _impl.PtrToItem(ListData(list));
}
}
finally
{
if (release)
safeAlpmHandle.DangerousRelease();
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public int Count => (int) alpm.alpm_list_count(_impl.GetItems());
}
}