136 const unsigned char *data;
139 unsigned char chunk_type;
146 i18n_log(
"i18n_set_language(" << directory <<
"," << base <<
")");
147 if (!directory || !base)
150 if (language.empty())
152 filename =
std::string(directory) +
"/" + base +
"_" + language +
".qm";
153 i18n_log(
"Loading translations for language " << language);
155 boost::system::error_code ignored_ec;
156 if (boost::filesystem::exists(filename, ignored_ec)) {
158 i18n_log(
"Failed to load translations file: " << filename);
162 i18n_log(
"Translations file not found: " << filename);
163 filename =
std::string(base) +
"_" + language +
".qm";
164 if (!find_embedded_file(filename, contents)) {
165 i18n_log(
"Embedded translations file not found: " << filename);
166 const char *underscore = strchr(language.c_str(),
'_');
169 filename =
std::string(directory) +
"/" + base +
"_" + fallback_language +
".qm";
170 i18n_log(
"Loading translations for language " << fallback_language);
171 if (boost::filesystem::exists(filename, ignored_ec)) {
173 i18n_log(
"Failed to load translations file: " << filename);
177 i18n_log(
"Translations file not found: " << filename);
178 filename =
std::string(base) +
"_" + fallback_language +
".qm";
179 if (!find_embedded_file(filename, contents)) {
180 i18n_log(
"Embedded translations file not found: " << filename);
190 data = (
const unsigned char*)contents.c_str();
191 datalen = contents.size();
193 i18n_log(
"Translations file size: " << datalen);
220 if (datalen <
sizeof(qm_magic) || memcmp(data, qm_magic,
sizeof(qm_magic))) {
221 i18n_log(
"Bad translations file format: " << filename);
224 idx +=
sizeof(qm_magic);
226 while (idx < datalen) {
227 if (idx + 5 > datalen) {
228 i18n_log(
"Bad translations file format: " << filename);
231 chunk_type = data[idx++];
232 chunk_size = be32(data+idx);
235 i18n_log(
"Found " << chunk_type <<
" of " << chunk_size <<
" bytes");
236 if (chunk_size >= datalen || idx > datalen - chunk_size) {
237 i18n_log(
"Bad translations file format: " << filename);
241 switch (chunk_type) {
243 i18n_log(
"Found offsets at " << idx);
246 num_messages = chunk_size / 8;
249 i18n_log(
"Found messages at " << idx);
253 i18n_log(
"Found unsupported chunk type: " << chunk_type);
265 i18n_log(
"No messages chunk found");
269 for (
uint32_t m = 0; m < num_messages; ++m) {
270 be32(data+offsets_idx+m*8);
271 idx = be32(data+offsets_idx+m*8+4);
274 if (idx > datalen || idx + 1 > datalen) {
275 i18n_log(
"Bad translations file format: " << filename);
280 if (idx + 5 > datalen) {
281 i18n_log(
"Bad translations file format: " << filename);
284 chunk_type = data[idx++];
286 if (chunk_type == 0x01) {
294 chunk_size = be32(data+idx);
296 i18n_log(
"Found " << chunk_type <<
" of " << chunk_size <<
" bytes");
297 if (chunk_size >= datalen || idx > datalen - chunk_size) {
298 i18n_log(
"Bad translations file format: " << filename);
301 switch (chunk_type) {
303 translation = utf16(data+idx, chunk_size);
304 i18n_log(
"Found translation: " << translation);
307 source = utf8(data+idx, chunk_size);
311 context = utf8(data+idx, chunk_size);
const CharType(& source)[N]
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.