using System;
using System.Collections.Generic;
using System.Linq;
using Vanara.Extensions;
using Vanara.PInvoke;
namespace Vanara.InteropServices
{
/// A safe unmanaged linked list of structures allocated on the global heap.
/// The type of the list elements.
/// The type of memory allocation to use.
public class SafeNativeLinkedList : SafeNativeListBase where TElem : struct where TMem : IMemoryMethods, new()
{
/// Initializes a new instance of the class.
/// The handle.
/// The size of memory allocated to the handle, in bytes.
/// if set to true if this class is responsible for freeing the memory on disposal.
/// The method to use to get the next item in the list.
public SafeNativeLinkedList(IntPtr ptr, SizeT size, bool ownsHandle, Func getNextMethod) : base(ptr, size, ownsHandle) { GetNextMethod = getNextMethod; }
/// Initializes a new instance of the class.
/// The number of bytes to allocate for this new array.
/// The method to use to get the next item in the list.
public SafeNativeLinkedList(SizeT byteCount, Func getNextMethod) : base(byteCount) { GetNextMethod = getNextMethod; }
/// Initializes a new instance of the class.
/// The handle.
/// The size of memory allocated to the handle, in bytes.
/// if set to true if this class is responsible for freeing the memory on disposal.
public SafeNativeLinkedList(IntPtr ptr, SizeT size, bool ownsHandle) : base(ptr, size, ownsHandle) { }
/// Initializes a new instance of the class.
/// The number of bytes to allocate for this new array.
public SafeNativeLinkedList(SizeT byteCount) : base(byteCount) { }
/// Gets or sets the method to use to get the next item in the list.
/// The method to get the next value. It should return if there are no more items.
public Func GetNextMethod { get; set; }
/// Gets or sets the method to use to get the next item in the list.
/// The method to get the next value. It should return if there are no more items.
public Func GetNextSizeMethod { get; set; }
/// Enumerates the elements.
/// An enumeration of values from the pointer.
protected override IEnumerable Items => GetNextMethod != null ? handle.LinkedListToIEnum(GetNextMethod) : (GetNextSizeMethod != null ? handle.LinkedListToIEnum(GetNextSizeMethod, Size) : Enumerable.Empty());
/*
///
/// Gets the pointers to the items in the linked list. This is useful when marshaling those values may invalidate internal pointers.
///
/// An array of pointers to the items.
public unsafe TElem*[] GetUnsafeItems()
{
var ret = new List();
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;
}
*/
}
}