diff options
author | Yuri Gorshenin <y@maps.me> | 2016-05-10 15:44:09 +0300 |
---|---|---|
committer | Yuri Gorshenin <y@maps.me> | 2016-05-11 15:58:57 +0300 |
commit | c9086ce741cf93eecada71a0f8e411476d66f1ff (patch) | |
tree | c1b1125a34304d55860bf6c730cc2a2003ae4704 /coding | |
parent | 18287be1dbd25e98d3ac59e13a86687c5e697605 (diff) |
Review fixes.
Diffstat (limited to 'coding')
-rw-r--r-- | coding/zip_reader.cpp | 98 | ||||
-rw-r--r-- | coding/zip_reader.hpp | 20 |
2 files changed, 65 insertions, 53 deletions
diff --git a/coding/zip_reader.cpp b/coding/zip_reader.cpp index 102bdd77a4..427048a903 100644 --- a/coding/zip_reader.cpp +++ b/coding/zip_reader.cpp @@ -3,13 +3,42 @@ #include "base/scope_guard.hpp" #include "base/logging.hpp" -#include "coding/file_writer.hpp" #include "coding/constants.hpp" #include "std/bind.hpp" #include "3party/minizip/unzip.h" +namespace +{ +class UnzipFileDelegate : public ZipFileReader::Delegate +{ +public: + UnzipFileDelegate(string const & path) + : m_file(make_unique<FileWriter>(path)), m_path(path), m_completed(false) + { + } + + ~UnzipFileDelegate() override + { + if (!m_completed) + { + m_file.reset(); + FileWriter::DeleteFileX(m_path); + } + } + + // ZipFileReader::Delegate overrides: + void OnBlockUnzipped(size_t size, char const * data) override { m_file->Write(data, size); } + + void OnCompleted() override { m_completed = true; } + +private: + unique_ptr<FileWriter> m_file; + string const m_path; + bool m_completed; +}; +} // namespace ZipFileReader::ZipFileReader(string const & container, string const & file, uint32_t logPageSize, uint32_t logPageCount) @@ -73,8 +102,9 @@ bool ZipFileReader::IsZip(string const & zipContainer) return true; } +// static void ZipFileReader::UnzipFile(string const & zipContainer, string const & fileInZip, - string const & outFilePath, ProgressFn progressFn) + Delegate & delegate) { unzFile zip = unzOpen64(zipContainer.c_str()); if (!zip) @@ -92,54 +122,28 @@ void ZipFileReader::UnzipFile(string const & zipContainer, string const & fileIn if (UNZ_OK != unzGetCurrentFileInfo64(zip, &fileInfo, NULL, 0, NULL, 0, NULL, 0)) MYTHROW(LocateZipException, ("Can't get uncompressed file size inside zip", fileInZip)); - // First outFile should be closed, then FileWriter::DeleteFileX is called, - // so make correct order of guards. - MY_SCOPE_GUARD(outFileGuard, bind(&FileWriter::DeleteFileX, cref(outFilePath))); - FileWriter outFile(outFilePath); - - uint64_t pos = 0; char buf[ZIP_FILE_BUFFER_SIZE]; - while (true) - { - int const readBytes = unzReadCurrentFile(zip, buf, ZIP_FILE_BUFFER_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; - - pos += readBytes; - - if (progressFn) - progressFn(fileInfo.uncompressed_size, pos); - } + int readBytes = 0; - outFileGuard.release(); + delegate.OnStarted(); + do + { + readBytes = unzReadCurrentFile(zip, buf, ZIP_FILE_BUFFER_SIZE); + if (readBytes < 0) + { + MYTHROW(InvalidZipException, + ("Error", readBytes, "while unzipping", fileInZip, "from", zipContainer)); + } + + delegate.OnBlockUnzipped(static_cast<size_t>(readBytes), buf); + } while (readBytes != 0); + delegate.OnCompleted(); } -void ZipFileReader::UnzipFileToMemory(string const & cont, string const & file, - vector<char> & data) +// static +void ZipFileReader::UnzipFile(string const & zipContainer, string const & fileInZip, + string const & outPath) { - unzFile zip = unzOpen64(cont.c_str()); - if (!zip) - MYTHROW(OpenZipException, ("Can't get zip file handle:", cont)); - MY_SCOPE_GUARD(zipCloser, bind(&unzClose, zip)); - - if (UNZ_OK != unzLocateFile(zip, file.c_str(), 1 /* case sensitivity */)) - MYTHROW(LocateZipException, ("Can't locate file inside zip container:", file)); - if (UNZ_OK != unzOpenCurrentFile(zip)) - MYTHROW(LocateZipException, ("Can't open file inside zip container:", file)); - MY_SCOPE_GUARD(currentFileCloser, bind(&unzCloseCurrentFile, zip)); - - unz_file_info64 info; - if (UNZ_OK != unzGetCurrentFileInfo64(zip, &info, NULL, 0, NULL, 0, NULL, 0)) - MYTHROW(LocateZipException, ("Can't get uncompressed file size inside zip:", file)); - - size_t const size = info.uncompressed_size; - data.resize(size); - - int const bytesRead = unzReadCurrentFile(zip, data.data(), size); - if (bytesRead < 0) - MYTHROW(InvalidZipException, ("Error:", bytesRead, "while unzipping", file, "in", cont)); + UnzipFileDelegate delegate(outPath); + UnzipFile(zipContainer, fileInZip, delegate); } diff --git a/coding/zip_reader.hpp b/coding/zip_reader.hpp index 7970cff087..bea0496ae5 100644 --- a/coding/zip_reader.hpp +++ b/coding/zip_reader.hpp @@ -1,6 +1,7 @@ #pragma once #include "coding/file_reader.hpp" +#include "coding/file_writer.hpp" #include "base/exception.hpp" @@ -13,6 +14,17 @@ private: uint64_t m_uncompressedFileSize; public: + struct Delegate + { + virtual ~Delegate() = default; + + // When |size| is zero, end of file is reached. + virtual void OnBlockUnzipped(size_t size, char const * data) = 0; + + virtual void OnStarted() {} + virtual void OnCompleted() {} + }; + typedef function<void(uint64_t, uint64_t)> ProgressFn; /// Contains file name inside zip and it's uncompressed size typedef vector<pair<string, uint32_t> > FileListT; @@ -29,13 +41,9 @@ public: uint64_t UncompressedSize() const { return m_uncompressedFileSize; } /// @warning Can also throw Writer::OpenException and Writer::WriteException + static void UnzipFile(string const & zipContainer, string const & fileInZip, Delegate & delegate); static void UnzipFile(string const & zipContainer, string const & fileInZip, - string const & outFilePath, ProgressFn progressFn = ProgressFn()); - - /// Unzips |file| in |cont| to |buffer|. - /// - /// @warning Can throw OpenZipException and LocateZipException. - static void UnzipFileToMemory(string const & cont, string const & file, vector<char> & data); + string const & outPath); static void FilesList(string const & zipContainer, FileListT & filesList); |