From 186990acc9a5fc3d2f83f340ac7e48026fa8e0bd Mon Sep 17 00:00:00 2001
From: Vojtech Moravec <vojtech.moravec.st@vsb.cz>
Date: Tue, 15 Dec 2020 14:45:00 +0100
Subject: [PATCH] Base prep for IQcmpFile abstraction.

---
 .../cz/it4i/qcmp/fileformat/IQcmpFile.java    |  9 ++
 .../java/cz/it4i/qcmp/io/QcmpFileReader.java  | 84 +++++++++++++++++++
 2 files changed, 93 insertions(+)
 create mode 100644 src/main/java/cz/it4i/qcmp/fileformat/IQcmpFile.java
 create mode 100644 src/main/java/cz/it4i/qcmp/io/QcmpFileReader.java

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 0000000..0713f17
--- /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 0000000..90e7905
--- /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;
+    }
+}
-- 
GitLab