CPF/CPF.Mac/Mac/CoreFoundation/CFAllocator.cs
2023-11-21 23:05:03 +08:00

111 lines
2.8 KiB
C#

using CPF.Mac.ObjCRuntime;
using System;
using System.Runtime.InteropServices;
namespace CPF.Mac.CoreFoundation
{
public class CFAllocator : INativeObject, IDisposable
{
private static CFAllocator Default_cf;
private static CFAllocator SystemDefault_cf;
private static CFAllocator Malloc_cf;
private static CFAllocator MallocZone_cf;
private static CFAllocator Null_cf;
private static readonly IntPtr default_ptr;
private static readonly IntPtr system_default_ptr;
private static readonly IntPtr malloc_ptr;
private static readonly IntPtr malloc_zone_ptr;
internal static readonly IntPtr null_ptr;
private IntPtr handle;
public IntPtr Handle => handle;
public static CFAllocator Default => Default_cf ?? (Default_cf = new CFAllocator(default_ptr));
public static CFAllocator SystemDefault => SystemDefault_cf ?? (SystemDefault_cf = new CFAllocator(system_default_ptr));
public static CFAllocator Malloc => Malloc_cf ?? (Malloc_cf = new CFAllocator(malloc_ptr));
public static CFAllocator MallocZone => MallocZone_cf ?? (MallocZone_cf = new CFAllocator(malloc_zone_ptr));
public static CFAllocator Null => Null_cf ?? (Null_cf = new CFAllocator(null_ptr));
static CFAllocator()
{
IntPtr intPtr = Dlfcn.dlopen("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", 0);
try
{
default_ptr = Dlfcn.GetIntPtr(intPtr, "kCFAllocatorDefault");
system_default_ptr = Dlfcn.GetIntPtr(intPtr, "kCFAllocatorSystemDefault");
malloc_ptr = Dlfcn.GetIntPtr(intPtr, "kCFAllocatorMalloc");
malloc_zone_ptr = Dlfcn.GetIntPtr(intPtr, "kCFAllocatorMallocZone");
null_ptr = Dlfcn.GetIntPtr(intPtr, "kCFAllocatorNull");
}
finally
{
Dlfcn.dlclose(intPtr);
}
}
public CFAllocator(IntPtr handle)
{
this.handle = handle;
}
public CFAllocator(IntPtr handle, bool owns)
{
if (!owns)
{
CFObject.CFRetain(handle);
}
this.handle = handle;
}
~CFAllocator()
{
Dispose(disposing: false);
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (handle != IntPtr.Zero)
{
CFObject.CFRelease(handle);
handle = IntPtr.Zero;
}
}
[DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
private static extern IntPtr CFAllocatorAllocate(IntPtr allocator, long size, CFAllocatorFlags hint);
public IntPtr Allocate(long size, CFAllocatorFlags hint = (CFAllocatorFlags)0uL)
{
return CFAllocatorAllocate(handle, size, hint);
}
[DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
private static extern void CFAllocatorDeallocate(IntPtr allocator, IntPtr ptr);
public void Deallocate(IntPtr ptr)
{
CFAllocatorDeallocate(handle, ptr);
}
}
}