diff options
author | Nils Schwabe | 2014-07-11 16:29:22 +0200 |
---|---|---|
committer | Nils Schwabe | 2014-07-11 16:29:22 +0200 |
commit | 17609bc347e11117de0e0644209eeae3bf18a1ff (patch) | |
tree | ab28d49db821411b27f1614f527a5dd2c79190f4 /src/main/java/org/openslx/imagemaster/crcchecker | |
parent | Merge branch 'master' of git.openslx.org:bwlp/master-sync-shared (diff) | |
download | master-sync-shared-17609bc347e11117de0e0644209eeae3bf18a1ff.tar.gz master-sync-shared-17609bc347e11117de0e0644209eeae3bf18a1ff.tar.xz master-sync-shared-17609bc347e11117de0e0644209eeae3bf18a1ff.zip |
Fix some todos (new errors, ...)
Diffstat (limited to 'src/main/java/org/openslx/imagemaster/crcchecker')
3 files changed, 113 insertions, 81 deletions
diff --git a/src/main/java/org/openslx/imagemaster/crcchecker/CRCChecker.java b/src/main/java/org/openslx/imagemaster/crcchecker/CRCChecker.java index 753809d..b7f288e 100644 --- a/src/main/java/org/openslx/imagemaster/crcchecker/CRCChecker.java +++ b/src/main/java/org/openslx/imagemaster/crcchecker/CRCChecker.java @@ -1,75 +1,79 @@ package org.openslx.imagemaster.crcchecker; import java.io.IOException; -import java.util.LinkedList; -import java.util.List; import java.util.zip.CRC32; -import org.apache.log4j.Logger; - public class CRCChecker { - - private static Logger log = Logger.getLogger( CRCChecker.class ); private static final int blockSize = 16 * 1024 * 1024; + private ImageFile imageFile; + private CRCFile crcFile; + + private byte[] block = new byte[ blockSize ]; // array that is used to read the blocks + /** - * Checks the CRC sum of given blocks of a given imageFile against a given crcFile. - * The caller needs to make sure that block that are going to be checked are complete! + * Initialize a crc checker with an image file and a crc file. * - * @param imageFile The imageFile to check - * @param crcFile The crcFile to check against - * @param blocks The blocks to check - * @return List of blocks where the crc matches, or null if the crc file is corrupted - * @throws IOException When crc file could not be read + * @param imageFile The image file to check + * @param crcFile The crc file to check against */ - public static List<Integer> checkCRC( String imageFile, String crcFile, List<Integer> blocks ) throws IOException + public CRCChecker( String imageFilename, String crcFilename ) { - List<Integer> result = new LinkedList<>(); + this.imageFile = new ImageFile( imageFilename, blockSize ); + } - ImageFile image = new ImageFile( imageFile, blockSize ); - CRCFile crc = new CRCFile( crcFile ); + public void done() + { + imageFile.close(); + } - log.debug( "Checking image file: '" + imageFile + "' with crc file: '" + crcFile + "'" ); + public boolean hasValidCrcFile() + { try { - if ( !crc.isValid() ) - return null; - // TODO: also return null if the crc file contains the wrong number of checksums (only makes sense if the upload is complete) + return crcFile.isValid(); } catch ( IOException e ) { - throw new IOException( "Could not read CRC file", e ); + return false; } + } - // check all blocks - byte[] block = new byte[blockSize]; - for ( Integer blockN : blocks ) { - try { - image.getBlock( blockN, block ); - } catch ( IOException e ) { - throw new IOException( "Could not read image file", e ); - } + /** + * Checks a chosen block against the crc file. + * + * @param block The block to check + * @return Whether the block was valid or not + * @throws IOException When image or crc file could not be read. + */ + public boolean checkBlock( int blockNumber ) throws IOException + { + if ( !this.hasValidCrcFile() ) + return false; - if ( block == null ) - continue; // some error occured (for example: someone tried to check a block that is not in the file) + int length; + try { + length = imageFile.getBlock( blockNumber, block ); + } catch ( IOException e ) { + throw new IOException( "Could not read image file", e ); + } - // check this block with CRC32 - // add this block to result, if check was ok with CRC file + if ( length <= 0 ) + return false; - CRC32 crcCalc = new CRC32(); + CRC32 crcCalc = new CRC32(); + if ( length == blockSize ) { crcCalc.update( block ); - int crcSum = Integer.reverseBytes( (int)crcCalc.getValue() ); - int crcSumFromFile; - try { - crcSumFromFile = crc.getCRCSum( blockN ); - } catch ( IOException e ) { - throw new IOException( "Could not read CRC file", e ); - } + } else { + crcCalc.update( block, 0, length ); + } - if ( crcSum == crcSumFromFile ) - result.add( blockN ); - else - log.debug( blockN + " was invalid" ); + int crcSum = Integer.reverseBytes( (int)crcCalc.getValue() ); + int crcSumFromFile; + try { + crcSumFromFile = crcFile.getCRCSum( blockNumber ); + } catch ( IOException e ) { + throw new IOException( "Could not read CRC file", e ); } - return result; + return ( crcSum == crcSumFromFile ); } } diff --git a/src/main/java/org/openslx/imagemaster/crcchecker/CRCFile.java b/src/main/java/org/openslx/imagemaster/crcchecker/CRCFile.java index 49c909d..7d059fc 100644 --- a/src/main/java/org/openslx/imagemaster/crcchecker/CRCFile.java +++ b/src/main/java/org/openslx/imagemaster/crcchecker/CRCFile.java @@ -11,10 +11,7 @@ import java.util.List; import java.util.zip.CRC32; /** - * Represents a crcfile - * - * @author nils - * + * Represents a crc file */ public class CRCFile { @@ -46,7 +43,7 @@ public class CRCFile DataOutputStream dos = new DataOutputStream( fos ); for ( Integer sum : listOfCrcSums ) { - dos.writeInt( Integer.reverseBytes( sum.intValue() ) ); // save byte-reversed integers to match right order in crc file + dos.writeInt( sum.intValue() ); // save byte-reversed integers to match right order in crc file TODO: is that right? } dos.close(); @@ -54,6 +51,23 @@ public class CRCFile } /** + * Checks if given sums are valid. + * @param listOfCrcSums + * @return + */ + public static boolean sumsAreValid( List<Integer> listOfCrcSums ) + { + byte[] bytes = new byte[ ( listOfCrcSums.size() - 1 ) * Integer.SIZE / 8 ]; + int masterSum = listOfCrcSums.remove( 0 ); + for ( int i = 0; i < bytes.length; i++ ) { + bytes[i] = listOfCrcSums.remove( 0 ).byteValue(); + } + CRC32 crcCalc = new CRC32(); + crcCalc.update( bytes ); + return ( masterSum == Integer.reverseBytes( (int)crcCalc.getValue() ) ); + } + + /** * Checks if this crc file is valid. * (If the crc over the file is equal to the first crc sum.) * @@ -90,7 +104,8 @@ public class CRCFile */ public int getCRCSum( int blockNumber ) throws IOException { - if (crcSums == null) loadSums(); + if ( crcSums == null ) + loadSums(); if ( blockNumber < 0 ) return 0; @@ -99,17 +114,20 @@ public class CRCFile return crcSums.get( blockNumber ); } - + /** * Returns the loaded crcSums. + * * @return The loaded crcSums * @throws IOException If the crcSums could not be loaded from file */ - public List<Integer> getCrcSums() throws IOException { - if (crcSums == null) loadSums(); + public List<Integer> getCrcSums() throws IOException + { + if ( crcSums == null ) + loadSums(); return this.crcSums; } - + private void loadSums() throws IOException { // the crcSums were not read yet diff --git a/src/main/java/org/openslx/imagemaster/crcchecker/ImageFile.java b/src/main/java/org/openslx/imagemaster/crcchecker/ImageFile.java index cb8c700..13bb0fd 100644 --- a/src/main/java/org/openslx/imagemaster/crcchecker/ImageFile.java +++ b/src/main/java/org/openslx/imagemaster/crcchecker/ImageFile.java @@ -7,51 +7,61 @@ import java.io.RandomAccessFile; /** * Representing an image file. * Is able to return certain blocks of this file. + * * @author nils - * + * */ public class ImageFile { private File f; private RandomAccessFile file = null; private int blockSize; - - public ImageFile(String filename, int blockSize) { + + public ImageFile( String filename, int blockSize ) + { this.f = new File( filename ); this.blockSize = blockSize; } - + /** * Get a certain block (uses RandomAccessFile) * If the last block is not full an array with a smaller size is set * and the actual number of bytes is returned. + * * @param block The number of the block you want to get - * @return The actual size of the array or 0 if the block number is < 0 or the block is not in the file + * @return The actual number of read bytes or -1 if nothing was read. * @throws IOException When file was not found or could not be read */ - public int getBlock(int block, byte[] array) throws IOException { - if (block < 0) return 0; - if (block > f.length()/blockSize) return 0; - - if (file == null) { + public int getBlock( int block, byte[] array ) throws IOException + { + if ( block < 0 ) + return 0; + if ( block > f.length() / blockSize ) + return 0; + + if ( file == null ) { file = new RandomAccessFile( f, "r" ); } - + file.seek( (long)block * blockSize ); - long remaining = length() - (block * blockSize); - if (blockSize > remaining) { - array = new byte[(int)remaining]; // only read available bytes - file.read( array ); - return (int)remaining; // return actual size of array - } else { - // size of array is ok, read the full array and return block size - file.read( array ); - return this.blockSize; - } + return file.read( array ); } - - public long length() { + + public long length() + { return f.length(); } -}
\ No newline at end of file + + /** + * Closes the file. + * It's not a problem to use getBlock() again. The file will then be re-opened. + */ + public void close() + { + try { + file.close(); + file = null; + } catch ( IOException e ) {/* Can't do anything about it.*/} + } +} |