Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/coding
diff options
context:
space:
mode:
authorYuri Gorshenin <y@maps.me>2016-05-10 15:44:09 +0300
committerYuri Gorshenin <y@maps.me>2016-05-11 15:58:57 +0300
commitc9086ce741cf93eecada71a0f8e411476d66f1ff (patch)
treec1b1125a34304d55860bf6c730cc2a2003ae4704 /coding
parent18287be1dbd25e98d3ac59e13a86687c5e697605 (diff)
Review fixes.
Diffstat (limited to 'coding')
-rw-r--r--coding/zip_reader.cpp98
-rw-r--r--coding/zip_reader.hpp20
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);