using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace Foodsoft.Alpm { public sealed class Handle : IDisposable { private readonly SafeAlpmHandle _handle; public Handle(string root, string dbpath) { _handle = alpm.alpm_initialize(root, dbpath, out var err); if (_handle.IsInvalid) { throw new Exception(err); } } public void Dispose() { _handle.Dispose(); } private Database ToDatabase(IntPtr ptr) { // It's ok that the database pointer is kept outside atomic section, because the resource is actually // managed by the alpm handle. if (ptr == IntPtr.Zero) { throw new Exception(_handle); } return new Database(new SafeDatabaseHandle(ptr, _handle)); } public Database LocalDB => ToDatabase(alpm.alpm_get_localdb(_handle)); public Database RegisterSyncDB(string treename, SigLevel sigLevel) => ToDatabase(alpm.alpm_register_syncdb(_handle, treename, sigLevel)); private readonly struct CacheDirsAccessor : IItemsAccessor { internal CacheDirsAccessor(SafeAlpmHandle safeAlpmHandle) { SafeAlpmHandle = safeAlpmHandle; } public SafeAlpmHandle SafeAlpmHandle { get; } public IntPtr GetItems() => alpm.alpm_option_get_cachedirs(SafeAlpmHandle); public int SetItems(IntPtr list) => alpm.alpm_option_set_cachedirs(SafeAlpmHandle, list); public int AddItem(string item) => alpm.alpm_option_add_cachedir(SafeAlpmHandle, item); public int RemoveItem(string item) => alpm.alpm_option_remove_cachedir(SafeAlpmHandle, item); public IntPtr FindItem(string item) => alpm.alpm_list_find_str(GetItems(), item); public string PtrToItem(IntPtr p) => Marshal.PtrToStringUTF8(p)!; } public ICollection CacheDirs { get => new CollectionWrapper(new CacheDirsAccessor(_handle)); set { foreach (var s in value) { API.WrapError(_handle, () => alpm.alpm_option_add_cachedir(_handle, s)); } } } public bool ShouldIgnorePackage(Package pkg) { return alpm.alpm_pkg_should_ignore(_handle, pkg.Handle) == 0; } } }