00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 #ifndef __FILECHECKSUMMER_H__
00021 #define __FILECHECKSUMMER_H__
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 class FileCheckSummer
00037 {
00038 public:
00039   FileCheckSummer(DiskFile   *diskfile,
00040                   u64         blocksize,
00041                   const u32 (&windowtable)[256],
00042                   u32         windowmask);
00043   ~FileCheckSummer(void);
00044 
00045   
00046   bool Start(void);
00047 
00048   
00049   bool Jump(u64 distance);
00050 
00051   
00052   bool Step(void);
00053 
00054   
00055   u32 Checksum(void) const;
00056 
00057   
00058   MD5Hash Hash(void);
00059 
00060   
00061   u32 ShortChecksum(u64 blocklength);
00062   MD5Hash ShortHash(u64 blocklength);
00063 
00064   
00065   bool ShortBlock(void) const;
00066   u64 BlockLength(void) const;
00067 
00068   
00069   u64 Offset(void) const;
00070 
00071   
00072   void GetFileHashes(MD5Hash &hashfull, MD5Hash &hash16k) const;
00073 
00074   
00075   const DiskFile* GetDiskFile(void) const {return diskfile;}
00076 
00077 protected:
00078   DiskFile   *diskfile;
00079   u64         blocksize;
00080   const u32 (&windowtable)[256];
00081   u32         windowmask;
00082 
00083   u64         filesize;
00084 
00085   u64         currentoffset; 
00086   char       *buffer;        
00087   char       *outpointer;    
00088   char       *inpointer;     
00089   char       *tailpointer;   
00090 
00091   
00092   u64         readoffset;
00093 
00094   
00095   u32         checksum;
00096 
00097   
00098   MD5Context  contextfull;
00099   MD5Context  context16k;
00100 
00101 protected:
00102   
00103   void UpdateHashes(u64 offset, const void *buffer, size_t length);
00104 
00106   bool Fill(void);
00107 };
00108 
00109 
00110 
00111 inline u32 FileCheckSummer::Checksum(void) const
00112 {
00113   return checksum;
00114 }
00115 
00116 
00117 
00118 inline u64 FileCheckSummer::BlockLength(void) const
00119 {
00120   return min(blocksize, filesize-currentoffset);
00121 }
00122 
00123 
00124 inline bool FileCheckSummer::ShortBlock(void) const
00125 {
00126   return BlockLength() 00127 }
00128 
00129 
00130 inline u64 FileCheckSummer::Offset(void) const
00131 {
00132   return currentoffset;
00133 }
00134 
00135 
00136 inline bool FileCheckSummer::Step(void)
00137 {
00138   
00139   if (currentoffset >= filesize)
00140     return false;
00141 
00142   
00143   
00144   if (++currentoffset >= filesize)
00145   {
00146     currentoffset = filesize;
00147     tailpointer = outpointer = buffer;
00148     memset(buffer, 0, (size_t)blocksize);
00149     checksum = 0;
00150 
00151     return true;
00152   }
00153 
00154   
00155   char inch = *inpointer++;
00156   char outch = *outpointer++;
00157 
00158   
00159   checksum = windowmask ^ CRCSlideChar(windowmask ^ checksum, inch, outch, windowtable);
00160 
00161   
00162   if (outpointer 00163     return true;
00164 
00165   assert(outpointer == &buffer[blocksize]);
00166 
00167   
00168   memmove(buffer, outpointer, (size_t)blocksize);
00169   inpointer = outpointer;
00170   outpointer = buffer;
00171   tailpointer -= blocksize;
00172 
00173   
00174   return Fill();
00175 }
00176 
00177 
00178 #endif // __FILECHECKSUMMER_H__