checkpoint for real
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user