From d35ad18930c452869e9802088a4e4940604b1fdd Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 19 Sep 2023 16:08:47 +0200
Subject: [PATCH] ZipUtil ready

---
 Base/Util/PathUtil.cpp              |   2 +-
 Device/IO/IOFactory.cpp             | 117 ++--------------------------
 GUI/View/Import/DatafilesViewer.cpp |   2 +-
 GUI/View/Import/DatafilesViewer.h   |   2 +-
 PyCore/Embed/PyObjectPtr.cpp        |   2 +-
 PyCore/Sample/ImportMultiLayer.cpp  |   2 +-
 6 files changed, 12 insertions(+), 115 deletions(-)

diff --git a/Base/Util/PathUtil.cpp b/Base/Util/PathUtil.cpp
index 8f7847c6682..06928e5faeb 100644
--- a/Base/Util/PathUtil.cpp
+++ b/Base/Util/PathUtil.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      Base/Util/FileSystemUtil.cpp
+//! @file      Base/Util/PathUtil.cpp
 //! @brief     Implements namespace Base::Path
 //!
 //! @homepage  http://www.bornagainproject.org
diff --git a/Device/IO/IOFactory.cpp b/Device/IO/IOFactory.cpp
index 6d5e216602a..8fb3ed66d2e 100644
--- a/Device/IO/IOFactory.cpp
+++ b/Device/IO/IOFactory.cpp
@@ -14,8 +14,6 @@
 
 #include "Device/IO/IOFactory.h"
 #include "Base/Util/Assert.h"
-#include "Base/Util/PathUtil.h"
-#include "Base/Util/StringUtil.h"
 #include "Device/Data/Datafield.h"
 #include "Device/IO/DiffUtil.h"
 #include "Device/IO/ImportSettings.h"
@@ -26,118 +24,17 @@
 #include "Device/IO/ReadWriteNicos.h"
 #include "Device/IO/ReadWriteNumpyTXT.h"
 #include "Device/IO/ReadWriteTiff.h"
-#include "Device/IO/boost_streams.h"
+#include "Device/IO/ZipUtil.h"
 #include <algorithm>
 #include <cctype>
 #include <exception>
-#include <fstream>
-#include <iostream>
 #include <memory>
 #include <sstream>
 
-namespace {
-
-const std::string GzipExtension = ".gz";
-const std::string BzipExtension = ".bz2";
-
-bool isGZipped(const std::string& fname)
-{
-    return Base::Path::hasExtension(fname, GzipExtension);
-}
-
-bool isBZipped(const std::string& fname)
-{
-    return Base::Path::hasExtension(fname, BzipExtension);
-}
-
-bool isCompressed(const std::string& fname)
-{
-    return isGZipped(fname) || isBZipped(fname);
-}
-
-std::string uncompressedExtension(std::string fname)
-{
-    if (isGZipped(fname))
-        fname = fname.substr(0, fname.size() - GzipExtension.size());
-    else if (isBZipped(fname))
-        fname = fname.substr(0, fname.size() - BzipExtension.size());
-
-    return Base::String::to_lower(Base::Path::extension(fname));
-}
-
-bool isNativeBinary(const std::string& fname)
-{
-    const std::string ext = uncompressedExtension(fname);
-    return ext == ".tif" || ext == ".tiff";
-}
-
-bool isBinary(const std::string& fname)
-{
-    return isCompressed(fname) || isNativeBinary(fname);
-}
-
-std::stringstream file2stream(const std::string& fname)
-{
-    if (!Base::Path::IsFileExists(fname))
-        throw std::runtime_error("File does not exist: " + fname);
-
-    std::ifstream input_stream;
-    std::ios_base::openmode openmode = std::ios::in;
-    if (isBinary(fname))
-        openmode |= std::ios_base::binary;
-
-    input_stream.open(Base::Path::osPath(fname), openmode);
-
-    if (!input_stream.is_open())
-        throw std::runtime_error("Cannot open file for reading: " + fname);
-    if (!input_stream.good())
-        throw std::runtime_error("File is not good, probably it is a directory:" + fname);
-
-    boost::iostreams::filtering_streambuf<boost::iostreams::input> input_filtered;
-    if (::isGZipped(fname))
-        input_filtered.push(boost::iostreams::gzip_decompressor());
-    else if (::isBZipped(fname))
-        input_filtered.push(boost::iostreams::bzip2_decompressor());
-    input_filtered.push(input_stream);
-    // we use stringstream since it provides random access which is important for tiff files
-    std::stringstream ss;
-    boost::iostreams::copy(input_filtered, ss);
-
-    return ss;
-}
-
-void stream2file(const std::string& fname, std::stringstream& s)
-{
-    std::ofstream fout;
-    std::ios_base::openmode openmode = std::ios::out;
-    if (isBinary(fname))
-        openmode |= std::ios_base::binary;
-
-    fout.open(Base::Path::osPath(fname), openmode);
-
-    if (!fout.is_open())
-        throw std::runtime_error("Cannot open file for writing: " + fname);
-    if (!fout.good())
-        throw std::runtime_error("File is not good, probably it is a directory: " + fname);
-
-    boost::iostreams::filtering_streambuf<boost::iostreams::input> input_filtered;
-    if (::isGZipped(fname))
-        input_filtered.push(boost::iostreams::gzip_compressor());
-    else if (::isBZipped(fname))
-        input_filtered.push(boost::iostreams::bzip2_compressor());
-    input_filtered.push(s);
-
-    boost::iostreams::copy(input_filtered, fout);
-
-    fout.close();
-}
-
-} // namespace
-
 
 IO::Filetype1D IO::filename2type1D(const std::string& filename)
 {
-    const std::string ext = ::uncompressedExtension(filename);
+    const std::string ext = ZipUtil::uncompressedExtension(filename);
 
     if (ext == ".int")
         return bornagain1D;
@@ -148,7 +45,7 @@ IO::Filetype1D IO::filename2type1D(const std::string& filename)
 
 IO::Filetype2D IO::filename2type2D(const std::string& filename)
 {
-    const std::string ext = ::uncompressedExtension(filename);
+    const std::string ext = ZipUtil::uncompressedExtension(filename);
 
     if (ext == ".int")
         return bornagain2D;
@@ -165,7 +62,7 @@ Datafield* IO::readData1D(const std::string& fname, Filetype1D ftype,
     if (ftype == unknown1D)
         ftype = filename2type1D(fname);
 
-    std::stringstream s = ::file2stream(fname);
+    std::stringstream s = ZipUtil::file2stream(fname);
 
     if (ftype == csv1D) {
         if (!importSettings)
@@ -190,7 +87,7 @@ Datafield* IO::readData2D(const std::string& fname, Filetype2D ftype)
     if (ftype == unknown2D)
         ftype = filename2type2D(fname);
 
-    std::stringstream s = ::file2stream(fname);
+    std::stringstream s = ZipUtil::file2stream(fname);
 
     if (ftype == bornagain2D)
         return Util::RW::readBAInt(s);
@@ -214,7 +111,7 @@ Datafield* IO::readData2D(const std::string& fname, Filetype2D ftype)
 
 void IO::writeDatafield(const Datafield& data, const std::string& fname)
 {
-    const std::string ext = ::uncompressedExtension(fname);
+    const std::string ext = ZipUtil::uncompressedExtension(fname);
     try {
         std::stringstream s;
 
@@ -229,7 +126,7 @@ void IO::writeDatafield(const Datafield& data, const std::string& fname)
         else
             Util::RW::writeNumpyTxt(data, s);
 
-        ::stream2file(fname, s);
+        ZipUtil::stream2file(fname, s);
 
     } catch (const std::exception& ex) {
         throw std::runtime_error("Failed writing to " + fname + ": " + ex.what());
diff --git a/GUI/View/Import/DatafilesViewer.cpp b/GUI/View/Import/DatafilesViewer.cpp
index 3311c1400f3..0738ed5529c 100644
--- a/GUI/View/Import/DatafilesViewer.cpp
+++ b/GUI/View/Import/DatafilesViewer.cpp
@@ -7,7 +7,7 @@
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @copyright Forschungszentrum Jülich GmbH 2023
 //! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
 //
 //  ************************************************************************************************
diff --git a/GUI/View/Import/DatafilesViewer.h b/GUI/View/Import/DatafilesViewer.h
index 0c78ebac996..0f71e607f6a 100644
--- a/GUI/View/Import/DatafilesViewer.h
+++ b/GUI/View/Import/DatafilesViewer.h
@@ -7,7 +7,7 @@
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @copyright Forschungszentrum Jülich GmbH 2023
 //! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
 //
 //  ************************************************************************************************
diff --git a/PyCore/Embed/PyObjectPtr.cpp b/PyCore/Embed/PyObjectPtr.cpp
index 34363bcf4ce..8d7d937adcc 100644
--- a/PyCore/Embed/PyObjectPtr.cpp
+++ b/PyCore/Embed/PyObjectPtr.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      PyCore/Embed/PyObjectPtr.h
+//! @file      PyCore/Embed/PyObjectPtr.cpp
 //! @brief     Implements class PyObjectPtr
 //!
 //! @homepage  http://www.bornagainproject.org
diff --git a/PyCore/Sample/ImportMultiLayer.cpp b/PyCore/Sample/ImportMultiLayer.cpp
index 6a35d88beae..bed354b6125 100644
--- a/PyCore/Sample/ImportMultiLayer.cpp
+++ b/PyCore/Sample/ImportMultiLayer.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      PyCore/Sample/ImportMultiLayer.h
+//! @file      PyCore/Sample/ImportMultiLayer.cpp
 //! @brief     Implements createMultiLayerFromPython.
 //!
 //! @homepage  http://www.bornagainproject.org
-- 
GitLab