1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-01 17:38:41 +00:00

Avoid copies when working with EnrichedString

This commit is contained in:
sfan5 2024-08-27 13:51:02 +02:00
parent fa4529b4f1
commit 19a58745c9
6 changed files with 53 additions and 54 deletions

View file

@ -670,23 +670,26 @@ std::string wrap_rows(std::string_view from, unsigned row_len, bool has_color_co
* before filling it again.
*/
static void translate_all(const std::wstring &s, size_t &i,
static void translate_all(std::wstring_view s, size_t &i,
Translations *translations, std::wstring &res);
static void translate_string(const std::wstring &s, Translations *translations,
static void translate_string(std::wstring_view s, Translations *translations,
const std::wstring &textdomain, size_t &i, std::wstring &res)
{
std::wostringstream output;
std::vector<std::wstring> args;
int arg_number = 1;
// Re-assemble the template.
std::wstring output;
output.reserve(s.length());
while (i < s.length()) {
// Not an escape sequence: just add the character.
if (s[i] != '\x1b') {
output.put(s[i]);
output += s[i];
// The character is a literal '@'; add it twice
// so that it is not mistaken for an argument.
if (s[i] == L'@')
output.put(L'@');
output += L'@';
++i;
continue;
}
@ -733,12 +736,12 @@ static void translate_string(const std::wstring &s, Translations *translations,
args.push_back(arg);
continue;
}
output.put(L'@');
output << arg_number;
output += L'@';
output += std::to_wstring(arg_number);
++arg_number;
std::wstring arg;
translate_all(s, i, translations, arg);
args.push_back(arg);
args.push_back(std::move(arg));
} else {
// This is an escape sequence *inside* the template string to translate itself.
// This should not happen, show an error message.
@ -747,21 +750,18 @@ static void translate_string(const std::wstring &s, Translations *translations,
}
}
std::wstring toutput;
// Translate the template.
if (translations != nullptr)
toutput = translations->getTranslation(
textdomain, output.str());
else
toutput = output.str();
const std::wstring &toutput = translations ?
translations->getTranslation(textdomain, output) : output;
// Put back the arguments in the translated template.
std::wostringstream result;
size_t j = 0;
res.clear();
res.reserve(toutput.length());
while (j < toutput.length()) {
// Normal character, add it to output and continue.
if (toutput[j] != L'@' || j == toutput.length() - 1) {
result.put(toutput[j]);
res += toutput[j];
++j;
continue;
}
@ -769,7 +769,7 @@ static void translate_string(const std::wstring &s, Translations *translations,
++j;
// Literal escape for '@'.
if (toutput[j] == L'@') {
result.put(L'@');
res += L'@';
++j;
continue;
}
@ -778,16 +778,15 @@ static void translate_string(const std::wstring &s, Translations *translations,
int arg_index = toutput[j] - L'1';
++j;
if (0 <= arg_index && (size_t)arg_index < args.size()) {
result << args[arg_index];
res += args[arg_index];
} else {
// This is not allowed: show an error message
errorstream << "Ignoring out-of-bounds argument escape sequence in translation" << std::endl;
}
}
res = result.str();
}
static void translate_all(const std::wstring &s, size_t &i,
static void translate_all(std::wstring_view s, size_t &i,
Translations *translations, std::wstring &res)
{
res.clear();
@ -849,7 +848,7 @@ static void translate_all(const std::wstring &s, size_t &i,
}
// Translate string server side
std::wstring translate_string(const std::wstring &s, Translations *translations)
std::wstring translate_string(std::wstring_view s, Translations *translations)
{
size_t i = 0;
std::wstring res;
@ -858,7 +857,7 @@ std::wstring translate_string(const std::wstring &s, Translations *translations)
}
// Translate string client side
std::wstring translate_string(const std::wstring &s)
std::wstring translate_string(std::wstring_view s)
{
#ifdef SERVER
return translate_string(s, nullptr);