From ca1e34c121fae839520b64dc812fc6d64092bb0c Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 6 Jun 2023 17:01:37 +0200 Subject: [PATCH] Codechange: use std::string to build ScriptText's encoded text --- src/script/api/script_text.cpp | 27 +++++++++++++-------------- src/script/api/script_text.hpp | 6 ++---- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/script/api/script_text.cpp b/src/script/api/script_text.cpp index 3d2a95650c..61df5e005d 100644 --- a/src/script/api/script_text.cpp +++ b/src/script/api/script_text.cpp @@ -159,24 +159,25 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm) const std::string ScriptText::GetEncodedText() { - static char buf[1024]; static StringIDList seen_ids; int param_count = 0; seen_ids.clear(); - this->_GetEncodedText(buf, lastof(buf), param_count, seen_ids); + std::string result; + auto output = std::back_inserter(result); + this->_GetEncodedText(output, param_count, seen_ids); if (param_count > SCRIPT_TEXT_MAX_PARAMETERS) throw Script_FatalError(fmt::format("{}: Too many parameters", GetGameStringName(this->string))); - return buf; + return result; } -char *ScriptText::_GetEncodedText(char *p, char *lastofp, int ¶m_count, StringIDList &seen_ids) +void ScriptText::_GetEncodedText(std::back_insert_iterator &output, int ¶m_count, StringIDList &seen_ids) { const std::string &name = GetGameStringName(this->string); if (std::find(seen_ids.begin(), seen_ids.end(), this->string) != seen_ids.end()) throw Script_FatalError(fmt::format("{}: Circular reference detected", name)); seen_ids.push_back(this->string); - p += Utf8Encode(p, SCC_ENCODED); - p += seprintf(p, lastofp, "%X", this->string); + Utf8Encode(output, SCC_ENCODED); + fmt::format_to(output, "{:X}", this->string); const StringParams ¶ms = GetGameStringParams(this->string); int cur_idx = 0; @@ -196,7 +197,7 @@ char *ScriptText::_GetEncodedText(char *p, char *lastofp, int ¶m_count, Stri /* No more extra parameters, assume SQInteger are expected. */ if (cur_idx >= this->paramc) throw Script_FatalError(fmt::format("{}: Not enough parameters", name)); if (!std::holds_alternative(this->param[cur_idx])) throw Script_FatalError(fmt::format("{}: Parameter {} expects an integer", name, param_count + i)); - p = strecpy(p, fmt::format(":{:X}", std::get(this->param[cur_idx++])).c_str(), lastofp); + fmt::format_to(output, ":{:X}", std::get(this->param[cur_idx++])); } } if (prev_idx == prev_count) { @@ -207,18 +208,18 @@ char *ScriptText::_GetEncodedText(char *p, char *lastofp, int ¶m_count, Stri switch (cur_param.type) { case StringParam::RAW_STRING: if (!std::holds_alternative(this->param[cur_idx])) throw Script_FatalError(fmt::format("{}: Parameter {} expects a raw string", name, param_count)); - p += seprintf(p, lastofp, ":\"%s\"", std::get(this->param[cur_idx++]).c_str()); + fmt::format_to(output, ":\"%s\"", std::get(this->param[cur_idx++])); break; case StringParam::STRING: { if (!std::holds_alternative(this->param[cur_idx])) throw Script_FatalError(fmt::format("{}: Parameter {} expects a substring", name, param_count)); int count = 0; - p = strecpy(p, ":", lastofp); - p = std::get(this->param[cur_idx++])->_GetEncodedText(p, lastofp, count, seen_ids); + fmt::format_to(output, ":"); + std::get(this->param[cur_idx++])->_GetEncodedText(output, count, seen_ids); if (++count != cur_param.consumes) { ScriptLog::Error(fmt::format("{}: Parameter {} substring consumes {}, but expected {} to be consumed", name, param_count, count - 1, cur_param.consumes - 1).c_str()); /* Fill missing params if needed. */ - for (int i = count; i < cur_param.consumes; i++) p += seprintf(p, lastofp, ":0"); + for (int i = count; i < cur_param.consumes; i++) fmt::format_to(output, ":0"); /* Disable validation for the extra params if any. */ if (count > cur_param.consumes) { prev_string = param_count; @@ -233,7 +234,7 @@ char *ScriptText::_GetEncodedText(char *p, char *lastofp, int ¶m_count, Stri if (cur_idx + cur_param.consumes > this->paramc) throw Script_FatalError(fmt::format("{}: Not enough parameters", name)); for (int i = 0; i < cur_param.consumes; i++) { if (!std::holds_alternative(this->param[cur_idx])) throw Script_FatalError(fmt::format("{}: Parameter {} expects an integer", name, param_count + i)); - p = strecpy(p, fmt::format(":{:X}", std::get(this->param[cur_idx++])).c_str(), lastofp); + fmt::format_to(output, ":{:X}", std::get(this->param[cur_idx++])); } } } @@ -242,8 +243,6 @@ char *ScriptText::_GetEncodedText(char *p, char *lastofp, int ¶m_count, Stri } seen_ids.pop_back(); - - return p; } const std::string Text::GetDecodedText() diff --git a/src/script/api/script_text.hpp b/src/script/api/script_text.hpp index 8c8171de85..92928b8b8f 100644 --- a/src/script/api/script_text.hpp +++ b/src/script/api/script_text.hpp @@ -138,13 +138,11 @@ private: /** * Internal function for recursive calling this function over multiple * instances, while writing in the same buffer. - * @param p The current position in the buffer. - * @param lastofp The last position valid in the buffer. + * @param output The output to write the encoded text to. * @param param_count The number of parameters that are in the string. * @param seen_ids The list of seen StringID. - * @return The new current position in the buffer. */ - char *_GetEncodedText(char *p, char *lastofp, int ¶m_count, StringIDList &seen_ids); + void _GetEncodedText(std::back_insert_iterator &output, int ¶m_count, StringIDList &seen_ids); /** * Set a parameter, where the value is the first item on the stack.