checkpoint for real

This commit is contained in:
2020-04-27 12:34:56 -04:00
parent 6ed92261ec
commit c1618deb83
31 changed files with 1429 additions and 626 deletions

View File

@@ -1,12 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Foodsoft.Alpm;
using System.Runtime.CompilerServices;
namespace Foodsoft.Alpm
{
internal struct CollectionWrapper<TImpl, TElement> : ICollection<TElement> where TImpl : struct,
IAlpmItemsAccessor<TElement>
internal class CollectionWrapper<TImpl, TElement> : ICollection<TElement> where TImpl : struct,
IItemsAccessor<TElement>
{
private TImpl _impl;
@@ -15,26 +15,31 @@ namespace Foodsoft.Alpm
_impl = impl;
}
IEnumerator<TElement> IEnumerable<TElement>.GetEnumerator()
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()
{
return (IEnumerator<TElement>) GetEnumerator();
}
var safeAlpmHandle = _impl.SafeAlpmHandle;
var release = false;
public IEnumerator GetEnumerator()
{
var result = new List<TElement>();
var intPtr = _impl.GetItems();
unsafe
RuntimeHelpers.PrepareConstrainedRegions();
try
{
for (var list = (alpm_list_t*) intPtr; list != null; list = alpm.alpm_list_next(list))
safeAlpmHandle.DangerousAddRef(ref release);
if (!release) throw new ObjectDisposedException(_impl.GetType().FullName);
for (var list = _impl.GetItems(); list != IntPtr.Zero; list = ListNext(list))
{
result.Add(_impl.PtrToItem(list->data));
yield return _impl.PtrToItem(ListData(list));
}
}
return result.GetEnumerator();
finally
{
if (release)
safeAlpmHandle.DangerousRelease();
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public void Add(TElement item)
{
@@ -47,19 +52,45 @@ namespace Foodsoft.Alpm
}
public bool Contains(TElement item) =>
_impl.FindItem(item) != IntPtr.Zero;
public bool Contains(TElement item)
{
var safeAlpmHandle = _impl.SafeAlpmHandle;
var release = false;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
safeAlpmHandle.DangerousAddRef(ref release);
return _impl.FindItem(item) != IntPtr.Zero;
}
finally
{
if (release)
safeAlpmHandle.DangerousRelease();
}
}
public void CopyTo(TElement[] array, int arrayIndex)
{
var intPtr = _impl.GetItems();
unsafe
var safeAlpmHandle = _impl.SafeAlpmHandle;
var release = false;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
for (var list = (alpm_list_t*) intPtr; list != null; list = alpm.alpm_list_next(list))
safeAlpmHandle.DangerousAddRef(ref release);
var intPtr = _impl.GetItems();
unsafe
{
array[arrayIndex++] = _impl.PtrToItem(list->data);
for (var list = (alpm_list_t*) intPtr; list != null; list = alpm.alpm_list_next(list))
{
array[arrayIndex++] = _impl.PtrToItem(list->data);
}
}
}
finally
{
if (release)
safeAlpmHandle.DangerousRelease();
}
}
public bool Remove(TElement item)
@@ -73,7 +104,26 @@ namespace Foodsoft.Alpm
return err == 0;
}
public int Count => (int) alpm.alpm_list_count(_impl.GetItems());
public int Count
{
get
{
var safeAlpmHandle = _impl.SafeAlpmHandle;
var release = false;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
safeAlpmHandle.DangerousAddRef(ref release);
return (int) alpm.alpm_list_count(_impl.GetItems());
}
finally
{
if (release)
safeAlpmHandle.DangerousRelease();
}
}
}
public bool IsReadOnly => false;
}
}