Statistics
| Branch: | Revision:

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
}