123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- ///|/ Copyright (c) Prusa Research 2019 - 2023 Oleksandra Iushchenko @YuSanka, David Kocík @kocikdav, Vojtěch Bubník @bubnikv, Tomáš Mészáros @tamasmeszaros, Vojtěch Král @vojtechkral
- ///|/
- ///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
- ///|/
- #include <exception>
- #include "Exception.hpp"
- #include "Zipper.hpp"
- #include "miniz_extension.hpp"
- #include <boost/log/trivial.hpp>
- #include "I18N.hpp"
- #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_Archive {
- public:
- std::string m_zipname;
- std::string formatted_errorstr() const
- {
- return _u8L("Error with ZIP archive") + " " + m_zipname + ": " +
- get_errorstr();
- }
- SLIC3R_NORETURN void blow_up() const
- {
- throw Slic3r::ExportError(formatted_errorstr());
- }
- bool is_alive()
- {
- return arch.m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
- }
- };
- 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));
- if (!open_zip_writer(&m_impl->arch, zipfname)) {
- m_impl->blow_up();
- }
- }
- Zipper::~Zipper()
- {
- if(m_impl->is_alive()) {
- // Flush the current entry if not finished yet.
- try { finish_entry(); } catch(...) {
- BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr();
- }
- if(!mz_zip_writer_finalize_archive(&m_impl->arch))
- BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr();
- }
- // The file should be closed no matter what...
- if(!close_zip_writer(&m_impl->arch))
- BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr();
- }
- 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) {}
- 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;
- return *this;
- }
- void Zipper::add_entry(const std::string &name)
- {
- if(!m_impl->is_alive()) return;
- finish_entry(); // finish previous business
- m_entry = name;
- }
- void Zipper::add_entry(const std::string &name, const void *data, size_t l)
- {
- if(!m_impl->is_alive()) return;
- finish_entry();
- mz_uint cmpr = MZ_NO_COMPRESSION;
- switch (m_compression) {
- case NO_COMPRESSION: cmpr = MZ_NO_COMPRESSION; break;
- case FAST_COMPRESSION: cmpr = MZ_BEST_SPEED; break;
- case TIGHT_COMPRESSION: cmpr = MZ_BEST_COMPRESSION; break;
- }
- if(!mz_zip_writer_add_mem(&m_impl->arch, name.c_str(), data, l, cmpr))
- m_impl->blow_up();
- m_entry.clear();
- m_data.clear();
- }
- void Zipper::finish_entry()
- {
- if(!m_impl->is_alive()) return;
- if(!m_data.empty() && !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;
- }
- 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();
- m_entry.clear();
- }
- void Zipper::finalize()
- {
- finish_entry();
- if(m_impl->is_alive()) if(!mz_zip_writer_finalize_archive(&m_impl->arch))
- m_impl->blow_up();
- }
- const std::string &Zipper::get_filename() const
- {
- return m_impl->m_zipname;
- }
- }
|