using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Vanara.Extensions;
namespace Vanara.InteropServices;
/// A memory pool that will automatically release all memory pointers on disposal.
/// The type of the memory allocator.
///
public class SafeMemoryPool : IDisposable where TMem : IMemoryMethods, new()
{
private static readonly TMem mem = new();
private readonly Stack stack = new();
private bool disposedValue;
/// Finalizes an instance of the class.
~SafeMemoryPool()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: false);
}
/// Adds the specified pointer to the memory pool.
/// The pointer to memory allocated with the same allocator as specified by .
/// The value of .
public IntPtr Add(IntPtr ptr) { stack.Push(ptr); return ptr; }
/// Adds the specified string to the memory pool.
/// The string value.
/// The character set.
/// The pointer to the allocated memory.
public IntPtr Add(string value, CharSet charSet = CharSet.Auto) => Add(StringHelper.AllocString(value, charSet, mem.AllocMem));
/// Adds the specified value to the memory pool.
/// The type of .
/// The value.
/// The pointer to the allocated memory.
public IntPtr Add(T value) => Add(value.MarshalToPtr(mem.AllocMem, out _, 0, mem.LockMem, mem.UnlockMem));
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
/// Releases unmanaged and - optionally - managed resources.
///
/// to release both managed and unmanaged resources; to release only unmanaged resources.
///
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
while (stack.Count > 0)
mem.FreeMem(stack.Pop());
disposedValue=true;
}
}
}