2016-01-15 02:47:19 +00:00
|
|
|
#pragma once
|
|
|
|
|
2017-08-24 14:51:13 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2018-12-10 15:25:45 +00:00
|
|
|
#include <Poco/Exception.h>
|
|
|
|
#include <common/StringRef.h>
|
|
|
|
#include <common/Types.h>
|
|
|
|
#include "GeodataProviders/INamesProvider.h"
|
2017-08-24 14:51:13 +00:00
|
|
|
|
2016-01-15 02:47:19 +00:00
|
|
|
|
2017-04-17 11:56:55 +00:00
|
|
|
/** A class that allows you to recognize by region id its text name in one of the supported languages: ru, en, ua, by, kz, tr.
|
2016-02-07 08:42:21 +00:00
|
|
|
*
|
2017-04-17 11:56:55 +00:00
|
|
|
* Information about region names loads from text files with the following format names:
|
2017-04-01 07:20:54 +00:00
|
|
|
* regions_names_xx.txt,
|
2017-04-17 11:56:55 +00:00
|
|
|
* where xx is one of the two letters of the following supported languages:
|
2017-04-01 07:20:54 +00:00
|
|
|
* ru, en, ua, by, kz, tr.
|
2016-02-07 08:42:21 +00:00
|
|
|
*
|
2017-04-17 11:56:55 +00:00
|
|
|
* Can on request update the data.
|
2016-01-15 02:47:19 +00:00
|
|
|
*/
|
|
|
|
class RegionsNames
|
|
|
|
{
|
|
|
|
public:
|
2019-11-11 20:54:57 +00:00
|
|
|
enum class Language : size_t
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
|
|
|
RU = 0,
|
|
|
|
EN,
|
|
|
|
UA,
|
|
|
|
BY,
|
|
|
|
KZ,
|
|
|
|
TR,
|
2019-11-11 20:54:57 +00:00
|
|
|
|
|
|
|
END
|
2017-04-01 07:20:54 +00:00
|
|
|
};
|
2016-01-15 02:47:19 +00:00
|
|
|
|
|
|
|
private:
|
2019-11-11 20:54:57 +00:00
|
|
|
static inline constexpr const char * supported_languages[] =
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2019-11-11 20:54:57 +00:00
|
|
|
"ru",
|
|
|
|
"en",
|
|
|
|
"ua",
|
|
|
|
"by",
|
|
|
|
"kz",
|
|
|
|
"tr"
|
|
|
|
};
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2019-11-11 20:54:57 +00:00
|
|
|
static inline constexpr std::pair<const char *, Language> language_aliases[] =
|
2018-12-10 15:25:45 +00:00
|
|
|
{
|
2019-11-11 20:54:57 +00:00
|
|
|
{"ru", Language::RU},
|
|
|
|
{"en", Language::EN},
|
|
|
|
{"ua", Language::UA},
|
|
|
|
{"uk", Language::UA},
|
|
|
|
{"by", Language::BY},
|
|
|
|
{"kz", Language::KZ},
|
|
|
|
{"tr", Language::TR}
|
2018-12-10 15:25:45 +00:00
|
|
|
};
|
2019-11-11 20:54:57 +00:00
|
|
|
|
|
|
|
static constexpr size_t ROOT_LANGUAGE = 0;
|
|
|
|
static constexpr size_t SUPPORTED_LANGUAGES_COUNT = size_t(Language::END);
|
|
|
|
static constexpr size_t LANGUAGE_ALIASES_COUNT = sizeof(language_aliases);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2017-11-28 22:15:06 +00:00
|
|
|
using NamesSources = std::vector<std::shared_ptr<ILanguageRegionsNamesDataSource>>;
|
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
using Chars = std::vector<char>;
|
|
|
|
using CharsForLanguageID = std::vector<Chars>;
|
|
|
|
using StringRefs = std::vector<StringRef>; /// Lookup table RegionID -> StringRef
|
|
|
|
using StringRefsForLanguageID = std::vector<StringRefs>;
|
2016-02-07 08:42:21 +00:00
|
|
|
|
2016-01-15 02:47:19 +00:00
|
|
|
public:
|
2017-11-28 22:15:06 +00:00
|
|
|
RegionsNames(IRegionsNamesDataProviderPtr data_provider);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
|
|
StringRef getRegionName(RegionID region_id, Language language = Language::RU) const
|
|
|
|
{
|
|
|
|
size_t language_id = static_cast<size_t>(language);
|
|
|
|
|
2019-01-09 15:44:20 +00:00
|
|
|
if (region_id >= names_refs[language_id].size())
|
2017-04-01 07:20:54 +00:00
|
|
|
return StringRef("", 0);
|
|
|
|
|
|
|
|
StringRef ref = names_refs[language_id][region_id];
|
|
|
|
|
|
|
|
while (ref.size == 0 && language_id != ROOT_LANGUAGE)
|
|
|
|
{
|
2018-12-10 15:25:45 +00:00
|
|
|
static const size_t FALLBACK[] = {0, 0, 0, 0, 0, 1};
|
2017-04-01 07:20:54 +00:00
|
|
|
language_id = FALLBACK[language_id];
|
|
|
|
ref = names_refs[language_id][region_id];
|
|
|
|
}
|
|
|
|
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Language getLanguageEnum(const std::string & language)
|
|
|
|
{
|
|
|
|
if (language.size() == 2)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < LANGUAGE_ALIASES_COUNT; ++i)
|
|
|
|
{
|
2019-11-11 20:54:57 +00:00
|
|
|
const auto & alias = language_aliases[i];
|
|
|
|
if (language[0] == alias.first[0] && language[1] == alias.first[1])
|
|
|
|
return alias.second;
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
throw Poco::Exception("Unsupported language for region name. Supported languages are: " + dumpSupportedLanguagesNames() + ".");
|
|
|
|
}
|
2016-02-07 08:42:21 +00:00
|
|
|
|
2017-11-28 22:15:06 +00:00
|
|
|
void reload();
|
|
|
|
|
2016-01-15 02:47:19 +00:00
|
|
|
private:
|
2017-04-01 07:20:54 +00:00
|
|
|
static std::string dumpSupportedLanguagesNames();
|
2017-01-21 04:24:28 +00:00
|
|
|
|
2017-11-28 22:15:06 +00:00
|
|
|
NamesSources names_sources = NamesSources(SUPPORTED_LANGUAGES_COUNT);
|
2016-02-07 08:42:21 +00:00
|
|
|
|
2017-04-17 11:56:55 +00:00
|
|
|
/// Bytes of names for each language, laid out in a row, separated by zeros
|
2017-04-01 07:20:54 +00:00
|
|
|
CharsForLanguageID chars = CharsForLanguageID(SUPPORTED_LANGUAGES_COUNT);
|
2016-02-07 08:42:21 +00:00
|
|
|
|
2017-04-17 11:56:55 +00:00
|
|
|
/// Mapping for each language from the region id into a pointer to the byte range of the name
|
2017-04-01 07:20:54 +00:00
|
|
|
StringRefsForLanguageID names_refs = StringRefsForLanguageID(SUPPORTED_LANGUAGES_COUNT);
|
2016-01-15 02:47:19 +00:00
|
|
|
};
|