/* * Copyright (c) 2012 Chris Ellison, Mike Deats, Liron Yahdav, Ryan Neal, * Brandon Sutherlin, Scott Griffin * * This software is released under the MIT license * (http://www.opensource.org/licenses/mit-license.php) * * Created on Apr 14, 2012 */ package edu.cmu.sv.arinc838.crc; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import edu.cmu.sv.arinc838.binary.BdfFile; import edu.cmu.sv.arinc838.dao.FileDefinitionDao; import edu.cmu.sv.arinc838.dao.IntegrityDefinitionDao; import edu.cmu.sv.arinc838.dao.IntegrityDefinitionDao.IntegrityType; import edu.cmu.sv.arinc838.dao.SoftwareDefinitionFileDao; public class CrcCalculator { public static byte[] calculateLspCrc(SoftwareDefinitionFileDao sdf, BdfFile bdf) throws IOException { int bdfLength = (int) bdf.readLspIntegrityDefinitionPointer() + 6; byte[] bdfData = new byte[bdfLength]; bdf.seek(0); bdf.read(bdfData); int length = bdfData.length; ArrayList<byte[]> fileDefData = new ArrayList<byte[]>(); for(FileDefinitionDao fileDef : sdf.getFileDefinitions()) { byte[] data = readFile(new File(sdf.getPath(), fileDef.getFileName())); length += data.length; fileDefData.add(data); } // TODO this algorithm is limited to files < 2GB byte[] fullData = new byte[length]; int offset = 0; for(byte[] data : fileDefData) { System.arraycopy(data, 0, fullData, offset, data.length); offset += data.length; } System.arraycopy(bdfData, 0, fullData, offset, bdfData.length); return calculateCrc(sdf.getLspIntegrityDefinition(), fullData); } public static byte[] calculateSdfCrc(SoftwareDefinitionFileDao sdf, BdfFile bdf) throws IOException { byte[] data = new byte[(int) bdf.readSdfIntegrityDefinitionPointer() + 6]; bdf.seek(0); bdf.read(data); return calculateCrc(sdf.getSdfIntegrityDefinition(), data); } public static byte[] readFile(File file) throws IOException { byte[] data = new byte[(int) file.length()]; DataInputStream dis = new DataInputStream(new FileInputStream(file)); dis.read(data); dis.close(); return data; } public static byte[] calculateCrc(IntegrityDefinitionDao integ, byte[] data) { IntegrityType type = IntegrityType.fromLong(integ.getIntegrityType()); ByteBuffer buffer = null; CrcGeneratorFactory factory = new CrcGeneratorFactory(); switch (type) { case CRC16: buffer = ByteBuffer.allocate(2); buffer.putShort((short) (factory.getCrc16Generator().calculateCrc(data) & 0xFFFFL)); break; case CRC32: buffer = ByteBuffer.allocate(4); buffer.putInt((int) (factory.getCrc32Generator().calculateCrc(data) & 0xFFFFFFFFL)); break; case CRC64: buffer = ByteBuffer.allocate(8); buffer.putLong(factory.getCrc64Generator().calculateCrc(data)); break; default: break; } return buffer.array(); } }