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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#include "clZipReader.h"
#include "file_logger.h"
#include "macros.h"
#include <cstdlib>
#include <wx/ffile.h>
#include <wx/file.h>
#include <wx/wfstream.h>
clZipReader::clZipReader(const wxFileName& zipfile)
{
// Read the entire content into memory
wxFile fp(zipfile.GetFullPath(), wxFile::read);
if(!fp.IsOpened()) {
clERROR() << "Failed to open file:" << zipfile;
return;
}
wxFileOffset size = fp.Length();
// increase the buffer size to match the file size
m_mb.SetBufSize(size);
fp.Read(m_mb.GetWriteBuf(size), size);
// update the data length
m_mb.SetDataLen(size);
fp.Close();
m_file = new wxMemoryInputStream(m_mb.GetData(), m_mb.GetDataLen());
m_zip = new wxZipInputStream(*m_file);
}
clZipReader::~clZipReader() { Close(); }
void clZipReader::Close()
{
// destory them in reverse order of the creation
wxDELETE(m_zip);
wxDELETE(m_file);
}
void clZipReader::Extract(const wxString& filename, const wxString& directory)
{
if(!m_zip) {
return;
}
wxZipEntry* entry(NULL);
entry = m_zip->GetNextEntry();
while(entry) {
if(::wxMatchWild(filename, entry->GetName())) {
DoExtractEntry(entry, directory);
}
wxDELETE(entry);
entry = m_zip->GetNextEntry();
}
}
void clZipReader::ExtractAll(const wxString& directory)
{
if(!m_zip) {
return;
}
wxZipEntry* entry(NULL);
wxString basedir = directory;
if(basedir.IsEmpty()) {
basedir = ".";
}
entry = m_zip->GetNextEntry();
while(entry) {
DoExtractEntry(entry, directory);
wxDELETE(entry);
entry = m_zip->GetNextEntry();
}
}
void clZipReader::DoExtractEntry(wxZipEntry* entry, const wxString& directory)
{
// Incase the entry name has a directory prefix, remove it
wxString fullpath;
fullpath << directory << "/" << entry->GetName();
// Change to posix style
fullpath.Replace("\\", "/");
// Remove any duplicate double slashes
while(fullpath.Replace("//", "/")) {}
if(entry->IsDir()) {
// a folder
wxFileName::Mkdir(fullpath, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
} else {
wxFileName outfile(fullpath);
// ensure that the path to the file exists
outfile.Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
wxFileOutputStream out(outfile.GetFullPath());
if(out.IsOk()) {
m_zip->Read(out);
out.Close();
}
}
}
void clZipReader::ExtractAll(std::unordered_map<wxString, Entry>& buffers)
{
// Incase the entry name has a directory prefix, remove it
if(!m_zip) {
return;
}
wxZipEntry* entry(NULL);
entry = m_zip->GetNextEntry();
while(entry) {
if(!entry->IsDir()) {
wxMemoryOutputStream out;
if(out.IsOk()) {
m_zip->Read(out);
Entry e;
e.len = out.GetLength();
e.buffer = malloc(e.len);
out.CopyTo(e.buffer, e.len);
buffers.insert({ entry->GetName(), e });
}
}
wxDELETE(entry);
entry = m_zip->GetNextEntry();
}
}
|