archive/zzip: use std::shared_ptr instead of class RefCount

This commit is contained in:
Max Kellermann 2017-12-22 16:20:05 +01:00
parent e1c39f3fdc
commit 17558102f2

View File

@ -28,31 +28,37 @@
#include "../ArchiveVisitor.hxx"
#include "input/InputStream.hxx"
#include "fs/Path.hxx"
#include "util/RefCount.hxx"
#include "util/RuntimeError.hxx"
#include <zzip/zzip.h>
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<ZzipDir> dir;
public:
ZzipArchiveFile(std::shared_ptr<ZzipDir> &&_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<ZzipDir>(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<ZzipDir> dir;
ZZIP_FILE *file;
ZzipInputStream(ZzipArchiveFile &_archive, const char *_uri,
ZzipInputStream(const std::shared_ptr<ZzipDir> _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);
}