/* * Copyright The National Archives 2005-2006. All rights reserved. * See Licence.txt for full licence details. * * Developed by: * Tessella Support Services plc * 3 Vineyard Chambers * Abingdon, OX14 3PX * United Kingdom * http://www.tessella.com * * Tessella/NPD/4305 * PRONOM 4 * * $Id: ByteSequence.java,v 1.7 2006/03/13 15:15:29 linb Exp $ * * $Log: ByteSequence.java,v $ * Revision 1.7 2006/03/13 15:15:29 linb * Changed copyright holder from Crown Copyright to The National Archives. * Added reference to licence.txt * Changed dates to 2005-2006 * * Revision 1.6 2006/02/09 15:04:37 gaur * Corrected formatting * * Revision 1.5 2006/02/08 16:14:01 gaur * Corrected error in merge * * Revision 1.4 2006/02/08 16:06:29 gaur * Moved endianness from internal signatures to byte sequences * * Revision 1.3 2006/02/07 17:16:22 linb * - Change fileReader to ByteReader in formal parameters of methods * - use new static constructors * - Add detection of if a filePath is a URL or not * * Revision 1.2 2006/02/07 11:30:04 gaur * Added support for endianness of signature * * * $History: ByteSequence.java $ * * ***************** Version 5 ***************** * User: Walm Date: 5/04/05 Time: 18:07 * Updated in $/PRONOM4/FFIT_SOURCE/signatureFile * review headers * */ package uk.gov.nationalarchives.droid.signatureFile; import java.util.ArrayList; import java.util.List; import uk.gov.nationalarchives.droid.MessageDisplay; import uk.gov.nationalarchives.droid.binFileReader.ByteReader; import uk.gov.nationalarchives.droid.xmlReader.SimpleElement; /** * holds details of a byte sequence * * @author Martin Waller * @version 4.0.0 */ public class ByteSequence extends SimpleElement { int parentSignature; List<SubSequence> subSequences = new ArrayList<SubSequence>(); String reference = ""; boolean bigEndian = true; // Assume a signature is big-endian unless we are told to the contrary. int indirectOffsetLength = 0; int indirectOffsetLocation = 0; //int MaxOffset = 0; /* setters */ public int getIndirectOffsetLength() { return indirectOffsetLength; } public int getIndirectOffsetLocation() { return indirectOffsetLocation; } public int getParentSignature() { return parentSignature; } public void setParentSignature(int parentSignature) { this.parentSignature = parentSignature; } public void addSubSequence(SubSequence sseq) { subSequences.add(sseq); } public void setSubSequences(List<SubSequence> SubSequences) { this.subSequences = SubSequences; } public void setReference(String theRef) { this.reference = theRef; } public void setEndianness(String endianness) { this.bigEndian = !endianness.equals("Little-endian"); } public void setIndirectOffsetLength(String indirectOffsetLength) { this.indirectOffsetLength = Integer.parseInt(indirectOffsetLength); } public void setIndirectOffsetLocation(String indirectOffsetLocation) { this.indirectOffsetLocation = Integer.parseInt(indirectOffsetLocation); } public boolean isBigEndian() { return bigEndian; } //public void setMaxOffset( String theMaxOffset ) { this.MaxOffset = Integer.parseInt(theMaxOffset); } public void setAttributeValue(String name, String value) { if (name.equals("Reference")) { setReference(value); } else if (name.equals("Endianness")) { setEndianness(value); } else if (name.equals("IndirectOffsetLength")) { setIndirectOffsetLength(value); } else if (name.equals("IndirectOffsetLocation")) { setIndirectOffsetLocation(value); } else { MessageDisplay.unknownAttributeWarning(name, this.getElementName()); } } /** * is this byte sequence anchored to either * BOF or EOF * * @return */ public boolean isAnchored() { return getReference().endsWith("EOFoffset") || getReference().endsWith("BOFoffset"); } /* getters */ public List getSubSequences() { return subSequences; } public int getNumSubSequences() { return subSequences.size(); } public SubSequence getSubSequence(int theIndex) { return (SubSequence) subSequences.get(theIndex); } public String getReference() { return reference; } //public int getMaxOffset() { return MaxOffset; } /** * checks whether the binary file specified by targetFile is compliant * with this byte sequence * * @param targetFile The binary file to be identified * @return boolean */ public boolean isFileCompliant(ByteReader targetFile) { //System.out.println("Looking at new byte sequence with reference "+Reference); //initialise variables and start with the file marker at the beginning of the file boolean isCompliant = true; boolean reverseOrder = (getReference().equalsIgnoreCase("EOFoffset")); int ssLoopStart = reverseOrder ? getNumSubSequences() - 1 : 0; int ssLoopEnd = reverseOrder ? -1 : getNumSubSequences(); int searchDirection = reverseOrder ? -1 : 1; if (reverseOrder) { targetFile.setFileMarker(targetFile.getNumBytes() - 1L); } else { targetFile.setFileMarker(0L); } //check whether each subsequence in turn is compliant for (int iSS = ssLoopStart; (searchDirection * iSS < searchDirection * ssLoopEnd) & isCompliant; iSS += searchDirection) { boolean isFixedStart = getReference().endsWith("EOFoffset") || getReference().endsWith("BOFoffset"); if ((iSS == ssLoopStart) && (isFixedStart)) { isCompliant = getSubSequence(iSS).isFoundAtStartOfFile(targetFile, reverseOrder, bigEndian); //, MaxOffset); } else { isCompliant = getSubSequence(iSS).isFoundAfterFileMarker(targetFile, reverseOrder, bigEndian); } } return isCompliant; } public String toString() { return reference + "{" + subSequences + "}"; } }