/*
* BioJava development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public Licence. This should
* be distributed with the code. If you do not have a copy,
* see:
*
* http://www.gnu.org/copyleft/lesser.html
*
* Copyright for this code is held jointly by the individual
* authors. These should be listed in @author doc comments.
*
* For more information on the BioJava project and its aims,
* or to join the biojava-l mailing list, visit the home page
* at:
*
* http://www.biojava.org/
*
*/
package org.biojava.bio.chromatogram;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.biojava.bio.program.abi.ABIFChromatogram;
import org.biojava.bio.program.scf.SCF;
import org.biojava.utils.io.CachingInputStream;
/**
* A factory that creates {@link Chromatogram} objects from files or streams.
* In either case, the type of object to create is determined from the first
* four bytes of the stream (the magic number).
*
* @author Rhett Sutphin (UI CBCB)
* @author Matthew Pocock
* @since 1.3
*/
public class ChromatogramFactory {
/**
* The magic number for SCF files.
*/
public static final int SCF_MAGIC = (((byte) '.') << 24)
+ (((byte) 's') << 16)
+ (((byte) 'c') << 8)
+ (((byte) 'f'));
/**
* The magic number for ABIF files.
*/
public static final int ABI_MAGIC = (((byte) 'A') << 24)
+ (((byte) 'B') << 16)
+ (((byte) 'I') << 8)
+ (((byte) 'F'));
/**
* Creates a new Chromatogram
object from the named file.
* @param f the file to read
* @return a new Chromatogram
*
* @throws IOException when the file can't be read or some other I/O error occurs
* @throws UnsupportedChromatogramFormatException when the file doesn't
* contain a chromatogram in a supported format
*/
public static Chromatogram create(File f)
throws IOException, UnsupportedChromatogramFormatException {
FileInputStream fin = new FileInputStream(f);
int magic = magicFromStream(fin);
fin.close();
switch (magic) {
case SCF_MAGIC:
return SCF.create(f);
case ABI_MAGIC:
return ABIFChromatogram.create(f);
default:
throw new UnsupportedChromatogramFormatException("File "+f+" with magic "+magic+" has an unsupported format");
}
}
/**
* Creates a new Chromatogram
object from the supplied stream.
* Note that for some chromatogram formats, this can be much more
* memory-intensive than reading from a file.
*
* Note also that if the provided stream is a
* {@link org.biojava.utils.io.CachingInputStream}, it will be seeked
* back to 0 before being passed to the parser. This is because the
* parsers that use CachingInputStream
assume that the
* "file" starts at 0.
*
* This assumes the magic array has at least 4 elements. *
* * @param magic the byte array of magic values * @return the magic number integer */ private static int makeMagic(byte[] magic) { return (magic[0] << 24) | (magic[1] << 16) | (magic[2] << 8) | (magic[3]); } /** * Reads the next four bytes from a stream to build a 32-bit magic number. * * @param src the source InputStream * @return an integer representing the magic number * @throws IOException if data could not be read from src */ private static int magicFromStream(InputStream src) throws IOException { byte[] magicBytes = new byte[4]; src.read(magicBytes); return makeMagic(magicBytes); } }