135 const unsigned char *data;
138 unsigned char chunk_type;
145 i18n_log(
"i18n_set_language(" << directory <<
"," << base <<
")");
146 if (!directory || !base)
149 if (language.empty())
151 filename =
std::string(directory) +
"/" + base +
"_" + language +
".qm";
152 i18n_log(
"Loading translations for language " << language);
154 boost::system::error_code ignored_ec;
155 if (boost::filesystem::exists(filename, ignored_ec)) {
157 i18n_log(
"Failed to load translations file: " << filename);
161 i18n_log(
"Translations file not found: " << filename);
162 filename =
std::string(base) +
"_" + language +
".qm";
163 if (!find_embedded_file(filename, contents)) {
164 i18n_log(
"Embedded translations file not found: " << filename);
165 const char *underscore = strchr(language.c_str(),
'_');
168 filename =
std::string(directory) +
"/" + base +
"_" + fallback_language +
".qm";
169 i18n_log(
"Loading translations for language " << fallback_language);
170 if (boost::filesystem::exists(filename, ignored_ec)) {
172 i18n_log(
"Failed to load translations file: " << filename);
176 i18n_log(
"Translations file not found: " << filename);
177 filename =
std::string(base) +
"_" + fallback_language +
".qm";
178 if (!find_embedded_file(filename, contents)) {
179 i18n_log(
"Embedded translations file not found: " << filename);
189 data = (
const unsigned char*)contents.c_str();
190 datalen = contents.size();
192 i18n_log(
"Translations file size: " << datalen);
219 if (datalen <
sizeof(qm_magic) || memcmp(data, qm_magic,
sizeof(qm_magic))) {
220 i18n_log(
"Bad translations file format: " << filename);
223 idx +=
sizeof(qm_magic);
225 while (idx < datalen) {
226 if (idx + 5 > datalen) {
227 i18n_log(
"Bad translations file format: " << filename);
230 chunk_type = data[idx++];
231 chunk_size = be32(data+idx);
234 i18n_log(
"Found " << chunk_type <<
" of " << chunk_size <<
" bytes");
235 if (chunk_size >= datalen || idx > datalen - chunk_size) {
236 i18n_log(
"Bad translations file format: " << filename);
240 switch (chunk_type) {
242 i18n_log(
"Found offsets at " << idx);
245 num_messages = chunk_size / 8;
248 i18n_log(
"Found messages at " << idx);
252 i18n_log(
"Found unsupported chunk type: " << chunk_type);
264 i18n_log(
"No messages chunk found");
268 for (
uint32_t m = 0; m < num_messages; ++m) {
269 be32(data+offsets_idx+m*8);
270 idx = be32(data+offsets_idx+m*8+4);
273 if (idx > datalen || idx + 1 > datalen) {
274 i18n_log(
"Bad translations file format: " << filename);
279 if (idx + 5 > datalen) {
280 i18n_log(
"Bad translations file format: " << filename);
283 chunk_type = data[idx++];
285 if (chunk_type == 0x01) {
293 chunk_size = be32(data+idx);
295 i18n_log(
"Found " << chunk_type <<
" of " << chunk_size <<
" bytes");
296 if (chunk_size >= datalen || idx > datalen - chunk_size) {
297 i18n_log(
"Bad translations file format: " << filename);
300 switch (chunk_type) {
302 translation = utf16(data+idx, chunk_size);
303 i18n_log(
"Found translation: " << translation);
306 source = utf8(data+idx, chunk_size);
310 context = utf8(data+idx, chunk_size);
std::string i18n_get_language()
bool load_file_to_string(const std::string &path_to_file, std::string &target_str, size_t max_size=1000000000)
std::unique_ptr< void, terminate > context
Unique ZMQ context handle, calls zmq_term on destruction.
const CharType(& source)[N]