Localization v1.5.0
Localization subsystem
Loading...
Searching...
No Matches
WTextLocalization.cpp
1#ifndef __LINUX__
2
3#include "WTextLocalization.h"
4
5static std::wstring to_wstring(std::string_view source);
6
7namespace localization
8{
9 void BaseTextLocalization<wchar_t>::convertLocalization(const TextLocalization& localizationModule)
10 {
11 using getDictionariesLanguages = const char** (*)(uint64_t* size);
12 using getDictionary = const char* (*)(const char* language, uint64_t* size, const char*** key, const char*** values);
13 using freeDictionary = void(*)(const char** keys, const char** values);
14
15 auto load = [this](HMODULE handle, const char* name)
16 {
17#ifdef __LINUX__
18 return dlsym(handle, name);
19#else
20 return GetProcAddress(handle, name);
21#endif
22 };
23
24 originalLanguage = localizationModule.getOriginalLanguage();
25 language = localizationModule.language;
26 pathToModule = localizationModule.getPathToModule();
27
28 getDictionariesLanguages dictionariesLanguagesFunction = reinterpret_cast<getDictionariesLanguages>(load(localizationModule.handle, "getDictionariesLanguages"));
29 getDictionary dictionaryFunction = reinterpret_cast<getDictionary>(load(localizationModule.handle, "getDictionary"));
30 freeDictionary freeDictionaryFunction = reinterpret_cast<freeDictionary>(load(localizationModule.handle, "freeDictionary"));
31
32 uint64_t languagesSize = 0;
33 const char** languages = dictionariesLanguagesFunction(&languagesSize);
34
35 for (uint64_t i = 0; i < languagesSize; i++)
36 {
37 const char* language = languages[i];
38 std::unordered_map<std::string, std::wstring, utility::StringViewHash, utility::StringViewEqual> convertedDictionary;
39 uint64_t dictionarySize = 0;
40 const char** keys;
41 const char** values;
42
43 dictionaryFunction(language, &dictionarySize, &keys, &values);
44
45 convertedDictionary.reserve(dictionarySize);
46
47 for (uint64_t j = 0; j < dictionarySize; j++)
48 {
49 convertedDictionary[keys[j]] = to_wstring(values[j]);
50 }
51
52 dictionaries[language] = move(convertedDictionary);
53
54 freeDictionaryFunction(keys, values);
55 }
56
57 reinterpret_cast<void(*)(const char**)>(load(localizationModule.handle, "freeDictionariesLanguages"))(languages);
58 }
59
60 BaseTextLocalization<wchar_t>::BaseTextLocalization(std::string_view localizationModule) :
61 handle(nullptr)
62 {
63 if (localizationModule == TextLocalization::get().getPathToModule())
64 {
65 this->convertLocalization(TextLocalization::get());
66 }
67 else
68 {
69 this->convertLocalization(TextLocalization(localizationModule));
70 }
71 }
72
73 BaseTextLocalization<wchar_t>::BaseTextLocalization(const TextLocalization& localizationModule) :
74 handle(nullptr)
75 {
76 this->convertLocalization(localizationModule);
77 }
78
79 BaseTextLocalization<wchar_t>::BaseTextLocalization(WTextLocalization&& other) noexcept
80 {
81 (*this) = std::move(other);
82 }
83
84 WTextLocalization& BaseTextLocalization<wchar_t>::operator = (WTextLocalization&& other) noexcept
85 {
86 dictionaries = std::move(other.dictionaries);
87 originalLanguage = std::move(other.originalLanguage);
88 language = std::move(other.language);
89 pathToModule = std::move(other.pathToModule);
90
91 return *this;
92 }
93
94 BaseTextLocalization<wchar_t>& BaseTextLocalization<wchar_t>::get()
95 {
96 static std::unique_ptr<BaseTextLocalization<wchar_t>> instance;
97
98 if (!instance)
99 {
100 json::JsonParser settings(std::ifstream(localizationModulesFile.data()));
101
102 instance = std::unique_ptr<WTextLocalization>(new WTextLocalization(settings.get<std::string>(settings::defaultModuleSetting)));
103 }
104
105 return *instance;
106 }
107
108 void BaseTextLocalization<wchar_t>::changeLanguage(std::string_view language)
109 {
110 if (dictionaries.find(language) == dictionaries.end())
111 {
112 throw std::runtime_error(format(R"(Wrong language value "{}")", language));
113 }
114
115 this->language = language;
116 }
117
118 std::string_view BaseTextLocalization<wchar_t>::getOriginalLanguage() const
119 {
120 return originalLanguage;
121 }
122
123 std::string_view BaseTextLocalization<wchar_t>::getCurrentLanguage() const
124 {
125 return language;
126 }
127
128 const std::filesystem::path& BaseTextLocalization<wchar_t>::getPathToModule() const
129 {
130 return pathToModule;
131 }
132
133 std::wstring_view BaseTextLocalization<wchar_t>::getString(std::string_view key, std::string_view language, bool allowOriginal) const
134 {
135 if (auto languageIterator = dictionaries.find(language); languageIterator != dictionaries.end())
136 {
137 if (auto keyIterator = languageIterator->second.find(key); keyIterator != languageIterator->second.end())
138 {
139 if (keyIterator->second.size())
140 {
141 return keyIterator->second;
142 }
143
144 if (allowOriginal)
145 {
146 return this->getString(key, originalLanguage, false);
147 }
148
149 throw std::runtime_error(std::format("Can't find localized string with key: {}", key));
150 }
151 else if (allowOriginal)
152 {
153 return this->getString(key, originalLanguage, false);
154 }
155 else
156 {
157 throw std::runtime_error(std::format("Can't find localized string with key: {}", key));
158 }
159 }
160 else
161 {
162 throw std::runtime_error(std::format("Can't find language: {}", language));
163 }
164
165 return {};
166 }
167
168 std::wstring_view BaseTextLocalization<wchar_t>::operator [](std::string_view key) const
169 {
170 return this->getString(key, language);
171 }
172}
173
174std::wstring to_wstring(std::string_view stringToConvert)
175{
176 std::wstring result;
177
178 int size = MultiByteToWideChar
179 (
180 CP_UTF8,
181 NULL,
182 stringToConvert.data(),
183 -1,
184 nullptr,
185 NULL
186 );
187
188 if (!size)
189 {
190 throw std::runtime_error("Can't convert to wstring");
191 }
192
193 result.resize(static_cast<size_t>(size) - 1);
194
195 if (!MultiByteToWideChar
196 (
197 CP_UTF8,
198 NULL,
199 stringToConvert.data(),
200 -1,
201 result.data(),
202 size
203 ))
204 {
205 throw std::runtime_error("Can't convert to wstring");
206 }
207
208 return result;
209}
210
211#endif