mirror of https://github.com/dahall/Vanara.git
69 lines
3.9 KiB
C#
69 lines
3.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Vanara.Extensions;
|
|
using Vanara.PInvoke;
|
|
|
|
namespace Vanara.InteropServices
|
|
{
|
|
/// <summary>A safe unmanaged linked list of structures allocated on the global heap.</summary>
|
|
/// <typeparam name="TElem">The type of the list elements.</typeparam>
|
|
/// <typeparam name="TMem">The type of memory allocation to use.</typeparam>
|
|
public class SafeNativeLinkedList<TElem, TMem> : SafeNativeListBase<TElem, TMem> where TElem : struct where TMem : IMemoryMethods, new()
|
|
{
|
|
/// <summary>Initializes a new instance of the <see cref="SafeNativeLinkedList{TElem, TMem}"/> class.</summary>
|
|
/// <param name="ptr">The handle.</param>
|
|
/// <param name="size">The size of memory allocated to the handle, in bytes.</param>
|
|
/// <param name="ownsHandle">if set to <c>true</c> if this class is responsible for freeing the memory on disposal.</param>
|
|
/// <param name="getNextMethod">The method to use to get the next item in the list.</param>
|
|
public SafeNativeLinkedList(IntPtr ptr, SizeT size, bool ownsHandle, Func<TElem, IntPtr> getNextMethod) : base(ptr, size, ownsHandle) { GetNextMethod = getNextMethod; }
|
|
|
|
/// <summary>Initializes a new instance of the <see cref="SafeNativeLinkedList{TElem, TMem}"/> class.</summary>
|
|
/// <param name="byteCount">The number of bytes to allocate for this new array.</param>
|
|
/// <param name="getNextMethod">The method to use to get the next item in the list.</param>
|
|
public SafeNativeLinkedList(SizeT byteCount, Func<TElem, IntPtr> getNextMethod) : base(byteCount) { GetNextMethod = getNextMethod; }
|
|
|
|
/// <summary>Initializes a new instance of the <see cref="SafeNativeLinkedList{TElem, TMem}"/> class.</summary>
|
|
/// <param name="ptr">The handle.</param>
|
|
/// <param name="size">The size of memory allocated to the handle, in bytes.</param>
|
|
/// <param name="ownsHandle">if set to <c>true</c> if this class is responsible for freeing the memory on disposal.</param>
|
|
public SafeNativeLinkedList(IntPtr ptr, SizeT size, bool ownsHandle) : base(ptr, size, ownsHandle) { }
|
|
|
|
/// <summary>Initializes a new instance of the <see cref="SafeNativeLinkedList{TElem, TMem}"/> class.</summary>
|
|
/// <param name="byteCount">The number of bytes to allocate for this new array.</param>
|
|
public SafeNativeLinkedList(SizeT byteCount) : base(byteCount) { }
|
|
|
|
/// <summary>Gets or sets the method to use to get the next item in the list.</summary>
|
|
/// <value>The method to get the next value. It should return <see cref="IntPtr.Zero"/> if there are no more items.</value>
|
|
public Func<TElem, IntPtr> GetNextMethod { get; set; }
|
|
|
|
/// <summary>Gets or sets the method to use to get the next item in the list.</summary>
|
|
/// <value>The method to get the next value. It should return <see cref="IntPtr.Zero"/> if there are no more items.</value>
|
|
public Func<TElem, long> GetNextSizeMethod { get; set; }
|
|
|
|
/// <summary>Enumerates the elements.</summary>
|
|
/// <returns>An enumeration of values from the pointer.</returns>
|
|
protected override IEnumerable<TElem> Items => GetNextMethod != null ? handle.LinkedListToIEnum(GetNextMethod) : (GetNextSizeMethod != null ? handle.LinkedListToIEnum(GetNextSizeMethod, Size) : Enumerable.Empty<TElem>());
|
|
|
|
/*
|
|
/// <summary>
|
|
/// Gets the pointers to the items in the linked list. This is useful when marshaling those values may invalidate internal pointers.
|
|
/// </summary>
|
|
/// <returns>An array of pointers to the items.</returns>
|
|
public unsafe TElem*[] GetUnsafeItems()
|
|
{
|
|
var ret = new List<IntPtr>();
|
|
for (byte* pCurrent = (byte*)handle, pEnd = pCurrent + Size; pCurrent < pEnd && pCurrent != null;)
|
|
{
|
|
ret.Add((IntPtr)pCurrent);
|
|
pCurrent = GetNextMethod != null ? (byte*)GetNextMethod(*(TElem*)pCurrent) : (GetNextSizeMethod != null ? pCurrent + GetNextSizeMethod(*(TElem*)pCurrent) : null);
|
|
}
|
|
|
|
var arr = new TElem*[ret.Count];
|
|
for (int i = 0; i < ret.Count; i++)
|
|
arr[i] = (TElem*)ret[i];
|
|
return arr;
|
|
}
|
|
*/
|
|
}
|
|
} |