~aleteoryx/muditaos

ref: f54ba2ee3cfcc0b699f628b570c850c6e96acf26 muditaos/module-utils/i18n/i18n.cpp -rw-r--r-- 4.1 KiB
f54ba2ee — Pawel.Paprocki [EGD-6112] Fix Service-desktop crashes during DOM dump 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "log/log.hpp"
#include "i18n.hpp"
#include "Utils.hpp"
#include <cstdio>
#include <purefs/filesystem_paths.hpp>

namespace utils
{
    namespace
    {
        auto returnNonEmptyString(const std::string &str, const std::string &ret) -> const std::string &
        {
            return str.empty() ? ret : str;
        }
    } // namespace

    i18n localize;
    json11::Json LangLoader::createJson(const std::string &filename)
    {
        const auto path = utils::localize.DisplayLanguageDirPath / (filename + utils::files::jsonExtension);
        auto fd         = std::fopen(path.c_str(), "r");
        if (fd == nullptr) {
            LOG_FATAL("Error during opening file %s", path.c_str());
            return json11::Json();
        }

        uint32_t fsize = std::filesystem::file_size(path);

        auto stream = std::make_unique<char[]>(fsize + 1); // +1 for NULL terminator

        std::fread(stream.get(), 1, fsize, fd);

        std::string err;
        json11::Json js = json11::Json::parse(stream.get(), err);

        std::fclose(fd);

        // Error
        if (err.length() != 0) {
            LOG_FATAL("%s", err.c_str());
            return json11::Json();
        }
        else {
            return js;
        }
    }

    std::vector<Language> LangLoader::getAvailableDisplayLanguages() const
    {
        std::vector<std::string> languageNames;
        for (const auto &entry : std::filesystem::directory_iterator(utils::localize.DisplayLanguageDirPath)) {
            languageNames.push_back(std::filesystem::path(entry.path()).stem());
        }
        return languageNames;
    }

    std::vector<Language> LangLoader::getAvailableInputLanguages() const
    {
        std::vector<std::string> languageNames;
        for (const auto &entry : std::filesystem::directory_iterator(utils::localize.InputLanguageDirPath)) {
            languageNames.push_back(std::filesystem::path(entry.path()).stem());
        }
        return languageNames;
    }

    void i18n::setInputLanguage(const Language &lang)
    {
        if (lang == inputLanguage) {
            return;
        }
        inputLanguage = lang;
    }

    const std::string &i18n::getInputLanguageFilename(const std::string &inputMode)
    {
        // if language pack returned nothing then try default language
        if (inputLanguage.empty()) {
            inputLanguageFilename = fallbackLanguageName + utils::files::breakSign + inputMode;
        }
        else {
            inputLanguageFilename = inputLanguage + utils::files::breakSign + inputMode;
        }
        return inputLanguageFilename;
    }

    const std::string &i18n::getInputLanguage()
    {
        return inputLanguage;
    }

    const std::string &i18n::getDisplayLanguage()
    {
        return currentDisplayLanguage;
    }

    const std::string &i18n::get(const std::string &str)
    {
        // if language pack returned nothing then try default language
        if (displayLanguage[str].string_value().empty()) {
            return returnNonEmptyString(fallbackLanguage[str].string_value(), str);
        }
        return returnNonEmptyString(displayLanguage[str].string_value(), str);
    }

    void i18n::setDisplayLanguage(const Language &lang)
    {
        if (!backupLanguageInitializer) {
            fallbackLanguage          = loader.createJson(fallbackLanguageName);
            displayLanguage           = fallbackLanguage;
            backupLanguageInitializer = true;
        }
        if (lang == currentDisplayLanguage) {
            return;
        }
        currentDisplayLanguage = lang;
        if (lang == fallbackLanguageName) {
            displayLanguage = fallbackLanguage;
        }
        else {
            json11::Json pack = loader.createJson(lang);
            // Suspend whole system during switching lang packs
            vTaskSuspendAll();
            displayLanguage = pack;
            xTaskResumeAll();
        }
    }

    void i18n::setFallbackLanguage(const Language &lang)
    {
        fallbackLanguageName = std::move(lang);
    }
} // namespace utils