diff options
author | Alex Zolotarev <deathbaba@gmail.com> | 2012-02-22 21:19:10 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:34:34 +0300 |
commit | 31061cd31a767c19d4dc96532aaf724ce98286ef (patch) | |
tree | 1b1edc2a1365f00fa029627bd31a430b7dc45c00 /coding/zip_reader.cpp | |
parent | b631f5de7c0fc5bccfb7964362071cee48b832cc (diff) |
Added ZipReader::UnzipFile() to unpack archived files from android apk
Diffstat (limited to 'coding/zip_reader.cpp')
-rw-r--r-- | coding/zip_reader.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/coding/zip_reader.cpp b/coding/zip_reader.cpp index 33d81eed3d..163e6aea65 100644 --- a/coding/zip_reader.cpp +++ b/coding/zip_reader.cpp @@ -3,6 +3,8 @@ #include "../base/scope_guard.hpp" #include "../base/logging.hpp" +#include "../coding/file_writer.hpp" + #include "../std/bind.hpp" #include "../3party/zlib/contrib/minizip/unzip.h" @@ -73,3 +75,45 @@ bool ZipFileReader::IsZip(string const & zipContainer) unzClose(zip); return true; } + +void ZipFileReader::UnzipFile(string const & zipContainer, string const & fileInZip, + string const & outFilePath) +{ + unzFile zip = unzOpen64(zipContainer.c_str()); + if (!zip) + MYTHROW(OpenZipException, ("Can't get zip file handle", zipContainer)); + MY_SCOPE_GUARD(zipGuard, bind(&unzClose, zip)); + + if (UNZ_OK != unzLocateFile(zip, fileInZip.c_str(), 1)) + MYTHROW(LocateZipException, ("Can't locate file inside zip", fileInZip)); + + if (UNZ_OK != unzOpenCurrentFile(zip)) + MYTHROW(LocateZipException, ("Can't open file inside zip", fileInZip)); + MY_SCOPE_GUARD(currentFileGuard, bind(&unzCloseCurrentFile, zip)); + + try + { + FileWriter outFile(outFilePath); + + int readBytes; + static size_t const BUF_SIZE = 4096; + char buf[BUF_SIZE]; + while (true) + { + readBytes = unzReadCurrentFile(zip, buf, BUF_SIZE); + if (readBytes > 0) + outFile.Write(buf, static_cast<size_t>(readBytes)); + else if (readBytes < 0) + MYTHROW(InvalidZipException, ("Error", readBytes, "while unzipping", fileInZip, "from", zipContainer)); + else + break; + } + } + catch (Exception const & e) + { + // Delete unfinished output file + FileWriter::DeleteFileX(outFilePath); + // Rethrow exception - we've failed + throw; + } +} |