diff modules/zip/ZipArchive.cpp @ 486:7ee8da32da98

Unify all in modules/
author David Demelier <markand@malikania.fr>
date Fri, 13 Nov 2015 09:26:46 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/zip/ZipArchive.cpp	Fri Nov 13 09:26:46 2015 +0100
@@ -0,0 +1,300 @@
+/*
+ * ZipArchive.cpp -- wrapper around libzip
+ *
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <stdexcept>
+
+#include "ZipArchive.h"
+
+namespace source {
+
+/* --------------------------------------------------------
+ * Buffer (zip_source_buffer)
+ * -------------------------------------------------------- */
+
+Buffer::Buffer(std::string data)
+	: m_data(std::move(data))
+{
+}
+
+struct zip_source *Buffer::source(struct zip *archive) const
+{
+	auto size = m_data.size();
+	auto data = static_cast<char *>(std::malloc(size));
+
+	if (data == nullptr)
+		throw std::runtime_error(std::strerror(errno));
+
+	std::memcpy(data, m_data.data(), size);
+
+	auto src = zip_source_buffer(archive, data, size, 1);
+
+	if (src == nullptr) {
+		std::free(data);
+		throw std::runtime_error(zip_strerror(archive));
+	}
+
+	return src;
+}
+
+/* --------------------------------------------------------
+ * File (zip_source_file)
+ * -------------------------------------------------------- */
+
+File::File(std::string path, ZipUint64 start, ZipInt64 length)
+	: m_path(std::move(path))
+	, m_start(start)
+	, m_length(length)
+{
+}
+
+struct zip_source *File::source(struct zip *archive) const
+{
+	auto src = zip_source_file(archive, m_path.c_str(), m_start, m_length);
+
+	if (src == nullptr)
+		throw std::runtime_error(zip_strerror(archive));
+
+	return src;
+}
+
+} // !source
+
+/* --------------------------------------------------------
+ * ZipArchive
+ * ------------------------------------------------------- */
+
+ZipArchive::ZipArchive(const std::string &path, ZipFlags flags)
+	: m_handle(nullptr, nullptr)
+{
+	int error;
+	struct zip *archive = zip_open(path.c_str(), flags, &error);
+
+	if (archive == nullptr)
+	{
+		char buf[128]{};
+
+		zip_error_to_str(buf, sizeof (buf), error, errno);
+
+		throw std::runtime_error(buf);
+	}
+
+	m_handle = { archive, zip_close };
+}
+
+void ZipArchive::setFileComment(ZipUint64 index, const std::string &text, ZipFlags flags)
+{
+	auto size = text.size();
+	auto cstr = (size == 0) ? nullptr : text.c_str();
+
+	if (zip_file_set_comment(m_handle.get(), index, cstr, size, flags) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+}
+
+std::string ZipArchive::getFileComment(ZipUint64 index, ZipFlags flags) const
+{
+	zip_uint32_t length = 0;
+	auto text = zip_file_get_comment(m_handle.get(), index, &length, flags);
+
+	if (text == nullptr)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+
+	return { text, length };
+}
+
+void ZipArchive::setComment(const std::string &comment)
+{
+	if (zip_set_archive_comment(m_handle.get(), comment.c_str(), comment.size()) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+}
+
+std::string ZipArchive::getComment(ZipFlags flags) const
+{
+	int length = 0;
+	auto text = zip_get_archive_comment(m_handle.get(), &length, flags);
+
+	if (text == nullptr)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+
+	return { text, static_cast<size_t>(length) };
+}
+
+bool ZipArchive::exists(const std::string &name, ZipFlags flags) const noexcept
+{
+	return zip_name_locate(m_handle.get(), name.c_str(), flags) >= 0;
+}
+
+ZipInt64 ZipArchive::find(const std::string &name, ZipFlags flags) const
+{
+	auto index = zip_name_locate(m_handle.get(), name.c_str(), flags);
+
+	if (index < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+
+	return index;
+}
+
+ZipStat ZipArchive::stat(const std::string &name, ZipFlags flags) const
+{
+	ZipStat st;
+
+	if (zip_stat(m_handle.get(), name.c_str(), flags, &st) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+
+	return st;
+}
+
+ZipStat ZipArchive::stat(ZipUint64 index, ZipFlags flags) const
+{
+	ZipStat st;
+
+	if (zip_stat_index(m_handle.get(), index, flags, &st) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+
+	return st;
+}
+
+ZipInt64 ZipArchive::add(const ZipSource &source, const std::string &name, ZipFlags flags)
+{
+	auto src = source.source(m_handle.get());
+	auto ret = zip_file_add(m_handle.get(), name.c_str(), src, flags);
+
+	if (ret < 0) {
+		zip_source_free(src);
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+	}
+
+	return ret;
+}
+
+ZipInt64 ZipArchive::addDirectory(const std::string &directory, ZipFlags flags)
+{
+	auto ret = zip_dir_add(m_handle.get(), directory.c_str(), flags);
+
+	if (ret < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+
+	return ret;
+}
+
+void ZipArchive::replace(const ZipSource &source, ZipUint64 index, ZipFlags flags)
+{
+	auto src = source.source(m_handle.get());
+
+	if (zip_file_replace(m_handle.get(), index, src, flags) < 0) {
+		zip_source_free(src);
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+	}
+}
+
+ZipFile ZipArchive::open(const std::string &name, ZipFlags flags, const std::string &password)
+{
+	struct zip_file *file;
+
+	if (password.size() > 0)
+		file = zip_fopen_encrypted(m_handle.get(), name.c_str(), flags, password.c_str());
+	else
+		file = zip_fopen(m_handle.get(), name.c_str(), flags);
+
+	if (file == nullptr)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+
+	return file;
+}
+
+ZipFile ZipArchive::open(ZipUint64 index, ZipFlags flags, const std::string &password)
+{
+	struct zip_file *file;
+
+	if (password.size() > 0)
+		file = zip_fopen_index_encrypted(m_handle.get(), index, flags, password.c_str());
+	else
+		file = zip_fopen_index(m_handle.get(), index, flags);
+
+	if (file == nullptr)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+
+	return file;
+}
+
+void ZipArchive::rename(ZipUint64 index, const std::string &name, ZipFlags flags)
+{
+	if (zip_file_rename(m_handle.get(), index, name.c_str(), flags) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+}
+
+void ZipArchive::setFileCompression(ZipUint64 index, ZipInt32 comp, ZipUint32 flags)
+{
+	if (zip_set_file_compression(m_handle.get(), index, comp, flags) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+}
+
+void ZipArchive::remove(ZipUint64 index)
+{
+	if (zip_delete(m_handle.get(), index) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+}
+
+ZipInt64 ZipArchive::numEntries(ZipFlags flags) const noexcept
+{
+	return zip_get_num_entries(m_handle.get(), flags);
+}
+
+void ZipArchive::unchange(ZipUint64 index)
+{
+	if (zip_unchange(m_handle.get(), index) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+}
+
+void ZipArchive::unchangeAll()
+{
+	if (zip_unchange_all(m_handle.get()) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+}
+
+void ZipArchive::unchangeArchive()
+{
+	if (zip_unchange_archive(m_handle.get()) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+}
+
+void ZipArchive::setDefaultPassword(const std::string &password)
+{
+	auto cstr = (password.size() > 0) ? password.c_str() : nullptr;
+
+	if (zip_set_default_password(m_handle.get(), cstr) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+}
+
+void ZipArchive::setFlag(ZipFlags flags, int value)
+{
+	if (zip_set_archive_flag(m_handle.get(), flags, value) < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+}
+
+int ZipArchive::getFlag(ZipFlags which, ZipFlags flags) const
+{
+	auto ret = zip_get_archive_flag(m_handle.get(), which, flags);
+
+	if (ret < 0)
+		throw std::runtime_error(zip_strerror(m_handle.get()));
+
+	return ret;
+}