Codechange: Replace Utf8Decode usages with StringConsumer.

This commit is contained in:
frosch 2025-03-28 19:15:18 +01:00 committed by frosch
parent 9bcd3feb17
commit 131b7c7122
3 changed files with 27 additions and 40 deletions

View File

@ -16,6 +16,7 @@
#include "querystring_gui.h" #include "querystring_gui.h"
#include "video/video_driver.hpp" #include "video/video_driver.hpp"
#include "zoom_func.h" #include "zoom_func.h"
#include "core/string_consumer.hpp"
#include "widgets/osk_widget.h" #include "widgets/osk_widget.h"
@ -358,17 +359,10 @@ void GetKeyboardLayout()
keyboard[1] = _keyboard_opt[1].empty() ? GetString(STR_OSK_KEYBOARD_LAYOUT_CAPS) : _keyboard_opt[1]; keyboard[1] = _keyboard_opt[1].empty() ? GetString(STR_OSK_KEYBOARD_LAYOUT_CAPS) : _keyboard_opt[1];
for (uint j = 0; j < 2; j++) { for (uint j = 0; j < 2; j++) {
auto kbd = keyboard[j].begin(); StringConsumer consumer(keyboard[j]);
bool ended = false;
for (uint i = 0; i < OSK_KEYBOARD_ENTRIES; i++) { for (uint i = 0; i < OSK_KEYBOARD_ENTRIES; i++) {
_keyboard[j][i] = Utf8Consume(kbd);
/* Be lenient when the last characters are missing (is quite normal) */ /* Be lenient when the last characters are missing (is quite normal) */
if (_keyboard[j][i] == '\0' || ended) { _keyboard[j][i] = consumer.AnyBytesLeft() ? consumer.ReadUtf8() : ' ';
ended = true;
_keyboard[j][i] = ' ';
continue;
}
if (IsPrintable(_keyboard[j][i])) { if (IsPrintable(_keyboard[j][i])) {
errormark[j] += ' '; errormark[j] += ' ';

View File

@ -30,6 +30,7 @@
#include "../strings_func.h" #include "../strings_func.h"
#include "../core/endian_func.hpp" #include "../core/endian_func.hpp"
#include "../core/string_builder.hpp" #include "../core/string_builder.hpp"
#include "../core/string_consumer.hpp"
#include "../vehicle_base.h" #include "../vehicle_base.h"
#include "../company_func.h" #include "../company_func.h"
#include "../timer/timer_game_economy.h" #include "../timer/timer_game_economy.h"
@ -935,13 +936,14 @@ void FixSCCEncoded(std::string &str, bool fix_code)
bool in_string = false; // Set if we in a string, between double-quotes. bool in_string = false; // Set if we in a string, between double-quotes.
bool need_type = true; // Set if a parameter type needs to be emitted. bool need_type = true; // Set if a parameter type needs to be emitted.
for (auto it = std::begin(str); it != std::end(str); /* nothing */) { StringConsumer consumer(str);
size_t len = Utf8EncodedCharLen(*it); while (consumer.AnyBytesLeft()) {
if (len == 0 || it + len > std::end(str)) break;
char32_t c; char32_t c;
Utf8Decode(&c, &*it); if (auto r = consumer.TryReadUtf8(); r.has_value()) {
it += len; c = *r;
} else {
break;
}
if (c == SCC_ENCODED || (fix_code && (c == 0xE028 || c == 0xE02A))) { if (c == SCC_ENCODED || (fix_code && (c == 0xE028 || c == 0xE02A))) {
builder.PutUtf8(SCC_ENCODED); builder.PutUtf8(SCC_ENCODED);
need_type = false; need_type = false;

View File

@ -39,8 +39,8 @@
#include "core/backup_type.hpp" #include "core/backup_type.hpp"
#include "gfx_layout.h" #include "gfx_layout.h"
#include "core/utf8.hpp" #include "core/utf8.hpp"
#include "core/string_consumer.hpp"
#include <stack> #include <stack>
#include <charconv>
#include "table/strings.h" #include "table/strings.h"
#include "table/control_codes.h" #include "table/control_codes.h"
@ -153,48 +153,39 @@ EncodedString EncodedString::ReplaceParam(size_t param, StringParameter &&data)
if (this->empty()) return {}; if (this->empty()) return {};
std::vector<StringParameter> params; std::vector<StringParameter> params;
StringConsumer consumer(this->string);
/* We need char * for std::from_chars. Iterate the underlying data, as string's own iterators may interfere. */ if (!consumer.ReadUtf8If(SCC_ENCODED_INTERNAL)) return {};
const char *p = this->string.data();
const char *e = this->string.data() + this->string.length();
char32_t c = Utf8Consume(p);
if (c != SCC_ENCODED_INTERNAL) return {};
StringID str; StringID str;
auto result = std::from_chars(p, e, str, 16); if (auto r = consumer.TryReadIntegerBase<uint32_t>(16); r.has_value()) {
if (result.ec != std::errc()) return {}; str = *r;
if (result.ptr != e && *result.ptr != SCC_RECORD_SEPARATOR) return {}; } else {
p = result.ptr; return {};
}
if (consumer.AnyBytesLeft() && !consumer.ReadUtf8If(SCC_RECORD_SEPARATOR)) return {};
while (p != e) { while (consumer.AnyBytesLeft()) {
auto s = ++p; StringConsumer record(consumer.ReadUntilUtf8(SCC_RECORD_SEPARATOR, StringConsumer::SKIP_ONE_SEPARATOR));
/* Find end of the parameter. */ if (!record.AnyBytesLeft()) {
for (; p != e && *p != SCC_RECORD_SEPARATOR; ++p) {}
if (s == p) {
/* This is an empty parameter. */ /* This is an empty parameter. */
params.emplace_back(std::monostate{}); params.emplace_back(std::monostate{});
continue; continue;
} }
/* Get the parameter type. */ /* Get the parameter type. */
char32_t parameter_type; char32_t parameter_type = record.ReadUtf8();
size_t len = Utf8Decode(&parameter_type, s);
s += len;
switch (parameter_type) { switch (parameter_type) {
case SCC_ENCODED_NUMERIC: { case SCC_ENCODED_NUMERIC: {
uint64_t value; uint64_t value = record.ReadIntegerBase<uint64_t>(16);
result = std::from_chars(s, p, value, 16); assert(!record.AnyBytesLeft());
if (result.ec != std::errc() || result.ptr != p) return {};
params.emplace_back(value); params.emplace_back(value);
break; break;
} }
case SCC_ENCODED_STRING: { case SCC_ENCODED_STRING: {
params.emplace_back(std::string(s, p)); params.emplace_back(std::string(record.Read(StringConsumer::npos)));
break; break;
} }