diff --git a/src/main/java/cz/it4i/qcmp/fileformat/IQcmpFile.java b/src/main/java/cz/it4i/qcmp/fileformat/IQcmpFile.java new file mode 100644 index 0000000000000000000000000000000000000000..0713f1757d0010acd0330fd7b47c3b67f7a8089a --- /dev/null +++ b/src/main/java/cz/it4i/qcmp/fileformat/IQcmpFile.java @@ -0,0 +1,9 @@ +package cz.it4i.qcmp.fileformat; + +import java.io.IOException; + +public interface IQcmpFile { + IFileHeader getHeader(); + + void convertToNewerVersion(final boolean inPlace, final String inputPath, final String outputPath) throws IOException; +} diff --git a/src/main/java/cz/it4i/qcmp/io/QcmpFileReader.java b/src/main/java/cz/it4i/qcmp/io/QcmpFileReader.java new file mode 100644 index 0000000000000000000000000000000000000000..90e7905d3bb57143383a2fdc842ae9977c62e700 --- /dev/null +++ b/src/main/java/cz/it4i/qcmp/io/QcmpFileReader.java @@ -0,0 +1,84 @@ +package cz.it4i.qcmp.io; + +import cz.it4i.qcmp.fileformat.IFileHeader; +import cz.it4i.qcmp.fileformat.IQcmpFile; +import cz.it4i.qcmp.fileformat.QCMPFileHeaderV1; +import cz.it4i.qcmp.fileformat.QCMPFileHeaderV2; + +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class QcmpFileReader { + private static final int QCMP_HEADER_MAGIC_VALUE_SIZE = 8; + + /** + * Read cache file from file. + * + * @param path File path. + * @return Cache file or null if reading fails. + */ + public static IQcmpFile readCacheFile(final String path) throws IOException { + try (final FileInputStream fis = new FileInputStream(path)) { + return readQcmpFile(fis); + } + } + + /** + * Make DataInputStream from InputStream. + * + * @param inputStream Some input stream. + * @return DataInputStream. + */ + private static DataInputStream asDataInputStream(final InputStream inputStream) { + if (inputStream instanceof DataInputStream) { + return (DataInputStream) inputStream; + } else { + return new DataInputStream(inputStream); + } + } + + + /** + * Create correct Qcmp header version by analyzing the magic value. + * + * @param magicValue Magic value of the qcmp file. + * @return Correct version of QCMP header. + * @throws IOException when the magic value is unknown. + */ + private static IFileHeader getCorrectQcmpHeader(final String magicValue) throws IOException { + switch (magicValue) { + case QCMPFileHeaderV1.MAGIC_VALUE: + return new QCMPFileHeaderV1(); + case QCMPFileHeaderV2.MAGIC_VALUE: + return new QCMPFileHeaderV2(); + default: + throw new IOException("Invalid QCMP file. Unknown QCMP magic value: " + magicValue); + } + } + + /** + * Read cache file by DataInputStream. + * + * @param inputStream Input stream. + * @return Cache file or null, if exception occurs. + */ + private static IQcmpFile readQcmpFile(final InputStream inputStream) throws IOException { + final DataInputStream dis = asDataInputStream(inputStream); + + final byte[] magicValueBuffer = new byte[QCMP_HEADER_MAGIC_VALUE_SIZE]; + RawDataIO.readFullBuffer(dis, magicValueBuffer); + final String magicValue = new String(magicValueBuffer); + + final IFileHeader header = getCorrectQcmpHeader(magicValue); + header.readFromStream(dis); + + assert ((header.getHeaderVersion() == 1 && header instanceof QCMPFileHeaderV1) || + header.getHeaderVersion() == 2 && header instanceof QCMPFileHeaderV2); + + + // TODO(Moravec): Create the IQcmpFile impl. Think about it! + return null; + } +}