30 # if !defined(_CRT_SECURE_NO_WARNINGS)
31 # define _CRT_SECURE_NO_WARNINGS
53 typedef struct zip_stat
stat;
122 using source = std::function<
struct zip_source* (
struct zip*)>;
129 std::unique_ptr<
struct zip_file, int (*)(
struct zip_file*)> handle_;
131 file(
const file&) =
delete;
132 file& operator=(
const file&) =
delete;
141 : handle_(
file, zip_fclose)
168 return zip_fread(handle_.get(), data, length);
177 template <
size_t Size>
178 inline int read(
char (&data)[Size]) noexcept
180 return read(data, Size);
195 result.resize(length);
196 auto count =
read(&result[0], length);
201 result.resize(count);
215 return [data = std::move(data)] (
struct zip* archive) ->
struct zip_source* {
216 auto size = data.size();
217 auto ptr =
static_cast<char*
>(std::malloc(size));
220 throw std::runtime_error(std::strerror(errno));
222 std::memcpy(ptr, data.data(), size);
224 auto src = zip_source_buffer(archive, ptr, size, 1);
226 if (src ==
nullptr) {
228 throw std::runtime_error(zip_strerror(archive));
245 return [path = std::move(path), start, length] (
struct zip* archive) ->
struct zip_source* {
246 auto src = zip_source_file(archive, path.c_str(), start, length);
249 throw std::runtime_error(zip_strerror(archive));
319 std::unique_ptr<
struct zip, int (*)(
struct zip *)> handle_;
321 archive(
const archive&) =
delete;
322 archive& operator=(
const archive&) =
delete;
328 class iterator :
public std::iterator<std::random_access_iterator_tag, libzip::stat> {
330 friend class archive;
332 archive *archive_{
nullptr};
356 return archive_->
stat(index_);
431 return iterator(archive_, index_ + inc);
442 return iterator(archive_, index_ - dec);
453 return index_ == other.index_;
464 return index_ != other.index_;
479 return archive_->
stat(index_ + index);
523 : handle_(nullptr, nullptr)
526 struct zip*
archive = zip_open(path.c_str(), flags, &error);
531 zip_error_to_str(buf,
sizeof (buf), error, errno);
533 throw std::runtime_error(buf);
536 handle_ = {
archive, zip_close };
624 auto size = text.size();
625 auto cstr = (size == 0) ?
nullptr : text.c_str();
627 if (zip_file_set_comment(handle_.get(), index, cstr, size, flags) < 0)
628 throw std::runtime_error(zip_strerror(handle_.get()));
641 zip_uint32_t length = 0;
642 auto text = zip_file_get_comment(handle_.get(), index, &length, flags);
645 throw std::runtime_error(zip_strerror(handle_.get()));
647 return std::string(text, length);
658 if (zip_set_archive_comment(handle_.get(),
comment.c_str(),
comment.size()) < 0)
659 throw std::runtime_error(zip_strerror(handle_.get()));
672 auto text = zip_get_archive_comment(handle_.get(), &length, flags);
675 throw std::runtime_error(zip_strerror(handle_.get()));
677 return std::string(text,
static_cast<std::size_t
>(length));
689 return zip_name_locate(handle_.get(), name.c_str(), flags) >= 0;
702 auto index = zip_name_locate(handle_.get(), name.c_str(), flags);
705 throw std::runtime_error(zip_strerror(handle_.get()));
722 if (zip_stat(handle_.get(), name.c_str(), flags, &st) < 0)
723 throw std::runtime_error(zip_strerror(handle_.get()));
740 if (zip_stat_index(handle_.get(), index, flags, &st) < 0)
741 throw std::runtime_error(zip_strerror(handle_.get()));
759 auto src =
source(handle_.get());
760 auto ret = zip_file_add(handle_.get(), name.c_str(), src, flags);
763 zip_source_free(src);
764 throw std::runtime_error(zip_strerror(handle_.get()));
780 auto ret = zip_dir_add(handle_.get(), directory.c_str(), flags);
783 throw std::runtime_error(zip_strerror(handle_.get()));
798 auto src =
source(handle_.get());
800 if (zip_file_replace(handle_.get(), index, src, flags) < 0) {
801 zip_source_free(src);
802 throw std::runtime_error(zip_strerror(handle_.get()));
815 file open(
const std::string& name,
flags_t flags = 0,
const std::string& password =
"")
817 struct zip_file*
file;
819 if (password.size() > 0)
820 file = zip_fopen_encrypted(handle_.get(), name.c_str(), flags, password.c_str());
822 file = zip_fopen(handle_.get(), name.c_str(), flags);
825 throw std::runtime_error(zip_strerror(handle_.get()));
841 struct zip_file*
file;
843 if (password.size() > 0)
844 file = zip_fopen_index_encrypted(handle_.get(), index, flags, password.c_str());
846 file = zip_fopen_index(handle_.get(), index, flags);
849 throw std::runtime_error(zip_strerror(handle_.get()));
864 if (zip_file_rename(handle_.get(), index, name.c_str(), flags) < 0)
865 throw std::runtime_error(zip_strerror(handle_.get()));
878 if (zip_set_file_compression(handle_.get(), index, comp, flags) < 0)
879 throw std::runtime_error(zip_strerror(handle_.get()));
890 if (zip_delete(handle_.get(), index) < 0)
891 throw std::runtime_error(zip_strerror(handle_.get()));
902 return zip_get_num_entries(handle_.get(), flags);
913 if (zip_unchange(handle_.get(), index) < 0)
914 throw std::runtime_error(zip_strerror(handle_.get()));
924 if (zip_unchange_all(handle_.get()) < 0)
925 throw std::runtime_error(zip_strerror(handle_.get()));
935 if (zip_unchange_archive(handle_.get()) < 0)
936 throw std::runtime_error(zip_strerror(handle_.get()));
947 auto cstr = (password.size() > 0) ? password.c_str() :
nullptr;
949 if (zip_set_default_password(handle_.get(), cstr) < 0)
950 throw std::runtime_error(zip_strerror(handle_.get()));
962 if (zip_set_archive_flag(handle_.get(),
flag, value) < 0)
963 throw std::runtime_error(zip_strerror(handle_.get()));
976 auto ret = zip_get_archive_flag(handle_.get(), which, flags);
979 throw std::runtime_error(zip_strerror(handle_.get()));