@@ -41,7 +41,7 @@ protected Filter(string name, IEnumerable<FilterAttributeEntry> attributes)
41
41
{
42
42
attributes = EncodingMarshaler . FromManaged ( Encoding . UTF8 , attributesAsString ) ,
43
43
init = InitializeCallback ,
44
- stream = StreamCallback ,
44
+ stream = StreamCreateCallback ,
45
45
} ;
46
46
}
47
47
@@ -199,129 +199,140 @@ int InitializeCallback(IntPtr filterPointer)
199
199
return Initialize ( ) ;
200
200
}
201
201
202
- unsafe int StreamCallback ( out IntPtr git_writestream_out , GitFilter self , IntPtr payload , IntPtr filterSourcePtr , IntPtr git_writestream_next )
202
+ int StreamCreateCallback ( out IntPtr git_writestream_out , GitFilter self , IntPtr payload , IntPtr filterSourcePtr , IntPtr git_writestream_next )
203
203
{
204
- if ( filterSourcePtr == IntPtr . Zero )
204
+ int result = 0 ;
205
+
206
+ try
205
207
{
206
- throw new ArgumentNullException ( "filterSourcePtr" ) ;
208
+ Ensure . ArgumentNotZeroIntPtr ( filterSourcePtr , "filterSourcePtr" ) ;
209
+ Ensure . ArgumentNotZeroIntPtr ( git_writestream_next , "git_writestream_next" ) ;
210
+
211
+ thisStream = new GitWriteStream ( ) ;
212
+ thisStream . close = StreamCloseCallback ;
213
+ thisStream . write = StreamWriteCallback ;
214
+ thisStream . free = StreamFreeCallback ;
215
+ thisPtr = Marshal . AllocHGlobal ( Marshal . SizeOf ( thisStream ) ) ;
216
+ Marshal . StructureToPtr ( thisStream , thisPtr , false ) ;
217
+ nextPtr = git_writestream_next ;
218
+ nextStream = new GitWriteStream ( ) ;
219
+ Marshal . PtrToStructure ( nextPtr , nextStream ) ;
220
+ filterSource = FilterSource . FromNativePtr ( filterSourcePtr ) ;
207
221
}
208
- if ( git_writestream_next == IntPtr . Zero )
222
+ catch ( Exception exception )
209
223
{
210
- throw new ArgumentNullException ( "git_writestream_next" ) ;
211
- }
224
+ // unexpected failures means memory clean up required
225
+ if ( thisPtr != IntPtr . Zero )
226
+ {
227
+ Marshal . FreeHGlobal ( thisPtr ) ;
228
+ thisPtr = IntPtr . Zero ;
229
+ }
212
230
213
- thisStream = new GitWriteStream ( ) ;
214
- thisStream . close = StreamCloseCallback ;
215
- thisStream . write = StreamWriteCallback ;
216
- thisStream . free = StreamFreeCallback ;
217
- thisPtr = Marshal . AllocHGlobal ( Marshal . SizeOf ( thisStream ) ) ;
218
- Marshal . StructureToPtr ( thisStream , thisPtr , false ) ;
219
- nextPtr = git_writestream_next ;
220
- nextStream = new GitWriteStream ( ) ;
221
- Marshal . PtrToStructure ( nextPtr , nextStream ) ;
222
- filterSource = FilterSource . FromNativePtr ( filterSourcePtr ) ;
231
+ Proxy . giterr_set_str ( GitErrorCategory . Filter , exception . Message ) ;
232
+ result = ( int ) GitErrorCode . Error ;
233
+ }
223
234
224
235
git_writestream_out = thisPtr ;
225
236
226
- return 0 ;
237
+ return result ;
227
238
}
228
239
229
- unsafe int StreamCloseCallback ( IntPtr stream )
240
+ int StreamCloseCallback ( IntPtr stream )
230
241
{
231
242
int result = 0 ;
232
243
233
- if ( stream == IntPtr . Zero )
234
- {
235
- throw new ArgumentNullException ( "stream" ) ;
236
- }
237
- if ( stream != thisPtr )
244
+ try
238
245
{
239
- throw new ArgumentException ( "Unexpected stream pointer" , "stream" ) ;
240
- }
246
+ Ensure . ArgumentNotZeroIntPtr ( stream , "stream" ) ;
247
+ Ensure . ArhumentIsExpectedIntPtr ( stream , thisPtr , "stream" ) ;
241
248
242
- using ( MemoryStream output = new MemoryStream ( ) )
249
+ result = nextStream . close ( nextPtr ) ;
250
+ }
251
+ catch ( Exception exception )
243
252
{
244
- Ensure . ZeroResult ( result = this . Complete ( filterSource . Path , filterSource . Root , output ) ) ;
245
- result = WriteToNextFilter ( output ) ;
253
+ Proxy . giterr_set_str ( GitErrorCategory . Filter , exception . Message ) ;
254
+ result = ( int ) GitErrorCode . Error ;
246
255
}
247
256
248
- return nextStream . close ( nextPtr ) ;
257
+ return result ;
249
258
}
250
259
251
- unsafe void StreamFreeCallback ( IntPtr stream )
260
+ void StreamFreeCallback ( IntPtr stream )
252
261
{
253
- if ( stream == IntPtr . Zero )
254
- throw new ArgumentNullException ( "stream" ) ;
255
- if ( stream != thisPtr )
256
- throw new ArgumentException ( "unexpected stream ptr ") ;
262
+ try
263
+ {
264
+ Ensure . ArgumentNotZeroIntPtr ( stream , "stream" ) ;
265
+ Ensure . ArhumentIsExpectedIntPtr ( stream , thisPtr , " stream") ;
257
266
258
- Marshal . FreeHGlobal ( thisPtr ) ;
267
+ Marshal . FreeHGlobal ( thisPtr ) ;
268
+ }
269
+ catch { }
259
270
}
260
271
261
- unsafe int StreamWriteCallback ( IntPtr stream , IntPtr buffer , uint len )
272
+ unsafe int StreamWriteCallback ( IntPtr stream , IntPtr buffer , UIntPtr len )
262
273
{
263
274
int result = 0 ;
264
275
265
- if ( stream == IntPtr . Zero )
266
- {
267
- throw new ArgumentNullException ( "stream" ) ;
268
- }
269
- if ( buffer == IntPtr . Zero )
270
- {
271
- throw new ArgumentNullException ( "buffer" ) ;
272
- }
273
- if ( stream != thisPtr )
276
+ try
274
277
{
275
- throw new ArgumentException ( "Unexpected GitWriteStream" , "stream" ) ;
276
- }
278
+ Ensure . ArgumentNotZeroIntPtr ( stream , "stream" ) ;
279
+ Ensure . ArgumentNotZeroIntPtr ( buffer , "buffer" ) ;
280
+ Ensure . ArhumentIsExpectedIntPtr ( stream , thisPtr , "stream" ) ;
277
281
278
- using ( UnmanagedMemoryStream input = new UnmanagedMemoryStream ( ( byte * ) buffer . ToPointer ( ) , len ) )
279
- using ( MemoryStream output = new MemoryStream ( ) )
280
- {
281
- switch ( filterSource . SourceMode )
282
+ using ( UnmanagedMemoryStream input = new UnmanagedMemoryStream ( ( byte * ) buffer . ToPointer ( ) , ( long ) len ) )
283
+ using ( MemoryStream output = new MemoryStream ( ) )
282
284
{
283
- case FilterMode . Clean :
284
- result = Clean ( filterSource . Path , filterSource . Root , input , output ) ;
285
- break ;
286
- case FilterMode . Smudge :
287
- result = Smudge ( filterSource . Path , filterSource . Root , input , output ) ;
288
- break ;
289
- default :
290
- Proxy . giterr_set_str ( GitErrorCategory . Filter , "Unexpected filter mode." ) ;
291
- return ( int ) GitErrorCode . Ambiguous ;
292
- }
293
285
294
- if ( result == ( int ) GitErrorCode . PassThrough )
295
- {
296
- input . CopyTo ( output ) ;
297
- }
298
- else if ( result < 0 )
299
- {
300
- return result ;
301
- }
286
+ switch ( filterSource . SourceMode )
287
+ {
288
+ case FilterMode . Clean :
289
+ result = Clean ( filterSource . Path , filterSource . Root , input , output ) ;
290
+ break ;
291
+ case FilterMode . Smudge :
292
+ result = Smudge ( filterSource . Path , filterSource . Root , input , output ) ;
293
+ break ;
294
+ default :
295
+ Proxy . giterr_set_str ( GitErrorCategory . Filter , "Unexpected filter mode." ) ;
296
+ return ( int ) GitErrorCode . Ambiguous ;
297
+ }
298
+
299
+ if ( result == ( int ) GitErrorCode . PassThrough )
300
+ {
301
+ input . CopyTo ( output ) ;
302
+ }
303
+ else if ( result < 0 )
304
+ {
305
+ return result ;
306
+ }
302
307
303
- result = WriteToNextFilter ( output ) ;
308
+ output . Seek ( 0 , SeekOrigin . Begin ) ;
309
+ result = WriteToNextFilter ( output ) ;
310
+ }
311
+ }
312
+ catch ( Exception exception )
313
+ {
314
+ Proxy . giterr_set_str ( GitErrorCategory . Filter , exception . Message ) ;
315
+ result = ( int ) GitErrorCode . Error ;
304
316
}
305
317
306
318
return result ;
307
319
}
308
320
309
321
private unsafe int WriteToNextFilter ( MemoryStream output )
310
322
{
311
- const int BufferSize = 64 * 1024 ; // 64K is optimal buffer size per https://technet.microsoft.com/en-us/library/cc938632.aspx
323
+ // 64K is optimal buffer size per https://technet.microsoft.com/en-us/library/cc938632.aspx
324
+ const int BufferSize = 64 * 1024 ;
312
325
313
326
int result = 0 ;
314
327
byte [ ] bytes = new byte [ BufferSize ] ;
315
328
IntPtr bytesPtr = Marshal . AllocHGlobal ( BufferSize ) ;
316
329
try
317
330
{
318
- output . Seek ( 0 , SeekOrigin . Begin ) ;
319
-
320
331
int read = 0 ;
321
332
while ( ( read = output . Read ( bytes , 0 , bytes . Length ) ) > 0 )
322
333
{
323
334
Marshal . Copy ( bytes , 0 , bytesPtr , read ) ;
324
- if ( ( result = nextStream . write ( nextPtr , bytesPtr , ( uint ) read ) ) < 0 )
335
+ if ( ( result = nextStream . write ( nextPtr , bytesPtr , ( UIntPtr ) read ) ) < 0 )
325
336
{
326
337
Proxy . giterr_set_str ( GitErrorCategory . Filter , "Filter write to next stream failed" ) ;
327
338
break ;
0 commit comments