checkpoint collections

This commit is contained in:
2020-04-27 04:32:44 -04:00
parent e681715c31
commit 6ed92261ec
26 changed files with 322 additions and 424 deletions

13
.idea/.idea.DotNetAplm.dir/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/contentModel.xml
/.idea.DotNetAplm.iml
/projectSettingsUpdater.xml
/modules.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

View File

@@ -0,0 +1,8 @@
<?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>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ContentModelUserStore">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -0,0 +1,7 @@
<?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>

4
API.cs Normal file
View File

@@ -0,0 +1,4 @@
$HEADER$namespace $NAMESPACE$
{
public class $CLASS$ {$END$}
}

View File

@@ -12,427 +12,12 @@ using System.Runtime.Serialization;
// ReSharper disable InconsistentNaming
namespace nalpm
namespace Alpm
{
public enum errno_t
{
ERR_OK = 0,
ERR_MEMORY,
ERR_SYSTEM,
ERR_BADPERMS,
ERR_NOT_A_FILE,
ERR_NOT_A_DIR,
ERR_WRONG_ARGS,
ERR_DISK_SPACE,
/* Interface */
ERR_HANDLE_NULL,
ERR_HANDLE_NOT_NULL,
ERR_HANDLE_LOCK,
/* Databases */
ERR_DB_OPEN,
ERR_DB_CREATE,
ERR_DB_NULL,
ERR_DB_NOT_NULL,
ERR_DB_NOT_FOUND,
ERR_DB_INVALID,
ERR_DB_INVALID_SIG,
ERR_DB_VERSION,
ERR_DB_WRITE,
ERR_DB_REMOVE,
/* Servers */
ERR_SERVER_BAD_URL,
ERR_SERVER_NONE,
/* Transactions */
ERR_TRANS_NOT_NULL,
ERR_TRANS_NULL,
ERR_TRANS_DUP_TARGET,
ERR_TRANS_NOT_INITIALIZED,
ERR_TRANS_NOT_PREPARED,
ERR_TRANS_ABORT,
ERR_TRANS_TYPE,
ERR_TRANS_NOT_LOCKED,
ERR_TRANS_HOOK_FAILED,
/* Packages */
ERR_PKG_NOT_FOUND,
ERR_PKG_IGNORED,
ERR_PKG_INVALID,
ERR_PKG_INVALID_CHECKSUM,
ERR_PKG_INVALID_SIG,
ERR_PKG_MISSING_SIG,
ERR_PKG_OPEN,
ERR_PKG_CANT_REMOVE,
ERR_PKG_INVALID_NAME,
ERR_PKG_INVALID_ARCH,
ERR_PKG_REPO_NOT_FOUND,
/* Signatures */
ERR_SIG_MISSING,
ERR_SIG_INVALID,
/* Dependencies */
ERR_UNSATISFIED_DEPS,
ERR_CONFLICTING_DEPS,
ERR_FILE_CONFLICTS,
/* Misc */
ERR_RETRIEVE,
ERR_INVALID_REGEX,
/* External library errors */
ERR_LIBARCHIVE,
ERR_LIBCURL,
ERR_EXTERNAL_DOWNLOAD,
ERR_GPGME,
/* Missing compile-time features */
ERR_MISSING_CAPABILITY_SIGNATURES
}
/** Package install reasons. */
enum alpm_pkgreason_t
{
/** Explicitly requested by the user. */
PKG_REASON_EXPLICIT = 0,
/** Installed as a dependency for another package. */
PKG_REASON_DEPEND = 1
}
/** Location a package object was loaded from. */
enum alpm_pkgfrom_t
{
PKG_FROM_FILE = 1,
PKG_FROM_LOCALDB,
PKG_FROM_SYNCDB
}
/** Method used to validate a package. */
enum alpm_pkgvalidation_t
{
PKG_VALIDATION_UNKNOWN = 0,
PKG_VALIDATION_NONE = (1 << 0),
PKG_VALIDATION_MD5SUM = (1 << 1),
PKG_VALIDATION_SHA256SUM = (1 << 2),
PKG_VALIDATION_SIGNATURE = (1 << 3)
}
/** Types of version constraints in dependency specs. */
public enum alpm_depmod_t
{
/** No version constraint */
DEP_MOD_ANY = 1,
/** Test version equality (package=x.y.z) */
DEP_MOD_EQ,
/** Test for at least a version (package>=x.y.z) */
DEP_MOD_GE,
/** Test for at most a version (package<=x.y.z) */
DEP_MOD_LE,
/** Test for greater than some version (package>x.y.z) */
DEP_MOD_GT,
/** Test for less than some version (package<x.y.z) */
DEP_MOD_LT
}
/**
* File conflict type.
* Whether the conflict results from a file existing on the filesystem, or with
* another target in the transaction.
*/
enum alpm_fileconflicttype_t
{
FILECONFLICT_TARGET = 1,
FILECONFLICT_FILESYSTEM
}
/** PGP signature verification options */
[Flags]
public enum SigLevel
{
SIG_PACKAGE = (1 << 0),
SIG_PACKAGE_OPTIONAL = (1 << 1),
SIG_PACKAGE_MARGINAL_OK = (1 << 2),
SIG_PACKAGE_UNKNOWN_OK = (1 << 3),
SIG_DATABASE = (1 << 10),
SIG_DATABASE_OPTIONAL = (1 << 11),
SIG_DATABASE_MARGINAL_OK = (1 << 12),
SIG_DATABASE_UNKNOWN_OK = (1 << 13),
SIG_USE_DEFAULT = (1 << 31)
}
/** PGP signature verification status return codes */
enum alpm_sigstatus_t
{
SIGSTATUS_VALID,
SIGSTATUS_KEY_EXPIRED,
SIGSTATUS_SIG_EXPIRED,
SIGSTATUS_KEY_UNKNOWN,
SIGSTATUS_KEY_DISABLED,
SIGSTATUS_INVALID
}
/** PGP signature verification status return codes */
enum alpm_sigvalidity_t
{
SIGVALIDITY_FULL,
SIGVALIDITY_MARGINAL,
SIGVALIDITY_NEVER,
SIGVALIDITY_UNKNOWN
}
/** Dependency */
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct alpm_depend_t
{
string name;
string version;
string desc;
public ulong name_hash;
public alpm_depmod_t mod;
}
[StructLayout(LayoutKind.Sequential)]
public struct AlpmDependPtr
{
private IntPtr ptr;
public alpm_depend_t Unmarshal()
{
return Marshal.PtrToStructure<alpm_depend_t>(ptr);
}
}
/** Missing dependency */
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct alpm_depmissing_t
{
public string target;
public AlpmDependPtr depend;
/* this is used only in the case of a remove dependency error */
public string causingpkg;
}
[StructLayout(LayoutKind.Sequential)]
/** Conflict */
public struct alpm_conflict_t
{
public ulong package1_hash;
public ulong package2_hash;
public string package1;
public string package2;
public AlpmDependPtr reason;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
/** File conflict */
struct alpm_fileconflict_t
{
public string target;
public alpm_fileconflicttype_t type;
public string file;
public string ctarget;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
/** Package group */
public readonly struct alpm_group_t
{
/** group name */
public readonly string name;
/** list of alpm_pkg_t packages */
public readonly unsafe alpm_list_t* packages;
}
/* TODO: alpm_pkg_get_files - need to wrap */
/** File in a package */
public readonly struct alpm_file_t
{
public readonly string name;
public readonly UIntPtr size;
public readonly uint mode;
}
/** Package filelist container */
public struct _alpm_filelist_t
{
public UIntPtr count;
private IntPtr files;
/* FIXME: This is broken as shit */
public alpm_file_t[] Unmarshal()
{
var iCount = (int) this.count;
var byteCount = Marshal.SizeOf<alpm_file_t>() * iCount;
var byteBuffer = new byte[byteCount];
Marshal.Copy(files, byteBuffer, 0, byteBuffer.Length);
var result = new alpm_file_t[iCount];
Buffer.BlockCopy(byteBuffer, 0, result, 0, byteBuffer.Length);
return result;
}
}
/** Local package or package file backup entry */
public struct _alpm_backup_t
{
string name;
string hash;
}
public class alpm_pgpkey_t
{
public byte[] data;
public string fingerprint;
public string uid;
public string name;
public string email;
public long created;
public long expires;
public uint revoked;
public char pubkey_algo;
}
public class PgpKeyInMarshaler : ICustomMarshaler
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
private class NativePgpKey
{
public IntPtr data;
public string fingerprint;
public string uid;
public string name;
public string email;
public long created;
public long expires;
public uint length;
public uint revoked;
public char pubkey_algo;
}
public void CleanUpManagedData(object ManagedObj) { }
public void CleanUpNativeData(IntPtr pNativeData) { }
public int GetNativeDataSize()
{
throw new NotImplementedException();
}
public IntPtr MarshalManagedToNative(object ManagedObj)
{
throw new NotImplementedException();
}
public object MarshalNativeToManaged(IntPtr pNativeData)
{
var raw = Marshal.PtrToStructure<NativePgpKey>(pNativeData);
var managed = new alpm_pgpkey_t()
{
data = new byte[raw.length],
fingerprint = raw.fingerprint,
uid = raw.uid,
name = raw.name,
email = raw.email,
created = raw.created,
expires = raw.expires,
revoked = raw.revoked,
pubkey_algo = raw.pubkey_algo
};
Marshal.Copy(raw.data, managed.data, 0, (int) raw.length);
return managed;
}
}
/**
* Signature result. Contains the key, status, and validity of a given
* signature.
*/
public readonly struct alpm_sigresult_t
{
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PgpKeyInMarshaler))]
readonly alpm_pgpkey_t key;
readonly alpm_sigstatus_t status;
readonly alpm_sigvalidity_t validity;
}
/**
* Signature list. Contains the number of signatures found and a pointer to an
* array of results. The array is of size count.
*/
public class SigListInMarshaler : ICustomMarshaler
{
public void CleanUpManagedData(object ManagedObj) { }
public void CleanUpNativeData(IntPtr pNativeData) { }
public int GetNativeDataSize()
{
throw new NotImplementedException();
}
public IntPtr MarshalManagedToNative(object ManagedObj)
{
throw new NotImplementedException();
}
public object MarshalNativeToManaged(IntPtr pNativeData)
{
UIntPtr count;
IntPtr data;
unsafe
{
count = *(UIntPtr*) pNativeData;
data = *(IntPtr*) (pNativeData + sizeof(UIntPtr));
}
var iCount = (int) count;
var result = new alpm_sigresult_t[iCount];
// NOTE: I expect this to fail cuz i didn't implement the above GetNativeDataSize
for (var i = 0; i < iCount; ++i, data += Marshal.SizeOf<alpm_sigresult_t>())
{
result[i] = Marshal.PtrToStructure<alpm_sigresult_t>(data);
}
return result;
}
}
/*
* Hooks
*/
enum alpm_hook_when_t
{
HOOK_PRE_TRANSACTION = 1,
HOOK_POST_TRANSACTION
}
/*
* Logging facilities
*/
/** Logging Levels */
enum _alpm_loglevel_t
{
LOG_ERROR = 1,
LOG_WARNING = (1 << 1),
LOG_DEBUG = (1 << 2),
LOG_FUNCTION = (1 << 3)
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct alpm_pkg_p
@@ -479,7 +64,7 @@ namespace nalpm
public Handle(string root, string dbpath)
{
var err = errno_t.ERR_OK;
var err = ErrNo.ERR_OK;
_handle = alpm.alpm_initialize(root, dbpath, ref err);
if (_handle.IsInvalid)
{
@@ -700,8 +285,8 @@ namespace nalpm
{
public Exception() { }
public Exception(SafeAlpmHandle handle) : base(Alpm.StrError(alpm.alpm_errno(handle))) { }
public Exception(errno_t errno) : base(Alpm.StrError(errno)) { }
public Exception(errno_t errno, System.Exception inner) : base(Alpm.StrError(errno), inner) { }
public Exception(ErrNo errno) : base(Alpm.StrError(errno)) { }
public Exception(ErrNo errno, System.Exception inner) : base(Alpm.StrError(errno), inner) { }
protected Exception(SerializationInfo info,
StreamingContext context) : base(info, context) { }
@@ -826,7 +411,7 @@ namespace nalpm
public SigLevel SigLevel => alpm.alpm_db_get_siglevel(_db);
public errno_t Valid => alpm.alpm_db_get_valid(_db) != 0 ? alpm.alpm_errno(_handle) : errno_t.ERR_OK;
public ErrNo Valid => alpm.alpm_db_get_valid(_db) != 0 ? alpm.alpm_errno(_handle) : ErrNo.ERR_OK;
public bool Update(bool force)
{
@@ -867,10 +452,10 @@ namespace nalpm
public static extern int alpm_option_remove_cachedir(SafeAlpmHandle handle, string cachedir);
[DllImport(nameof(alpm))]
public static extern errno_t alpm_errno(SafeAlpmHandle handle);
public static extern ErrNo alpm_errno(SafeAlpmHandle handle);
[DllImport(nameof(alpm))]
public static extern IntPtr alpm_strerror(errno_t err);
public static extern IntPtr alpm_strerror(ErrNo err);
[DllImport(nameof(alpm))]
public static extern IntPtr alpm_get_localdb(SafeAlpmHandle handle);
@@ -906,7 +491,7 @@ namespace nalpm
public static extern caps alpm_capabilities();
[DllImport(nameof(alpm), CharSet = CharSet.Ansi)]
public static extern SafeAlpmHandle alpm_initialize(string root, string dbpath, ref errno_t err);
public static extern SafeAlpmHandle alpm_initialize(string root, string dbpath, ref ErrNo err);
[DllImport(nameof(alpm))]
public static extern int alpm_release(IntPtr handle);
@@ -941,12 +526,13 @@ namespace nalpm
internal static class Alpm
{
public static string Version()
{
return Marshal.PtrToStringUTF8(alpm.alpm_version());
}
public static string StrError(errno_t err)
public static string StrError(ErrNo err)
{
return Marshal.PtrToStringUTF8(alpm.alpm_strerror(err));
}

79
CollectionWrapper`2.cs Normal file
View File

@@ -0,0 +1,79 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Foodsoft.Alpm;
namespace Foodsoft.Alpm
{
internal struct CollectionWrapper<TImpl, TElement> : ICollection<TElement> where TImpl : struct,
IAlpmItemsAccessor<TElement>
{
private TImpl _impl;
public CollectionWrapper(TImpl impl)
{
_impl = impl;
}
IEnumerator<TElement> IEnumerable<TElement>.GetEnumerator()
{
return (IEnumerator<TElement>) GetEnumerator();
}
public IEnumerator GetEnumerator()
{
var result = new List<TElement>();
var intPtr = _impl.GetItems();
unsafe
{
for (var list = (alpm_list_t*) intPtr; list != null; list = alpm.alpm_list_next(list))
{
result.Add(_impl.PtrToItem(list->data));
}
}
return result.GetEnumerator();
}
public void Add(TElement item)
{
_impl.AddItem(item);
}
public void Clear()
{
_impl.SetItems(IntPtr.Zero);
}
public bool Contains(TElement item) =>
_impl.FindItem(item) != IntPtr.Zero;
public void CopyTo(TElement[] array, int arrayIndex)
{
var intPtr = _impl.GetItems();
unsafe
{
for (var list = (alpm_list_t*) intPtr; list != null; list = alpm.alpm_list_next(list))
{
array[arrayIndex++] = _impl.PtrToItem(list->data);
}
}
}
public bool Remove(TElement item)
{
var err = _impl.RemoveItem(item);
if (err < 0)
{
throw new Exception(alpm.alpm_errno(_impl.SafeAlpmHandle));
}
return err == 0;
}
public int Count => (int) alpm.alpm_list_count(_impl.GetItems());
public bool IsReadOnly => false;
}
}

4
Database.cs Normal file
View File

@@ -0,0 +1,4 @@
$HEADER$namespace $NAMESPACE$
{
public class $CLASS$ {$END$}
}

View File

@@ -5,6 +5,7 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
<RootNamespace>nalpm</RootNamespace>
</PropertyGroup>
</Project>

4
ErrNo.cs Normal file
View File

@@ -0,0 +1,4 @@
$HEADER$namespace $NAMESPACE$
{
public enum $ENUM$ {$END$}
}

4
Exception.cs Normal file
View File

@@ -0,0 +1,4 @@
$HEADER$namespace $NAMESPACE$
{
public class $CLASS$ {$END$}
}

4
Handle.cs Normal file
View File

@@ -0,0 +1,4 @@
$HEADER$namespace $NAMESPACE$
{
public class $CLASS$ {$END$}
}

16
IAlpmItemsAccessor`1.cs Normal file
View File

@@ -0,0 +1,16 @@
using System;
namespace Foodsoft.Alpm
{
internal interface IAlpmItemsAccessor<TElement>
{
SafeAlpmHandle SafeAlpmHandle { get; }
public IntPtr GetItems();
public int SetItems(IntPtr list);
public int AddItem(TElement item);
public int RemoveItem(TElement item);
public IntPtr FindItem(TElement item);
public TElement PtrToItem(IntPtr p);
}
}

View File

@@ -0,0 +1,7 @@
namespace Foodsoft.Alpm
{
public class IAlpmReadOnlyItemsAccessor
{
}
}

7
Junk.cs Normal file
View File

@@ -0,0 +1,7 @@
namespace Alpm
{
public class Junk
{
}
}

View File

@@ -0,0 +1,4 @@
$HEADER$namespace $NAMESPACE$
{
public class $CLASS$ {$END$}
}

4
SafeAlpmHandle.cs Normal file
View File

@@ -0,0 +1,4 @@
$HEADER$namespace $NAMESPACE$
{
public class $CLASS$ {$END$}
}

4
SafeDatabaseHandle.cs Normal file
View File

@@ -0,0 +1,4 @@
$HEADER$namespace $NAMESPACE$
{
public class $CLASS$ {$END$}
}

46
SafeListHandle.cs Normal file
View File

@@ -0,0 +1,46 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
namespace Foodsoft.Alpm
{
internal struct ListRef : CriticalFinalIDisposable
{
public SafeAlpmHandle SafeAlpmHandle
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[PrePrepareMethod]
get;
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), PrePrepareMethod]
public ListRef(SafeAlpmHandle handle)
{
SafeAlpmHandle = null!;
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
SafeAlpmHandle = handle;
var success = false;
handle.DangerousAddRef(ref success);
if (success)
SafeAlpmHandle = handle;
else
{
SafeAlpmHandle = null!;
throw new ObjectDisposedException(GetType().FullName);
}
}
}
~ListRef()
{
}
public void Dispose()
{
}
}
}

54
UTF8InMarshaler.cs Normal file
View File

@@ -0,0 +1,54 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Foodsoft.Alpm
{
internal readonly struct UTF8Marshaler : ICustomMarshaler
{
private static readonly UTF8Marshaler _instance = default;
// ReSharper disable once UnusedMember.Local
// ReSharper disable once UnusedParameter.Local
private static ICustomMarshaler GetInstance(string cookie)
{
return _instance;
}
public void CleanUpManagedData(object managedObj) { }
public void CleanUpNativeData(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero)
return;
Marshal.FreeHGlobal(pNativeData);
}
public int GetNativeDataSize() => -1;
public unsafe IntPtr MarshalManagedToNative(object? managedObj)
{
if (managedObj is null) return IntPtr.Zero;
var s = (string) managedObj;
var nb = Encoding.UTF8.GetMaxByteCount(s.Length);
var pMem = Marshal.AllocHGlobal(nb + 1);
var pbMem = (byte*) pMem;
int nbWritten;
fixed (char* firstChar = s)
{
nbWritten = Encoding.UTF8.GetBytes(firstChar, s.Length, pbMem, nb);
}
pbMem[nbWritten] = 0;
return pMem;
}
public object MarshalNativeToManaged(IntPtr pNativeData)
{
return Marshal.PtrToStringUTF8(pNativeData)!;
}
}
}

4
UTF8OutMarshaler.cs Normal file
View File

@@ -0,0 +1,4 @@
$HEADER$namespace $NAMESPACE$
{
public class $CLASS$ {$END$}
}

7
Wrapper.cs Normal file
View File

@@ -0,0 +1,7 @@
namespace Foodsoft.Alpm
{
public class Wrapper
{
}
}

7
alpm.cs Normal file
View File

@@ -0,0 +1,7 @@
namespace Alpm
{
public class alpm
{
}
}