Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / Agents / BlockExtensions.cs @ 3906933e

History | View | Annotate | Download (9.9 kB)

1
#region
2
/* -----------------------------------------------------------------------
3
 * <copyright file="BlockExtensions.cs" company="GRNet">
4
 * 
5
 * Copyright 2011-2012 GRNET S.A. All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or
8
 * without modification, are permitted provided that the following
9
 * conditions are met:
10
 *
11
 *   1. Redistributions of source code must retain the above
12
 *      copyright notice, this list of conditions and the following
13
 *      disclaimer.
14
 *
15
 *   2. Redistributions in binary form must reproduce the above
16
 *      copyright notice, this list of conditions and the following
17
 *      disclaimer in the documentation and/or other materials
18
 *      provided with the distribution.
19
 *
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
 * POSSIBILITY OF SUCH DAMAGE.
33
 *
34
 * The views and conclusions contained in the software and
35
 * documentation are those of the authors and should not be
36
 * interpreted as representing official policies, either expressed
37
 * or implied, of GRNET S.A.
38
 * </copyright>
39
 * -----------------------------------------------------------------------
40
 */
41
#endregion
42
using System;
43
using System.Collections.Generic;
44
using System.Diagnostics;
45
using System.Diagnostics.Contracts;
46
using System.Linq;
47
using System.Reflection;
48

    
49
using System.Text;
50
using System.IO;
51
using System.Text.RegularExpressions;
52
using System.Threading;
53
using System.Threading.Tasks;
54
using Pithos.Network;
55
using log4net;
56
using OpenSSL.Core;
57
using OpenSSL.Crypto;
58

    
59

    
60
namespace Pithos.Core.Agents
61
{
62
    static class BlockExtensions
63
    {
64

    
65
        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
66

    
67
        public static int Read(this FileInfo fileInfo,byte[] buffer,long offset,int count)
68
        {
69
            if (offset < 0)
70
                throw new ArgumentOutOfRangeException("offset", offset, "The file offset can't be negative");
71
            Contract.EndContractBlock();
72
            //Open the stream only long enough to read a block
73
            using (var stream = fileInfo.OpenRead())
74
            {
75
                stream.Seek(offset, SeekOrigin.Begin);
76
                return  stream.Read(buffer, 0, count);                
77
            }
78
        }
79

    
80
    
81
       public static string CalculateHash(this FileSystemInfo info,int blockSize,string algorithm,CancellationToken token,IProgress<double> progress )
82
        {
83
            if (info==null)
84
                throw new ArgumentNullException("info");
85
            if (String.IsNullOrWhiteSpace(info.FullName))
86
                throw new ArgumentException("info");
87
            if (blockSize<=0)
88
                throw new ArgumentOutOfRangeException("blockSize",blockSize,"blockSize must be greater than 0");
89
            if (String.IsNullOrWhiteSpace(algorithm))
90
                throw new ArgumentNullException("algorithm");
91
            Contract.EndContractBlock();
92
           info.Refresh();
93
           if (info.FullName.Split('/').Contains(".pithos.cache"))
94
               throw new ArgumentException(String.Format("Trying to hash file from the cache folder: [{0}]", info.FullName));
95

    
96
           //The hash for directories is an empty string
97
           if (info is DirectoryInfo)
98
                return String.Empty;
99
           //The hash for non-existent files is an empty string
100
           if (!info.Exists)
101
               return String.Empty;
102

    
103
           return Signature.CalculateTreeHash(info.FullName, blockSize, algorithm,token,progress).TopHash.ToHashString();
104

    
105
        }
106

    
107
       /// <summary>
108
       ///Calculates a simple hash for an entire file
109
       /// </summary>
110
       /// <param name="info">The file to hash</param>
111
       /// <param name="hasher">The hash algorithm to use</param>
112
       /// <returns>A hash value for the entire file. An empty string if the file does not exist.</returns>
113
       //public static string ComputeShortHash(this FileInfo info, MessageDigestContext hasher,IStatusNotification notification)
114
       //{
115
       //    if(info == null)
116
       //        throw new ArgumentNullException("info");
117
       //    if(hasher== null)
118
       //        throw new ArgumentNullException("hasher");
119
       //    Contract.EndContractBlock();
120
       //    info.Refresh();
121

    
122
       //    if (!info.Exists)
123
       //        return String.Empty;
124
       //    if (info.FullName.Split('/').Contains(".pithos.cache"))
125
       //        throw new ArgumentException(String.Format("Trying to hash file from the cache folder: [{0}]", info.FullName));
126

    
127
       //    if (Log.IsDebugEnabled)
128
       //         Log.DebugFormat("Short Hashing [{0}] ",info.FullName);
129

    
130
       //    if (info.Length==0)
131
       //        return Signature.MD5_EMPTY;
132

    
133
       //    var progress = new StatusNotification("");
134

    
135
       //    using (var stream = new FileStream(info.FullName,FileMode.Open, FileAccess.Read, FileShare.Read,Signature.BufferSize))
136
       //    {
137
       //        var buffer = new byte[65536];
138
       //        int counter=0;
139
       //        int bytesRead;
140
       //        do
141
       //        {
142
       //            bytesRead = stream.Read(buffer, 0, 32768);
143
       //            if (bytesRead > 0)
144
       //            {
145
       //                if (bytesRead == buffer.Length)
146
       //                {
147
       //                    hasher.Update(buffer);
148
       //                }
149
       //                else
150
       //                {
151
       //                    var block = new byte[bytesRead];
152
       //                    Buffer.BlockCopy(buffer, 0, block, 0, bytesRead);
153
       //                    hasher.Update(block);
154
       //                }
155
       //            }
156
       //            counter++;
157
       //            if (counter % 100 == 0)
158
       //            {
159
       //                progress.Title = String.Format("Hashing {0:p} of {1}", stream.Position*1.0/stream.Length,
160
       //                                               info.Name);
161
       //                notification.Notify(progress);
162
       //            }
163
       //        } while (bytesRead > 0);               
164
       //        var hash = hasher.DigestFinal();
165

    
166
       //        progress.Title = String.Format("Hashed {0} ", info.Name);
167
       //        notification.Notify(progress);
168

    
169
       //        var hashString = hash.ToHashString();
170

    
171
       //        return hashString;
172
       //    }
173
       //}
174

    
175
/*
176
        public static async Task<string> ComputeShortHash(this FileInfo info, MD5BlockCalculator calculator,IStatusNotification notification)
177
       {
178
           if(info == null)
179
               throw new ArgumentNullException("info");
180
           if(calculator== null)
181
               throw new ArgumentNullException("calculator");
182
           Contract.EndContractBlock();
183
           info.Refresh();
184
           if (!info.Exists)
185
               return String.Empty;
186

    
187
           if (info.FullName.Split('/').Contains(".pithos.cache"))
188
               throw new ArgumentException(String.Format("Trying to hash file from the cache folder: [{0}]", info.FullName));
189

    
190
           if (Log.IsDebugEnabled)
191
                Log.DebugFormat("Short Hashing [{0}] ",info.FullName);
192

    
193
           if (info.Length == 0)
194
               return Signature.MD5_EMPTY;
195

    
196
           var progress = new StatusNotification("");
197

    
198
          
199

    
200
           using (var stream = new FileStream(info.FullName,FileMode.Open, FileAccess.Read, FileShare.Read,Signature.BufferSize))
201
           {
202
               int counter=0;
203
               int bytesRead;
204
               do
205
               {
206
                   var buffer = new byte[65536];
207
                   bytesRead = stream.Read(buffer, 0, 32768);
208
                   if (bytesRead > 0)
209
                   {
210
                       calculator.PostBlock(counter,buffer,bytesRead);
211
                   }
212
                   counter++;
213
                   if (counter % 100 == 0)
214
                   {
215
                       progress.Title = String.Format("Hashing {0:p} of {1}", stream.Position*1.0/stream.Length,
216
                                                      info.Name);
217
                       notification.Notify(progress);
218
                   }
219
               } while (bytesRead > 0);
220

    
221
               var hashString = await calculator.GetHash();
222
               
223

    
224
               progress.Title = String.Format("Hashed {0} ", info.Name);
225
               notification.Notify(progress);
226

    
227

    
228
               return hashString;
229
           }
230
       }
231
*/
232

    
233
       // public static string ComputeShortHash(this FileInfo info,IStatusNotification notification)
234
       //{
235
       //    if(info == null)
236
       //        throw new ArgumentNullException("info");
237
       //     Contract.EndContractBlock();
238
       //     if (info.FullName.Split('/').Contains(".pithos.cache"))
239
       //         throw new ArgumentException(String.Format("Trying to hash file from the cache folder: [{0}]", info.FullName));
240

    
241
       //    using (var hasher=new MessageDigestContext(MessageDigest.CreateByName("md5")))
242
       //    {               
243
       //        //hasher.Init();
244
       //        //return ComputeShortHash(info,hasher,notification);
245
       //        return null;
246
       //    }
247
       //}
248

    
249
    }
250
}