From dc7e75b522f6d1721ec1bd07a5a726c986ae9395 Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Thu, 14 Mar 2019 19:07:16 +0100
Subject: [PATCH 1/5] Miniz zipping seems to work.

---
 src/libslic3r/CMakeLists.txt                |  2 +
 src/libslic3r/PrintExport.hpp               |  2 +-
 src/libslic3r/SLAPrint.hpp                  | 31 +++++++++-
 src/libslic3r/Zipper.cpp                    | 68 +++++++++++++++++++++
 src/libslic3r/Zipper.hpp                    | 51 ++++++++++++++++
 src/slic3r/GUI/BackgroundSlicingProcess.cpp | 10 +--
 6 files changed, 158 insertions(+), 6 deletions(-)
 create mode 100644 src/libslic3r/Zipper.cpp
 create mode 100644 src/libslic3r/Zipper.hpp

diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt
index 2502c1b3e..6ab5dad76 100644
--- a/src/libslic3r/CMakeLists.txt
+++ b/src/libslic3r/CMakeLists.txt
@@ -161,6 +161,8 @@ add_library(libslic3r STATIC
     utils.cpp
     Utils.hpp
     MTUtils.hpp
+    Zipper.hpp
+    Zipper.cpp
     SLA/SLABoilerPlate.hpp
     SLA/SLABasePool.hpp
     SLA/SLABasePool.cpp
diff --git a/src/libslic3r/PrintExport.hpp b/src/libslic3r/PrintExport.hpp
index df9446cf5..99a2110b3 100644
--- a/src/libslic3r/PrintExport.hpp
+++ b/src/libslic3r/PrintExport.hpp
@@ -97,7 +97,7 @@ public:
 
     bool is_ok() { return false; }
 
-    template<class T> LayerWriter& operator<<(const T& /*arg*/) {
+    template<class T> LayerWriter& operator<<(T&& /*arg*/) {
         return *this;
     }
 
diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp
index eb927c769..a8f35a406 100644
--- a/src/libslic3r/SLAPrint.hpp
+++ b/src/libslic3r/SLAPrint.hpp
@@ -6,6 +6,7 @@
 #include "PrintExport.hpp"
 #include "Point.hpp"
 #include "MTUtils.hpp"
+#include "Zipper.hpp"
 
 namespace Slic3r {
 
@@ -200,6 +201,32 @@ struct SLAPrintStatistics
     }
 };
 
+struct SLAminzFmt {};
+
+// The implementation of creating zipped archives with wxWidgets
+template<> class LayerWriter<SLAminzFmt> {
+    Zipper m_zip;
+public:
+
+    inline LayerWriter(const std::string& zipfile_path): m_zip(zipfile_path) {}
+
+    inline void next_entry(const std::string& fname) { m_zip.add_entry(fname); }
+
+    inline std::string get_name() const {
+        return m_zip.get_name();
+    }
+
+    template<class T> inline LayerWriter& operator<<(T&& arg) {
+        m_zip << std::forward<T>(arg); return *this;
+    }
+
+    bool is_ok() const {
+        return true; // m_zip blows up if something goes wrong...
+    }
+
+    inline void close() { /* m_zip closes upon destruction */ }
+};
+
 /**
  * @brief This class is the high level FSM for the SLA printing process.
  *
@@ -231,9 +258,11 @@ public:
     // Returns true if the last step was finished with success.
 	bool                finished() const override { return this->is_step_done(slaposIndexSlices) && this->Inherited::is_step_done(slapsRasterize); }
 
-    template<class Fmt> void export_raster(const std::string& fname) {
+    template<class Fmt = SLAminzFmt>
+    void export_raster(const std::string& fname) {
         if(m_printer) m_printer->save<Fmt>(fname);
     }
+
     const PrintObjects& objects() const { return m_objects; }
 
 	std::string         output_filename() const override;
diff --git a/src/libslic3r/Zipper.cpp b/src/libslic3r/Zipper.cpp
new file mode 100644
index 000000000..2dd91c616
--- /dev/null
+++ b/src/libslic3r/Zipper.cpp
@@ -0,0 +1,68 @@
+#include <exception>
+#include <sstream>
+#include <iostream>
+
+#include "Zipper.hpp"
+#include "miniz/miniz_zip.h"
+#include <boost/filesystem/path.hpp>
+
+namespace Slic3r {
+
+class Zipper::Impl {
+public:
+    mz_zip_archive arch;
+};
+
+Zipper::Zipper(const std::string &zipfname, e_compression compression)
+{
+    m_impl.reset(new Impl());
+
+    memset(&m_impl->arch, 0, sizeof(m_impl->arch));
+
+    // Initialize the archive data
+    if(!mz_zip_writer_init_file(&m_impl->arch, zipfname.c_str(), 0))
+        throw std::runtime_error("Cannot open zip archive!");
+
+    m_compression = compression;
+    m_zipname = zipfname;
+}
+
+Zipper::~Zipper()
+{
+    finish_entry();
+    mz_zip_writer_finalize_archive(&m_impl->arch);
+    mz_zip_writer_end(&m_impl->arch);
+}
+
+void Zipper::add_entry(const std::string &name)
+{
+    finish_entry(); // finish previous business
+    m_entry = name;
+}
+
+void Zipper::finish_entry()
+{
+    if(!m_data.empty() > 0 && !m_entry.empty()) {
+        mz_uint compression = MZ_NO_COMPRESSION;
+
+        switch (m_compression) {
+        case NO_COMPRESSION: compression = MZ_NO_COMPRESSION; break;
+        case FAST_COMPRESSION: compression = MZ_BEST_SPEED; break;
+        case TIGHT_COMPRESSION: compression = MZ_BEST_COMPRESSION; break;
+        }
+
+        mz_zip_writer_add_mem(&m_impl->arch, m_entry.c_str(),
+                              m_data.c_str(),
+                              m_data.size(),
+                              compression);
+    }
+
+    m_data.clear();
+    m_entry.clear();
+}
+
+std::string Zipper::get_name() const {
+    return boost::filesystem::path(m_zipname).stem().string();
+}
+
+}
diff --git a/src/libslic3r/Zipper.hpp b/src/libslic3r/Zipper.hpp
new file mode 100644
index 000000000..d83e33e6b
--- /dev/null
+++ b/src/libslic3r/Zipper.hpp
@@ -0,0 +1,51 @@
+#ifndef ZIPPER_HPP
+#define ZIPPER_HPP
+
+#include <string>
+#include <memory>
+
+namespace Slic3r {
+
+class Zipper {
+public:
+    enum e_compression {
+        NO_COMPRESSION,
+        FAST_COMPRESSION,
+        TIGHT_COMPRESSION
+    };
+
+private:
+    class Impl;
+    std::unique_ptr<Impl> m_impl;
+    std::string m_data;
+    std::string m_entry;
+    e_compression m_compression;
+    std::string m_zipname;
+
+public:
+
+    // Will blow up in a runtime exception if the file cannot be created.
+    explicit Zipper(const std::string& zipfname,
+                    e_compression level = NO_COMPRESSION);
+    ~Zipper();
+
+    Zipper(const Zipper&) = delete;
+    Zipper& operator=(const Zipper&) = delete;
+
+    Zipper(Zipper&&) = default;
+    Zipper& operator=(Zipper&&) = default;
+
+    void add_entry(const std::string& name);
+    void finish_entry();
+
+    inline Zipper& operator<<(const std::string& content) {
+        std::copy(content.begin(), content.end(), std::back_inserter(m_data));
+        return *this;
+    }
+
+    std::string get_name() const;
+};
+
+}
+
+#endif // ZIPPER_HPP
diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
index 7c2f6c68c..2ba1d6cdc 100644
--- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp
+++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
@@ -129,8 +129,8 @@ public:
         return fpath.GetName().ToUTF8().data();
     }
 
-    template<class T> inline LayerWriter& operator<<(const T& arg) {
-        pngstream << arg; return *this;
+    template<class T> inline LayerWriter& operator<<(T&& arg) {
+        pngstream << std::forward<T>(arg); return *this;
     }
 
     bool is_ok() const {
@@ -149,7 +149,8 @@ void BackgroundSlicingProcess::process_sla()
     m_print->process();
     if (this->set_step_started(bspsGCodeFinalize)) {
         if (! m_export_path.empty()) {
-            m_sla_print->export_raster<SLAZipFmt>(m_export_path);
+            // m_sla_print->export_raster<SLAZipFmt>(m_export_path);
+            m_sla_print->export_raster<SLAminzFmt>(m_export_path);
             m_print->set_status(100, "Masked SLA file exported to " + m_export_path);
         } else if (! m_upload_job.empty()) {
             prepare_upload();
@@ -450,7 +451,8 @@ void BackgroundSlicingProcess::prepare_upload()
 		run_post_process_scripts(source_path.string(), m_fff_print->config());
 		m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());
 	} else {
-		m_sla_print->export_raster<SLAZipFmt>(source_path.string());
+        // m_sla_print->export_raster<SLAZipFmt>(source_path.string());
+        m_sla_print->export_raster<SLAminzFmt>(source_path.string());
 		// TODO: Also finalize upload path like with FFF when there are statistics for SLA print
 	}
 

From 4643106be4fab4f9a88e17ff88ea63a789d7a47d Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Fri, 15 Mar 2019 11:23:27 +0100
Subject: [PATCH 2/5] Zipper made universally usable and documented.

---
 src/libslic3r/Zipper.hpp | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/libslic3r/Zipper.hpp b/src/libslic3r/Zipper.hpp
index d83e33e6b..685303955 100644
--- a/src/libslic3r/Zipper.hpp
+++ b/src/libslic3r/Zipper.hpp
@@ -6,8 +6,10 @@
 
 namespace Slic3r {
 
+// Class for creating zip archives.
 class Zipper {
 public:
+    // Three compression levels supported
     enum e_compression {
         NO_COMPRESSION,
         FAST_COMPRESSION,
@@ -29,23 +31,47 @@ public:
                     e_compression level = NO_COMPRESSION);
     ~Zipper();
 
+    // No copies allwed, this is a file resource...
     Zipper(const Zipper&) = delete;
     Zipper& operator=(const Zipper&) = delete;
 
+    // Moving is fine.
     Zipper(Zipper&&) = default;
     Zipper& operator=(Zipper&&) = default;
 
+    /// Adding an entry means a file inside the new archive. Name param is the
+    /// name of the new file. To create directories, append a forward slash.
     void add_entry(const std::string& name);
-    void finish_entry();
 
-    inline Zipper& operator<<(const std::string& content) {
-        std::copy(content.begin(), content.end(), std::back_inserter(m_data));
+    // Writing data to the archive works like with standard streams. The target
+    // within the zip file is the entry created with the add_entry method.
+
+    // Template taking only arithmetic values, that std::to_string can handle.
+    template<class T> inline
+    typename std::enable_if<std::is_arithmetic<T>::value, Zipper&>::type
+    operator<<(T &&val) {
+        return this->operator<<(std::to_string(std::forward<T>(val)));
+    }
+
+    // Template applied only for types that std::string can handle for append
+    // and copy. This includes c style strings...
+    template<class T> inline
+    typename std::enable_if<!std::is_arithmetic<T>::value, Zipper&>::type
+    operator<<(T &&val) {
+        if(m_data.empty()) m_data = std::forward<T>(val);
+        else m_data.append(val);
         return *this;
     }
 
+    /// Finishing an entry means that subsequent writes will no longer be
+    /// appended to the previous entry.
+    void finish_entry();
+
+    /// Gets the name of the archive without the path or extension.
     std::string get_name() const;
 };
 
+
 }
 
 #endif // ZIPPER_HPP

From 4f1a10c0f8d7e3bd2b55c08d760502e2a326d21b Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Fri, 15 Mar 2019 12:16:05 +0100
Subject: [PATCH 3/5] Error handling and more comments for Zipper.

---
 src/libslic3r/SLAPrint.hpp                  |   6 +-
 src/libslic3r/Zipper.cpp                    | 116 ++++++++++++++++++--
 src/libslic3r/Zipper.hpp                    |  13 ++-
 src/slic3r/GUI/BackgroundSlicingProcess.cpp |   8 +-
 4 files changed, 126 insertions(+), 17 deletions(-)

diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp
index a8f35a406..931c87d79 100644
--- a/src/libslic3r/SLAPrint.hpp
+++ b/src/libslic3r/SLAPrint.hpp
@@ -201,10 +201,10 @@ struct SLAPrintStatistics
     }
 };
 
-struct SLAminzFmt {};
+struct SLAminzZipper {};
 
 // The implementation of creating zipped archives with wxWidgets
-template<> class LayerWriter<SLAminzFmt> {
+template<> class LayerWriter<SLAminzZipper> {
     Zipper m_zip;
 public:
 
@@ -258,7 +258,7 @@ public:
     // Returns true if the last step was finished with success.
 	bool                finished() const override { return this->is_step_done(slaposIndexSlices) && this->Inherited::is_step_done(slapsRasterize); }
 
-    template<class Fmt = SLAminzFmt>
+    template<class Fmt = SLAminzZipper>
     void export_raster(const std::string& fname) {
         if(m_printer) m_printer->save<Fmt>(fname);
     }
diff --git a/src/libslic3r/Zipper.cpp b/src/libslic3r/Zipper.cpp
index 2dd91c616..5a412bcf4 100644
--- a/src/libslic3r/Zipper.cpp
+++ b/src/libslic3r/Zipper.cpp
@@ -6,11 +6,96 @@
 #include "miniz/miniz_zip.h"
 #include <boost/filesystem/path.hpp>
 
+#include "I18N.hpp"
+
+//! macro used to mark string used at localization,
+//! return same string
+#define L(s) Slic3r::I18N::translate(s)
+
 namespace Slic3r {
 
 class Zipper::Impl {
 public:
     mz_zip_archive arch;
+
+    std::string get_errorstr(mz_zip_error mz_err)
+    {
+        switch (mz_err)
+        {
+            case MZ_ZIP_NO_ERROR:
+                return "no error";
+            case MZ_ZIP_UNDEFINED_ERROR:
+                return L("undefined error");
+            case MZ_ZIP_TOO_MANY_FILES:
+                return L("too many files");
+            case MZ_ZIP_FILE_TOO_LARGE:
+                return L("file too large");
+            case MZ_ZIP_UNSUPPORTED_METHOD:
+                return L("unsupported method");
+            case MZ_ZIP_UNSUPPORTED_ENCRYPTION:
+                return L("unsupported encryption");
+            case MZ_ZIP_UNSUPPORTED_FEATURE:
+                return L("unsupported feature");
+            case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR:
+                return L("failed finding central directory");
+            case MZ_ZIP_NOT_AN_ARCHIVE:
+                return L("not a ZIP archive");
+            case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED:
+                return L("invalid header or archive is corrupted");
+            case MZ_ZIP_UNSUPPORTED_MULTIDISK:
+                return L("unsupported multidisk archive");
+            case MZ_ZIP_DECOMPRESSION_FAILED:
+                return L("decompression failed or archive is corrupted");
+            case MZ_ZIP_COMPRESSION_FAILED:
+                return L("compression failed");
+            case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE:
+                return L("unexpected decompressed size");
+            case MZ_ZIP_CRC_CHECK_FAILED:
+                return L("CRC-32 check failed");
+            case MZ_ZIP_UNSUPPORTED_CDIR_SIZE:
+                return L("unsupported central directory size");
+            case MZ_ZIP_ALLOC_FAILED:
+                return L("allocation failed");
+            case MZ_ZIP_FILE_OPEN_FAILED:
+                return L("file open failed");
+            case MZ_ZIP_FILE_CREATE_FAILED:
+                return L("file create failed");
+            case MZ_ZIP_FILE_WRITE_FAILED:
+                return L("file write failed");
+            case MZ_ZIP_FILE_READ_FAILED:
+                return L("file read failed");
+            case MZ_ZIP_FILE_CLOSE_FAILED:
+                return L("file close failed");
+            case MZ_ZIP_FILE_SEEK_FAILED:
+                return L("file seek failed");
+            case MZ_ZIP_FILE_STAT_FAILED:
+                return L("file stat failed");
+            case MZ_ZIP_INVALID_PARAMETER:
+                return L("invalid parameter");
+            case MZ_ZIP_INVALID_FILENAME:
+                return L("invalid filename");
+            case MZ_ZIP_BUF_TOO_SMALL:
+                return L("buffer too small");
+            case MZ_ZIP_INTERNAL_ERROR:
+                return L("internal error");
+            case MZ_ZIP_FILE_NOT_FOUND:
+                return L("file not found");
+            case MZ_ZIP_ARCHIVE_TOO_LARGE:
+                return L("archive is too large");
+            case MZ_ZIP_VALIDATION_FAILED:
+                return L("validation failed");
+            case MZ_ZIP_WRITE_CALLBACK_FAILED:
+                return L("write calledback failed");
+            default:
+                break;
+        }
+
+        return "unknown error";
+    }
+
+    [[noreturn]] void blow_up() {
+        throw std::runtime_error(get_errorstr(arch.m_last_error));
+    }
 };
 
 Zipper::Zipper(const std::string &zipfname, e_compression compression)
@@ -21,7 +106,7 @@ Zipper::Zipper(const std::string &zipfname, e_compression compression)
 
     // Initialize the archive data
     if(!mz_zip_writer_init_file(&m_impl->arch, zipfname.c_str(), 0))
-        throw std::runtime_error("Cannot open zip archive!");
+        m_impl->blow_up();
 
     m_compression = compression;
     m_zipname = zipfname;
@@ -30,8 +115,25 @@ Zipper::Zipper(const std::string &zipfname, e_compression compression)
 Zipper::~Zipper()
 {
     finish_entry();
-    mz_zip_writer_finalize_archive(&m_impl->arch);
-    mz_zip_writer_end(&m_impl->arch);
+
+    if(!mz_zip_writer_finalize_archive(&m_impl->arch)) m_impl->blow_up();
+    if(!mz_zip_writer_end(&m_impl->arch)) m_impl->blow_up();
+}
+
+Zipper::Zipper(Zipper &&m):
+    m_impl(std::move(m.m_impl)),
+    m_data(std::move(m.m_data)),
+    m_entry(std::move(m.m_entry)),
+    m_compression(m.m_compression),
+    m_zipname(m.m_zipname) {}
+
+Zipper &Zipper::operator=(Zipper &&m) {
+    m_impl = std::move(m.m_impl);
+    m_data = std::move(m.m_data);
+    m_entry = std::move(m.m_entry);
+    m_compression = m.m_compression;
+    m_zipname = std::move(m.m_zipname);
+    return *this;
 }
 
 void Zipper::add_entry(const std::string &name)
@@ -51,10 +153,10 @@ void Zipper::finish_entry()
         case TIGHT_COMPRESSION: compression = MZ_BEST_COMPRESSION; break;
         }
 
-        mz_zip_writer_add_mem(&m_impl->arch, m_entry.c_str(),
-                              m_data.c_str(),
-                              m_data.size(),
-                              compression);
+        if(!mz_zip_writer_add_mem(&m_impl->arch, m_entry.c_str(),
+                                  m_data.c_str(),
+                                  m_data.size(),
+                                  compression)) m_impl->blow_up();
     }
 
     m_data.clear();
diff --git a/src/libslic3r/Zipper.hpp b/src/libslic3r/Zipper.hpp
index 685303955..30c1dfb9a 100644
--- a/src/libslic3r/Zipper.hpp
+++ b/src/libslic3r/Zipper.hpp
@@ -36,11 +36,15 @@ public:
     Zipper& operator=(const Zipper&) = delete;
 
     // Moving is fine.
-    Zipper(Zipper&&) = default;
-    Zipper& operator=(Zipper&&) = default;
+    // Zipper(Zipper&&) = default;
+    // Zipper& operator=(Zipper&&) = default;
+    // All becouse of VS2013:
+    Zipper(Zipper &&m);
+    Zipper& operator=(Zipper &&m);
 
     /// Adding an entry means a file inside the new archive. Name param is the
     /// name of the new file. To create directories, append a forward slash.
+    /// The previous entry is finished (see finish_entry)
     void add_entry(const std::string& name);
 
     // Writing data to the archive works like with standard streams. The target
@@ -64,7 +68,10 @@ public:
     }
 
     /// Finishing an entry means that subsequent writes will no longer be
-    /// appended to the previous entry.
+    /// appended to the previous entry. They will be written into the internal
+    /// buffer and ones an entry is added, the buffer will bind to the new entry
+    /// If the buffer was written, but no entry was added, the buffer will be
+    /// cleared after this call.
     void finish_entry();
 
     /// Gets the name of the archive without the path or extension.
diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
index 2ba1d6cdc..2b4e0f16a 100644
--- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp
+++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
@@ -93,10 +93,10 @@ void BackgroundSlicingProcess::process_fff()
 }
 
 // Pseudo type for specializing LayerWriter trait class
-struct SLAZipFmt {};
+struct SLAwxZipper {};
 
 // The implementation of creating zipped archives with wxWidgets
-template<> class LayerWriter<SLAZipFmt> {
+template<> class LayerWriter<SLAwxZipper> {
     wxFileName fpath;
     wxFFileOutputStream zipfile;
     wxZipOutputStream zipstream;
@@ -150,7 +150,7 @@ void BackgroundSlicingProcess::process_sla()
     if (this->set_step_started(bspsGCodeFinalize)) {
         if (! m_export_path.empty()) {
             // m_sla_print->export_raster<SLAZipFmt>(m_export_path);
-            m_sla_print->export_raster<SLAminzFmt>(m_export_path);
+            m_sla_print->export_raster<SLAminzZipper>(m_export_path);
             m_print->set_status(100, "Masked SLA file exported to " + m_export_path);
         } else if (! m_upload_job.empty()) {
             prepare_upload();
@@ -452,7 +452,7 @@ void BackgroundSlicingProcess::prepare_upload()
 		m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());
 	} else {
         // m_sla_print->export_raster<SLAZipFmt>(source_path.string());
-        m_sla_print->export_raster<SLAminzFmt>(source_path.string());
+        m_sla_print->export_raster<SLAminzZipper>(source_path.string());
 		// TODO: Also finalize upload path like with FFF when there are statistics for SLA print
 	}
 

From 0343b825340008b052ddeda27ac5a86a29671c13 Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Fri, 15 Mar 2019 12:30:41 +0100
Subject: [PATCH 4/5] Fixing build issues with msvc2013

---
 src/libslic3r/Zipper.cpp | 25 ++++++++++++++++---------
 src/libslic3r/Zipper.hpp |  1 -
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/libslic3r/Zipper.cpp b/src/libslic3r/Zipper.cpp
index 5a412bcf4..941d9719d 100644
--- a/src/libslic3r/Zipper.cpp
+++ b/src/libslic3r/Zipper.cpp
@@ -12,11 +12,18 @@
 //! return same string
 #define L(s) Slic3r::I18N::translate(s)
 
+#if defined(_MSC_VER) &&  _MSC_VER <= 1800 || __cplusplus < 201103L
+    #define SLIC3R_NORETURN
+#elif __cplusplus >= 201103L
+    #define SLIC3R_NORETURN [[noreturn]]
+#endif
+
 namespace Slic3r {
 
 class Zipper::Impl {
 public:
     mz_zip_archive arch;
+    std::string m_zipname;
 
     std::string get_errorstr(mz_zip_error mz_err)
     {
@@ -93,8 +100,10 @@ public:
         return "unknown error";
     }
 
-    [[noreturn]] void blow_up() {
-        throw std::runtime_error(get_errorstr(arch.m_last_error));
+    SLIC3R_NORETURN void blow_up() {
+        std::string prefix(L("Error with zip archive"));
+        throw std::runtime_error(prefix + " " + m_zipname + ": " +
+                                 get_errorstr(arch.m_last_error) + "!");
     }
 };
 
@@ -102,14 +111,14 @@ Zipper::Zipper(const std::string &zipfname, e_compression compression)
 {
     m_impl.reset(new Impl());
 
+    m_compression = compression;
+    m_impl->m_zipname = zipfname;
+
     memset(&m_impl->arch, 0, sizeof(m_impl->arch));
 
     // Initialize the archive data
     if(!mz_zip_writer_init_file(&m_impl->arch, zipfname.c_str(), 0))
         m_impl->blow_up();
-
-    m_compression = compression;
-    m_zipname = zipfname;
 }
 
 Zipper::~Zipper()
@@ -124,15 +133,13 @@ Zipper::Zipper(Zipper &&m):
     m_impl(std::move(m.m_impl)),
     m_data(std::move(m.m_data)),
     m_entry(std::move(m.m_entry)),
-    m_compression(m.m_compression),
-    m_zipname(m.m_zipname) {}
+    m_compression(m.m_compression) {}
 
 Zipper &Zipper::operator=(Zipper &&m) {
     m_impl = std::move(m.m_impl);
     m_data = std::move(m.m_data);
     m_entry = std::move(m.m_entry);
     m_compression = m.m_compression;
-    m_zipname = std::move(m.m_zipname);
     return *this;
 }
 
@@ -164,7 +171,7 @@ void Zipper::finish_entry()
 }
 
 std::string Zipper::get_name() const {
-    return boost::filesystem::path(m_zipname).stem().string();
+    return boost::filesystem::path(m_impl->m_zipname).stem().string();
 }
 
 }
diff --git a/src/libslic3r/Zipper.hpp b/src/libslic3r/Zipper.hpp
index 30c1dfb9a..526ffed2e 100644
--- a/src/libslic3r/Zipper.hpp
+++ b/src/libslic3r/Zipper.hpp
@@ -22,7 +22,6 @@ private:
     std::string m_data;
     std::string m_entry;
     e_compression m_compression;
-    std::string m_zipname;
 
 public:
 

From c91d21f7c1d7e71c5ab9f8034797a942d6034125 Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Fri, 15 Mar 2019 12:34:58 +0100
Subject: [PATCH 5/5] Remove wxWidgets zipper.

---
 src/slic3r/GUI/BackgroundSlicingProcess.cpp | 59 ++-------------------
 1 file changed, 3 insertions(+), 56 deletions(-)

diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
index 2b4e0f16a..2601842ef 100644
--- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp
+++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp
@@ -92,65 +92,13 @@ void BackgroundSlicingProcess::process_fff()
 	}
 }
 
-// Pseudo type for specializing LayerWriter trait class
-struct SLAwxZipper {};
-
-// The implementation of creating zipped archives with wxWidgets
-template<> class LayerWriter<SLAwxZipper> {
-    wxFileName fpath;
-    wxFFileOutputStream zipfile;
-    wxZipOutputStream zipstream;
-    wxStdOutputStream pngstream;
-
-public:
-
-    inline LayerWriter(const std::string& zipfile_path):
-        fpath(zipfile_path),
-        zipfile(zipfile_path),
-        zipstream(zipfile),
-        pngstream(zipstream)
-    {
-        if(!is_ok())
-            throw std::runtime_error("Cannot create zip file.");
-    }
-
-    ~LayerWriter() {
-        // In case of an error (disk space full) zipstream destructor would
-        // crash.
-        pngstream.clear();
-        zipstream.CloseEntry();
-    }
-
-    inline void next_entry(const std::string& fname) {
-        zipstream.PutNextEntry(fname);
-    }
-
-    inline std::string get_name() const {
-        return fpath.GetName().ToUTF8().data();
-    }
-
-    template<class T> inline LayerWriter& operator<<(T&& arg) {
-        pngstream << std::forward<T>(arg); return *this;
-    }
-
-    bool is_ok() const {
-        return pngstream.good() && zipstream.IsOk() && zipfile.IsOk();
-    }
-
-    inline void close() {
-        zipstream.Close();
-        zipfile.Close();
-    }
-};
-
 void BackgroundSlicingProcess::process_sla()
 {
     assert(m_print == m_sla_print);
     m_print->process();
     if (this->set_step_started(bspsGCodeFinalize)) {
         if (! m_export_path.empty()) {
-            // m_sla_print->export_raster<SLAZipFmt>(m_export_path);
-            m_sla_print->export_raster<SLAminzZipper>(m_export_path);
+            m_sla_print->export_raster(m_export_path);
             m_print->set_status(100, "Masked SLA file exported to " + m_export_path);
         } else if (! m_upload_job.empty()) {
             prepare_upload();
@@ -450,9 +398,8 @@ void BackgroundSlicingProcess::prepare_upload()
 		}
 		run_post_process_scripts(source_path.string(), m_fff_print->config());
 		m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());
-	} else {
-        // m_sla_print->export_raster<SLAZipFmt>(source_path.string());
-        m_sla_print->export_raster<SLAminzZipper>(source_path.string());
+    } else {
+        m_sla_print->export_raster(source_path.string());
 		// TODO: Also finalize upload path like with FFF when there are statistics for SLA print
 	}