#include "emailer.h"
#include "compose.hpp"
#include "log.h"
+#include "zipper.h"
#include "dcpomatic_log.h"
-#include <zip.h>
#include <boost/foreach.hpp>
#include "i18n.h"
void
CinemaKDMs::make_zip_file (boost::filesystem::path zip_file, dcp::NameFormat name_format, dcp::NameFormat::Map name_values) const
{
- int error;
- struct zip* zip = zip_open (zip_file.string().c_str(), ZIP_CREATE | ZIP_EXCL, &error);
- if (!zip) {
- if (error == ZIP_ER_EXISTS) {
- throw FileError ("ZIP file already exists", zip_file);
- }
- throw FileError ("could not create ZIP file", zip_file);
- }
-
- list<shared_ptr<string> > kdm_strings;
+ Zipper zipper (zip_file);
name_values['c'] = cinema->name;
BOOST_FOREACH (shared_ptr<ScreenKDM> i, screen_kdms) {
- shared_ptr<string> kdm (new string(i->kdm_as_xml()));
- kdm_strings.push_back (kdm);
-
- struct zip_source* source = zip_source_buffer (zip, kdm->c_str(), kdm->length(), 0);
- if (!source) {
- throw runtime_error ("could not create ZIP source");
- }
-
name_values['s'] = i->screen->name;
name_values['i'] = i->kdm_id ();
string const name = careful_string_filter(name_format.get(name_values, ".xml"));
- if (zip_add (zip, name.c_str(), source) == -1) {
- throw runtime_error ("failed to add KDM to ZIP archive");
- }
+ zipper.add (name, i->kdm_as_xml());
}
- if (zip_close (zip) == -1) {
- throw runtime_error ("failed to close ZIP archive");
- }
+ zipper.close ();
}
/** Collect a list of ScreenKDMs into a list of CinemaKDMs so that each
video_mxf_examiner.cc
video_ring_buffers.cc
writer.cc
+ zipper.cc
"""
def build(bld):
--- /dev/null
+/*
+ Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "zipper.h"
+#include "exceptions.h"
+#include "dcpomatic_assert.h"
+#include <zip.h>
+#include <boost/filesystem.hpp>
+#include <stdexcept>
+
+using std::string;
+using std::runtime_error;
+using boost::shared_ptr;
+
+
+Zipper::Zipper (boost::filesystem::path file)
+{
+ int error;
+ _zip = zip_open (file.string().c_str(), ZIP_CREATE | ZIP_EXCL, &error);
+ if (!_zip) {
+ if (error == ZIP_ER_EXISTS) {
+ throw FileError ("ZIP file already exists", file);
+ }
+ throw FileError ("could not create ZIP file", file);
+ }
+}
+
+
+void
+Zipper::add (string name, string content)
+{
+ shared_ptr<string> copy(new string(content));
+ _store.push_back (copy);
+
+ struct zip_source* source = zip_source_buffer (_zip, copy->c_str(), copy->length(), 0);
+ if (!source) {
+ throw runtime_error ("could not create ZIP source");
+ }
+
+ if (zip_add(_zip, name.c_str(), source) == -1) {
+ throw runtime_error ("failed to add data to ZIP archive");
+ }
+}
+
+
+void
+Zipper::close ()
+{
+ if (zip_close(_zip) == -1) {
+ throw runtime_error ("failed to close ZIP archive");
+ }
+ _zip = 0;
+}
+
+
+Zipper::~Zipper ()
+{
+ if (_zip) {
+ zip_close(_zip);
+ }
+}
--- /dev/null
+/*
+ Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <boost/noncopyable.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+class Zipper : public boost::noncopyable
+{
+public:
+ Zipper (boost::filesystem::path file);
+ ~Zipper ();
+
+ void add (std::string name, std::string content);
+ void close ();
+
+private:
+ struct zip* _zip;
+ std::vector<boost::shared_ptr<std::string> > _store;
+};
+
video_content_scale_test.cc
video_mxf_content_test.cc
vf_kdm_test.cc
+ zipper_test.cc
"""
# Some difference in font rendering between the test machine and others...
--- /dev/null
+/*
+ Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+/** @file test/zipper_test.cc
+ * @brief Tests of Zipper class.
+ * @ingroup selfcontained
+ */
+
+#include "lib/zipper.h"
+#include "lib/exceptions.h"
+#include "test.h"
+#include <dcp/util.h>
+#include <boost/test/unit_test.hpp>
+#include <boost/filesystem.hpp>
+
+/** Basic test of Zipper working normally */
+BOOST_AUTO_TEST_CASE (zipper_test1)
+{
+ boost::system::error_code ec;
+ boost::filesystem::remove ("build/test/zipped.zip", ec);
+
+ Zipper zipper ("build/test/zipped.zip");
+ zipper.add ("foo.txt", "1234567890");
+ zipper.add ("bar.txt", "xxxxxxCCCCbbbbbbb1");
+ zipper.close ();
+
+ boost::filesystem::remove_all ("build/test/zipper_test1", ec);
+ int const r = system ("unzip build/test/zipped.zip -d build/test/zipper_test1");
+ BOOST_REQUIRE (r == 0);
+
+ BOOST_CHECK_EQUAL (dcp::file_to_string("build/test/zipper_test1/foo.txt"), "1234567890");
+ BOOST_CHECK_EQUAL (dcp::file_to_string("build/test/zipper_test1/bar.txt"), "xxxxxxCCCCbbbbbbb1");
+}
+
+
+/** Test failure when trying to overwrite a file */
+BOOST_AUTO_TEST_CASE (zipper_test2, * boost::unit_test::depends_on("zipper_test1"))
+{
+ BOOST_CHECK_THROW (Zipper("build/test/zipped.zip"), FileError);
+}
+