Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/File/VFS/ZipFileReader.h
5673 views
1
#pragma once
2
3
#ifdef SHARED_LIBZIP
4
#include <zip.h>
5
#else
6
#include "ext/libzip/zip.h"
7
#endif
8
9
#include <mutex>
10
#include <set>
11
#include <string>
12
#include <utility>
13
14
#include "Common/File/VFS/VFS.h"
15
#include "Common/File/FileUtil.h"
16
#include "Common/File/Path.h"
17
18
class ZipContainer {
19
public:
20
ZipContainer() noexcept;
21
ZipContainer(const Path &path);
22
~ZipContainer();
23
ZipContainer(const ZipContainer &) = delete;
24
ZipContainer(ZipContainer &&) noexcept;
25
ZipContainer &operator=(const ZipContainer &) = delete;
26
ZipContainer &operator=(ZipContainer &&) noexcept;
27
void close() noexcept;
28
operator zip_t *() const noexcept;
29
30
private:
31
struct SourceData {
32
Path path;
33
FILE *file;
34
} *sourceData_;
35
zip_t *zip_;
36
37
static zip_int64_t SourceCallback(void *userdata, void *data, zip_uint64_t len, zip_source_cmd_t cmd);
38
};
39
40
class ZipFileReader : public VFSBackend {
41
public:
42
static ZipFileReader *Create(const Path &zipFile, std::string_view inZipPath, bool logErrors = true);
43
~ZipFileReader();
44
45
bool IsValid() const { return zip_file_ != nullptr; }
46
47
// use delete[] on the returned value.
48
uint8_t *ReadFile(std::string_view path, size_t *size) override;
49
50
VFSFileReference *GetFile(std::string_view path) override;
51
bool GetFileInfo(VFSFileReference *vfsReference, File::FileInfo *fileInfo) override;
52
void ReleaseFile(VFSFileReference *vfsReference) override;
53
54
VFSOpenFile *OpenFileForRead(VFSFileReference *vfsReference, size_t *size) override;
55
void Rewind(VFSOpenFile *vfsOpenFile) override;
56
size_t Read(VFSOpenFile *vfsOpenFile, void *buffer, size_t length) override;
57
void CloseFile(VFSOpenFile *vfsOpenFile) override;
58
59
bool GetFileListing(std::string_view path, std::vector<File::FileInfo> *listing, const char *filter) override;
60
bool GetFileInfo(std::string_view path, File::FileInfo *info) override;
61
std::string toString() const override {
62
std::string retval = zipPath_.ToVisualString();
63
if (!inZipPath_.empty()) {
64
retval += ": ";
65
retval += inZipPath_;
66
}
67
return retval;
68
}
69
70
private:
71
ZipFileReader(ZipContainer &&zip, const Path &zipPath, const std::string &inZipPath) : zip_file_(std::move(zip)), zipPath_(zipPath), inZipPath_(inZipPath) {}
72
// Path has to be either an empty string, or a string ending with a /.
73
bool GetZipListings(const std::string &path, std::set<std::string> &files, std::set<std::string> &directories);
74
75
ZipContainer zip_file_;
76
std::mutex lock_;
77
std::string inZipPath_;
78
Path zipPath_;
79
};
80
81
// When you just want a single file from a ZIP, and don't care about accurate error reporting, use this.
82
// The buffer should be free'd with free. Mutex will be locked while updating data, if non-null.
83
bool ReadSingleFileFromZip(Path zipFile, const char *path, std::string *data, std::mutex *mutex);
84
85