forked from dotnet/runtime
/
Interop.CoreFoundation.CFData.cs
75 lines (61 loc) · 2 KB
/
Interop.CoreFoundation.CFData.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
// Declared as signed long, which has sizeof(void*) on OSX.
using CFIndex=System.IntPtr;
internal static partial class Interop
{
internal static partial class CoreFoundation
{
[DllImport(Libraries.CoreFoundationLibrary)]
private static extern unsafe byte* CFDataGetBytePtr(SafeCFDataHandle cfData);
[DllImport(Libraries.CoreFoundationLibrary)]
private static extern CFIndex CFDataGetLength(SafeCFDataHandle cfData);
internal static byte[] CFGetData(SafeCFDataHandle cfData)
{
bool addedRef = false;
try
{
cfData.DangerousAddRef(ref addedRef);
byte[] bytes = new byte[CFDataGetLength(cfData).ToInt64()];
unsafe
{
byte* dataBytes = CFDataGetBytePtr(cfData);
Marshal.Copy((IntPtr)dataBytes, bytes, 0, bytes.Length);
}
return bytes;
}
finally
{
if (addedRef)
{
cfData.DangerousRelease();
}
}
}
}
}
namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafeCFDataHandle : SafeHandle
{
internal SafeCFDataHandle()
: base(IntPtr.Zero, ownsHandle: true)
{
}
internal SafeCFDataHandle(IntPtr handle, bool ownsHandle)
: base(handle, ownsHandle)
{
}
protected override bool ReleaseHandle()
{
Interop.CoreFoundation.CFRelease(handle);
SetHandle(IntPtr.Zero);
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero;
}
}