forked from libgit2/libgit2sharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFilePathMarshaler.cs
More file actions
134 lines (110 loc) · 3.91 KB
/
FilePathMarshaler.cs
File metadata and controls
134 lines (110 loc) · 3.91 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.Runtime.InteropServices;
namespace LibGit2Sharp.Core
{
/// <summary>
/// This marshaler is to be used for capturing a UTF-8 string owned by libgit2 and
/// converting it to a managed FilePath instance. The marshaler will not attempt to
/// free the native pointer after conversion, because the memory is owned by libgit2.
///
/// Use this marshaler for return values, for example:
/// [return: MarshalAs(UnmanagedType.CustomMarshaler,
/// MarshalTypeRef = typeof(FilePathNoCleanupMarshaler))]
/// </summary>
internal class FilePathNoCleanupMarshaler : FilePathMarshaler
{
private static readonly FilePathNoCleanupMarshaler staticInstance = new FilePathNoCleanupMarshaler();
public static new ICustomMarshaler GetInstance(String cookie)
{
return staticInstance;
}
#region ICustomMarshaler
public override void CleanUpNativeData(IntPtr pNativeData)
{
}
#endregion
}
/// <summary>
/// This marshaler is to be used for sending managed FilePath instances to libgit2.
/// The marshaler will allocate a buffer in native memory to hold the UTF-8 string
/// and perform the encoding conversion using that buffer as the target. The pointer
/// received by libgit2 will be to this buffer. After the function call completes, the
/// native buffer is freed.
///
/// Use this marshaler for function parameters, for example:
/// [DllImport(libgit2)]
/// internal static extern int git_index_open(out IndexSafeHandle index,
/// [MarshalAs(UnmanagedType.CustomMarshaler,
/// MarshalTypeRef = typeof(FilePathMarshaler))] FilePath indexpath);
/// </summary>
internal class FilePathMarshaler : ICustomMarshaler
{
private static readonly FilePathMarshaler staticInstance = new FilePathMarshaler();
public static ICustomMarshaler GetInstance(String cookie)
{
return staticInstance;
}
#region ICustomMarshaler
public void CleanUpManagedData(Object managedObj)
{
}
public virtual void CleanUpNativeData(IntPtr pNativeData)
{
if (IntPtr.Zero != pNativeData)
{
Marshal.FreeHGlobal(pNativeData);
}
}
public int GetNativeDataSize()
{
// Not a value type
return -1;
}
public IntPtr MarshalManagedToNative(Object managedObj)
{
if (null == managedObj)
{
return IntPtr.Zero;
}
var filePath = managedObj as FilePath;
if (null == filePath)
{
throw new MarshalDirectiveException("FilePathMarshaler must be used on a FilePath.");
}
return FromManaged(filePath);
}
public Object MarshalNativeToManaged(IntPtr pNativeData)
{
return FromNative(pNativeData);
}
#endregion
public static IntPtr FromManaged(FilePath filePath)
{
if (null == filePath)
{
return IntPtr.Zero;
}
return Utf8Marshaler.FromManaged(filePath.Posix);
}
public static FilePath FromNative(IntPtr pNativeData)
{
if (IntPtr.Zero == pNativeData)
{
return null;
}
if (0 == Marshal.ReadByte(pNativeData))
{
return FilePath.Empty;
}
return Utf8Marshaler.FromNative(pNativeData);
}
public static FilePath FromNative(IntPtr pNativeData, int length)
{
if (0 == length)
{
return FilePath.Empty;
}
return Utf8Marshaler.FromNative(pNativeData, length);
}
}
}