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 AlpmException(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 AlpmException(_handle); } return new Database(new SafeDatabaseHandle(ptr, _handle)); } public Database LocalDB => ToDatabase(alpm.alpm_get_localdb(_handle)); public Database RegisterSyncDB(string treename, SigLevel sigLevel = 0) => ToDatabase(alpm.alpm_register_syncdb(_handle, treename, sigLevel)); public void AddCacheDir(string dir) => API.WrapError(_handle, () => alpm.alpm_option_add_cachedir(_handle, dir)); public bool RemoveCacheDir(string dir) => API.WrapErrorBool(_handle, () => alpm.alpm_option_add_cachedir(_handle, dir)); private readonly struct CacheDirsImpl : ICollectionImpl { private readonly SafeAlpmHandle _handle; internal CacheDirsImpl(SafeAlpmHandle handle) => _handle = handle; public SafeHandle Handle => _handle; public IntPtr GetItems() => alpm.alpm_option_get_cachedirs(_handle); public string PtrToItem(IntPtr p) => Marshal.PtrToStringUTF8(p)!; } public ICollection CacheDirs { get => EnumerableWrapperEx.Create(_handle, alpm.alpm_option_get_cachedirs, Marshal.PtrToStringUTF8!); set => Wrapper.SetStringCollection(value, _handle, (s) => alpm.alpm_option_add_cachedir(_handle, s)); } public bool ShouldIgnorePackage(Package pkg) => alpm.alpm_pkg_should_ignore(_handle, pkg.Handle) == 0; } }