root / trunk / Pithos.Network / MD5BlockCalculator.cs @ db63c1ae
History | View | Annotate | Download (1.8 kB)
1 |
using System; |
---|---|
2 |
using System.Collections.Generic; |
3 |
using System.Diagnostics; |
4 |
using System.Linq; |
5 |
using System.Security.Cryptography; |
6 |
using System.Text; |
7 |
using System.Threading; |
8 |
using System.Threading.Tasks; |
9 |
using System.Threading.Tasks.Dataflow; |
10 |
|
11 |
namespace Pithos.Network |
12 |
{ |
13 |
class MD5BlockCalculator:IDisposable |
14 |
{ |
15 |
private HashAlgorithm _hasher = HashAlgorithm.Create("md5"); |
16 |
|
17 |
private ActionBlock<Tuple<long, byte[],int>> _actionBlock; |
18 |
|
19 |
private long _currentBlock = 0; |
20 |
|
21 |
public MD5BlockCalculator() |
22 |
{ |
23 |
_actionBlock=new ActionBlock<Tuple<long, byte[],int>>(t=> ProcessBlock(t)); |
24 |
} |
25 |
|
26 |
private void ProcessBlock(Tuple<long,byte[],int> tuple) |
27 |
{ |
28 |
if (tuple.Item1 == _currentBlock) |
29 |
{ |
30 |
_hasher.TransformBlock(tuple.Item2, 0, tuple.Item3, null, 0); |
31 |
Interlocked.Increment(ref _currentBlock); |
32 |
} |
33 |
else |
34 |
{ |
35 |
_actionBlock.Post(tuple); |
36 |
} |
37 |
} |
38 |
|
39 |
public void PostBlock(long blockIndex,byte[] buffer,int size) |
40 |
{ |
41 |
_actionBlock.Post(Tuple.Create(blockIndex, buffer, size)); |
42 |
} |
43 |
|
44 |
public async Task<string> GetHash() |
45 |
{ |
46 |
_actionBlock.Complete(); |
47 |
await _actionBlock.Completion; |
48 |
Debug.Assert(_actionBlock.InputCount == 0); |
49 |
_hasher.TransformFinalBlock(new byte[0], 0, 0); |
50 |
var hash=_hasher.Hash.ToHashString(); |
51 |
return hash; |
52 |
} |
53 |
|
54 |
public void Dispose() |
55 |
{ |
56 |
Dispose(true); |
57 |
GC.SuppressFinalize(this); |
58 |
} |
59 |
|
60 |
protected virtual void Dispose(bool disposing) |
61 |
{ |
62 |
if (disposing && _hasher!=null) |
63 |
_hasher.Dispose(); |
64 |
_hasher = null; |
65 |
} |
66 |
} |
67 |
} |