This repository was archived by the owner on Oct 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathArchiveExtractor.cpp
More file actions
69 lines (55 loc) · 2.03 KB
/
ArchiveExtractor.cpp
File metadata and controls
69 lines (55 loc) · 2.03 KB
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
#include "ArchiveExtractor.h"
#include "FileEntry.h"
#include <archive.h>
#include <archive_entry.h>
#include <wx/dir.h>
#include <wx/log.h>
#include <wx/stdpaths.h>
Entry *ArchiveExtractor::Create(const wxFileName &filename,
std::function<bool()> updateFnc) {
wxFile inputFile(filename.GetFullPath());
auto strTempDir = wxStandardPaths::Get().GetTempDir();
wxFileName tempDirName(strTempDir + wxFileName::GetPathSeparator() +
"__ZPV__" + wxFileName::GetPathSeparator() +
filename.GetFullName(),
"");
if (tempDirName.DirExists())
tempDirName.Rmdir(wxPATH_RMDIR_RECURSIVE);
if (!tempDirName.Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL))
return nullptr;
archive_entry *entry;
int r;
auto a = archive_read_new();
archive_read_support_format_all(a);
if ((r = archive_read_open_fd(a, inputFile.fd(), 10240)))
return nullptr;
bool success = true;
while ((r = archive_read_next_header(a, &entry)) == ARCHIVE_OK) {
success = updateFnc();
if (!success)
break;
if (archive_entry_size(entry) < 0) {
continue;
}
auto entryPathName = archive_entry_pathname_w(entry);
auto entryType = archive_entry_filetype(entry);
if (entryType != AE_IFREG && entryType != AE_IFDIR)
continue;
wxFileName entryFilename(entryPathName);
wxFileName entryInTemp(tempDirName.GetFullPath() +
entryFilename.GetFullPath());
entryInTemp.Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
if (entryType == AE_IFREG) {
wxFile targetFile(entryInTemp.GetFullPath(), wxFile::write);
auto result = archive_read_data_into_fd(a, targetFile.fd());
targetFile.Close();
if (result < ARCHIVE_WARN)
wxRemoveFile(entryInTemp.GetFullPath());
}
}
archive_read_close(a);
archive_read_free(a);
if (!success)
return nullptr;
return FileEntry::Create(tempDirName, updateFnc);
}