120 lines
3.5 KiB
C#
120 lines
3.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Dynamic;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Foodsoft.Alpm
|
|
{
|
|
internal static class EnumerableWrapper<TElement>
|
|
{
|
|
internal static EnumerableWrapper<TElement, TImpl> Create<TImpl>(TImpl impl)
|
|
where TImpl : struct, ICollectionImpl<TElement>
|
|
{
|
|
return new EnumerableWrapper<TElement, TImpl>(impl);
|
|
}
|
|
}
|
|
|
|
internal struct EnumerableWrapper<TElement, TImpl> : ICollection<TElement> where TImpl : struct,
|
|
ICollectionImpl<TElement>
|
|
{
|
|
private TImpl _impl;
|
|
|
|
public static EnumerableWrapper<TElement, TImpl> Create(TImpl impl)
|
|
{
|
|
return new EnumerableWrapper<TElement, 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();
|
|
|
|
public int Count
|
|
{
|
|
get
|
|
{
|
|
var impl = _impl;
|
|
return impl.Handle.UseHandle((_) => (int) alpm.alpm_list_count(impl.GetItems()));
|
|
}
|
|
}
|
|
|
|
public bool Contains(TElement item)
|
|
{
|
|
var impl = _impl;
|
|
switch (item)
|
|
{
|
|
case string s:
|
|
return impl.Handle.UseHandle((_) => alpm.alpm_list_find_str(impl.GetItems(), s) != (IntPtr.Zero));
|
|
default:
|
|
var comparer = EqualityComparer<TElement>.Default;
|
|
return _impl.Handle.UseHandle((_) =>
|
|
{
|
|
for (var list = impl.GetItems(); list != IntPtr.Zero; list = Wrapper.ListNext(list))
|
|
{
|
|
if (comparer.Equals(item, impl.PtrToItem(Wrapper.ListData(list))))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
}
|
|
}
|
|
|
|
public void CopyTo(TElement[] array, int arrayIndex)
|
|
{
|
|
var impl = _impl;
|
|
impl.Handle.UseHandle((_) =>
|
|
{
|
|
for (var list = impl.GetItems(); list != IntPtr.Zero; list = Wrapper.ListNext(list))
|
|
{
|
|
array[arrayIndex++] = impl.PtrToItem(Wrapper.ListData(list));
|
|
}
|
|
|
|
return arrayIndex;
|
|
});
|
|
}
|
|
|
|
public void Add(TElement item)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
public bool Remove(TElement item)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
public bool IsReadOnly => true;
|
|
}
|
|
} |