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__