using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; namespace Foodsoft.Alpm { internal class ReadOnlyCollectionWrapper : IReadOnlyCollection where TImpl : struct, IReadOnlyItemsAccessor { 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 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()); } }