-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathI18n.cpp
More file actions
144 lines (113 loc) · 3.03 KB
/
Copy pathI18n.cpp
File metadata and controls
144 lines (113 loc) · 3.03 KB
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
136
137
138
139
140
141
142
143
144
#include <clocale>
#include <cstring>
#include <fstream>
#include <cpp3ds/System/Err.hpp>
#include <cpp3ds/System/I18n.hpp>
#include <cpp3ds/System/String.hpp>
#include <cpp3ds/System/Service.hpp>
#define TOKEN_COMMENT '#'
namespace {
static bool replace(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
if(start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
static void replaceAll(std::string& str, const std::string& from, const std::string& to) {
if(from.empty())
return;
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
} // namespace
namespace cpp3ds {
I18n& I18n::getInstance()
{
static I18n self;
return self;
}
I18n::I18n()
{
Uint8 langcode;
Service::enable(CONFIG);
#ifdef EMULATION
langcode = 1; // TODO: get actual locale of PC
#else
CFGU_GetSystemLanguage(&langcode);
#endif
m_language = static_cast<Language>(langcode);
loadFromLanguage(m_language);
}
const std::string I18n::getLangString(const Language langcode) const
{
switch (langcode) {
case Japanese: return "jp";
case English: return "en";
case French: return "fr";
case German: return "de";
case Italian: return "it";
case Spanish: return "es";
case ChineseSimplified: return "zh";
case Korean: return "ko";
case Dutch: return "nl";
case Portuguese: return "pt";
case Russian: return "ru";
case ChineseTraditional: return "tw";
default: return "en";
}
}
void I18n::loadLanguage(Language language)
{
getInstance().loadFromLanguage(language);
}
Language I18n::getLanguage()
{
return static_cast<Language>(getInstance().m_language);
}
bool I18n::loadFromLanguage(const Language language)
{
std::string filename = "lang/" + getLangString(language) + ".lang";
return loadFromFile(filename);
}
void I18n::loadLanguageFile(const std::string& filename)
{
getInstance().loadFromFile(filename);
}
bool I18n::loadFromFile(const std::string filename)
{
std::ifstream file(filename);
if (file)
{
m_content.clear();
std::string line;
std::string content;
const std::map<std::string, std::string> replaceList = {
{"\\n", "\n"}, {"\\'", "\'"}
};
while (std::getline(file, line)) {
if (line.empty() || line[0] == TOKEN_COMMENT)
continue;
std::string key = line;
while (std::getline(file, content)) {
if (!content.empty() && content[0] != TOKEN_COMMENT)
break;
}
replaceAll(key, "\\\\", "\\");
replaceAll(content, "\\\\", "\\");
for (auto& s : replaceList) {
replaceAll(key, s.first, s.second);
replaceAll(content, s.first, s.second);
}
m_content[key] = content;
}
return true;
} else {
err() << "Failed to load language file: " << filename << std::endl;
}
return false;
}
}