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
diff options
context:
space:
mode:
authorvng <viktor.govako@gmail.com>2012-10-29 22:24:17 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:46:26 +0300
commit74f36cfc00ef77209261c5c2c241498022dda9eb (patch)
treedc3c048363d169d1c2a46f092bd06f948f114b58 /platform
parent4ebdce7bb3b72f2d47a989b6e57908fc60a1fbc7 (diff)
- Fix bug with resume downloading - truncate "downloading" file if resume info is invalid;
- Reserve size for "downloading" file; - Process FileWriter exceptions in download initializing;
Diffstat (limited to 'platform')
-rw-r--r--platform/http_request.cpp71
-rw-r--r--platform/http_request.hpp12
2 files changed, 52 insertions, 31 deletions
diff --git a/platform/http_request.cpp b/platform/http_request.cpp
index 5cbc6158e7..2b4803abd0 100644
--- a/platform/http_request.cpp
+++ b/platform/http_request.cpp
@@ -212,17 +212,7 @@ class FileHttpRequest : public HttpRequest, public IHttpThreadCallback
if (m_status != EInProgress)
{
- try
- {
- m_writer.reset();
- }
- catch (Writer::Exception const & ex)
- {
- LOG(LWARNING, ("Can't close file correctly. There is not enough space, possibly."));
-
- ASSERT_EQUAL ( m_status, EFailed, () );
- m_status = EFailed;
- }
+ CloseWriter();
// clean up resume file with chunks range on success
if (m_status == ECompleted)
@@ -242,6 +232,20 @@ class FileHttpRequest : public HttpRequest, public IHttpThreadCallback
}
}
+ void CloseWriter()
+ {
+ try
+ {
+ m_writer.reset();
+ }
+ catch (Writer::Exception const & ex)
+ {
+ LOG(LWARNING, ("Can't close file correctly. There is not enough space, possibly."));
+
+ m_status = EFailed;
+ }
+ }
+
public:
FileHttpRequest(vector<string> const & urls, string const & filePath, int64_t fileSize,
CallbackT const & onFinish, CallbackT const & onProgress,
@@ -251,13 +255,29 @@ public:
{
ASSERT ( !urls.empty(), () );
- // Open file here. Avoid throwing exceptions from constructor's initialization list.
- m_writer.reset(new FileWriter(filePath + DOWNLOADING_FILE_EXTENSION, FileWriter::OP_WRITE_EXISTING));
-
+ // Load resume downloading information.
m_progress.first = m_strategy.LoadOrInitChunks(m_filePath + RESUME_FILE_EXTENSION,
fileSize, chunkSize);
m_progress.second = fileSize;
+ FileWriter::Op openMode = FileWriter::OP_WRITE_TRUNCATE;
+ if (m_progress.first != 0)
+ {
+ // Check that resume information is correct with existing file.
+ uint64_t size;
+ if (my::GetFileSize(filePath + DOWNLOADING_FILE_EXTENSION, size) && size == fileSize)
+ openMode = FileWriter::OP_WRITE_EXISTING;
+ else
+ m_strategy.InitChunks(fileSize, chunkSize);
+ }
+
+ // Create file and reserve needed size.
+ scoped_ptr<FileWriter> writer(new FileWriter(filePath + DOWNLOADING_FILE_EXTENSION, openMode));
+ writer->Reserve(fileSize);
+
+ // Assign here, because previous functions can throw an exception.
+ m_writer.swap(writer);
+
#ifdef OMIM_OS_IPHONE
m_writer->Flush();
DisableBackupForFile(filePath + DOWNLOADING_FILE_EXTENSION);
@@ -274,12 +294,12 @@ public:
if (m_status == EInProgress)
{
// means that client canceled download process, so delete all temporary files
- m_writer.reset();
+ CloseWriter();
if (m_doCleanProgressFiles)
{
- my::DeleteFileX(m_filePath + DOWNLOADING_FILE_EXTENSION);
- my::DeleteFileX(m_filePath + RESUME_FILE_EXTENSION);
+ (void)my::DeleteFileX(m_filePath + DOWNLOADING_FILE_EXTENSION);
+ (void)my::DeleteFileX(m_filePath + RESUME_FILE_EXTENSION);
}
}
}
@@ -328,29 +348,26 @@ namespace
};
}
-HttpRequest * HttpRequest::GetFile(vector<string> const & urls, string const & filePath, int64_t fileSize,
+HttpRequest * HttpRequest::GetFile(vector<string> const & urls,
+ string const & filePath, int64_t fileSize,
CallbackT const & onFinish, CallbackT const & onProgress,
- int64_t chunkSize, bool doCleanProgressFiles)
+ int64_t chunkSize, bool doCleanOnCancel)
{
- FileHttpRequest * p = 0;
try
{
- p = new FileHttpRequest(urls, filePath, fileSize, onFinish, onProgress, chunkSize, doCleanProgressFiles);
+ return new FileHttpRequest(urls, filePath, fileSize, onFinish, onProgress, chunkSize, doCleanOnCancel);
}
catch (FileWriter::Exception const & e)
{
- // Can't create file for writing.
+ // Can't create or open file for writing.
LOG(LERROR, ("Can't create FileHttpRequest for", filePath, e.what()));
- delete p;
- p = 0;
-
// Mark the end of download with error.
ErrorHttpRequest error(filePath);
onFinish(error);
- }
- return p;
+ return 0;
+ }
}
} // namespace downloader
diff --git a/platform/http_request.hpp b/platform/http_request.hpp
index 8f03e033cc..af3e055b86 100644
--- a/platform/http_request.hpp
+++ b/platform/http_request.hpp
@@ -22,7 +22,7 @@ public:
/// <current, total>, total can be -1 if size is unknown
typedef pair<int64_t, int64_t> ProgressT;
- typedef function<void(HttpRequest &)> CallbackT;
+ typedef function<void (HttpRequest &)> CallbackT;
protected:
StatusT m_status;
@@ -44,16 +44,20 @@ public:
static HttpRequest * Get(string const & url,
CallbackT const & onFinish,
CallbackT const & onProgress = CallbackT());
+
/// Content-type for request is always "application/json"
static HttpRequest * PostJson(string const & url, string const & postData,
CallbackT const & onFinish,
CallbackT const & onProgress = CallbackT());
- static HttpRequest * GetFile(vector<string> const & urls, string const & filePath,
- int64_t projectedFileSize,
+
+ /// Download file to filePath.
+ /// @param[in] fileSize Correct file size (needed for resuming and reserving).
+ static HttpRequest * GetFile(vector<string> const & urls,
+ string const & filePath, int64_t fileSize,
CallbackT const & onFinish,
CallbackT const & onProgress = CallbackT(),
int64_t chunkSize = 512 * 1024,
- bool doCleanProgressFiles = true);
+ bool doCleanOnCancel = true);
};
} // namespace downloader