Minor refactorings

Signed-off-by: Alexander Borsuk <me@alex.bio>
This commit is contained in:
Alexander Borsuk 2022-03-13 00:27:19 +01:00 committed by Viktor Govako
parent b591f17f1e
commit c5fc2b533f
13 changed files with 158 additions and 123 deletions

View file

@ -76,6 +76,9 @@ UNIT_TEST(FilePath_Slash)
UNIT_TEST(FilePath_Join)
{
TEST_EQUAL("dir", base::JoinPath("", "dir"), ());
TEST_EQUAL("dir", base::JoinPath("", "/dir"), ());
TEST_EQUAL("dir/file", base::JoinPath("", "dir", "file"), ());
TEST_EQUAL("omim/strings.txt", base::JoinPath("omim", "strings.txt"), ());
TEST_EQUAL("omim/strings.txt", base::JoinPath("omim/", "strings.txt"), ());
TEST_EQUAL("../../omim/strings.txt", base::JoinPath("..", "..", "omim", "strings.txt"), ());

View file

@ -882,6 +882,8 @@ UNIT_TEST(StartsWith)
std::string s("xyz");
TEST(StartsWith(s, ""), ());
TEST(StartsWith(s, "x"), ());
TEST(StartsWith(s, 'x'), ());
TEST(!StartsWith(s, 'z'), ());
TEST(StartsWith(s, "xyz"), ());
TEST(!StartsWith(s, "xyzabc"), ());
TEST(!StartsWith(s, "ayz"), ());
@ -906,6 +908,8 @@ UNIT_TEST(EndsWith)
std::string const s("xyz");
TEST(EndsWith(s, ""), ());
TEST(EndsWith(s, "z"), ());
TEST(EndsWith(s, 'z'), ());
TEST(!EndsWith(s, 'x'), ());
TEST(EndsWith(s, "yz"), ());
TEST(EndsWith(s, "xyz"), ());
TEST(!EndsWith(s, "abcxyz"), ());

View file

@ -49,31 +49,31 @@ string GetNameFromFullPathWithoutExt(string const & path)
string GetDirectory(string const & name)
{
string const sep = GetNativeSeparator();
size_t const sepSize = sep.size();
auto const sep = GetNativeSeparator();
size_t const sepSize = sizeof(sep);
string::size_type i = name.rfind(sep);
if (i == string::npos)
return ".";
while (i > sepSize && (name.substr(i - sepSize, sepSize) == sep))
while (i > sepSize && (name[i - sepSize] == sep))
i -= sepSize;
return i == 0 ? sep : name.substr(0, i);
return name.substr(0, i ? i : sepSize);
}
string GetNativeSeparator()
string::value_type GetNativeSeparator()
{
#ifdef OMIM_OS_WINDOWS
return "\\";
return '\\';
#else
return "/";
return '/';
#endif
}
string AddSlashIfNeeded(string const & path)
{
string const sep = GetNativeSeparator();
auto const sep = GetNativeSeparator();
string::size_type const pos = path.rfind(sep);
if ((pos != string::npos) && (pos + sep.size() == path.size()))
if ((pos != string::npos) && (pos + sizeof(sep) == path.size()))
return path;
return path + sep;
}

View file

@ -25,8 +25,8 @@ std::string GetNameFromFullPathWithoutExt(std::string const & path);
/// root directory. If the argument is a single component, returns ".".
std::string GetDirectory(std::string const & path);
/// Get folder separator for specific platform
std::string GetNativeSeparator();
/// Get native folder separator for the platform.
std::string::value_type GetNativeSeparator();
/// Add the terminating slash to the folder path std::string if it's not already there.
std::string AddSlashIfNeeded(std::string const & path);

View file

@ -313,6 +313,11 @@ bool StartsWith(std::string const & s1, char const * s2)
return (s1.compare(0, strlen(s2), s2) == 0);
}
bool StartsWith(std::string const & s, std::string::value_type c)
{
return s.empty() ? false : s.front() == c;
}
bool StartsWith(std::string const & s1, std::string const & s2)
{
return (s1.compare(0, s2.length(), s2) == 0);
@ -335,6 +340,11 @@ bool EndsWith(std::string const & s1, char const * s2)
return (s1.compare(n - m, m, s2) == 0);
}
bool EndsWith(std::string const & s, std::string::value_type c)
{
return s.empty() ? false : s.back() == c;
}
bool EndsWith(std::string const & s1, std::string const & s2)
{
return s1.size() >= s2.size() && s1.compare(s1.size() - s2.size(), s2.size(), s2) == 0;

View file

@ -143,14 +143,14 @@ public:
using reference = std::string;
using iterator_category = std::input_iterator_tag;
// *NOTE* |s| must be not temporary!
// *NOTE* |s| must not be a temporary!
TokenizeIterator(std::string const & s, DelimFn const & delimFn)
: m_start(s.begin()), m_end(s.begin()), m_finish(s.end()), m_delimFn(delimFn)
{
Move();
}
// *NOTE* |s| must be not temporary!
// *NOTE* |s| must not be a temporary!
TokenizeIterator(UniString const & s, DelimFn const & delimFn)
: m_start(s.begin()), m_end(s.begin()), m_finish(s.end()), m_delimFn(delimFn)
{
@ -591,15 +591,13 @@ bool StartsWith(IterT1 beg, IterT1 end, IterT2 begPrefix, IterT2 endPrefix)
}
bool StartsWith(UniString const & s, UniString const & p);
bool StartsWith(std::string const & s1, char const * s2);
bool StartsWith(std::string const & s, std::string::value_type c);
bool StartsWith(std::string const & s1, std::string const & s2);
bool EndsWith(UniString const & s1, UniString const & s2);
bool EndsWith(std::string const & s1, char const * s2);
bool EndsWith(std::string const & s, std::string::value_type c);
bool EndsWith(std::string const & s1, std::string const & s2);
// If |s| starts with |prefix|, deletes it from |s| and returns true.

View file

@ -27,6 +27,7 @@ LocalizedUnits GetLocalizedUnits(measurement_utils::Units units, MeasurementType
case measurement_utils::Units::Imperial: return {GetLocalizedString("foot"), GetLocalizedString("mile")};
case measurement_utils::Units::Metric: return {GetLocalizedString("meter"), GetLocalizedString("kilometer")};
}
break;
case MeasurementType::Speed:
switch (units)
{

View file

@ -125,6 +125,16 @@ void Platform::SetSettingsDir(string const & path)
m_settingsDir = base::AddSlashIfNeeded(path);
}
std::string Platform::SettingsPathForFile(std::string const & file) const
{
return base::JoinPath(SettingsDir(), file);
}
std::string Platform::WritablePathForFile(std::string const & file) const
{
return base::JoinPath(WritableDir(), file);
}
string Platform::ReadPathForFile(string const & file, string searchScope) const
{
if (searchScope.empty())
@ -297,9 +307,9 @@ bool Platform::MkDirChecked(string const & dirName)
// static
bool Platform::MkDirRecursively(string const & dirName)
{
auto const sep = base::GetNativeSeparator();
string::value_type const sep[] = { base::GetNativeSeparator(), 0};
string path = strings::StartsWith(dirName, sep) ? sep : "";
auto const tokens = strings::Tokenize(dirName, sep.c_str());
auto const tokens = strings::Tokenize(dirName, sep);
for (auto const & t : tokens)
{
path = base::JoinPath(path, t);

View file

@ -134,7 +134,7 @@ public:
/// Set writable dir — use for testing and linux stuff only
void SetWritableDirForTests(std::string const & path);
/// @return full path to file in user's writable directory
std::string WritablePathForFile(std::string const & file) const { return WritableDir() + file; }
std::string WritablePathForFile(std::string const & file) const;
/// Uses m_writeableDir [w], m_resourcesDir [r], m_settingsDir [s].
std::string ReadPathForFile(std::string const & file,
std::string searchScope = std::string()) const;
@ -185,7 +185,7 @@ public:
std::string const & SettingsDir() const { return m_settingsDir; }
void SetSettingsDir(std::string const & path);
/// @return full path to file in the settings directory
std::string SettingsPathForFile(std::string const & file) const { return SettingsDir() + file; }
std::string SettingsPathForFile(std::string const & file) const;
/// @return reader for file decriptor.
/// @throws FileAbsentException

View file

@ -14,112 +14,113 @@
#include <numeric>
#include <string>
using namespace std;
namespace
namespace apk_test
{
char const * arrFiles[] = {
"copyright.html",
"resources-mdpi_clear/symbols.sdf",
"resources-mdpi_clear/symbols.png",
"resources-hdpi_clear/symbols.sdf",
"resources-hdpi_clear/symbols.png",
"resources-xhdpi_clear/symbols.sdf",
"resources-xhdpi_clear/symbols.png",
"categories.txt",
"categories_cuisines.txt",
"classificator.txt",
"types.txt",
"fonts_blacklist.txt",
"fonts_whitelist.txt",
"languages.txt",
"unicode_blocks.txt",
"drules_proto_clear.bin",
"external_resources.txt",
"packed_polygons.bin",
"countries.txt"
};
using std::string, std::vector;
class ApkTester : public threads::IRoutine
char const * arrFiles[] = {
"copyright.html",
"resources-mdpi_clear/symbols.sdf",
"resources-mdpi_clear/symbols.png",
"resources-hdpi_clear/symbols.sdf",
"resources-hdpi_clear/symbols.png",
"resources-xhdpi_clear/symbols.sdf",
"resources-xhdpi_clear/symbols.png",
"categories.txt",
"categories_cuisines.txt",
"classificator.txt",
"types.txt",
"fonts_blacklist.txt",
"fonts_whitelist.txt",
"languages.txt",
"unicode_blocks.txt",
"drules_proto_clear.bin",
"external_resources.txt",
"packed_polygons.bin",
"countries.txt"
};
class ApkTester : public threads::IRoutine
{
static const int COUNT = ARRAY_SIZE(arrFiles);
string const & m_cont;
public:
explicit ApkTester(string const & cont) : m_cont(cont), m_hashes(COUNT)
{
static const int COUNT = ARRAY_SIZE(arrFiles);
string const & m_cont;
}
public:
explicit ApkTester(string const & cont) : m_cont(cont), m_hashes(COUNT)
virtual void Do()
{
string const prefix("assets/");
while (true)
{
}
virtual void Do()
{
string const prefix("assets/");
while (true)
size_t ind = rand() % COUNT;
if (m_hashes[ind] != 0)
{
size_t ind = rand() % COUNT;
if (m_hashes[ind] != 0)
{
ind = COUNT;
for (size_t i = 0; i < COUNT; ++i)
if (m_hashes[i] == 0)
{
ind = i;
break;
}
}
ind = COUNT;
for (size_t i = 0; i < COUNT; ++i)
if (m_hashes[i] == 0)
{
ind = i;
break;
}
}
if (ind == COUNT)
break;
if (ind == COUNT)
break;
try
{
ZipFileReader reader(m_cont, prefix + arrFiles[ind]);
try
{
ZipFileReader reader(m_cont, prefix + arrFiles[ind]);
size_t const size = reader.Size();
vector<char> buffer(size);
reader.Read(0, &buffer[0], size);
size_t const size = reader.Size();
vector<char> buffer(size);
reader.Read(0, &buffer[0], size);
m_hashes[ind] = accumulate(buffer.begin(), buffer.end(), static_cast<uint64_t>(0));
}
catch (Reader::Exception const & ex)
{
LOG(LERROR, (ex.Msg()));
break;
}
m_hashes[ind] = accumulate(buffer.begin(), buffer.end(), static_cast<uint64_t>(0));
}
catch (Reader::Exception const & ex)
{
LOG(LERROR, (ex.Msg()));
break;
}
}
}
vector<uint64_t> m_hashes;
};
}
vector<uint64_t> m_hashes;
};
/*
UNIT_TEST(ApkReader_Multithreaded)
{
/// @todo Update test with current apk path.
/// @todo Update test with current apk path.
string const path = GetPlatform().WritableDir() + "../android/MapsWithMePro/bin/MapsWithMePro-production.apk";
uint64_t size;
if (!base::GetFileSize(path, size))
{
LOG(LINFO, ("Apk not found"));
return;
}
srand(static_cast<unsigned>(size));
size_t const count = 20;
base::thread_pool::routine_simple::ThreadPool pool(count);
for (size_t i = 0; i < count; ++i)
pool.Add(make_unique<ApkTester>(path));
pool.Join();
typedef ApkTester const * PtrT;
PtrT etalon = dynamic_cast<PtrT>(pool.GetRoutine(0));
for (size_t i = 1; i < count; ++i)
{
PtrT p = dynamic_cast<PtrT>(pool.GetRoutine(i));
TEST_EQUAL(etalon->m_hashes, p->m_hashes, ());
}
uint64_t size;
if (!base::GetFileSize(path, size))
{
LOG(LINFO, ("Apk not found"));
return;
}
srand(static_cast<unsigned>(size));
size_t const count = 20;
base::thread_pool::routine_simple::ThreadPool pool(count);
for (size_t i = 0; i < count; ++i)
pool.Add(make_unique<ApkTester>(path));
pool.Join();
typedef ApkTester const * PtrT;
PtrT etalon = dynamic_cast<PtrT>(pool.GetRoutine(0));
for (size_t i = 1; i < count; ++i)
{
PtrT p = dynamic_cast<PtrT>(pool.GetRoutine(i));
TEST_EQUAL(etalon->m_hashes, p->m_hashes, ());
}
*/
} // namespace apk_test

View file

@ -181,26 +181,29 @@ UNIT_TEST(GetFileSize)
TEST(!pl.GetFileSizeByName("adsmngfuwrbfyfwe", size), ());
TEST(!pl.IsFileExistsByFullPath("adsmngfuwrbfyfwe"), ());
char const kContent[] = "HOHOHO";
size_t const kSize = ARRAY_SIZE(kContent);
std::string const fileName = pl.WritablePathForFile(TEST_FILE_NAME);
{
FileWriter testFile(fileName);
testFile.Write("HOHOHO", 6);
testFile.Write(kContent, kSize);
}
size = 0;
TEST(Platform::GetFileSizeByFullPath(fileName, size), ());
TEST_EQUAL(size, 6, ());
TEST_EQUAL(size, kSize, ());
FileWriter::DeleteFileX(fileName);
TEST(!pl.IsFileExistsByFullPath(fileName), ());
{
FileWriter testFile(pl.WritablePathForFile(TEST_FILE_NAME));
testFile.Write("HOHOHO", 6);
FileWriter testFile(fileName);
testFile.Write(kContent, kSize);
}
size = 0;
TEST(pl.GetFileSizeByName(TEST_FILE_NAME, size), ());
TEST_EQUAL(size, 6, ());
TEST_EQUAL(size, kSize, ());
FileWriter::DeleteFileX(pl.WritablePathForFile(TEST_FILE_NAME));
FileWriter::DeleteFileX(fileName);
}
UNIT_TEST(CpuCores)

View file

@ -1,5 +1,6 @@
#include "platform/platform.hpp"
#include "base/file_name_utils.hpp"
#include "base/scope_guard.hpp"
#include "base/logging.hpp"
@ -70,9 +71,10 @@ Platform::Platform()
// writable path:
// 1. the same as resources if we have write access to this folder
// 2. otherwise, use system-specific folder
string const tmpFilePath = base::JoinPath(m_resourcesDir, "mapswithmetmptestfile");
try
{
FileWriter tmpfile(m_resourcesDir + "mapswithmetmptestfile");
FileWriter tmpfile(tmpFilePath);
tmpfile.Write("Hi from Alex!", 13);
m_writableDir = m_resourcesDir;
}
@ -80,17 +82,17 @@ Platform::Platform()
{
CHECK(GetUserWritableDir(m_writableDir), ("Can't get writable directory"));
}
FileWriter::DeleteFileX(m_resourcesDir + "mapswithmetmptestfile");
FileWriter::DeleteFileX(tmpFilePath);
m_settingsDir = m_writableDir;
char pathBuf[MAX_PATH] = {0};
GetTempPathA(MAX_PATH, pathBuf);
m_tmpDir = pathBuf;
LOG(LDEBUG, ("Resources Directory:", m_resourcesDir));
LOG(LDEBUG, ("Writable Directory:", m_writableDir));
LOG(LDEBUG, ("Tmp Directory:", m_tmpDir));
LOG(LDEBUG, ("Settings Directory:", m_settingsDir));
LOG(LINFO, ("Resources Directory:", m_resourcesDir));
LOG(LINFO, ("Writable Directory:", m_writableDir));
LOG(LINFO, ("Tmp Directory:", m_tmpDir));
LOG(LINFO, ("Settings Directory:", m_settingsDir));
}
bool Platform::IsFileExistsByFullPath(string const & filePath)

View file

@ -24,6 +24,8 @@
#include <string>
#include <vector>
namespace house_detector_tests
{
using namespace std;
using platform::LocalCountryFile;
@ -496,3 +498,4 @@ UNIT_TEST(HS_MWMSearch)
LOG(LINFO, ("Matched =", matched, "Not matched =", notMatched, "Not found =", all - matched - notMatched));
LOG(LINFO, ("All count =", all, "Percent matched =", matched / double(all)));
}
} // namespace house_detector_tests