From 17558102f282213e695f8b4a24855a316318b11c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 22 Dec 2017 16:20:05 +0100 Subject: archive/zzip: use std::shared_ptr instead of class RefCount --- src/archive/plugins/ZzipArchivePlugin.cxx | 56 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'src/archive') diff --git a/src/archive/plugins/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx index ad89a28c8..2d156c025 100644 --- a/src/archive/plugins/ZzipArchivePlugin.cxx +++ b/src/archive/plugins/ZzipArchivePlugin.cxx @@ -28,31 +28,37 @@ #include "../ArchiveVisitor.hxx" #include "input/InputStream.hxx" #include "fs/Path.hxx" -#include "util/RefCount.hxx" #include "util/RuntimeError.hxx" #include -class ZzipArchiveFile final : public ArchiveFile { -public: - RefCount ref; - +struct ZzipDir { ZZIP_DIR *const dir; - ZzipArchiveFile(ZZIP_DIR *_dir) - :dir(_dir) {} + explicit ZzipDir(Path path) + :dir(zzip_dir_open(path.c_str(), nullptr)) { + if (dir == nullptr) + throw FormatRuntimeError("Failed to open ZIP file %s", + path.c_str()); + } - ~ZzipArchiveFile() { + ~ZzipDir() noexcept { zzip_dir_close(dir); } - void Unref() { - if (ref.Decrement()) - delete this; - } + ZzipDir(const ZzipDir &) = delete; + ZzipDir &operator=(const ZzipDir &) = delete; +}; + +class ZzipArchiveFile final : public ArchiveFile { + std::shared_ptr dir; + +public: + ZzipArchiveFile(std::shared_ptr &&_dir) + :dir(std::move(_dir)) {} virtual void Close() override { - Unref(); + delete this; } virtual void Visit(ArchiveVisitor &visitor) override; @@ -66,21 +72,16 @@ public: static ArchiveFile * zzip_archive_open(Path pathname) { - ZZIP_DIR *dir = zzip_dir_open(pathname.c_str(), nullptr); - if (dir == nullptr) - throw FormatRuntimeError("Failed to open ZIP file %s", - pathname.c_str()); - - return new ZzipArchiveFile(dir); + return new ZzipArchiveFile(std::make_shared(pathname)); } inline void ZzipArchiveFile::Visit(ArchiveVisitor &visitor) { - zzip_rewinddir(dir); + zzip_rewinddir(dir->dir); ZZIP_DIRENT dirent; - while (zzip_dir_read(dir, &dirent)) + while (zzip_dir_read(dir->dir, &dirent)) //add only files if (dirent.st_size > 0) visitor.VisitArchiveEntry(dirent.d_name); @@ -89,15 +90,15 @@ ZzipArchiveFile::Visit(ArchiveVisitor &visitor) /* single archive handling */ struct ZzipInputStream final : public InputStream { - ZzipArchiveFile *archive; + std::shared_ptr dir; ZZIP_FILE *file; - ZzipInputStream(ZzipArchiveFile &_archive, const char *_uri, + ZzipInputStream(const std::shared_ptr _dir, const char *_uri, Mutex &_mutex, Cond &_cond, ZZIP_FILE *_file) :InputStream(_uri, _mutex, _cond), - archive(&_archive), file(_file) { + dir(_dir), file(_file) { //we are seekable (but its not recommendent to do so) seekable = true; @@ -106,13 +107,10 @@ struct ZzipInputStream final : public InputStream { size = z_stat.st_size; SetReady(); - - archive->ref.Increment(); } ~ZzipInputStream() { zzip_file_close(file); - archive->Unref(); } /* virtual methods from InputStream */ @@ -125,12 +123,12 @@ InputStream * ZzipArchiveFile::OpenStream(const char *pathname, Mutex &mutex, Cond &cond) { - ZZIP_FILE *_file = zzip_file_open(dir, pathname, 0); + ZZIP_FILE *_file = zzip_file_open(dir->dir, pathname, 0); if (_file == nullptr) throw FormatRuntimeError("not found in the ZIP file: %s", pathname); - return new ZzipInputStream(*this, pathname, + return new ZzipInputStream(dir, pathname, mutex, cond, _file); } -- cgit v1.2.3