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
parentc53d7f1494773d1c5b499e858caa7fab436ac5fa (diff)
Review fixes.
-rw-r--r--android/jni/com/mapswithme/country/country_helper.cpp2
-rw-r--r--android/jni/com/mapswithme/country/country_helper.hpp2
-rw-r--r--android/jni/com/mapswithme/maps/Framework.hpp7
-rw-r--r--coding/coding_tests/file_utils_test.cpp21
-rw-r--r--coding/file_name_utils.cpp18
-rw-r--r--coding/file_name_utils.hpp5
-rw-r--r--iphone/Maps/ActiveMapsVC.mm2
-rw-r--r--iphone/Maps/Classes/CustomAlert/DownloadTransitMapsAlert/MWMDownloadTransitMapAlert.mm10
-rw-r--r--iphone/Maps/Classes/MapCell.h1
-rw-r--r--iphone/Maps/Classes/MapViewController.mm2
-rw-r--r--iphone/Maps/CountryTreeVC.mm2
-rw-r--r--map/active_maps_layout.cpp6
-rw-r--r--map/active_maps_layout.hpp2
-rw-r--r--map/country_status_display.cpp2
-rw-r--r--map/country_status_display.hpp6
-rw-r--r--map/framework.cpp10
-rw-r--r--map/framework.hpp7
-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
-rw-r--r--qt/draw_widget.cpp2
-rw-r--r--qt/update_dialog.cpp12
-rw-r--r--storage/country.cpp14
-rw-r--r--storage/country.hpp2
-rw-r--r--storage/storage.cpp21
-rw-r--r--storage/storage_defines.hpp10
-rw-r--r--storage/storage_tests/storage_tests.cpp4
37 files changed, 490 insertions, 147 deletions
diff --git a/android/jni/com/mapswithme/country/country_helper.cpp b/android/jni/com/mapswithme/country/country_helper.cpp
index 6e9f6796a3..248fc86244 100644
--- a/android/jni/com/mapswithme/country/country_helper.cpp
+++ b/android/jni/com/mapswithme/country/country_helper.cpp
@@ -8,7 +8,7 @@ namespace storage_utils
storage::CountryTree & GetTree() { return frm()->GetCountryTree(); }
storage::ActiveMapsLayout::TGroup ToGroup(int group) { return static_cast<storage::ActiveMapsLayout::TGroup>(group); }
- storage::TMapOptions ToOptions(int options) {return static_cast<storage::TMapOptions>(options); }
+ TMapOptions ToOptions(int options) { return static_cast<TMapOptions>(options); }
jlongArray ToArray(JNIEnv * env, storage::LocalAndRemoteSizeT const & size)
{
jlongArray result = env->NewLongArray(2);
diff --git a/android/jni/com/mapswithme/country/country_helper.hpp b/android/jni/com/mapswithme/country/country_helper.hpp
index e6636e7417..f02772d613 100644
--- a/android/jni/com/mapswithme/country/country_helper.hpp
+++ b/android/jni/com/mapswithme/country/country_helper.hpp
@@ -12,6 +12,6 @@ namespace storage_utils
storage::CountryTree & GetTree();
storage::ActiveMapsLayout::TGroup ToGroup(int group);
- storage::TMapOptions ToOptions(int options);
+ TMapOptions ToOptions(int options);
jlongArray ToArray(JNIEnv * env, storage::LocalAndRemoteSizeT const & sizes);
}
diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp
index 505e56bc37..e27ba812b4 100644
--- a/android/jni/com/mapswithme/maps/Framework.hpp
+++ b/android/jni/com/mapswithme/maps/Framework.hpp
@@ -6,6 +6,8 @@
#include "../../../../../search/result.hpp"
+#include "../../../../../platform/country_defines.hpp"
+
#include "../../../../../geometry/avg_vector.hpp"
#include "../../../../../base/deferred_task.hpp"
@@ -174,8 +176,9 @@ namespace android
storage::ActiveMapsLayout::TGroup const & newGroup, int newPosition);
virtual void CountryStatusChanged(storage::ActiveMapsLayout::TGroup const & group, int position,
storage::TStatus const & oldStatus, storage::TStatus const & newStatus);
- virtual void CountryOptionsChanged(storage::ActiveMapsLayout::TGroup const & group, int position,
- storage::TMapOptions const & oldOpt, storage::TMapOptions const & newOpt);
+ virtual void CountryOptionsChanged(storage::ActiveMapsLayout::TGroup const & group,
+ int position, TMapOptions const & oldOpt,
+ TMapOptions const & newOpt);
virtual void DownloadingProgressUpdate(storage::ActiveMapsLayout::TGroup const & group, int position,
storage::LocalAndRemoteSizeT const & progress);
};
diff --git a/coding/coding_tests/file_utils_test.cpp b/coding/coding_tests/file_utils_test.cpp
index d5c8ca565c..bba7856b39 100644
--- a/coding/coding_tests/file_utils_test.cpp
+++ b/coding/coding_tests/file_utils_test.cpp
@@ -38,3 +38,24 @@ UNIT_TEST(FileName_Smoke)
my::GetNameWithoutExt(name);
TEST_EQUAL(name, "test", ());
}
+
+UNIT_TEST(FileName_GetDirectory)
+{
+// TODO (@gorshenin): implement a Clean() method to clean file path
+// (remove redundant separators, correctly collapse dots, dot-dots, etc.).
+#if !defined(OMIM_OS_WINDOWS)
+ TEST_EQUAL("/tmp", my::GetDirectory("/tmp/evil\\file"), ());
+ TEST_EQUAL(".", my::GetDirectory("evil\\file"), ());
+
+ TEST_EQUAL("/", my::GetDirectory("/somefile.txt"), ());
+
+ TEST_EQUAL("/", my::GetDirectory("////somefile"), ());
+ TEST_EQUAL("a/b", my::GetDirectory("a/b///somefile.txt"), ());
+
+ TEST_EQUAL("/a/b", my::GetDirectory("/a/b/c"), ());
+ TEST_EQUAL("/a/b", my::GetDirectory("/a/b/c.txt"), ());
+
+ TEST_EQUAL(".", my::GetDirectory("somefile.txt"), ());
+ TEST_EQUAL(".", my::GetDirectory("somefile"), ());
+#endif // !defined(OMIM_OS_WINDOWS)
+}
diff --git a/coding/file_name_utils.cpp b/coding/file_name_utils.cpp
index 9533705ada..3750c3673c 100644
--- a/coding/file_name_utils.cpp
+++ b/coding/file_name_utils.cpp
@@ -1,9 +1,7 @@
#include "coding/file_name_utils.hpp"
-
namespace my
{
-
void GetNameWithoutExt(string & name)
{
string::size_type const i = name.rfind('.');
@@ -24,6 +22,19 @@ void GetNameFromFullPath(string & name)
name = name.substr(i+1);
}
+string GetDirectory(string const & name)
+{
+ string const sep = GetNativeSeparator();
+ size_t const sepSize = sep.size();
+
+ string::size_type i = name.rfind(sep);
+ if (i == string::npos)
+ return ".";
+ while (i > sepSize && (name.substr(i - sepSize, sepSize) == sep))
+ i -= sepSize;
+ return i == 0 ? sep : name.substr(0, i);
+}
+
string GetNativeSeparator()
{
#ifdef OMIM_OS_WINDOWS
@@ -63,5 +74,4 @@ string JoinFoldersToPath(const vector<string> & folders, const string & file)
result += file;
return result;
}
-
-}
+} // namespace my
diff --git a/coding/file_name_utils.hpp b/coding/file_name_utils.hpp
index 91f38fda77..ddef2af4a9 100644
--- a/coding/file_name_utils.hpp
+++ b/coding/file_name_utils.hpp
@@ -13,6 +13,11 @@ namespace my
/// Get file name from full path.
void GetNameFromFullPath(string & name);
+ /// Returns all but last components of the path. After dropping the last
+ /// component, all trailing slashes are removed, unless the result is a
+ /// root directory. If the argument is a single component, returns ".".
+ string GetDirectory(string const & path);
+
/// Get folder separator for specific platform
string GetNativeSeparator();
diff --git a/iphone/Maps/ActiveMapsVC.mm b/iphone/Maps/ActiveMapsVC.mm
index adba16cadc..0ac86b236a 100644
--- a/iphone/Maps/ActiveMapsVC.mm
+++ b/iphone/Maps/ActiveMapsVC.mm
@@ -128,7 +128,7 @@ extern NSString * const MapsStatusChangedNotification;
return [NSString stringWithUTF8String:self.mapsLayout.GetCountryName(self.selectedGroup, self.selectedPosition).c_str()];
}
-- (uint64_t)selectedMapSizeWithOptions:(storage::TMapOptions)options
+- (uint64_t)selectedMapSizeWithOptions:(TMapOptions)options
{
return self.mapsLayout.GetCountrySize(self.selectedGroup, self.selectedPosition, options).second;
}
diff --git a/iphone/Maps/Classes/CustomAlert/DownloadTransitMapsAlert/MWMDownloadTransitMapAlert.mm b/iphone/Maps/Classes/CustomAlert/DownloadTransitMapsAlert/MWMDownloadTransitMapAlert.mm
index e99e4383fa..567183be8d 100644
--- a/iphone/Maps/Classes/CustomAlert/DownloadTransitMapsAlert/MWMDownloadTransitMapAlert.mm
+++ b/iphone/Maps/Classes/CustomAlert/DownloadTransitMapsAlert/MWMDownloadTransitMapAlert.mm
@@ -33,10 +33,12 @@ extern UIColor * const kActiveDownloaderViewColor;
MWMDownloadTransitMapAlert *alert = [[[NSBundle mainBundle] loadNibNamed:kDownloadTransitMapAlertNibName owner:self options:nil] firstObject];
ActiveMapsLayout& layout = GetFramework().GetCountryTree().GetActiveMapLayout();
alert.countryLabel.text = [NSString stringWithUTF8String:layout.GetFormatedCountryName(index).c_str()];
- alert.sizeLabel.text = [NSString stringWithFormat:@"%@ %@", @(layout.GetCountrySize(index, storage::TMapOptions::EMapWithCarRouting).second/(1024 * 1024)), L(@"mb")];
- alert.downloaderBlock = ^{
- layout.DownloadMap(index, storage::TMapOptions::EMapWithCarRouting);
- };
+ alert.sizeLabel.text = [NSString
+ stringWithFormat:@"%@ %@",
+ @(layout.GetCountrySize(index, TMapOptions::EMapWithCarRouting).second /
+ (1024 * 1024)),
+ L(@"mb")];
+ alert.downloaderBlock = ^{ layout.DownloadMap(index, TMapOptions::EMapWithCarRouting); };
[alert configure];
return alert;
}
diff --git a/iphone/Maps/Classes/MapCell.h b/iphone/Maps/Classes/MapCell.h
index ae2c3d1d35..5630cb06f3 100644
--- a/iphone/Maps/Classes/MapCell.h
+++ b/iphone/Maps/Classes/MapCell.h
@@ -4,6 +4,7 @@
#import "BadgeView.h"
#include "../../storage/storage_defines.hpp"
+#include "../../platform/country_defines.hpp"
using namespace storage;
diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm
index 1b9c2dc497..17bc886935 100644
--- a/iphone/Maps/Classes/MapViewController.mm
+++ b/iphone/Maps/Classes/MapViewController.mm
@@ -676,7 +676,7 @@ typedef NS_ENUM(NSUInteger, UserTouchesAction)
LocalAndRemoteSizeT sizes = layout.GetRemoteCountrySizes(idx);
uint64_t sizeToDownload = sizes.first;
TMapOptions options = static_cast<TMapOptions>(opt);
- if(options & TMapOptions::ECarRouting)
+ if(HasOptions(options, TMapOptions::ECarRouting))
sizeToDownload += sizes.second;
NSString * name = [NSString stringWithUTF8String:layout.GetCountryName(idx).c_str()];
diff --git a/iphone/Maps/CountryTreeVC.mm b/iphone/Maps/CountryTreeVC.mm
index a192c7e890..ede8d89437 100644
--- a/iphone/Maps/CountryTreeVC.mm
+++ b/iphone/Maps/CountryTreeVC.mm
@@ -135,7 +135,7 @@ extern NSString * const MapsStatusChangedNotification;
return [NSString stringWithUTF8String:self.tree.GetChildName(self.selectedPosition).c_str()];
}
-- (uint64_t)selectedMapSizeWithOptions:(storage::TMapOptions)options
+- (uint64_t)selectedMapSizeWithOptions:(TMapOptions)options
{
return self.tree.GetLeafSize(self.selectedPosition, options).second;
}
diff --git a/map/active_maps_layout.cpp b/map/active_maps_layout.cpp
index e4fce36dd1..8dc200ded3 100644
--- a/map/active_maps_layout.cpp
+++ b/map/active_maps_layout.cpp
@@ -647,13 +647,13 @@ void ActiveMapsLayout::NotifyOptionsChanged(TGroup const & group, int position,
TMapOptions ActiveMapsLayout::ValidOptionsForDownload(TMapOptions const & options)
{
- return options | TMapOptions::EMap;
+ return SetOptions(options, TMapOptions::EMap);
}
TMapOptions ActiveMapsLayout::ValidOptionsForDelete(TMapOptions const & options)
{
- if (options & TMapOptions::EMap)
- return options | TMapOptions::ECarRouting;
+ if (HasOptions(options, TMapOptions::EMap))
+ return SetOptions(options, TMapOptions::ECarRouting);
return options;
}
diff --git a/map/active_maps_layout.hpp b/map/active_maps_layout.hpp
index 8c3ae584ac..27c1e101e4 100644
--- a/map/active_maps_layout.hpp
+++ b/map/active_maps_layout.hpp
@@ -3,6 +3,8 @@
#include "storage/storage_defines.hpp"
#include "storage/index.hpp"
+#include "platform/country_defines.hpp"
+
#include "base/buffer_vector.hpp"
#include "std/string.hpp"
diff --git a/map/country_status_display.cpp b/map/country_status_display.cpp
index 0fdf2fd697..bcad44fdfb 100644
--- a/map/country_status_display.cpp
+++ b/map/country_status_display.cpp
@@ -449,7 +449,7 @@ void CountryStatusDisplay::OnButtonClicked(gui::Element const * button)
TMapOptions options = TMapOptions::EMap;
if (button == m_secondaryButton.get())
- options |= TMapOptions::ECarRouting;
+ options = SetOptions(options, TMapOptions::ECarRouting);
ASSERT(m_downloadCallback, ());
int opt = static_cast<int>(options);
diff --git a/map/country_status_display.hpp b/map/country_status_display.hpp
index e7aced902b..c9ab39e62a 100644
--- a/map/country_status_display.hpp
+++ b/map/country_status_display.hpp
@@ -3,7 +3,7 @@
#include "map/active_maps_layout.hpp"
#include "gui/element.hpp"
-#include "storage/storage_defines.hpp"
+#include "platform/country_defines.hpp"
#ifdef OMIM_OS_ANDROID
#include "../base/mutex.hpp"
@@ -70,7 +70,9 @@ private:
virtual void CountryStatusChanged(storage::ActiveMapsLayout::TGroup const & group, int position,
storage::TStatus const & oldStatus, storage::TStatus const & newStatus);
virtual void CountryOptionsChanged(storage::ActiveMapsLayout::TGroup const & group, int position,
- storage::TMapOptions const & oldOpt, storage::TMapOptions const & newOpt){}
+ TMapOptions const & oldOpt, TMapOptions const & newOpt)
+ {
+ }
virtual void DownloadingProgressUpdate(storage::ActiveMapsLayout::TGroup const & group, int position,
storage::LocalAndRemoteSizeT const & progress);
diff --git a/map/framework.cpp b/map/framework.cpp
index 88fb96885f..f6c80d25e0 100644
--- a/map/framework.cpp
+++ b/map/framework.cpp
@@ -396,20 +396,20 @@ double Framework::GetVisualScale() const
void Framework::DeleteCountry(TIndex const & index, TMapOptions opt)
{
- if (opt & TMapOptions::EMap)
+ if (HasOptions(opt, TMapOptions::EMap))
opt = TMapOptions::EMapWithCarRouting;
if (!m_storage.DeleteFromDownloader(index))
{
CountryFile const & file = m_storage.CountryByIndex(index).GetFile();
- if (opt & TMapOptions::EMap)
+ if (HasOptions(opt, TMapOptions::EMap))
{
if (m_model.DeleteMap(file.GetFileWithExt(TMapOptions::EMap)))
InvalidateRect(GetCountryBounds(file.GetFileWithoutExt()), true);
}
- if (opt & TMapOptions::ECarRouting)
+ if (HasOptions(opt, TMapOptions::ECarRouting))
m_routingSession.DeleteIndexFile(file.GetFileWithExt(TMapOptions::ECarRouting));
m_storage.NotifyStatusChanged(index);
@@ -470,7 +470,7 @@ void Framework::ShowCountry(TIndex const & index)
void Framework::UpdateAfterDownload(string const & fileName, TMapOptions opt)
{
- if (opt & TMapOptions::EMap)
+ if (HasOptions(opt, TMapOptions::EMap))
{
// Delete old (splitted) map files, if any.
char const * arr[] = { "Japan", "Brazil" };
@@ -496,7 +496,7 @@ void Framework::UpdateAfterDownload(string const & fileName, TMapOptions opt)
}
// Replace routing file.
- if (opt & TMapOptions::ECarRouting)
+ if (HasOptions(opt, TMapOptions::ECarRouting))
{
string routingName = fileName + ROUTING_FILE_EXTENSION;
m_routingSession.DeleteIndexFile(routingName);
diff --git a/map/framework.hpp b/map/framework.hpp
index 0959f6d9d9..d42279b2b8 100644
--- a/map/framework.hpp
+++ b/map/framework.hpp
@@ -33,6 +33,7 @@
#include "storage/storage.hpp"
+#include "platform/country_defines.hpp"
#include "platform/location.hpp"
#ifndef USE_DRAPE
@@ -135,7 +136,7 @@ protected:
/// This function is called by m_storage to notify that country downloading is finished.
/// @param[in] file Country file name (without extensions).
- void UpdateAfterDownload(string const & file, storage::TMapOptions opt);
+ void UpdateAfterDownload(string const & file, TMapOptions opt);
//my::Timer m_timer;
inline double ElapsedSeconds() const
@@ -211,9 +212,9 @@ public:
/// @name This functions is used by Downloader UI.
//@{
/// options - flags that signal about parts of map that must be deleted
- void DeleteCountry(storage::TIndex const & index, storage::TMapOptions opt);
+ void DeleteCountry(storage::TIndex const & index, TMapOptions opt);
/// options - flags that signal about parts of map that must be downloaded
- void DownloadCountry(storage::TIndex const & index, storage::TMapOptions opt);
+ void DownloadCountry(storage::TIndex const & index, TMapOptions opt);
storage::TStatus GetCountryStatus(storage::TIndex const & index) const;
string GetCountryName(storage::TIndex const & index) const;
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
diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp
index 6a7f94772d..92b8aca160 100644
--- a/qt/draw_widget.cpp
+++ b/qt/draw_widget.cpp
@@ -99,7 +99,7 @@ namespace qt
if (opt == -1)
layout.RetryDownloading(idx);
else
- layout.DownloadMap(idx, static_cast<storage::TMapOptions>(opt));
+ layout.DownloadMap(idx, static_cast<TMapOptions>(opt));
});
m_framework->SetRouteBuildingListener([] (routing::IRouter::ResultCode, vector<storage::TIndex> const &)
diff --git a/qt/update_dialog.cpp b/qt/update_dialog.cpp
index 9afa8b8172..e94964a90c 100644
--- a/qt/update_dialog.cpp
+++ b/qt/update_dialog.cpp
@@ -150,10 +150,10 @@ namespace qt
QAbstractButton * res = ask.clickedButton();
if (res == btns[0])
- m_framework.DownloadCountry(countryIndex, storage::TMapOptions::EMapWithCarRouting);
+ m_framework.DownloadCountry(countryIndex, TMapOptions::EMapWithCarRouting);
if (res == btns[1])
- m_framework.DeleteCountry(countryIndex, storage::TMapOptions::EMapWithCarRouting);
+ m_framework.DeleteCountry(countryIndex, TMapOptions::EMapWithCarRouting);
}
break;
@@ -167,18 +167,18 @@ namespace qt
ask.setDefaultButton(QMessageBox::No);
if (ask.exec() == QMessageBox::Yes)
- m_framework.DeleteCountry(countryIndex, storage::TMapOptions::EMapWithCarRouting);
+ m_framework.DeleteCountry(countryIndex, TMapOptions::EMapWithCarRouting);
}
break;
case TStatus::ENotDownloaded:
case TStatus::EDownloadFailed:
- m_framework.DownloadCountry(countryIndex, storage::TMapOptions::EMapWithCarRouting);
+ m_framework.DownloadCountry(countryIndex, TMapOptions::EMapWithCarRouting);
break;
case TStatus::EInQueue:
case TStatus::EDownloading:
- m_framework.DeleteCountry(countryIndex, storage::TMapOptions::EMapWithCarRouting);
+ m_framework.DeleteCountry(countryIndex, TMapOptions::EMapWithCarRouting);
break;
default:
@@ -247,7 +247,7 @@ namespace qt
QString statusString;
LocalAndRemoteSizeT size(0, 0);
- storage::TMapOptions const options = storage::TMapOptions::EMapWithCarRouting;
+ TMapOptions const options = TMapOptions::EMapWithCarRouting;
Storage const & st = GetStorage();
switch (m_framework.GetCountryStatus(index))
diff --git a/storage/country.cpp b/storage/country.cpp
index 022a4f06fc..3e39eb674a 100644
--- a/storage/country.cpp
+++ b/storage/country.cpp
@@ -41,13 +41,15 @@ uint32_t CountryFile::GetRemoteSize(TMapOptions opt) const
{
switch (opt)
{
- case TMapOptions::EMap: return m_mapSize;
- case TMapOptions::ECarRouting: return m_routingSize;
- case TMapOptions::EMapWithCarRouting : return m_mapSize + m_routingSize;
+ case TMapOptions::ENothing:
+ return 0;
+ case TMapOptions::EMap:
+ return m_mapSize;
+ case TMapOptions::ECarRouting:
+ return m_routingSize;
+ case TMapOptions::EMapWithCarRouting:
+ return m_mapSize + m_routingSize;
}
-
- ASSERT(false, ());
- return 0;
}
/*
diff --git a/storage/country.hpp b/storage/country.hpp
index a5ce677a4c..0140722634 100644
--- a/storage/country.hpp
+++ b/storage/country.hpp
@@ -4,6 +4,8 @@
#include "storage/simple_tree.hpp"
#include "storage/country_decl.hpp"
+#include "platform/country_defines.hpp"
+
#include "defines.hpp"
#include "geometry/rect2d.hpp"
diff --git a/storage/storage.cpp b/storage/storage.cpp
index 3d432e69c4..bad306c873 100644
--- a/storage/storage.cpp
+++ b/storage/storage.cpp
@@ -62,8 +62,8 @@ namespace storage
// Don't queue files with 0-size on server (empty or absent).
// Downloader has lots of assertions about it. If car routing was
// requested for downloading, try to download it first.
- if ((m_init & TMapOptions::ECarRouting) &&
- (m_pFile->GetRemoteSize(TMapOptions::ECarRouting) > 0))
+ if (HasOptions(m_init, TMapOptions::ECarRouting) &&
+ m_pFile->GetRemoteSize(TMapOptions::ECarRouting) > 0)
{
m_current = TMapOptions::ECarRouting;
}
@@ -78,10 +78,10 @@ namespace storage
TMapOptions const arr[] = { TMapOptions::EMap, TMapOptions::ECarRouting };
for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
{
- if (opt & arr[i] && !(m_init & arr[i]))
+ if (HasOptions(opt, arr[i]) && !HasOptions(m_init, arr[i]))
{
- m_init |= arr[i];
- m_left |= arr[i];
+ m_init = SetOptions(m_init, arr[i]);
+ m_left = SetOptions(m_left, arr[i]);
}
}
}
@@ -114,9 +114,9 @@ namespace storage
ASSERT(m_pFile->GetFileSize(TMapOptions::ECarRouting) == 0, ());
#endif
- if (m_init & TMapOptions::ECarRouting)
+ if (HasOptions(m_init, TMapOptions::ECarRouting))
{
- ASSERT(m_init & TMapOptions::EMap, ());
+ ASSERT(HasOptions(m_init, TMapOptions::EMap), ());
if (currentStatus == TStatus::EOnDisk)
{
@@ -141,7 +141,7 @@ namespace storage
TMapOptions const arr[] = { TMapOptions::EMap, TMapOptions::ECarRouting };
for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
{
- if (m_init & arr[i])
+ if (HasOptions(m_init, arr[i]))
{
res.first += m_pFile->GetFileSize(arr[i]);
res.second += m_pFile->GetRemoteSize(arr[i]);
@@ -157,7 +157,7 @@ namespace storage
TMapOptions const arr[] = { TMapOptions::EMap, TMapOptions::ECarRouting };
for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
{
- if (m_init & arr[i])
+ if (HasOptions(m_init, arr[i]))
res += m_pFile->GetRemoteSize(arr[i]);
}
@@ -311,7 +311,7 @@ namespace storage
string const fName = QueuedCountry(*this, index, TMapOptions::ECarRouting).GetFileName();
Platform const & pl = GetPlatform();
if (pl.IsFileExistsByFullPath(pl.WritablePathForFile(fName)))
- options |= TMapOptions::ECarRouting;
+ options = SetOptions(options, TMapOptions::ECarRouting);
}
}
@@ -474,6 +474,7 @@ namespace storage
string optionName;
switch (cnt.GetInitOptions())
{
+ case TMapOptions::ENothing: optionName = "Nothing"; break;
case TMapOptions::EMap: optionName = "Map"; break;
case TMapOptions::ECarRouting: optionName = "CarRouting"; break;
case TMapOptions::EMapWithCarRouting: optionName = "MapWithCarRouting"; break;
diff --git a/storage/storage_defines.hpp b/storage/storage_defines.hpp
index 9cea845c27..5da65a105c 100644
--- a/storage/storage_defines.hpp
+++ b/storage/storage_defines.hpp
@@ -1,7 +1,5 @@
#pragma once
-#include "3party/enum_flags.hpp"
-
#include "std/stdint.hpp"
#include "std/string.hpp"
#include "std/utility.hpp"
@@ -23,13 +21,5 @@ namespace storage
string DebugPrint(TStatus status);
- ENUM_FLAGS(TMapOptions)
- enum class TMapOptions
- {
- EMap = 0x1,
- ECarRouting = 0x2,
- EMapWithCarRouting = 0x3
- };
-
typedef pair<uint64_t, uint64_t> LocalAndRemoteSizeT;
}
diff --git a/storage/storage_tests/storage_tests.cpp b/storage/storage_tests/storage_tests.cpp
index 5ce8f52b68..60d795d4c7 100644
--- a/storage/storage_tests/storage_tests.cpp
+++ b/storage/storage_tests/storage_tests.cpp
@@ -190,9 +190,9 @@ void OnCountryDownloaded(string const & mapFileName, TMapOptions files)
string const localMapFile = my::JoinFoldersToPath(platform.WritableDir(), mapFileName);
string const localRoutingFile = localMapFile + ROUTING_FILE_EXTENSION;
- if (files & TMapOptions::EMap)
+ if (HasOptions(files, TMapOptions::EMap))
CHECK(my::RenameFileX(localMapFile + READY_FILE_EXTENSION, localMapFile), ());
- if (files & TMapOptions::ECarRouting)
+ if (HasOptions(files, TMapOptions::ECarRouting))
CHECK(my::RenameFileX(localRoutingFile + READY_FILE_EXTENSION, localRoutingFile), ());
}