Error handling and more comments for Zipper.

This commit is contained in:
tamasmeszaros 2019-03-15 12:16:05 +01:00
parent 4643106be4
commit 4f1a10c0f8
4 changed files with 126 additions and 17 deletions

View File

@ -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);
}

View File

@ -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();

View File

@ -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.

View File

@ -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
}