102 lines
3.2 KiB
C#
102 lines
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Foodsoft.Alpm.Interop;
|
|
|
|
namespace Foodsoft.Alpm
|
|
{
|
|
public sealed class Handle : IDisposable
|
|
{
|
|
private readonly object _eventLock = new object();
|
|
private readonly SafeAlpmHandle _handle;
|
|
|
|
private EventHandler<LogEventArgs>? _logEvent;
|
|
|
|
public Handle(string root, string dbPath)
|
|
{
|
|
_handle = alpm.alpm_initialize(root, dbPath, out var err);
|
|
if (_handle.IsInvalid) throw new AlpmException(err);
|
|
}
|
|
|
|
public Database LocalDB => ToDatabase(alpm.alpm_get_localdb(_handle));
|
|
|
|
public ICollection<string> CacheDirs
|
|
{
|
|
get =>
|
|
EnumerableWrapper.Create(_handle, alpm.alpm_option_get_cachedirs);
|
|
set => Detail.SetStringCollection(value, _handle, s => alpm.alpm_option_add_cachedir(_handle, s));
|
|
}
|
|
|
|
public LogLevel LogLevel { get; set; } = LogLevel.Error;
|
|
|
|
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 RegisterSyncDB(string treename, SigLevel sigLevel = 0)
|
|
{
|
|
return ToDatabase(alpm.alpm_register_syncdb(_handle, treename, sigLevel));
|
|
}
|
|
|
|
public void AddCacheDir(string dir)
|
|
{
|
|
Detail.WrapError(_handle, () => alpm.alpm_option_add_cachedir(_handle, dir));
|
|
}
|
|
|
|
public bool RemoveCacheDir(string dir)
|
|
{
|
|
return Detail.WrapErrorBool(_handle, () => alpm.alpm_option_remove_cachedir(_handle, dir));
|
|
}
|
|
|
|
public bool ShouldIgnorePackage(Package pkg)
|
|
{
|
|
return alpm.alpm_pkg_should_ignore(_handle, pkg.Handle) == 0;
|
|
}
|
|
|
|
public event EventHandler<LogEventArgs> Log
|
|
{
|
|
add
|
|
{
|
|
void LogCallback(LogLevel level, IntPtr format, IntPtr args)
|
|
{
|
|
if (level > LogLevel) return;
|
|
_logEvent?.Invoke(this,
|
|
new LogEventArgs {Level = level, Message = CFormatter.Format(format, args)});
|
|
}
|
|
|
|
lock (_eventLock)
|
|
{
|
|
var wasEmpty = _logEvent == null;
|
|
_logEvent += value;
|
|
if (wasEmpty)
|
|
alpm.alpm_option_set_logcb(_handle, LogCallback);
|
|
}
|
|
}
|
|
remove
|
|
{
|
|
lock (_eventLock)
|
|
{
|
|
// ReSharper disable once DelegateSubtraction
|
|
_logEvent -= value;
|
|
if (_logEvent == null)
|
|
alpm.alpm_option_set_logcb(_handle, null);
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct LogEventArgs
|
|
{
|
|
public LogLevel Level;
|
|
public string Message;
|
|
}
|
|
}
|
|
} |