-
Notifications
You must be signed in to change notification settings - Fork 897
/
Copy pathRemoteCallbacks.cs
154 lines (128 loc) · 5.61 KB
/
RemoteCallbacks.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
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using LibGit2Sharp.Core;
using LibGit2Sharp.Handlers;
namespace LibGit2Sharp
{
/// <summary>
/// Class to translate libgit2 callbacks into delegates exposed by LibGit2Sharp.
/// Handles generating libgit2 git_remote_callbacks datastructure given a set
/// of LibGit2Sharp delegates and handles propagating libgit2 callbacks into
/// corresponding LibGit2Sharp exposed delegates.
/// </summary>
internal class RemoteCallbacks
{
internal RemoteCallbacks(
ProgressHandler onProgress = null,
TransferProgressHandler onDownloadProgress = null,
UpdateTipsHandler onUpdateTips = null,
Credentials credentials = null)
{
Progress = onProgress;
DownloadTransferProgress = onDownloadProgress;
UpdateTips = onUpdateTips;
Credentials = credentials;
}
#region Delegates
/// <summary>
/// Progress callback. Corresponds to libgit2 progress callback.
/// </summary>
private readonly ProgressHandler Progress;
/// <summary>
/// UpdateTips callback. Corresponds to libgit2 update_tips callback.
/// </summary>
private readonly UpdateTipsHandler UpdateTips;
/// <summary>
/// Managed delegate to be called in response to a git_transfer_progress_callback callback from libgit2.
/// This will in turn call the user provided delegate.
/// </summary>
private readonly TransferProgressHandler DownloadTransferProgress;
#endregion
/// <summary>
/// The credentials to use for the credential callback.
/// </summary>
Credentials Credentials;
internal GitRemoteCallbacks GenerateCallbacks()
{
var callbacks = new GitRemoteCallbacks {version = 1};
if (Progress != null)
{
callbacks.progress = GitProgressHandler;
}
if (UpdateTips != null)
{
callbacks.update_tips = GitUpdateTipsHandler;
}
if (Credentials != null)
{
callbacks.acquire_credentials = GitCredentialHandler;
}
if (DownloadTransferProgress != null)
{
callbacks.download_progress = GitDownloadTransferProgressHandler;
}
return callbacks;
}
#region Handlers to respond to callbacks raised by libgit2
/// <summary>
/// Handler for libgit2 Progress callback. Converts values
/// received from libgit2 callback to more suitable types
/// and calls delegate provided by LibGit2Sharp consumer.
/// </summary>
/// <param name="str">IntPtr to string from libgit2</param>
/// <param name="len">length of string</param>
/// <param name="data">IntPtr to optional payload passed back to the callback.</param>
/// <returns>0 on success; a negative value to abort the process.</returns>
private int GitProgressHandler(IntPtr str, int len, IntPtr data)
{
ProgressHandler onProgress = Progress;
bool shouldContinue = true;
if (onProgress != null)
{
string message = LaxUtf8Marshaler.FromNative(str, len);
shouldContinue = onProgress(message);
}
return Proxy.ConvertResultToCancelFlag(shouldContinue);
}
/// <summary>
/// Handler for libgit2 update_tips callback. Converts values
/// received from libgit2 callback to more suitable types
/// and calls delegate provided by LibGit2Sharp consumer.
/// </summary>
/// <param name="str">IntPtr to string</param>
/// <param name="oldId">Old reference ID</param>
/// <param name="newId">New referene ID</param>
/// <param name="data">IntPtr to optional payload passed back to the callback.</param>
/// <returns>0 on success; a negative value to abort the process.</returns>
private int GitUpdateTipsHandler(IntPtr str, ref GitOid oldId, ref GitOid newId, IntPtr data)
{
UpdateTipsHandler onUpdateTips = UpdateTips;
bool shouldContinue = true;
if (onUpdateTips != null)
{
string refName = LaxUtf8Marshaler.FromNative(str);
shouldContinue = onUpdateTips(refName, oldId, newId);
}
return Proxy.ConvertResultToCancelFlag(shouldContinue);
}
/// <summary>
/// The delegate with the signature that matches the native git_transfer_progress_callback function's signature.
/// </summary>
/// <param name="progress"><see cref="GitTransferProgress"/> structure containing progress information.</param>
/// <param name="payload">Payload data.</param>
/// <returns>the result of the wrapped <see cref="TransferProgressHandler"/></returns>
private int GitDownloadTransferProgressHandler(ref GitTransferProgress progress, IntPtr payload)
{
bool shouldContinue = true;
if (DownloadTransferProgress != null)
{
shouldContinue = DownloadTransferProgress(new TransferProgress(progress));
}
return Proxy.ConvertResultToCancelFlag(shouldContinue);
}
private int GitCredentialHandler(out IntPtr cred, IntPtr url, IntPtr username_from_url, uint types, IntPtr payload)
{
return NativeMethods.git_cred_userpass_plaintext_new(out cred, Credentials.Username, Credentials.Password);
}
#endregion
}
}