using CPF.Mac.ObjCRuntime; using System; using System.Runtime.InteropServices; namespace CPF.Mac.CoreFoundation { internal class CFData : INativeObject, IDisposable { internal IntPtr handle; public IntPtr Handle => handle; public int Length => CFDataGetLength(handle); public IntPtr Bytes => CFDataGetBytePtr(handle); public CFData(IntPtr handle) : this(handle, owns: false) { } public CFData(IntPtr handle, bool owns) { if (!owns) { CFObject.CFRetain(handle); } this.handle = handle; } ~CFData() { Dispose(disposing: false); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", EntryPoint = "CFDataGetTypeID")] public static extern int GetTypeID(); protected virtual void Dispose(bool disposing) { if (handle != IntPtr.Zero) { CFObject.CFRelease(handle); handle = IntPtr.Zero; } } public static CFData FromDataNoCopy(IntPtr buffer, int length) { return new CFData(CFDataCreateWithBytesNoCopy(IntPtr.Zero, buffer, length, CFAllocator.null_ptr), owns: true); } [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern IntPtr CFDataCreateWithBytesNoCopy(IntPtr allocator, IntPtr bytes, int len, IntPtr deallocator); [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern CFIndex CFDataGetLength(IntPtr data); public byte[] GetBuffer() { byte[] array = new byte[Length]; Marshal.Copy(CFDataGetBytePtr(handle), array, 0, array.Length); return array; } [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern IntPtr CFDataGetBytePtr(IntPtr data); [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern IntPtr CFDataCreate(IntPtr allocator, IntPtr bytes, CFIndex len); public static CFData FromData(IntPtr buffer, int length) { return new CFData(CFDataCreate(IntPtr.Zero, buffer, length), owns: true); } [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")] private static extern IntPtr CFDataCreateCopy(IntPtr allocator, IntPtr data); public CFData Copy() { return new CFData(CFDataCreateCopy(IntPtr.Zero, Handle), owns: true); } } }