1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#include "generator/update_generator.hpp"
#include "defines.hpp"
#include "platform/platform.hpp"
#include "storage/country.hpp"
#include "coding/file_writer.hpp"
#include "base/string_utils.hpp"
#include "base/logging.hpp"
#include "base/macros.hpp"
#include "base/timer.hpp"
#include "std/iterator.hpp"
using namespace storage;
namespace update
{
// we don't support files without name or without extension
/*
bool SplitExtension(string const & file, string & name, string & ext)
{
// get extension
size_t const index = file.find_last_of('.');
if (index == string::npos || (index + 1) == file.size() || index == 0 || file == "." || file == "..")
{
name = file;
ext.clear();
return false;
}
ext = file.substr(index);
name = file.substr(0, index);
return true;
}
*/
class SizeUpdater
{
size_t m_processedFiles;
string m_dataDir;
Platform::FilesList & m_files;
uint64_t GetFileSize(CountryFile const & cnt, TMapOptions opt) const
{
uint64_t sz = 0;
string const fName = cnt.GetFileWithExt(opt);
if (!GetPlatform().GetFileSizeByFullPath(m_dataDir + fName, sz))
{
LOG(opt == TMapOptions::EMapOnly ? LCRITICAL : LWARNING, ("File was not found:", fName));
return 0;
}
CHECK_GREATER(sz, 0, ("Zero file size?", fName));
return sz;
}
public:
SizeUpdater(string const & dataDir, Platform::FilesList & files)
: m_processedFiles(0), m_dataDir(dataDir), m_files(files)
{
}
~SizeUpdater()
{
LOG(LINFO, (m_processedFiles, "file sizes were updated in the country list"));
if (!m_files.empty())
LOG(LWARNING, ("Files left unprocessed:", m_files));
}
template <class T> void operator() (T & c)
{
for (size_t i = 0; i < c.Value().m_files.size(); ++i)
{
CountryFile & cnt = c.Value().m_files[i];
++m_processedFiles;
cnt.AssignSizes(GetFileSize(cnt, TMapOptions::EMapOnly),
GetFileSize(cnt, TMapOptions::ECarRouting));
string const fName = cnt.GetFileWithoutExt() + DATA_FILE_EXTENSION;
auto found = find(m_files.begin(), m_files.end(), fName);
if (found != m_files.end())
m_files.erase(found);
else
LOG(LWARNING, ("No file ", fName, " on disk for the record in countries.txt"));
}
}
};
bool UpdateCountries(string const & dataDir)
{
Platform::FilesList mwmFiles;
GetPlatform().GetFilesByExt(dataDir, DATA_FILE_EXTENSION, mwmFiles);
// remove some files from list
char const * filesToRemove[] = {
"minsk-pass" DATA_FILE_EXTENSION,
WORLD_FILE_NAME DATA_FILE_EXTENSION,
WORLD_COASTS_FILE_NAME DATA_FILE_EXTENSION
};
for (size_t i = 0; i < ARRAY_SIZE(filesToRemove); ++i)
{
auto found = find(mwmFiles.begin(), mwmFiles.end(), filesToRemove[i]);
if (found != mwmFiles.end())
mwmFiles.erase(found);
}
if (mwmFiles.empty())
return false;
else
LOG(LINFO, (mwmFiles.size(), "mwm files were found"));
// load current countries information to update file sizes
storage::CountriesContainerT countries;
string jsonBuffer;
{
ReaderPtr<Reader>(GetPlatform().GetReader(COUNTRIES_FILE)).ReadAsString(jsonBuffer);
storage::LoadCountries(jsonBuffer, countries);
// using move semantics for mwmFiles
SizeUpdater sizeUpdater(dataDir, mwmFiles);
countries.ForEachChildren(sizeUpdater);
}
storage::SaveCountries(my::TodayAsYYMMDD(), countries, jsonBuffer);
{
string const outFileName = GetPlatform().WritablePathForFile(COUNTRIES_FILE".updated");
FileWriter f(outFileName);
f.Write(&jsonBuffer[0], jsonBuffer.size());
LOG(LINFO, ("Saved updated countries to", outFileName));
}
return true;
}
} // namespace update
|