checkpoint
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,2 +1,2 @@
|
|||||||
/bin/
|
bin/
|
||||||
/obj/
|
obj/
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
/shelf/
|
/shelf/
|
||||||
/workspace.xml
|
/workspace.xml
|
||||||
# Rider ignored files
|
# Rider ignored files
|
||||||
/contentModel.xml
|
|
||||||
/.idea.DotNetAplm.iml
|
|
||||||
/projectSettingsUpdater.xml
|
|
||||||
/modules.xml
|
/modules.xml
|
||||||
|
/contentModel.xml
|
||||||
|
/projectSettingsUpdater.xml
|
||||||
|
/.idea.DotNetAlpm.iml
|
||||||
# Datasource local storage ignored files
|
# Datasource local storage ignored files
|
||||||
/dataSources/
|
/dataSources/
|
||||||
/dataSources.local.xml
|
/dataSources.local.xml
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="RIDER_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
13
.idea/.idea.nalpm.dir/.idea/.gitignore
generated
vendored
13
.idea/.idea.nalpm.dir/.idea/.gitignore
generated
vendored
@@ -1,13 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# Rider ignored files
|
|
||||||
/modules.xml
|
|
||||||
/contentModel.xml
|
|
||||||
/projectSettingsUpdater.xml
|
|
||||||
/.idea.nalpm.iml
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
||||||
# Editor-based HTTP Client requests
|
|
||||||
/httpRequests/
|
|
||||||
8
.idea/.idea.nalpm.dir/.idea/.idea.nalpm.dir.iml
generated
8
.idea/.idea.nalpm.dir/.idea/.idea.nalpm.dir.iml
generated
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="RIDER_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
4
.idea/.idea.nalpm.dir/.idea/encodings.xml
generated
4
.idea/.idea.nalpm.dir/.idea/encodings.xml
generated
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
|
||||||
</project>
|
|
||||||
8
.idea/.idea.nalpm.dir/.idea/indexLayout.xml
generated
8
.idea/.idea.nalpm.dir/.idea/indexLayout.xml
generated
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ContentModelUserStore">
|
|
||||||
<attachedFolders />
|
|
||||||
<explicitIncludes />
|
|
||||||
<explicitExcludes />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
.idea/.idea.nalpm.dir/.idea/misc.xml
generated
6
.idea/.idea.nalpm.dir/.idea/misc.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="JavaScriptSettings">
|
|
||||||
<option name="languageLevel" value="ES6" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
.idea/.idea.nalpm.dir/.idea/vcs.xml
generated
6
.idea/.idea.nalpm.dir/.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
7
.idea/.idea.nalpm.dir/riderModule.iml
generated
7
.idea/.idea.nalpm.dir/riderModule.iml
generated
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="RIDER_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$/../.." />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
18
API.cs
18
API.cs
@@ -1,18 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Foodsoft.Alpm
|
|
||||||
{
|
|
||||||
public static class API
|
|
||||||
{
|
|
||||||
public static readonly string Version = alpm.alpm_version();
|
|
||||||
|
|
||||||
internal static void WrapError(SafeAlpmHandle h, Func<int> f)
|
|
||||||
{
|
|
||||||
var err = f();
|
|
||||||
if (err != 0)
|
|
||||||
{
|
|
||||||
throw new Exception(alpm.alpm_errno(h));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
33
Alpm/API.cs
Normal file
33
Alpm/API.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Foodsoft.Alpm
|
||||||
|
{
|
||||||
|
public static class API
|
||||||
|
{
|
||||||
|
public static readonly string Version = alpm.alpm_version();
|
||||||
|
|
||||||
|
internal static void WrapError(SafeAlpmHandle h, Func<int> f)
|
||||||
|
{
|
||||||
|
var err = f();
|
||||||
|
if (err != 0)
|
||||||
|
{
|
||||||
|
throw new Exception(alpm.alpm_errno(h));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles the pattern where <0 is exceptional, but 1 is some "false"
|
||||||
|
* condition.
|
||||||
|
*/
|
||||||
|
internal static bool WrapErrorBool(SafeAlpmHandle h, Func<int> f)
|
||||||
|
{
|
||||||
|
var err = f();
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
throw new Exception(alpm.alpm_errno(h));
|
||||||
|
}
|
||||||
|
return err == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Module</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
@@ -3,6 +3,8 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
// FIXME: This is increasing the ref-count on AlpmHandle all the time, so this is NOT correct for database handles,
|
||||||
|
// or other handles that have a dispose that is not a no-op.
|
||||||
namespace Foodsoft.Alpm
|
namespace Foodsoft.Alpm
|
||||||
{
|
{
|
||||||
internal class CollectionWrapper<TImpl, TElement> : ICollection<TElement> where TImpl : struct,
|
internal class CollectionWrapper<TImpl, TElement> : ICollection<TElement> where TImpl : struct,
|
||||||
@@ -10,27 +10,38 @@ namespace Foodsoft.Alpm
|
|||||||
|
|
||||||
internal Database(SafeDatabaseHandle handle) => _handle = handle;
|
internal Database(SafeDatabaseHandle handle) => _handle = handle;
|
||||||
|
|
||||||
private readonly struct ServersAccessor : IItemsAccessor<string>
|
public void Unregister()
|
||||||
{
|
{
|
||||||
private readonly SafeDatabaseHandle _handle;
|
try
|
||||||
|
{
|
||||||
|
API.WrapError(_handle.SafeAlpmHandle, () => alpm.alpm_db_unregister(_handle));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_handle.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private readonly struct ServersAccessor : IItemsReader<string, SafeDatabaseHandle>
|
||||||
|
{
|
||||||
internal ServersAccessor(SafeDatabaseHandle handle)
|
internal ServersAccessor(SafeDatabaseHandle handle)
|
||||||
{
|
{
|
||||||
_handle = handle;
|
Handle = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SafeAlpmHandle SafeAlpmHandle => _handle.SafeAlpmHandle;
|
public SafeDatabaseHandle Handle { get; }
|
||||||
public IntPtr GetItems() => alpm.alpm_db_get_servers(_handle);
|
public IntPtr GetItems() => alpm.alpm_db_get_servers(Handle);
|
||||||
public int SetItems(IntPtr list) => alpm.alpm_db_set_servers(_handle, list);
|
|
||||||
public int AddItem(string item) => alpm.alpm_db_add_server(_handle, item);
|
|
||||||
public int RemoveItem(string item) => alpm.alpm_db_remove_server(_handle, item);
|
|
||||||
public IntPtr FindItem(string item) => alpm.alpm_list_find_str(GetItems(), item);
|
|
||||||
public string PtrToItem(IntPtr p) => Marshal.PtrToStringUTF8(p)!;
|
public string PtrToItem(IntPtr p) => Marshal.PtrToStringUTF8(p)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICollection<string> Servers
|
public void AddServer(string url) => API.WrapError(_handle.SafeAlpmHandle, () => alpm.alpm_db_add_server(_handle, url));
|
||||||
|
|
||||||
|
public bool RemoveServer(string url) => API.WrapErrorBool(_handle.SafeAlpmHandle, () => alpm.alpm_db_remove_server(_handle, url));
|
||||||
|
|
||||||
|
public IEnumerable<string> Servers
|
||||||
{
|
{
|
||||||
get => new CollectionWrapper<ServersAccessor, string>(new ServersAccessor(_handle));
|
get => new EnumerableWrapper<ServersAccessor, string, SafeDatabaseHandle>(new ServersAccessor(_handle));
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
foreach (var s in value)
|
foreach (var s in value)
|
||||||
@@ -40,7 +51,6 @@ namespace Foodsoft.Alpm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public string Name => alpm.alpm_db_get_name(_handle);
|
public string Name => alpm.alpm_db_get_name(_handle);
|
||||||
|
|
||||||
public SigLevel SigLevel => alpm.alpm_db_get_siglevel(_handle);
|
public SigLevel SigLevel => alpm.alpm_db_get_siglevel(_handle);
|
||||||
@@ -48,7 +58,7 @@ namespace Foodsoft.Alpm
|
|||||||
public ErrNo Valid =>
|
public ErrNo Valid =>
|
||||||
alpm.alpm_db_get_valid(_handle) != 0 ? alpm.alpm_errno(_handle.SafeAlpmHandle) : ErrNo.ERR_OK;
|
alpm.alpm_db_get_valid(_handle) != 0 ? alpm.alpm_errno(_handle.SafeAlpmHandle) : ErrNo.ERR_OK;
|
||||||
|
|
||||||
public bool Update(bool force)
|
public bool Update(bool force = false)
|
||||||
{
|
{
|
||||||
var err = alpm.alpm_db_update(force ? 1 : 0, _handle);
|
var err = alpm.alpm_db_update(force ? 1 : 0, _handle);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@@ -69,21 +79,18 @@ namespace Foodsoft.Alpm
|
|||||||
return null;
|
return null;
|
||||||
throw new Exception(err);
|
throw new Exception(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CachePackage(new SafeCachePackageHandle(pkgPtr, _handle), this);
|
return new CachePackage(new SafeCachePackageHandle(pkgPtr, _handle), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly struct PkgCacheAccessor : IReadOnlyItemsAccessor<Package>
|
|
||||||
{
|
|
||||||
private readonly SafeDatabaseHandle _handle;
|
|
||||||
public SafeAlpmHandle SafeAlpmHandle => _handle.SafeAlpmHandle;
|
|
||||||
public IntPtr GetItems()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Package PtrToItem(IntPtr p)
|
public PackageList PackageCache
|
||||||
|
{
|
||||||
|
get
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var listPtr = alpm.alpm_db_get_pkgcache(_handle);
|
||||||
|
if (listPtr == IntPtr.Zero)
|
||||||
|
throw new Exception(alpm.alpm_errno(_handle.SafeAlpmHandle));
|
||||||
|
return new PackageList(new SafeListHandle<SafeDatabaseHandle>(listPtr, _handle), this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
44
Alpm/EnumerableWrapper`3.cs
Normal file
44
Alpm/EnumerableWrapper`3.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Foodsoft.Alpm
|
||||||
|
{
|
||||||
|
internal struct EnumerableWrapper<TImpl, TElement, THandle> : IEnumerable<TElement> where TImpl : struct,
|
||||||
|
IItemsReader<TElement, THandle>
|
||||||
|
where THandle : SafeHandle
|
||||||
|
{
|
||||||
|
private TImpl _impl;
|
||||||
|
|
||||||
|
public EnumerableWrapper(TImpl impl)
|
||||||
|
{
|
||||||
|
_impl = impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<TElement> GetEnumerator()
|
||||||
|
{
|
||||||
|
var handle = _impl.Handle;
|
||||||
|
var release = false;
|
||||||
|
|
||||||
|
RuntimeHelpers.PrepareConstrainedRegions();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
handle.DangerousAddRef(ref release);
|
||||||
|
if (!release) throw new ObjectDisposedException(_impl.GetType().FullName);
|
||||||
|
for (var list = _impl.GetItems(); list != IntPtr.Zero; list = Wrapper.ListNext(list))
|
||||||
|
{
|
||||||
|
yield return _impl.PtrToItem(Wrapper.ListData(list));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (release)
|
||||||
|
handle.DangerousRelease();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Alpm/IItemsReader`2.cs
Normal file
12
Alpm/IItemsReader`2.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Foodsoft.Alpm
|
||||||
|
{
|
||||||
|
internal interface IItemsReader<out TElement, out THandle> where THandle : SafeHandle
|
||||||
|
{
|
||||||
|
public THandle Handle { get; }
|
||||||
|
public IntPtr GetItems();
|
||||||
|
public TElement PtrToItem(IntPtr p);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ namespace Foodsoft.Alpm
|
|||||||
Signature = (1 << 3)
|
Signature = (1 << 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IPackageData
|
public interface IPackageData : IDisposable
|
||||||
{
|
{
|
||||||
public string Filename { get; }
|
public string Filename { get; }
|
||||||
public string Base { get; }
|
public string Base { get; }
|
||||||
@@ -44,7 +44,7 @@ namespace Foodsoft.Alpm
|
|||||||
public long Size { get; }
|
public long Size { get; }
|
||||||
public long InstalledSize { get; }
|
public long InstalledSize { get; }
|
||||||
public InstallReason InstallReason { get; }
|
public InstallReason InstallReason { get; }
|
||||||
public IReadOnlyCollection<string> Licenses { get; }
|
public IEnumerable<string> Licenses { get; }
|
||||||
public IReadOnlyCollection<string> Groups { get; }
|
public IReadOnlyCollection<string> Groups { get; }
|
||||||
public IReadOnlyCollection<Depend> Depends { get; }
|
public IReadOnlyCollection<Depend> Depends { get; }
|
||||||
public IReadOnlyCollection<Depend> OptDepends { get; }
|
public IReadOnlyCollection<Depend> OptDepends { get; }
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Foodsoft.Alpm
|
namespace Foodsoft.Alpm
|
||||||
{
|
{
|
||||||
public class Package : IPackageData
|
public abstract class Package : IPackageData
|
||||||
{
|
{
|
||||||
internal SafePackageHandle Handle { get; }
|
internal SafePackageHandle Handle { get; }
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ namespace Foodsoft.Alpm
|
|||||||
public long InstalledSize => alpm.alpm_pkg_get_isize(Handle);
|
public long InstalledSize => alpm.alpm_pkg_get_isize(Handle);
|
||||||
public InstallReason InstallReason => alpm.alpm_pkg_get_reason(Handle);
|
public InstallReason InstallReason => alpm.alpm_pkg_get_reason(Handle);
|
||||||
|
|
||||||
public IReadOnlyCollection<string> Licenses { get; }
|
public IEnumerable<string> Licenses { get; }
|
||||||
public IReadOnlyCollection<string> Groups { get; }
|
public IReadOnlyCollection<string> Groups { get; }
|
||||||
public IReadOnlyCollection<Depend> Depends { get; }
|
public IReadOnlyCollection<Depend> Depends { get; }
|
||||||
public IReadOnlyCollection<Depend> OptDepends { get; }
|
public IReadOnlyCollection<Depend> OptDepends { get; }
|
||||||
@@ -61,8 +62,12 @@ namespace Foodsoft.Alpm
|
|||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Handle.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
51
Alpm/PackageList.cs
Normal file
51
Alpm/PackageList.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Foodsoft.Alpm
|
||||||
|
{
|
||||||
|
public struct PackageList : IEnumerable<Package>, IDisposable
|
||||||
|
{
|
||||||
|
private SafeListHandle<SafeDatabaseHandle> _handle;
|
||||||
|
private Database _db;
|
||||||
|
|
||||||
|
internal PackageList(SafeListHandle<SafeDatabaseHandle> handle, Database db)
|
||||||
|
{
|
||||||
|
_handle = handle;
|
||||||
|
_db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<Package> GetEnumerator()
|
||||||
|
{
|
||||||
|
var release = false;
|
||||||
|
|
||||||
|
RuntimeHelpers.PrepareConstrainedRegions();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_handle.DangerousAddRef(ref release);
|
||||||
|
if (!release) throw new ObjectDisposedException(_handle.GetType().FullName);
|
||||||
|
for (var list = _handle.DangerousGetHandle(); list != IntPtr.Zero; list = Wrapper.ListNext(list))
|
||||||
|
{
|
||||||
|
yield return new CachePackage(
|
||||||
|
new SafeCachePackageHandle(Wrapper.ListData(list), _handle.ParentHandle), _db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (release)
|
||||||
|
_handle.DangerousRelease();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_handle.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,21 +6,16 @@ namespace Foodsoft.Alpm
|
|||||||
{
|
{
|
||||||
internal sealed class SafeCachePackageHandle : SafePackageHandle
|
internal sealed class SafeCachePackageHandle : SafePackageHandle
|
||||||
{
|
{
|
||||||
internal SafeDatabaseHandle SafeDatabaseHandle
|
|
||||||
{
|
|
||||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
|
||||||
[PrePrepareMethod]
|
|
||||||
get;
|
|
||||||
} = null!;
|
|
||||||
|
|
||||||
internal SafeAlpmHandle SafeAlpmHandle => SafeDatabaseHandle.SafeAlpmHandle;
|
internal SafeAlpmHandle SafeAlpmHandle => SafeDatabaseHandle.SafeAlpmHandle;
|
||||||
|
internal SafeDatabaseHandle SafeDatabaseHandle { get; } = null!;
|
||||||
|
|
||||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||||
[PrePrepareMethod]
|
[PrePrepareMethod]
|
||||||
internal SafeCachePackageHandle(IntPtr pkgPtr, SafeDatabaseHandle dbHandle)
|
internal SafeCachePackageHandle(IntPtr ptr, SafeDatabaseHandle dbHandle)
|
||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
var success = false;
|
var success = false;
|
||||||
|
|
||||||
RuntimeHelpers.PrepareConstrainedRegions();
|
RuntimeHelpers.PrepareConstrainedRegions();
|
||||||
try { }
|
try { }
|
||||||
finally
|
finally
|
||||||
@@ -28,15 +23,14 @@ namespace Foodsoft.Alpm
|
|||||||
dbHandle.DangerousAddRef(ref success);
|
dbHandle.DangerousAddRef(ref success);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
handle = pkgPtr;
|
|
||||||
SafeDatabaseHandle = dbHandle;
|
SafeDatabaseHandle = dbHandle;
|
||||||
|
handle = ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success) throw new ObjectDisposedException(GetType().FullName);
|
if (!success) throw new ObjectDisposedException(GetType().FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), PrePrepareMethod]
|
|
||||||
protected override bool ReleaseHandle()
|
protected override bool ReleaseHandle()
|
||||||
{
|
{
|
||||||
SafeDatabaseHandle.DangerousRelease();
|
SafeDatabaseHandle.DangerousRelease();
|
||||||
@@ -39,9 +39,8 @@ namespace Foodsoft.Alpm
|
|||||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), PrePrepareMethod]
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), PrePrepareMethod]
|
||||||
protected override bool ReleaseHandle()
|
protected override bool ReleaseHandle()
|
||||||
{
|
{
|
||||||
var ret = alpm.alpm_db_unregister(handle) == 0;
|
|
||||||
SafeAlpmHandle.DangerousRelease();
|
SafeAlpmHandle.DangerousRelease();
|
||||||
return ret;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsInvalid
|
public override bool IsInvalid
|
||||||
@@ -5,18 +5,18 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Foodsoft.Alpm
|
namespace Foodsoft.Alpm
|
||||||
{
|
{
|
||||||
internal sealed class SafeListHandle : SafeHandle
|
internal sealed class SafeListHandle<TParent> : SafeHandle where TParent: SafeHandle
|
||||||
{
|
{
|
||||||
public SafeAlpmHandle SafeAlpmHandle
|
internal TParent ParentHandle
|
||||||
{
|
{
|
||||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||||
[PrePrepareMethod]
|
[PrePrepareMethod]
|
||||||
get;
|
get;
|
||||||
} = null!;
|
} = null!;
|
||||||
|
|
||||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||||
[PrePrepareMethod]
|
[PrePrepareMethod]
|
||||||
internal SafeListHandle(SafeAlpmHandle safeAlpmHandle)
|
internal SafeListHandle(IntPtr listPtr, TParent parentHandle)
|
||||||
: base(IntPtr.Zero, true)
|
: base(IntPtr.Zero, true)
|
||||||
{
|
{
|
||||||
var success = false;
|
var success = false;
|
||||||
@@ -24,11 +24,14 @@ namespace Foodsoft.Alpm
|
|||||||
try { }
|
try { }
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
safeAlpmHandle.DangerousAddRef(ref success);
|
parentHandle.DangerousAddRef(ref success);
|
||||||
if (success)
|
if (success)
|
||||||
SafeAlpmHandle = safeAlpmHandle;
|
{
|
||||||
}
|
ParentHandle = parentHandle;
|
||||||
|
handle = listPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
if (!success)
|
if (!success)
|
||||||
throw new ObjectDisposedException(GetType().FullName);
|
throw new ObjectDisposedException(GetType().FullName);
|
||||||
}
|
}
|
||||||
@@ -36,14 +39,14 @@ namespace Foodsoft.Alpm
|
|||||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), PrePrepareMethod]
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), PrePrepareMethod]
|
||||||
protected override bool ReleaseHandle()
|
protected override bool ReleaseHandle()
|
||||||
{
|
{
|
||||||
SafeAlpmHandle.DangerousRelease();
|
ParentHandle.DangerousRelease();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsInvalid
|
public override bool IsInvalid
|
||||||
{
|
{
|
||||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), PrePrepareMethod]
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), PrePrepareMethod]
|
||||||
get => SafeAlpmHandle.IsInvalid;
|
get => ParentHandle.IsInvalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,6 @@ namespace Foodsoft.Alpm
|
|||||||
{
|
{
|
||||||
private static readonly UTF8InMarshaler _instance = default;
|
private static readonly UTF8InMarshaler _instance = default;
|
||||||
|
|
||||||
|
|
||||||
public void CleanUpManagedData(object managedObj) { }
|
public void CleanUpManagedData(object managedObj) { }
|
||||||
|
|
||||||
public void CleanUpNativeData(IntPtr pNativeData)
|
public void CleanUpNativeData(IntPtr pNativeData)
|
||||||
10
Alpm/Wrapper.cs
Normal file
10
Alpm/Wrapper.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Foodsoft.Alpm
|
||||||
|
{
|
||||||
|
internal static class Wrapper
|
||||||
|
{
|
||||||
|
internal static unsafe IntPtr ListNext(IntPtr list) => ((alpm_list_t*) list)->next;
|
||||||
|
internal static unsafe IntPtr ListData(IntPtr list) => ((alpm_list_t*) list)->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -187,7 +187,7 @@ namespace Foodsoft.Alpm
|
|||||||
string url);
|
string url);
|
||||||
|
|
||||||
[DllImport(nameof(alpm))]
|
[DllImport(nameof(alpm))]
|
||||||
public static extern int alpm_db_unregister(IntPtr db);
|
public static extern int alpm_db_unregister(SafeDatabaseHandle db);
|
||||||
|
|
||||||
[DllImport(nameof(alpm))]
|
[DllImport(nameof(alpm))]
|
||||||
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8OutMarshaler))]
|
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8OutMarshaler))]
|
||||||
@@ -219,7 +219,7 @@ namespace Foodsoft.Alpm
|
|||||||
string name);
|
string name);
|
||||||
|
|
||||||
[DllImport(nameof(alpm))]
|
[DllImport(nameof(alpm))]
|
||||||
public static extern IntPtr alpm_pkg_get_pkgcache(SafeDatabaseHandle db);
|
public static extern IntPtr alpm_db_get_pkgcache(SafeDatabaseHandle db);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
21
AlpmOld.cs
21
AlpmOld.cs
@@ -1,21 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.ConstrainedExecution;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// ReSharper disable MemberCanBePrivate.Global
|
|
||||||
// ReSharper disable UnassignedReadonlyField
|
|
||||||
// ReSharper disable UnusedMember.Global
|
|
||||||
|
|
||||||
// ReSharper disable InconsistentNaming
|
|
||||||
|
|
||||||
namespace Foodsoft.Alpm
|
|
||||||
{
|
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
|
||||||
public struct alpm_pkg_p
|
|
||||||
{
|
|
||||||
private IntPtr ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
22
DotNetAlpm.sln
Normal file
22
DotNetAlpm.sln
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Alpm", "Alpm\Alpm.csproj", "{6AEC7D1A-DA7C-44CB-A339-7CBE5FCB88B1}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "Samples\Samples.csproj", "{1215BE9E-B4F4-4F42-B4A2-E890C5EAA903}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{6AEC7D1A-DA7C-44CB-A339-7CBE5FCB88B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6AEC7D1A-DA7C-44CB-A339-7CBE5FCB88B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6AEC7D1A-DA7C-44CB-A339-7CBE5FCB88B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6AEC7D1A-DA7C-44CB-A339-7CBE5FCB88B1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1215BE9E-B4F4-4F42-B4A2-E890C5EAA903}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1215BE9E-B4F4-4F42-B4A2-E890C5EAA903}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1215BE9E-B4F4-4F42-B4A2-E890C5EAA903}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1215BE9E-B4F4-4F42-B4A2-E890C5EAA903}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
2
DotNetAlpm.sln.DotSettings
Normal file
2
DotNetAlpm.sln.DotSettings
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=alpm/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=alpm/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cachedir/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cachedirs/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Foodsoft/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=libalpm/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Marshaler/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=siglevel/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=strerror/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=syncdb/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=syncdbs/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=treename/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Foodsoft.Alpm
|
|
||||||
{
|
|
||||||
internal interface IReadOnlyItemsAccessor<out TElement>
|
|
||||||
{
|
|
||||||
SafeAlpmHandle SafeAlpmHandle { get; }
|
|
||||||
public IntPtr GetItems();
|
|
||||||
public TElement PtrToItem(IntPtr p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
27
Program.cs
27
Program.cs
@@ -1,27 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Foodsoft.Alpm;
|
|
||||||
|
|
||||||
namespace Foodsoft.Alpm
|
|
||||||
{
|
|
||||||
class Program
|
|
||||||
{
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
ErrNo err = ErrNo.ERR_OK;
|
|
||||||
|
|
||||||
using var h = new Handle("/", "/home/luebsj/db");
|
|
||||||
using var db = h.RegisterSyncDB("jkl-repo", SigLevel.SIG_PACKAGE_OPTIONAL | SigLevel.SIG_USE_DEFAULT);
|
|
||||||
|
|
||||||
db.Servers = new List<string> {"http://a.b.c", "http://d.e.f", "http://arch.johnluebs.com/x86_64"};
|
|
||||||
foreach (var a in db.Servers)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Hello {0}", a);
|
|
||||||
}
|
|
||||||
var b = new string[3];
|
|
||||||
db.Servers.CopyTo(b, 0);
|
|
||||||
Console.WriteLine("Hello World! {0} {1} {2}", db.Name, API.Version,
|
|
||||||
b[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace Foodsoft.Alpm
|
|
||||||
{
|
|
||||||
internal class ReadOnlyCollectionWrapper<TImpl, TElement> : IReadOnlyCollection<TElement> where TImpl : struct,
|
|
||||||
IReadOnlyItemsAccessor<TElement>
|
|
||||||
{
|
|
||||||
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<TElement> 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
39
Samples/Program.cs
Normal file
39
Samples/Program.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using Foodsoft.Alpm;
|
||||||
|
|
||||||
|
namespace Samples
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Other()
|
||||||
|
{
|
||||||
|
using var h = new Handle("/", "/home/luebsj/db");
|
||||||
|
using var db = h.RegisterSyncDB("jkl-repo", SigLevel.SIG_PACKAGE_OPTIONAL | SigLevel.SIG_USE_DEFAULT);
|
||||||
|
|
||||||
|
db.AddServer("http://arch.johnluebs.com/x86_64");
|
||||||
|
db.Update(false);
|
||||||
|
foreach (var a in db.Servers)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hello {0}", a);
|
||||||
|
}
|
||||||
|
|
||||||
|
var servers = db.Servers;
|
||||||
|
var b = new string[3];
|
||||||
|
var l = db.Servers.ToImmutableList();
|
||||||
|
|
||||||
|
using var cache = db.PackageCache;
|
||||||
|
foreach ( var p in cache) using(p)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hello: {0} {1} {2}", p.Name, p.Filename, p.BuildDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Hello World! {0} {1} {2}", db.Name, API.Version,
|
||||||
|
l[0]);
|
||||||
|
}
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Other();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Samples/Samples.csproj
Normal file
12
Samples/Samples.csproj
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Alpm\Alpm.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Foodsoft.Alpm
|
|
||||||
{
|
|
||||||
public class Wrapper
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user