-
Notifications
You must be signed in to change notification settings - Fork 32
/
ArchiveUtil.h
100 lines (75 loc) · 2.76 KB
/
ArchiveUtil.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#pragma once
enum class Formats : uint8_t {
TAR = 0,
ZIP = 1
};
enum Compressions {
None = 0,
Gzip = 1,
BZip2 = 2,
XZ = 3
};
using archive_type_ = std::pair<Formats, Compressions>;
using ext_list = std::vector<std::wstring>;
enum class FileTypes : uint8_t {
Regular = 0,
Directory = 1
};
class ArchiveBase {
protected:
bool open_{ false };
std::string error_str;
archive* archive_{ nullptr };
std::wstring archive_file_path_;
virtual DWORD Open() = 0;
virtual DWORD Close() = 0;
virtual ~ArchiveBase() = default;
public:
std::string getLastError() const {
return error_str;
}
archive* getArchivePtr() const {
return archive_;
}
};
class WriterUtil final : public ArchiveBase {
public:
explicit WriterUtil(const std::wstring& ArchiveFilePath, const archive_type_& Type);
~WriterUtil();
DWORD Open() override;
DWORD SetFormatOption(const std::string& Option, const std::string& Value);
DWORD AddFile(const std::wstring& FilePath, const std::wstring& EntryName = L"");
DWORD AddDirectory(const std::wstring& DirectoryName);
DWORD AddDirectoryFromFS(const std::wstring& DirPath);
DWORD AddEntriesFromAnotherArchive(archive* From, const std::wstring& SkipEntry = L"");
DWORD Close() override;
private:
int addHeader(const std::wstring& EntryName, const FileTypes EntryType, const uint64_t Size = 0, const int Permission = 0644);
int addHeader(const std::wstring& FilePath, const std::wstring& EntryName = L"");
int addFinish();
archive_entry* entry_{ nullptr };
const Formats format_;
const Compressions compression_;
};
class ReaderUtil final : public ArchiveBase {
public:
explicit ReaderUtil(const std::wstring& ArchiveFileName);
~ReaderUtil();
DWORD Open() override;
DWORD ExtractFileTo(const std::wstring& RootPath, const std::wstring& EntryPath = L"");
DWORD Close() override;
private:
bool ExtractNext(const std::wstring& RootPath, const std::wstring& EntryPath = L"");
};
class ArchiveUtil final {
public:
static ext_list supported_zip_exts;
static ext_list supported_tar_exts;
static ext_list supported_gzip_exts;
static ext_list supported_bzip_exts;
static DWORD CopyArchive(const std::wstring& Source, const std::wstring& Destination, const archive_type_& Type, const std::wstring& SkipEntry = L"");
static DWORD RemoveFile(const std::wstring& Source, const std::wstring& EntryPath, const archive_type_& Type);
static DWORD ExtractFile(const std::wstring& Source, const std::wstring& ToPath, const std::wstring& EntryPath);
static DWORD ReplaceEntry(const std::wstring& ArchivePath, const std::wstring& EntryPath, const std::wstring& FilePath, const archive_type_& Type);
static bool GetFormatAndArchiveType(const std::wstring& Path, std::pair<Formats, Compressions>& ArchiveType);
};