summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/imagemaster/crcchecker/CRCChecker.java
blob: 753809d0e7be877f23ba065e0b6f8f2fe2c2a7a1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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;

	/**
	 * 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!
	 * 
	 * @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
	 */
	public static List<Integer> checkCRC( String imageFile, String crcFile, List<Integer> blocks ) throws IOException
	{
		List<Integer> result = new LinkedList<>();

		ImageFile image = new ImageFile( imageFile, blockSize );
		CRCFile crc = new CRCFile( crcFile );

		log.debug( "Checking image file: '" + imageFile + "' with crc file: '" + crcFile + "'" );
		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)
		} catch ( IOException e ) {
			throw new IOException( "Could not read CRC file", e );
		}

		// 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 );
			}

			if ( block == null )
				continue; // some error occured (for example: someone tried to check a block that is not in the file)

			// check this block with CRC32
			// add this block to result, if check was ok with CRC file

			CRC32 crcCalc = new CRC32();
			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 );
			}

			if ( crcSum == crcSumFromFile )
				result.add( blockN );
			else
				log.debug( blockN + " was invalid" );
		}

		return result;
	}
}