using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; namespace Foodsoft.Alpm { public class CachePackageList : IPackageList, ICollection { private readonly SafeDatabaseHandle _parentHandle; private readonly IntPtr _listPtr; private readonly Database _db; internal CachePackageList(IntPtr listPtr, SafeDatabaseHandle parentHandle, Database db) { _parentHandle = parentHandle; _listPtr = listPtr; _db = db; } public IEnumerator GetEnumerator() { var release = false; RuntimeHelpers.PrepareConstrainedRegions(); try { _parentHandle.DangerousAddRef(ref release); if (!release) throw new ObjectDisposedException(_parentHandle.GetType().FullName); for (var list = _listPtr; list != IntPtr.Zero; list = Wrapper.ListNext(list)) { yield return new CachePackage( new SafeCachePackageHandle(Wrapper.ListData(list), _parentHandle), _db); } } finally { if (release) _parentHandle.DangerousRelease(); } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public bool Contains(CachePackage item) { var name = item.Name; return _parentHandle.UseHandle(_listPtr, (list) => { for (; list != IntPtr.Zero; list = Wrapper.ListNext(list)) { if (name == alpm.alpm_pkg_get_name(list)) return true; } return false; }); } public void CopyTo(CachePackage[] array, int arrayIndex) { _parentHandle.UseHandle(_listPtr, (list) => { for (; list != IntPtr.Zero; list = Wrapper.ListNext(list)) { array[arrayIndex++] = new CachePackage( new SafeCachePackageHandle(Wrapper.ListData(list), _parentHandle), _db); } return 0; }); } public CachePackage? FindSatisfier(string depString) { return _parentHandle.UseHandle(_listPtr, (list) => { var pkgPtr = alpm.alpm_find_satisfier(list, depString); return pkgPtr != IntPtr.Zero ? new CachePackage(new SafeCachePackageHandle(pkgPtr, _parentHandle), _db) : null; }); } public void Add(CachePackage item) { throw new NotSupportedException(); } public bool Remove(CachePackage item) { throw new NotSupportedException(); } public void Clear() { throw new NotSupportedException(); } public int Count => _parentHandle.UseHandle(_listPtr, (list) => (int) alpm.alpm_list_count(list)); public bool IsReadOnly => true; } }