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; } } }