From 4f1a10c0f8d7e3bd2b55c08d760502e2a326d21b Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 15 Mar 2019 12:16:05 +0100 Subject: [PATCH] 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 { +template<> class LayerWriter { 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 + template void export_raster(const std::string& fname) { if(m_printer) m_printer->save(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 +#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 { +template<> class LayerWriter { 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(m_export_path); - m_sla_print->export_raster(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(); @@ -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(source_path.string()); - m_sla_print->export_raster(source_path.string()); + m_sla_print->export_raster(source_path.string()); // TODO: Also finalize upload path like with FFF when there are statistics for SLA print }