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:
authorYuri Gorshenin <y@maps.me>2015-06-16 13:24:50 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:51:37 +0300
commit6afccd14ac29c038bd2261168d0e66c91ff79e1f (patch)
tree5764fd28ec9beabc8673b33e0eab604fd618dbce /platform
parentc53d7f1494773d1c5b499e858caa7fab436ac5fa (diff)
Review fixes.
Diffstat (limited to 'platform')
-rw-r--r--platform/country_defines.cpp12
-rw-r--r--platform/country_defines.hpp10
-rw-r--r--platform/country_file.cpp9
-rw-r--r--platform/country_file.hpp5
-rw-r--r--platform/local_country_file.cpp30
-rw-r--r--platform/local_country_file.hpp3
-rw-r--r--platform/local_country_file_utils.cpp149
-rw-r--r--platform/local_country_file_utils.hpp37
-rw-r--r--platform/platform.cpp2
-rw-r--r--platform/platform.hpp1
-rw-r--r--platform/platform_qt.cpp2
-rw-r--r--platform/platform_tests/country_file_tests.cpp10
-rw-r--r--platform/platform_tests/local_country_file_tests.cpp197
13 files changed, 384 insertions, 83 deletions
diff --git a/platform/country_defines.cpp b/platform/country_defines.cpp
index fa5a5ec31f..5a3ab9e8f5 100644
--- a/platform/country_defines.cpp
+++ b/platform/country_defines.cpp
@@ -2,13 +2,23 @@
#include "base/assert.hpp"
+bool HasOptions(TMapOptions options, TMapOptions bits)
+{
+ return (static_cast<uint8_t>(options) & static_cast<uint8_t>(bits)) == static_cast<uint8_t>(bits);
+}
+
+TMapOptions SetOptions(TMapOptions options, TMapOptions bits)
+{
+ return static_cast<TMapOptions>(static_cast<uint8_t>(options) | static_cast<uint8_t>(bits));
+}
+
string DebugPrint(TMapOptions options)
{
switch (options)
{
case TMapOptions::ENothing:
return "Nothing";
- case TMapOptions::EMapOnly:
+ case TMapOptions::EMap:
return "MapOnly";
case TMapOptions::ECarRouting:
return "CarRouting";
diff --git a/platform/country_defines.hpp b/platform/country_defines.hpp
index 57ba90de80..11e6f97842 100644
--- a/platform/country_defines.hpp
+++ b/platform/country_defines.hpp
@@ -1,15 +1,17 @@
#pragma once
#include "std/string.hpp"
-#include "3party/enum_flags.hpp"
-ENUM_FLAGS(TMapOptions)
-enum class TMapOptions
+enum class TMapOptions : uint8_t
{
ENothing = 0x0,
- EMapOnly = 0x1,
+ EMap = 0x1,
ECarRouting = 0x2,
EMapWithCarRouting = 0x3
};
+bool HasOptions(TMapOptions options, TMapOptions bits);
+
+TMapOptions SetOptions(TMapOptions options, TMapOptions bits);
+
string DebugPrint(TMapOptions options);
diff --git a/platform/country_file.cpp b/platform/country_file.cpp
index 2055e5cb14..8fffb2a52d 100644
--- a/platform/country_file.cpp
+++ b/platform/country_file.cpp
@@ -4,6 +4,8 @@
#include "base/assert.hpp"
#include "std/sstream.hpp"
+namespace platform
+{
CountryFile::CountryFile() : m_mapSize(0), m_routingSize(0) {}
CountryFile::CountryFile(string const & name) : m_name(name), m_mapSize(0), m_routingSize(0) {}
@@ -14,7 +16,7 @@ string CountryFile::GetNameWithExt(TMapOptions file) const
{
switch (file)
{
- case TMapOptions::EMapOnly:
+ case TMapOptions::EMap:
return m_name + DATA_FILE_EXTENSION;
case TMapOptions::ECarRouting:
return m_name + DATA_FILE_EXTENSION + ROUTING_FILE_EXTENSION;
@@ -33,9 +35,9 @@ void CountryFile::SetRemoteSizes(uint32_t mapSize, uint32_t routingSize)
uint32_t CountryFile::GetRemoteSize(TMapOptions filesMask) const
{
uint32_t size = 0;
- if (filesMask & TMapOptions::EMapOnly)
+ if (HasOptions(filesMask, TMapOptions::EMap))
size += m_mapSize;
- if (filesMask & TMapOptions::ECarRouting)
+ if (HasOptions(filesMask, TMapOptions::ECarRouting))
size += m_routingSize;
return size;
}
@@ -46,3 +48,4 @@ string DebugPrint(CountryFile const & file)
os << "CountryFile [" << file.m_name << "]";
return os.str();
}
+} // namespace platform
diff --git a/platform/country_file.hpp b/platform/country_file.hpp
index 342ad8b4fc..e23a81e85e 100644
--- a/platform/country_file.hpp
+++ b/platform/country_file.hpp
@@ -3,9 +3,11 @@
#include "platform/country_defines.hpp"
#include "std/string.hpp"
+namespace platform
+{
// This class represents a country file name and sizes of
// corresponding map files on a server, which should correspond to an
-// entry in counties.txt file. Also, this class can be used to
+// entry in countries.txt file. Also, this class can be used to
// represent a hand-made-country name. Instances of this class don't
// represent paths to disk files.
class CountryFile
@@ -34,3 +36,4 @@ private:
};
string DebugPrint(CountryFile const & file);
+} // namespace platform
diff --git a/platform/local_country_file.cpp b/platform/local_country_file.cpp
index 621a4e7a3f..48c9f92da8 100644
--- a/platform/local_country_file.cpp
+++ b/platform/local_country_file.cpp
@@ -8,6 +8,8 @@
#include "std/sstream.hpp"
+namespace platform
+{
LocalCountryFile::LocalCountryFile()
: m_version(0), m_files(TMapOptions::ENothing), m_mapSize(0), m_routingSize()
{
@@ -32,21 +34,23 @@ void LocalCountryFile::SyncWithDisk()
Platform & platform = GetPlatform();
- string const mapPath = GetPath(TMapOptions::EMapOnly);
- if (platform.GetFileSizeByName(mapPath, m_mapSize))
- m_files = m_files | TMapOptions::EMapOnly;
+ if (platform.GetFileSizeByName(GetPath(TMapOptions::EMap), m_mapSize))
+ m_files = SetOptions(m_files, TMapOptions::EMap);
string const routingPath = GetPath(TMapOptions::ECarRouting);
if (platform.GetFileSizeByName(routingPath, m_routingSize))
- m_files = m_files | TMapOptions::ECarRouting;
+ m_files = SetOptions(m_files, TMapOptions::ECarRouting);
}
void LocalCountryFile::DeleteFromDisk()
{
- for (TMapOptions file : {TMapOptions::EMapOnly, TMapOptions::ECarRouting})
+ for (TMapOptions file : {TMapOptions::EMap, TMapOptions::ECarRouting})
{
if (OnDisk(file))
- my::DeleteFileX(GetPath(file));
+ {
+ bool const deleted = my::DeleteFileX(GetPath(file));
+ ASSERT(deleted, (file, "from", *this, "wasn't deleted from disk."));
+ }
}
}
@@ -58,9 +62,9 @@ string LocalCountryFile::GetPath(TMapOptions file) const
uint32_t LocalCountryFile::GetSize(TMapOptions filesMask) const
{
uint64_t size64 = 0;
- if (filesMask & TMapOptions::EMapOnly)
+ if (HasOptions(filesMask, TMapOptions::EMap))
size64 += m_mapSize;
- if (filesMask & TMapOptions::ECarRouting)
+ if (HasOptions(filesMask, TMapOptions::ECarRouting))
size64 += m_routingSize;
uint32_t const size32 = static_cast<uint32_t>(size64);
ASSERT_EQUAL(size32, size64, ());
@@ -73,12 +77,17 @@ bool LocalCountryFile::operator<(LocalCountryFile const & rhs) const
return m_countryFile < rhs.m_countryFile;
if (m_version != rhs.m_version)
return m_version < rhs.m_version;
- return m_files < rhs.m_files;
+ if (m_directory != rhs.m_directory)
+ return m_directory < rhs.m_directory;
+ if (m_files != rhs.m_files)
+ return m_files < rhs.m_files;
+ return false;
}
bool LocalCountryFile::operator==(LocalCountryFile const & rhs) const
{
- return m_countryFile == rhs.m_countryFile && m_version == rhs.m_version && m_files == rhs.m_files;
+ return m_directory == rhs.m_directory && m_countryFile == rhs.m_countryFile &&
+ m_version == rhs.m_version && m_files == rhs.m_files;
}
// static
@@ -97,3 +106,4 @@ string DebugPrint(LocalCountryFile const & file)
<< file.m_version << ", " << DebugPrint(file.m_files) << "]";
return os.str();
}
+} // namespace platform
diff --git a/platform/local_country_file.hpp b/platform/local_country_file.hpp
index 87570bdb06..c73975f772 100644
--- a/platform/local_country_file.hpp
+++ b/platform/local_country_file.hpp
@@ -6,6 +6,8 @@
#include "std/string.hpp"
#include "std/vector.hpp"
+namespace platform
+{
// This class represents a path to disk files corresponding to some
// country region.
class LocalCountryFile
@@ -71,3 +73,4 @@ private:
};
string DebugPrint(LocalCountryFile const & file);
+} // namespace platform
diff --git a/platform/local_country_file_utils.cpp b/platform/local_country_file_utils.cpp
index e01b5c69bd..cba1ac3dbb 100644
--- a/platform/local_country_file_utils.cpp
+++ b/platform/local_country_file_utils.cpp
@@ -2,17 +2,71 @@
#include "platform/platform.hpp"
#include "coding/file_name_utils.hpp"
-
+#include "coding/file_writer.hpp"
+#include "base/string_utils.hpp"
+#include "base/logging.hpp"
#include "std/algorithm.hpp"
#include "std/cctype.hpp"
-namespace local_country_file_utils
+namespace platform
{
namespace
{
size_t const kMaxTimestampLength = 18;
+
+bool IsSpecialFile(string const & file) { return file == "." || file == ".."; }
} // namespace
+void CleanupMapsDirectory()
+{
+ Platform & platform = GetPlatform();
+
+ string const mapsDir = platform.WritableDir();
+
+ // Remove partially downloaded maps.
+ {
+ Platform::FilesList files;
+ string const regexp = "\\" DATA_FILE_EXTENSION "\\.(downloading2?$|resume2?$)";
+ platform.GetFilesByRegExp(mapsDir, regexp, files);
+ for (string const & file : files)
+ FileWriter::DeleteFileX(file);
+ }
+
+ // Find and remove Brazil and Japan maps.
+ vector<LocalCountryFile> localFiles;
+ FindAllLocalMaps(localFiles);
+ for (LocalCountryFile & localFile : localFiles)
+ {
+ CountryFile const countryFile = localFile.GetCountryFile();
+ if (countryFile.GetNameWithoutExt() == "Japan" || countryFile.GetNameWithoutExt() == "Brazil")
+ {
+ localFile.SyncWithDisk();
+ localFile.DeleteFromDisk();
+ }
+ }
+
+ // Try to delete empty folders.
+ Platform::FilesList subdirs;
+ Platform::GetFilesByType(mapsDir, Platform::FILE_TYPE_DIRECTORY, subdirs);
+ for (string const & subdir : subdirs)
+ {
+ int64_t version;
+ if (ParseVersion(subdir, version))
+ {
+ vector<string> files;
+ string const subdirPath = my::JoinFoldersToPath(mapsDir, subdir);
+ platform.GetFilesByType(subdirPath,
+ Platform::FILE_TYPE_REGULAR | Platform::FILE_TYPE_DIRECTORY, files);
+ if (all_of(files.begin(), files.end(), &IsSpecialFile))
+ {
+ Platform::EError ret = Platform::RmDir(subdirPath);
+ ASSERT_EQUAL(Platform::ERR_OK, ret,
+ ("Can't remove empty directory:", subdirPath, "error:", ret));
+ }
+ }
+ }
+}
+
void FindAllLocalMapsInDirectory(string const & directory, int64_t version,
vector<LocalCountryFile> & localFiles)
{
@@ -22,11 +76,10 @@ void FindAllLocalMapsInDirectory(string const & directory, int64_t version,
platform.GetFilesByRegExp(directory, ".*\\" DATA_FILE_EXTENSION "$", files);
for (string const & file : files)
{
+ // Remove DATA_FILE_EXTENSION and use base name as a country file name.
string name = file;
my::GetNameWithoutExt(name);
-
- CountryFile const countryFile(name);
- localFiles.emplace_back(directory, countryFile, version);
+ localFiles.emplace_back(directory, CountryFile(name), version);
}
}
@@ -34,7 +87,13 @@ void FindAllLocalMaps(vector<LocalCountryFile> & localFiles)
{
vector<LocalCountryFile> allFiles;
Platform & platform = GetPlatform();
- for (string const & directory : {platform.ResourcesDir(), platform.WritableDir()})
+ vector<string> baseDirectories = {
+ platform.ResourcesDir(), platform.WritableDir(),
+ };
+ sort(baseDirectories.begin(), baseDirectories.end());
+ baseDirectories.erase(unique(baseDirectories.begin(), baseDirectories.end()),
+ baseDirectories.end());
+ for (string const & directory : baseDirectories)
{
FindAllLocalMapsInDirectory(directory, 0 /* version */, allFiles);
@@ -47,12 +106,35 @@ void FindAllLocalMaps(vector<LocalCountryFile> & localFiles)
FindAllLocalMapsInDirectory(my::JoinFoldersToPath(directory, subdir), version, allFiles);
}
}
-#ifdef OMIM_OS_ANDROID
+#if defined(OMIM_OS_ANDROID)
// On Android World and WorldCoasts can be stored in alternative /Android/obb/ path.
- FindAllLocalMapsInDirectory("/Android/obb/", 0 /* version */, allFiles);
-#endif
- sort(allFiles.begin(), allFiles.end());
- allFiles.erase(unique(allFiles.begin(), allFiles.end()), allFiles.end());
+ for (string const & file : {WORLD_FILE_NAME, WORLD_COASTS_FILE_NAME})
+ {
+ bool found = false;
+ for (LocalCountryFile const & localFile : allFiles)
+ {
+ if (localFile.GetCountryFile().GetNameWithoutExt() == file)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ try
+ {
+ ModelReaderPtr reader = platform.GetReader(file + DATA_FILE_EXTENSION);
+ allFiles.emplace_back(my::GetDirectory(reader.GetName()), CountryFile(file),
+ 0 /* version */);
+ }
+ catch (FileAbsentException const & e)
+ {
+ LOG(LERROR, ("Can't find map file for", file, "."));
+ }
+ }
+ }
+#endif // defined(OMIM_OS_ANDROID)
+
localFiles.insert(localFiles.end(), allFiles.begin(), allFiles.end());
}
@@ -60,14 +142,41 @@ bool ParseVersion(string const & s, int64_t & version)
{
if (s.empty() || s.size() > kMaxTimestampLength)
return false;
- if (!all_of(s.begin(), s.end(), [](char c) -> bool
- {
- return isdigit(c);
- }))
- return false;
- version = 0;
- for (char c : s)
- version = version * 10 + c - '0';
+ int64_t v = 0;
+ for (char const c : s)
+ {
+ if (!isdigit(c))
+ return false;
+ v = v * 10 + c - '0';
+ }
+ version = v;
return true;
}
-} // namespace local_country_file_utils
+
+shared_ptr<LocalCountryFile> PreparePlaceForCountryFiles(CountryFile const & countryFile,
+ int64_t version)
+{
+ Platform & platform = GetPlatform();
+ if (version == 0)
+ return make_shared<LocalCountryFile>(platform.WritableDir(), countryFile, version);
+ string const directory =
+ my::JoinFoldersToPath(platform.WritableDir(), strings::to_string(version));
+ switch (platform.MkDir(directory))
+ {
+ case Platform::ERR_OK:
+ return make_shared<LocalCountryFile>(directory, countryFile, version);
+ case Platform::ERR_FILE_ALREADY_EXISTS:
+ {
+ Platform::EFileType type;
+ if (Platform::GetFileType(directory, type) != Platform::ERR_OK ||
+ type != Platform::FILE_TYPE_DIRECTORY)
+ {
+ return shared_ptr<LocalCountryFile>();
+ }
+ return make_shared<LocalCountryFile>(directory, countryFile, version);
+ }
+ default:
+ return shared_ptr<LocalCountryFile>();
+ };
+}
+} // namespace platform
diff --git a/platform/local_country_file_utils.hpp b/platform/local_country_file_utils.hpp
index 74b7775375..2b9b852c17 100644
--- a/platform/local_country_file_utils.hpp
+++ b/platform/local_country_file_utils.hpp
@@ -2,14 +2,47 @@
#include "platform/local_country_file.hpp"
+#include "std/shared_ptr.hpp"
#include "std/utility.hpp"
#include "std/vector.hpp"
-namespace local_country_file_utils
+namespace platform
{
+// Removes partially downloaded maps, empty directories and old
+// (format v1) maps. Also, removes old (splitted) Japan and Brazil
+// maps.
+void CleanupMapsDirectory();
+
+// Finds all local map files in a directory. Version of these files is
+// passed as an argument.
void FindAllLocalMapsInDirectory(string const & directory, int64_t version,
vector<LocalCountryFile> & localFiles);
+
+// Finds all local map files in resources and writable
+// directory. Also, for Android, checks /Android/obb directory.
+// Directories should have the following structure:
+//
+// dir/*.mwm -- map files, base name should correspond to countries.txt,
+// -- version is assumed to be zero (unknown).
+// dir/*.mwm.routing -- routing files for corresponding map files,
+// -- version is assumed to be zero (unknown).
+// dir/[0-9]+/*.mwm -- map files, base name should correspond to countries.txt,
+// -- version is assumed to be the name of a directory.
+// dir/[0-9]{1,18}/*.mwm.routing -- routing file for corresponding map files,
+// -- version is assumed to be the name of a directory.
+//
+// We can't derive version of a map file from its header because
+// currently header stores format version + individual mwm's file
+// generation timestamp, not timestamp mentioned in countries.txt.
void FindAllLocalMaps(vector<LocalCountryFile> & localFiles);
+// Tries to parse a version from a string of size not longer than 18
+// symbols and representing an unsigned decimal number. Leading zeroes
+// are allowed.
bool ParseVersion(string const & s, int64_t & version);
-} // namespace local_country_file_utils
+
+// When version is zero, uses writable directory, otherwise, creates
+// directory with name equal to decimal representation of version.
+shared_ptr<LocalCountryFile> PreparePlaceForCountryFiles(CountryFile const & countryFile,
+ int64_t version);
+} // namespace platform
diff --git a/platform/platform.cpp b/platform/platform.cpp
index e9c2841a2b..76d0fe2c38 100644
--- a/platform/platform.cpp
+++ b/platform/platform.cpp
@@ -20,6 +20,8 @@ Platform::EError Platform::ErrnoToError()
return ERR_ACCESS_FAILED;
case ENOTEMPTY:
return ERR_DIRECTORY_NOT_EMPTY;
+ case EEXIST:
+ return ERR_FILE_ALREADY_EXISTS;
default:
return ERR_UNKNOWN;
}
diff --git a/platform/platform.hpp b/platform/platform.hpp
index 28698ed1c2..91f86740d7 100644
--- a/platform/platform.hpp
+++ b/platform/platform.hpp
@@ -25,6 +25,7 @@ public:
ERR_FILE_DOES_NOT_EXIST,
ERR_ACCESS_FAILED,
ERR_DIRECTORY_NOT_EMPTY,
+ ERR_FILE_ALREADY_EXISTS,
ERR_UNKNOWN
};
diff --git a/platform/platform_qt.cpp b/platform/platform_qt.cpp
index 5d4e185dde..004c273446 100644
--- a/platform/platform_qt.cpp
+++ b/platform/platform_qt.cpp
@@ -59,6 +59,8 @@ int Platform::VideoMemoryLimit() const
Platform::EError Platform::MkDir(string const & dirName) const
{
+ if (QDir().exists(dirName.c_str()))
+ return Platform::ERR_FILE_ALREADY_EXISTS;
if(!QDir().mkdir(dirName.c_str()))
{
LOG(LWARNING, ("Can't create directory: ", dirName));
diff --git a/platform/platform_tests/country_file_tests.cpp b/platform/platform_tests/country_file_tests.cpp
index b160876a5b..136aceede6 100644
--- a/platform/platform_tests/country_file_tests.cpp
+++ b/platform/platform_tests/country_file_tests.cpp
@@ -3,24 +3,26 @@
#include "defines.hpp"
#include "platform/country_file.hpp"
+namespace platform
+{
UNIT_TEST(CountryFile_Smoke)
{
CountryFile countryFile("TestCountry");
TEST_EQUAL("TestCountry", countryFile.GetNameWithoutExt(), ());
- TEST_EQUAL("TestCountry" DATA_FILE_EXTENSION, countryFile.GetNameWithExt(TMapOptions::EMapOnly),
- ());
+ TEST_EQUAL("TestCountry" DATA_FILE_EXTENSION, countryFile.GetNameWithExt(TMapOptions::EMap), ());
TEST_EQUAL("TestCountry" DATA_FILE_EXTENSION ROUTING_FILE_EXTENSION,
countryFile.GetNameWithExt(TMapOptions::ECarRouting), ());
TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::ENothing), ());
- TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::EMapOnly), ());
+ TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::EMap), ());
TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::ECarRouting), ());
TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::EMapWithCarRouting), ());
countryFile.SetRemoteSizes(1 /* mapSize */, 2 /* routingSize */);
TEST_EQUAL(0, countryFile.GetRemoteSize(TMapOptions::ENothing), ());
- TEST_EQUAL(1, countryFile.GetRemoteSize(TMapOptions::EMapOnly), ());
+ TEST_EQUAL(1, countryFile.GetRemoteSize(TMapOptions::EMap), ());
TEST_EQUAL(2, countryFile.GetRemoteSize(TMapOptions::ECarRouting), ());
TEST_EQUAL(3, countryFile.GetRemoteSize(TMapOptions::EMapWithCarRouting), ());
}
+} // namespace platform
diff --git a/platform/platform_tests/local_country_file_tests.cpp b/platform/platform_tests/local_country_file_tests.cpp
index 0ae32e93e5..5594a4e63f 100644
--- a/platform/platform_tests/local_country_file_tests.cpp
+++ b/platform/platform_tests/local_country_file_tests.cpp
@@ -16,22 +16,73 @@
#include "std/bind.hpp"
#include "std/set.hpp"
-using namespace local_country_file_utils;
-
+namespace platform
+{
namespace
{
-void CreateTestDir(string const & testDir)
+template <typename T>
+bool Contains(vector<T> const & v, T const & t)
{
- Platform & platform = GetPlatform();
- TEST(!Platform::IsFileExistsByFullPath(testDir),
- ("Please, remove", testDir, "before running the test."));
- TEST_EQUAL(Platform::ERR_OK, platform.MkDir(testDir), ("Can't create directory", testDir));
+ return find(v.begin(), v.end(), t) != v.end();
}
+class ScopedTestDir
+{
+public:
+ ScopedTestDir(string const & path) : m_path(path), m_reset(false)
+ {
+ Platform & platform = GetPlatform();
+ Platform::EError ret = platform.MkDir(m_path);
+ switch (ret)
+ {
+ case Platform::ERR_OK:
+ break;
+ case Platform::ERR_FILE_ALREADY_EXISTS:
+ Platform::EFileType type;
+ TEST_EQUAL(Platform::ERR_OK, Platform::GetFileType(m_path, type), ());
+ TEST_EQUAL(Platform::FILE_TYPE_DIRECTORY, type, ());
+ break;
+ default:
+ CHECK(false, ("Can't create directory:", m_path, "error:", ret));
+ break;
+ }
+ }
+
+ ~ScopedTestDir()
+ {
+ if (m_reset)
+ return;
+
+ Platform::EError ret = Platform::RmDir(m_path);
+ switch (ret)
+ {
+ case Platform::ERR_OK:
+ break;
+ case Platform::ERR_FILE_DOES_NOT_EXIST:
+ LOG(LWARNING, (m_path, "was deleted before destruction of ScopedTestDir."));
+ break;
+ case Platform::ERR_DIRECTORY_NOT_EMPTY:
+ LOG(LWARNING, ("There are files in", m_path));
+ break;
+ default:
+ LOG(LWARNING, ("Platform::RmDir() error:", ret));
+ break;
+ }
+ }
+
+ inline void Reset() { m_reset = true; }
+
+ inline string const GetPath() const { return m_path; }
+
+private:
+ string const m_path;
+ bool m_reset;
+
+ DISALLOW_COPY_AND_MOVE(ScopedTestDir);
+};
+
void CreateTestFile(string const & testFile, string const & contents)
{
- TEST(!Platform::IsFileExistsByFullPath(testFile),
- ("Please, remove", testFile, "before running the test."));
{
FileWriter writer(testFile);
writer.Write(contents.data(), contents.size());
@@ -59,6 +110,7 @@ UNIT_TEST(LocalCountryFile_ParseVersion)
TEST_EQUAL(version, 999999999999999999, ());
TEST(!ParseVersion("1000000000000000000", version), ());
+ TEST(!ParseVersion("00000000000000000000000000000000123", version), ());
TEST(!ParseVersion("", version), ());
TEST(!ParseVersion("150309 ", version), ());
@@ -75,8 +127,7 @@ UNIT_TEST(LocalCountryFile_Smoke)
LocalCountryFile localFile("/test-dir", countryFile, 150309);
- TEST_EQUAL("/test-dir/TestCountry" DATA_FILE_EXTENSION, localFile.GetPath(TMapOptions::EMapOnly),
- ());
+ TEST_EQUAL("/test-dir/TestCountry" DATA_FILE_EXTENSION, localFile.GetPath(TMapOptions::EMap), ());
TEST_EQUAL("/test-dir/TestCountry" DATA_FILE_EXTENSION ROUTING_FILE_EXTENSION,
localFile.GetPath(TMapOptions::ECarRouting), ());
@@ -86,14 +137,14 @@ UNIT_TEST(LocalCountryFile_Smoke)
// Any statement is true about elements of an empty set.
TEST(localFile.OnDisk(TMapOptions::ENothing), ());
- TEST(!localFile.OnDisk(TMapOptions::EMapOnly), ());
+ TEST(!localFile.OnDisk(TMapOptions::EMap), ());
TEST(!localFile.OnDisk(TMapOptions::ECarRouting), ());
TEST(!localFile.OnDisk(TMapOptions::EMapWithCarRouting), ());
TEST_EQUAL("/test-dir", localFile.GetDirectory(), ());
TEST_EQUAL(0, localFile.GetSize(TMapOptions::ENothing), ());
- TEST_EQUAL(0, localFile.GetSize(TMapOptions::EMapOnly), ());
+ TEST_EQUAL(0, localFile.GetSize(TMapOptions::EMap), ());
TEST_EQUAL(0, localFile.GetSize(TMapOptions::ECarRouting), ());
TEST_EQUAL(0, localFile.GetSize(TMapOptions::EMapWithCarRouting), ());
@@ -109,31 +160,31 @@ UNIT_TEST(LocalCountryFile_DiskFiles)
CountryFile countryFile("TestCountry");
countryFile.SetRemoteSizes(1 /* mapSize */, 2 /* routingSize */);
- string const testMapFile = my::JoinFoldersToPath(
- platform.WritableDir(), countryFile.GetNameWithExt(TMapOptions::EMapOnly));
+ string const testMapFile =
+ my::JoinFoldersToPath(platform.WritableDir(), countryFile.GetNameWithExt(TMapOptions::EMap));
string const testRoutingFile = my::JoinFoldersToPath(
platform.WritableDir(), countryFile.GetNameWithExt(TMapOptions::ECarRouting));
LocalCountryFile localFile(platform.WritableDir(), countryFile, 0 /* version */);
- TEST(!localFile.OnDisk(TMapOptions::EMapOnly), ());
+ TEST(!localFile.OnDisk(TMapOptions::EMap), ());
TEST(!localFile.OnDisk(TMapOptions::ECarRouting), ());
TEST(!localFile.OnDisk(TMapOptions::EMapWithCarRouting), ());
CreateTestFile(testMapFile, "map");
localFile.SyncWithDisk();
- TEST(localFile.OnDisk(TMapOptions::EMapOnly), ());
+ TEST(localFile.OnDisk(TMapOptions::EMap), ());
TEST(!localFile.OnDisk(TMapOptions::ECarRouting), ());
TEST(!localFile.OnDisk(TMapOptions::EMapWithCarRouting), ());
- TEST_EQUAL(3, localFile.GetSize(TMapOptions::EMapOnly), ());
+ TEST_EQUAL(3, localFile.GetSize(TMapOptions::EMap), ());
CreateTestFile(testRoutingFile, "routing");
localFile.SyncWithDisk();
- TEST(localFile.OnDisk(TMapOptions::EMapOnly), ());
+ TEST(localFile.OnDisk(TMapOptions::EMap), ());
TEST(localFile.OnDisk(TMapOptions::ECarRouting), ());
TEST(localFile.OnDisk(TMapOptions::EMapWithCarRouting), ());
- TEST_EQUAL(3, localFile.GetSize(TMapOptions::EMapOnly), ());
+ TEST_EQUAL(3, localFile.GetSize(TMapOptions::EMap), ());
TEST_EQUAL(7, localFile.GetSize(TMapOptions::ECarRouting), ());
TEST_EQUAL(10, localFile.GetSize(TMapOptions::EMapWithCarRouting), ());
@@ -144,6 +195,52 @@ UNIT_TEST(LocalCountryFile_DiskFiles)
("Routing file", testRoutingFile, "wasn't deleted by LocalCountryFile."));
}
+UNIT_TEST(LocalCountryFile_DirectoryCleanup)
+{
+ Platform & platform = GetPlatform();
+ string const mapsDir = platform.WritableDir();
+
+ CountryFile japanFile("Japan");
+ CountryFile brazilFile("Brazil");
+ CountryFile irelandFile("Ireland");
+
+ ScopedTestDir testDir1(my::JoinFoldersToPath(mapsDir, "1"));
+ LocalCountryFile japanLocalFile(testDir1.GetPath(), japanFile, 1 /* version */);
+ CreateTestFile(japanLocalFile.GetPath(TMapOptions::EMap), "Japan");
+
+ ScopedTestDir testDir2(my::JoinFoldersToPath(mapsDir, "2"));
+ LocalCountryFile brazilLocalFile(testDir2.GetPath(), brazilFile, 2 /* version */);
+ CreateTestFile(brazilLocalFile.GetPath(TMapOptions::EMap), "Brazil");
+
+ ScopedTestDir testDir3(my::JoinFoldersToPath(mapsDir, "3"));
+
+ LocalCountryFile irelandLocalFile(testDir2.GetPath(), irelandFile, 2 /* version */);
+ CreateTestFile(irelandLocalFile.GetPath(TMapOptions::EMap), "Ireland");
+
+ vector<LocalCountryFile> localFiles;
+ FindAllLocalMaps(localFiles);
+ TEST(Contains(localFiles, japanLocalFile), (japanLocalFile));
+ TEST(Contains(localFiles, brazilLocalFile), (brazilLocalFile));
+ TEST(Contains(localFiles, irelandLocalFile), (irelandLocalFile));
+
+ CleanupMapsDirectory();
+
+ japanLocalFile.SyncWithDisk();
+ TEST_EQUAL(TMapOptions::ENothing, japanLocalFile.GetFiles(), ());
+ TEST(!Platform::IsFileExistsByFullPath(testDir1.GetPath()), ("Empty directory wasn't removed."));
+ testDir1.Reset();
+
+ brazilLocalFile.SyncWithDisk();
+ TEST_EQUAL(TMapOptions::ENothing, brazilLocalFile.GetFiles(), ());
+
+ irelandLocalFile.SyncWithDisk();
+ TEST_EQUAL(TMapOptions::EMap, irelandLocalFile.GetFiles(), ());
+ irelandLocalFile.DeleteFromDisk();
+
+ TEST(!Platform::IsFileExistsByFullPath(testDir3.GetPath()), ("Empty directory wasn't removed."));
+ testDir3.Reset();
+}
+
// Creates test-dir and following files:
// * test-dir/Ireland.mwm
// * test-dir/Netherlands.mwm
@@ -158,41 +255,39 @@ UNIT_TEST(LocalCountryFile_DirectoryLookup)
Platform & platform = GetPlatform();
- string const testDir = my::JoinFoldersToPath(platform.WritableDir(), "test-dir");
- CreateTestDir(testDir);
- MY_SCOPE_GUARD(removeTestDir, bind(&Platform::RmDir, testDir));
+ ScopedTestDir testDir(my::JoinFoldersToPath(platform.WritableDir(), "test-dir"));
string const testIrelandMapFile =
- my::JoinFoldersToPath(testDir, irelandFile.GetNameWithExt(TMapOptions::EMapOnly));
+ my::JoinFoldersToPath(testDir.GetPath(), irelandFile.GetNameWithExt(TMapOptions::EMap));
CreateTestFile(testIrelandMapFile, "Ireland-map");
MY_SCOPE_GUARD(removeTestIrelandMapFile, bind(&FileWriter::DeleteFileX, testIrelandMapFile));
string const testNetherlandsMapFile =
- my::JoinFoldersToPath(testDir, netherlandsFile.GetNameWithExt(TMapOptions::EMapOnly));
+ my::JoinFoldersToPath(testDir.GetPath(), netherlandsFile.GetNameWithExt(TMapOptions::EMap));
CreateTestFile(testNetherlandsMapFile, "Netherlands-map");
MY_SCOPE_GUARD(removeTestNetherlandsMapFile,
bind(&FileWriter::DeleteFileX, testNetherlandsMapFile));
- string const testNetherlandsRoutingFile =
- my::JoinFoldersToPath(testDir, netherlandsFile.GetNameWithExt(TMapOptions::ECarRouting));
+ string const testNetherlandsRoutingFile = my::JoinFoldersToPath(
+ testDir.GetPath(), netherlandsFile.GetNameWithExt(TMapOptions::ECarRouting));
CreateTestFile(testNetherlandsRoutingFile, "Netherlands-routing");
MY_SCOPE_GUARD(removeTestNetherlandsRoutingFile,
bind(&FileWriter::DeleteFileX, testNetherlandsRoutingFile));
vector<LocalCountryFile> localFiles;
- FindAllLocalMapsInDirectory(testDir, 150309, localFiles);
+ FindAllLocalMapsInDirectory(testDir.GetPath(), 150309, localFiles);
sort(localFiles.begin(), localFiles.end());
for (LocalCountryFile & localFile : localFiles)
localFile.SyncWithDisk();
- LocalCountryFile expectedIrelandFile(testDir, irelandFile, 150309);
- expectedIrelandFile.m_files = TMapOptions::EMapOnly;
+ LocalCountryFile expectedIrelandFile(testDir.GetPath(), irelandFile, 150309);
+ expectedIrelandFile.m_files = TMapOptions::EMap;
- LocalCountryFile expectedNetherlandsFile(testDir, netherlandsFile, 150309);
+ LocalCountryFile expectedNetherlandsFile(testDir.GetPath(), netherlandsFile, 150309);
expectedNetherlandsFile.m_files = TMapOptions::EMapWithCarRouting;
vector<LocalCountryFile> expectedLocalFiles = {expectedIrelandFile, expectedNetherlandsFile};
-
+ sort(expectedLocalFiles.begin(), expectedLocalFiles.end());
TEST_EQUAL(expectedLocalFiles, localFiles, ());
}
@@ -206,18 +301,15 @@ UNIT_TEST(LocalCountryFile_AllLocalFilesLookup)
Platform & platform = GetPlatform();
- string const testDir = my::JoinFoldersToPath(platform.WritableDir(), "010101");
- CreateTestDir(testDir);
- MY_SCOPE_GUARD(removeTestDir, bind(&Platform::RmDir, testDir));
+ ScopedTestDir testDir(my::JoinFoldersToPath(platform.WritableDir(), "010101"));
string const testItalyMapFile =
- my::JoinFoldersToPath(testDir, italyFile.GetNameWithExt(TMapOptions::EMapOnly));
+ my::JoinFoldersToPath(testDir.GetPath(), italyFile.GetNameWithExt(TMapOptions::EMap));
CreateTestFile(testItalyMapFile, "Italy-map");
MY_SCOPE_GUARD(remoteTestItalyMapFile, bind(&FileWriter::DeleteFileX, testItalyMapFile));
vector<LocalCountryFile> localFiles;
FindAllLocalMaps(localFiles);
- LOG(LINFO, (localFiles));
multiset<LocalCountryFile> localFilesSet(localFiles.begin(), localFiles.end());
LocalCountryFile expectedWorldFile(platform.WritableDir(), CountryFile(WORLD_FILE_NAME),
@@ -228,6 +320,35 @@ UNIT_TEST(LocalCountryFile_AllLocalFilesLookup)
CountryFile(WORLD_COASTS_FILE_NAME), 0 /* version */);
TEST_EQUAL(1, localFilesSet.count(expectedWorldCoastsFile), ());
- LocalCountryFile expectedItalyFile(testDir, italyFile, 10101);
+ LocalCountryFile expectedItalyFile(testDir.GetPath(), italyFile, 10101);
TEST_EQUAL(1, localFilesSet.count(expectedItalyFile), ());
}
+
+UNIT_TEST(LocalCountryFile_PreparePlaceForCountryFiles)
+{
+ Platform & platform = GetPlatform();
+
+ CountryFile italyFile("Italy");
+ LocalCountryFile expectedItalyFile(platform.WritableDir(), italyFile, 0 /* version */);
+ shared_ptr<LocalCountryFile> italyLocalFile =
+ PreparePlaceForCountryFiles(italyFile, 0 /* version */);
+ TEST(italyLocalFile.get(), ());
+ TEST_EQUAL(expectedItalyFile, *italyLocalFile, ());
+
+ ScopedTestDir directoryForV1(my::JoinFoldersToPath(platform.WritableDir(), "1"));
+
+ CountryFile germanyFile("Germany");
+ LocalCountryFile expectedGermanyFile(directoryForV1.GetPath(), germanyFile, 1 /* version */);
+ shared_ptr<LocalCountryFile> germanyLocalFile =
+ PreparePlaceForCountryFiles(germanyFile, 1 /* version */);
+ TEST(germanyLocalFile.get(), ());
+ TEST_EQUAL(expectedGermanyFile, *germanyLocalFile, ());
+
+ CountryFile franceFile("France");
+ LocalCountryFile expectedFranceFile(directoryForV1.GetPath(), franceFile, 1 /* version */);
+ shared_ptr<LocalCountryFile> franceLocalFile =
+ PreparePlaceForCountryFiles(franceFile, 1 /* version */);
+ TEST(franceLocalFile.get(), ());
+ TEST_EQUAL(expectedFranceFile, *franceLocalFile, ());
+}
+} // namespace platform