filechecksummer.h

Go to the documentation of this file.
00001 // This file is part of par2cmdline (a PAR 2.0 compatible file verification and
00002 // repair tool). See https://parchive.sourceforge.net for details of PAR 2.0.
00003 //
00004 // Copyright (c) 2003 Peter Brian Clements
00005 //
00006 // par2cmdline is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // par2cmdline is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with this program; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00019 
00020 #ifndef __FILECHECKSUMMER_H__
00021 #define __FILECHECKSUMMER_H__
00022 
00023 // This source file defines the FileCheckSummer object which is used
00024 // when scanning a data file to find blocks of undamaged data.
00025 //
00026 // The object uses a "window" into the data file and slides that window
00027 // along the file computing the CRC of the data in that window as it
00028 // goes. If the computed CRC matches the value for a block of data
00029 // from a target data file, then the MD5 Hash value is also computed
00030 // and compared with the value for that block of data. When a match
00031 // has been confirmed, the object jumps forward to where the next
00032 // block of data is expected to start. Whilst the file is being scanned
00033 // the object also computes the MD5 Hash of the whole file and of
00034 // the first 16k of the file for later tests.
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   // Start reading the file at the beginning
00046   bool Start(void);
00047 
00048   // Jump ahead the specified distance
00049   bool Jump(u64 distance);
00050 
00051   // Step forward one byte
00052   bool Step(void);
00053 
00054   // Return the current checksum
00055   u32 Checksum(void) const;
00056 
00057   // Compute and return the current hash
00058   MD5Hash Hash(void);
00059 
00060   // Compute short values of checksum and hash
00061   u32 ShortChecksum(u64 blocklength);
00062   MD5Hash ShortHash(u64 blocklength);
00063 
00064   // Do we have less than a full block of data
00065   bool ShortBlock(void) const;
00066   u64 BlockLength(void) const;
00067 
00068   // Return the current file offset
00069   u64 Offset(void) const;
00070 
00071   // Return the full file hash and the 16k file hash
00072   void GetFileHashes(MD5Hash &hashfull, MD5Hash &hash16k) const;
00073 
00074   // Which disk file is this
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; // file offset for current window position
00086   char       *buffer;        // buffer for reading from the file
00087   char       *outpointer;    // position in buffer of scan window
00088   char       *inpointer;     // &outpointer[blocksize];
00089   char       *tailpointer;   // after last valid data in buffer
00090 
00091   // File offset for next read
00092   u64         readoffset;
00093 
00094   // The current checksum
00095   u32         checksum;
00096 
00097   // MD5 hash of whole file and of first 16k
00098   MD5Context  contextfull;
00099   MD5Context  context16k;
00100 
00101 protected:
00102   //void ComputeCurrentCRC(void);
00103   void UpdateHashes(u64 offset, const void *buffer, size_t length);
00104 
00106   bool Fill(void);
00107 };
00108 
00109 // Return the current checksum
00110 
00111 inline u32 FileCheckSummer::Checksum(void) const
00112 {
00113   return checksum;
00114 }
00115 
00116 // Return the current block length
00117 
00118 inline u64 FileCheckSummer::BlockLength(void) const
00119 {
00120   return min(blocksize, filesize-currentoffset);
00121 }
00122 
00123 // Return whether or not the current block is a short one.
00124 inline bool FileCheckSummer::ShortBlock(void) const
00125 {
00126   return BlockLength() 00127 }
00128 
00129 // Return the current file offset
00130 inline u64 FileCheckSummer::Offset(void) const
00131 {
00132   return currentoffset;
00133 }
00134 
00135 // Step forward one byte
00136 inline bool FileCheckSummer::Step(void)
00137 {
00138   // Are we already at the end of the file
00139   if (currentoffset >= filesize)
00140     return false;
00141 
00142   // Advance the file offset and check to see if 
00143   // we have reached the end of the file
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   // Get the incoming and outgoing characters
00155   char inch = *inpointer++;
00156   char outch = *outpointer++;
00157 
00158   // Update the checksum
00159   checksum = windowmask ^ CRCSlideChar(windowmask ^ checksum, inch, outch, windowtable);
00160 
00161   // Can the window slide further
00162   if (outpointer 00163     return true;
00164 
00165   assert(outpointer == &buffer[blocksize]);
00166 
00167   // Copy the data back to the beginning of the buffer
00168   memmove(buffer, outpointer, (size_t)blocksize);
00169   inpointer = outpointer;
00170   outpointer = buffer;
00171   tailpointer -= blocksize;
00172 
00173   // Fill the rest of the buffer
00174   return Fill();
00175 }
00176 
00177 
00178 #endif // __FILECHECKSUMMER_H__

Generated on Sun Oct 12 01:45:29 2008 for NNTPGrab by  1.5.4