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-07-03 09:20:08 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:40:32 +0300
commit8eb9f95264fb11e1bd6dcaef6e735b083def7a59 (patch)
treef700e713629097eff30802c69b0a679d5bfb6703 /platform
parentcae1c655f994b27bde665d417e6581fba3a0eaa2 (diff)
New extensions for resume/downloading logic to avoid mixing with old user's temporary files.
Diffstat (limited to 'platform')
-rw-r--r--platform/chunks_download_strategy.cpp42
-rw-r--r--platform/chunks_download_strategy.hpp11
-rw-r--r--platform/http_request.cpp9
-rw-r--r--platform/platform_tests/downloader_test.cpp8
4 files changed, 46 insertions, 24 deletions
diff --git a/platform/chunks_download_strategy.cpp b/platform/chunks_download_strategy.cpp
index b6cd42f79d..9c6be13b27 100644
--- a/platform/chunks_download_strategy.cpp
+++ b/platform/chunks_download_strategy.cpp
@@ -2,6 +2,7 @@
#include "../coding/file_writer.hpp"
#include "../coding/file_reader.hpp"
+#include "../coding/varint.hpp"
#include "../base/logging.hpp"
@@ -60,13 +61,15 @@ void ChunksDownloadStrategy::AddChunk(RangeT const & range, ChunkStatusT status)
m_chunks.push_back(ChunkT(range.second + 1, CHUNK_AUX));
}
-void ChunksDownloadStrategy::SaveChunks(string const & fName)
+void ChunksDownloadStrategy::SaveChunks(int64_t fileSize, string const & fName)
{
if (!m_chunks.empty())
{
try
{
FileWriter w(fName);
+ WriteVarInt(w, fileSize);
+
w.Write(&m_chunks[0], sizeof(ChunkT) * m_chunks.size());
return;
}
@@ -89,23 +92,32 @@ int64_t ChunksDownloadStrategy::LoadOrInitChunks( string const & fName,
try
{
FileReader r(fName);
+ ReaderSource<FileReader> src(r);
- // Load chunks.
- size_t const count = r.Size() / sizeof(ChunkT);
- m_chunks.resize(count);
- r.Read(0, &m_chunks[0], sizeof(ChunkT) * count);
-
- // Reset status "downloading" to "free".
- int64_t downloadedSize = 0;
- for (size_t i = 0; i < count-1; ++i)
+ int64_t const readedSize = ReadVarInt<int64_t>(src);
+ if (readedSize == fileSize)
{
- if (m_chunks[i].m_status != CHUNK_COMPLETE)
- m_chunks[i].m_status = CHUNK_FREE;
- else
- downloadedSize += (m_chunks[i+1].m_pos - m_chunks[i].m_pos);
- }
+ // Load chunks.
+ uint64_t const size = src.Size();
+ int const stSize = sizeof(ChunkT);
+ size_t const count = size / stSize;
+ ASSERT_EQUAL(size, stSize * count, ());
+
+ m_chunks.resize(count);
+ src.Read(&m_chunks[0], stSize * count);
+
+ // Reset status "downloading" to "free".
+ int64_t downloadedSize = 0;
+ for (size_t i = 0; i < count-1; ++i)
+ {
+ if (m_chunks[i].m_status != CHUNK_COMPLETE)
+ m_chunks[i].m_status = CHUNK_FREE;
+ else
+ downloadedSize += (m_chunks[i+1].m_pos - m_chunks[i].m_pos);
+ }
- return downloadedSize;
+ return downloadedSize;
+ }
}
catch(FileReader::Exception const & e)
{
diff --git a/platform/chunks_download_strategy.hpp b/platform/chunks_download_strategy.hpp
index c3ae0cd841..6b7e701e13 100644
--- a/platform/chunks_download_strategy.hpp
+++ b/platform/chunks_download_strategy.hpp
@@ -4,6 +4,7 @@
#include "../std/vector.hpp"
#include "../std/utility.hpp"
#include "../std/stdint.hpp"
+#include "../std/static_assert.hpp"
namespace downloader
@@ -16,6 +17,7 @@ public:
enum ChunkStatusT { CHUNK_FREE = 0, CHUNK_DOWNLOADING = 1, CHUNK_COMPLETE = 2, CHUNK_AUX = -1 };
private:
+#pragma pack(push, 1)
struct ChunkT
{
/// position of chunk in file
@@ -23,9 +25,14 @@ private:
/// @see ChunkStatusT
int8_t m_status;
- ChunkT() : m_pos(-1), m_status(-1) {}
+ ChunkT() : m_pos(-1), m_status(-1)
+ {
+ // Be sure to avoid overhead in writing to file.
+ STATIC_ASSERT(sizeof(ChunkT) == 9);
+ }
ChunkT(int64_t pos, int8_t st) : m_pos(pos), m_status(st) {}
};
+#pragma pack(pop)
vector<ChunkT> m_chunks;
@@ -61,7 +68,7 @@ public:
/// Used in unit tests only!
void AddChunk(RangeT const & range, ChunkStatusT status);
- void SaveChunks(string const & fName);
+ void SaveChunks(int64_t fileSize, string const & fName);
/// @return Already downloaded size.
int64_t LoadOrInitChunks(string const & fName, int64_t fileSize, int64_t chunkSize);
diff --git a/platform/http_request.cpp b/platform/http_request.cpp
index a86bf89c61..b270458baa 100644
--- a/platform/http_request.cpp
+++ b/platform/http_request.cpp
@@ -159,6 +159,11 @@ class FileHttpRequest : public HttpRequest, public IHttpThreadCallback
}
}
+ void SaveResumeChunks()
+ {
+ m_strategy.SaveChunks(m_progress.second, m_filePath + RESUME_FILE_EXTENSION);
+ }
+
/// Called for each chunk by one main (GUI) thread.
virtual void OnFinish(long httpCode, int64_t begRange, int64_t endRange)
{
@@ -195,7 +200,7 @@ class FileHttpRequest : public HttpRequest, public IHttpThreadCallback
// save information for download resume
++m_goodChunksCount;
if (m_status != ECompleted && m_goodChunksCount % 10 == 0)
- m_strategy.SaveChunks(m_filePath + RESUME_FILE_EXTENSION);
+ SaveResumeChunks();
}
if (m_status != EInProgress)
@@ -224,7 +229,7 @@ class FileHttpRequest : public HttpRequest, public IHttpThreadCallback
DisableBackupForFile(m_filePath);
}
else // or save "chunks left" otherwise
- m_strategy.SaveChunks(m_filePath + RESUME_FILE_EXTENSION);
+ SaveResumeChunks();
m_onFinish(*this);
}
diff --git a/platform/platform_tests/downloader_test.cpp b/platform/platform_tests/downloader_test.cpp
index b62703146d..a9a97a8431 100644
--- a/platform/platform_tests/downloader_test.cpp
+++ b/platform/platform_tests/downloader_test.cpp
@@ -572,13 +572,11 @@ UNIT_TEST(DownloadResumeChunks)
FileWriter f(DOWNLOADING_FILENAME, FileWriter::OP_WRITE_EXISTING);
f.Seek(beg1);
- char b1[end1 - beg1 + 1];
- for (size_t i = 0; i < ARRAY_SIZE(b1); ++i) b1[i] = 0;
+ char b1[end1 - beg1 + 1] = {0};
f.Write(b1, ARRAY_SIZE(b1));
f.Seek(beg2);
- char b2[end2 - beg2 + 1];
- for (size_t i = 0; i < ARRAY_SIZE(b2); ++i) b2[i] = 0;
+ char b2[end2 - beg2 + 1] = {0};
f.Write(b2, ARRAY_SIZE(b2));
ChunksDownloadStrategy strategy((vector<string>()));
@@ -587,7 +585,7 @@ UNIT_TEST(DownloadResumeChunks)
strategy.AddChunk(make_pair(end1+1, beg2-1), ChunksDownloadStrategy::CHUNK_COMPLETE);
strategy.AddChunk(make_pair(beg2, end2), ChunksDownloadStrategy::CHUNK_FREE);
- strategy.SaveChunks(RESUME_FILENAME);
+ strategy.SaveChunks(FILESIZE, RESUME_FILENAME);
}
// 3rd step - check that resume works