@@ -22,6 +22,14 @@ public static class GlobalSettings
22
22
private static bool nativeLibraryPathLocked ;
23
23
private static string nativeLibraryDefaultPath ;
24
24
25
+ internal class SmartSubtransportData
26
+ {
27
+ internal bool isCustom ;
28
+ internal SmartSubtransportRegistrationData defaultSubtransport ;
29
+ }
30
+
31
+ private static readonly Dictionary < string , SmartSubtransportData > smartSubtransportData = new Dictionary < string , SmartSubtransportData > ( ) ;
32
+
25
33
static GlobalSettings ( )
26
34
{
27
35
bool netFX = Platform . IsRunningOnNetFramework ( ) ;
@@ -79,6 +87,42 @@ public static Version Version
79
87
}
80
88
}
81
89
90
+ private static SmartSubtransportData GetOrCreateSmartSubtransportData ( string scheme )
91
+ {
92
+ Ensure . ArgumentNotNull ( scheme , "scheme" ) ;
93
+
94
+ lock ( smartSubtransportData )
95
+ {
96
+ if ( ! smartSubtransportData . ContainsKey ( scheme ) )
97
+ {
98
+ smartSubtransportData [ scheme ] = new SmartSubtransportData ( ) ;
99
+ }
100
+
101
+ return smartSubtransportData [ scheme ] ;
102
+ }
103
+ }
104
+
105
+ internal static SmartSubtransportRegistration < T > RegisterDefaultSmartSubtransport < T > ( string scheme )
106
+ where T : SmartSubtransport , new ( )
107
+ {
108
+ Ensure . ArgumentNotNull ( scheme , "scheme" ) ;
109
+
110
+ lock ( smartSubtransportData )
111
+ {
112
+ var data = GetOrCreateSmartSubtransportData ( scheme ) ;
113
+
114
+ if ( data . defaultSubtransport != null )
115
+ {
116
+ throw new Exception ( string . Format ( "A default subtransport is already configured for {0}" , scheme ) ) ;
117
+ }
118
+
119
+ var registration = RegisterSmartSubtransportInternal < T > ( scheme ) ;
120
+
121
+ data . defaultSubtransport = registration ;
122
+ return registration ;
123
+ }
124
+ }
125
+
82
126
/// <summary>
83
127
/// Registers a new <see cref="SmartSubtransport"/> as a custom
84
128
/// smart-protocol transport with libgit2. Any Git remote with
@@ -96,8 +140,34 @@ public static Version Version
96
140
public static SmartSubtransportRegistration < T > RegisterSmartSubtransport < T > ( string scheme )
97
141
where T : SmartSubtransport , new ( )
98
142
{
143
+ SmartSubtransportRegistration < T > registration ;
144
+
99
145
Ensure . ArgumentNotNull ( scheme , "scheme" ) ;
100
146
147
+ lock ( smartSubtransportData )
148
+ {
149
+ var data = GetOrCreateSmartSubtransportData ( scheme ) ;
150
+
151
+ if ( data . isCustom )
152
+ {
153
+ throw new EntryExistsException ( string . Format ( "A smart subtransport is already registered for {0}" , scheme ) ) ;
154
+ }
155
+
156
+ if ( data . defaultSubtransport != null )
157
+ {
158
+ Proxy . git_transport_unregister ( scheme ) ;
159
+ }
160
+
161
+ registration = RegisterSmartSubtransportInternal < T > ( scheme ) ;
162
+ data . isCustom = true ;
163
+ }
164
+
165
+ return registration ;
166
+ }
167
+
168
+ private static SmartSubtransportRegistration < T > RegisterSmartSubtransportInternal < T > ( string scheme )
169
+ where T : SmartSubtransport , new ( )
170
+ {
101
171
var registration = new SmartSubtransportRegistration < T > ( scheme ) ;
102
172
103
173
try
@@ -126,6 +196,59 @@ public static void UnregisterSmartSubtransport<T>(SmartSubtransportRegistration<
126
196
{
127
197
Ensure . ArgumentNotNull ( registration , "registration" ) ;
128
198
199
+ var scheme = registration . Scheme ;
200
+
201
+ lock ( smartSubtransportData )
202
+ {
203
+ var data = GetOrCreateSmartSubtransportData ( scheme ) ;
204
+
205
+ if ( ! data . isCustom )
206
+ {
207
+ throw new NotFoundException ( string . Format ( "No smart subtransport has been registered for {0}" , scheme ) ) ;
208
+ }
209
+
210
+ UnregisterSmartSubtransportInternal ( registration ) ;
211
+
212
+ data . isCustom = false ;
213
+
214
+ if ( data . defaultSubtransport != null )
215
+ {
216
+ var defaultRegistration = data . defaultSubtransport ;
217
+
218
+ Proxy . git_transport_register ( defaultRegistration . Scheme ,
219
+ defaultRegistration . FunctionPointer ,
220
+ defaultRegistration . RegistrationPointer ) ;
221
+ }
222
+ }
223
+ }
224
+
225
+ internal static void UnregisterDefaultSmartSubtransport < T > ( SmartSubtransportRegistration < T > registration )
226
+ where T : SmartSubtransport , new ( )
227
+ {
228
+ Ensure . ArgumentNotNull ( registration , "registration" ) ;
229
+
230
+ var scheme = registration . Scheme ;
231
+
232
+ lock ( smartSubtransportData )
233
+ {
234
+ if ( ! smartSubtransportData . ContainsKey ( scheme ) )
235
+ {
236
+ throw new Exception ( string . Format ( "No default smart subtransport has been registered for {0}" , scheme ) ) ;
237
+ }
238
+
239
+ if ( registration != smartSubtransportData [ scheme ] . defaultSubtransport )
240
+ {
241
+ throw new Exception ( string . Format ( "The given smart subtransport is not the default for {0}" , scheme ) ) ;
242
+ }
243
+
244
+ smartSubtransportData . Remove ( scheme ) ;
245
+ UnregisterSmartSubtransportInternal ( registration ) ;
246
+ }
247
+ }
248
+
249
+ private static void UnregisterSmartSubtransportInternal < T > ( SmartSubtransportRegistration < T > registration )
250
+ where T : SmartSubtransport , new ( )
251
+ {
129
252
Proxy . git_transport_unregister ( registration . Scheme ) ;
130
253
registration . Free ( ) ;
131
254
}
0 commit comments