diff --git a/src/network/core/network_game_info.cpp b/src/network/core/network_game_info.cpp index 004cac1b6c..623be7fa84 100644 --- a/src/network/core/network_game_info.cpp +++ b/src/network/core/network_game_info.cpp @@ -163,7 +163,7 @@ const NetworkServerGameInfo &GetCurrentNetworkServerGameInfo() * @param config The GRF to handle. * @param name The name of the NewGRF, empty when unknown. */ -static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config, std::string name) +static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config, std::string_view name) { /* Find the matching GRF file */ const GRFConfig *f = FindGRFConfig(config->ident.grfid, FGCM_EXACT, &config->ident.md5sum); diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 1203a19ef9..cbd44526b9 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -269,22 +269,14 @@ public: } } - const char *ReadString() + std::string_view ReadString() { char *string = reinterpret_cast(data); size_t string_length = ttd_strnlen(string, Remaining()); - if (string_length == Remaining()) { - /* String was not NUL terminated, so make sure it is now. */ - string[string_length - 1] = '\0'; - GrfMsg(7, "String was not terminated with a zero byte."); - } else { - /* Increase the string length to include the NUL byte. */ - string_length++; - } Skip(string_length); - return string; + return std::string_view(string, string_length); } inline size_t Remaining() const @@ -2859,27 +2851,27 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By uint8_t newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier. while (newgrf_id != 0) { - const char *name = buf->ReadString(); // The name for the OpenTTD identifier. + std::string_view name = buf->ReadString(); // The name for the OpenTTD identifier. /* We'll just ignore the UTF8 identifier character. This is (fairly) * safe as OpenTTD's strings gender/cases are usually in ASCII which * is just a subset of UTF8, or they need the bigger UTF8 characters * such as Cyrillic. Thus we will simply assume they're all UTF8. */ char32_t c; - size_t len = Utf8Decode(&c, name); - if (c == NFO_UTF8_IDENTIFIER) name += len; + size_t len = Utf8Decode(&c, name.data()); + if (c == NFO_UTF8_IDENTIFIER) name = name.substr(len); LanguageMap::Mapping map; map.newgrf_id = newgrf_id; if (prop == 0x13) { - map.openttd_id = lang->GetGenderIndex(name); + map.openttd_id = lang->GetGenderIndex(name.data()); if (map.openttd_id >= MAX_NUM_GENDERS) { GrfMsg(1, "GlobalVarChangeInfo: Gender name {} is not known, ignoring", name); } else { _cur.grffile->language_map[curidx].gender_map.push_back(map); } } else { - map.openttd_id = lang->GetCaseIndex(name); + map.openttd_id = lang->GetCaseIndex(name.data()); if (map.openttd_id >= MAX_NUM_CASES) { GrfMsg(1, "GlobalVarChangeInfo: Case name {} is not known, ignoring", name); } else { @@ -6295,7 +6287,7 @@ static void FeatureNewName(ByteReader *buf) id, endid, feature, lang); for (; id < endid && buf->HasData(); id++) { - const char *name = buf->ReadString(); + const std::string_view name = buf->ReadString(); GrfMsg(8, "FeatureNewName: 0x{:04X} <- {}", id, name); switch (feature) { @@ -7013,7 +7005,7 @@ static void ScanInfo(ByteReader *buf) { uint8_t grf_version = buf->ReadByte(); uint32_t grfid = buf->ReadDWord(); - const char *name = buf->ReadString(); + std::string_view name = buf->ReadString(); _cur.grfconfig->ident.grfid = grfid; @@ -7028,7 +7020,7 @@ static void ScanInfo(ByteReader *buf) AddGRFTextToList(_cur.grfconfig->name, 0x7F, grfid, false, name); if (buf->HasData()) { - const char *info = buf->ReadString(); + std::string_view info = buf->ReadString(); AddGRFTextToList(_cur.grfconfig->info, 0x7F, grfid, true, info); } @@ -7048,7 +7040,7 @@ static void GRFInfo(ByteReader *buf) uint8_t version = buf->ReadByte(); uint32_t grfid = buf->ReadDWord(); - const char *name = buf->ReadString(); + std::string_view name = buf->ReadString(); if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) { DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8); @@ -7198,7 +7190,7 @@ static void GRFLoadError(ByteReader *buf) if (message_id == 0xFF) { /* This is a custom error message. */ if (buf->HasData()) { - const char *message = buf->ReadString(); + std::string_view message = buf->ReadString(); error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, SCC_RAW_STRING_POINTER); } else { @@ -7210,7 +7202,7 @@ static void GRFLoadError(ByteReader *buf) } if (buf->HasData()) { - const char *data = buf->ReadString(); + std::string_view data = buf->ReadString(); error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data); } else { @@ -7234,7 +7226,7 @@ static void GRFComment(ByteReader *buf) if (!buf->HasData()) return; - const char *text = buf->ReadString(); + std::string_view text = buf->ReadString(); GrfMsg(2, "GRFComment: {}", text); } @@ -7761,7 +7753,7 @@ static void FeatureTownName(ByteReader *buf) do { ClrBit(lang, 7); - const char *name = buf->ReadString(); + std::string_view name = buf->ReadString(); std::string lang_name = TranslateTTDPatchCodes(grfid, lang, false, name); GrfMsg(6, "FeatureTownName: lang 0x{:X} -> '{}'", lang, lang_name); @@ -7801,7 +7793,7 @@ static void FeatureTownName(ByteReader *buf) part.id = ref_id; GrfMsg(6, "FeatureTownName: part {}, text {}, uses intermediate definition 0x{:02X} (with probability {})", partnum, textnum, ref_id, part.prob & 0x7F); } else { - const char *text = buf->ReadString(); + std::string_view text = buf->ReadString(); part.text = TranslateTTDPatchCodes(grfid, 0, false, text); GrfMsg(6, "FeatureTownName: part {}, text {}, '{}' (with probability {})", partnum, textnum, part.text, part.prob); } @@ -8079,9 +8071,9 @@ static void TranslateGRFStrings(ByteReader *buf) } for (uint i = 0; i < num_strings && buf->HasData(); i++) { - const char *string = buf->ReadString(); + std::string_view string = buf->ReadString(); - if (StrEmpty(string)) { + if (string.empty()) { GrfMsg(7, "TranslateGRFString: Ignoring empty string."); continue; } @@ -8091,21 +8083,21 @@ static void TranslateGRFStrings(ByteReader *buf) } /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */ -static bool ChangeGRFName(uint8_t langid, const char *str) +static bool ChangeGRFName(uint8_t langid, std::string_view str) { AddGRFTextToList(_cur.grfconfig->name, langid, _cur.grfconfig->ident.grfid, false, str); return true; } /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */ -static bool ChangeGRFDescription(uint8_t langid, const char *str) +static bool ChangeGRFDescription(uint8_t langid, std::string_view str) { AddGRFTextToList(_cur.grfconfig->info, langid, _cur.grfconfig->ident.grfid, true, str); return true; } /** Callback function for 'INFO'->'URL_' to set the newgrf url. */ -static bool ChangeGRFURL(uint8_t langid, const char *str) +static bool ChangeGRFURL(uint8_t langid, std::string_view str) { AddGRFTextToList(_cur.grfconfig->url, langid, _cur.grfconfig->ident.grfid, false, str); return true; @@ -8207,14 +8199,14 @@ static bool ChangeGRFMinVersion(size_t len, ByteReader *buf) static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf. /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */ -static bool ChangeGRFParamName(uint8_t langid, const char *str) +static bool ChangeGRFParamName(uint8_t langid, std::string_view str) { AddGRFTextToList(_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str); return true; } /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */ -static bool ChangeGRFParamDescription(uint8_t langid, const char *str) +static bool ChangeGRFParamDescription(uint8_t langid, std::string_view str) { AddGRFTextToList(_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str); return true; @@ -8294,7 +8286,7 @@ static bool ChangeGRFParamDefault(size_t len, ByteReader *buf) } typedef bool (*DataHandler)(size_t, ByteReader *); ///< Type of callback function for binary nodes -typedef bool (*TextHandler)(uint8_t, const char *str); ///< Type of callback function for text nodes +typedef bool (*TextHandler)(uint8_t, std::string_view str); ///< Type of callback function for text nodes typedef bool (*BranchHandler)(ByteReader *); ///< Type of callback function for branch nodes /** @@ -8398,7 +8390,7 @@ static bool ChangeGRFParamValueNames(ByteReader *buf) } uint8_t langid = buf->ReadByte(); - const char *name_string = buf->ReadString(); + std::string_view name_string = buf->ReadString(); auto val_name = _cur_parameter->value_names.find(id); if (val_name != _cur_parameter->value_names.end()) { diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index 967af68196..97eb460795 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -233,12 +233,12 @@ struct UnmappedChoiceList { * @param byte80 The control code to use as replacement for the 0x80-value. * @return The translated string. */ -std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool allow_newlines, const std::string &str, StringControlCode byte80) +std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool allow_newlines, std::string_view str, StringControlCode byte80) { /* Empty input string? Nothing to do here. */ - if (str.empty()) return str; + if (str.empty()) return {}; - std::string::const_iterator src = str.cbegin(); + std::string_view::const_iterator src = str.cbegin(); /* Is this an unicode string? */ bool unicode = false; @@ -482,7 +482,7 @@ string_end: * @param langid The The language of the new text. * @param text_to_add The text to add to the list. */ -static void AddGRFTextToList(GRFTextList &list, uint8_t langid, const std::string &text_to_add) +static void AddGRFTextToList(GRFTextList &list, uint8_t langid, std::string_view text_to_add) { /* Loop through all languages and see if we can replace a string */ for (auto &text : list) { @@ -493,7 +493,7 @@ static void AddGRFTextToList(GRFTextList &list, uint8_t langid, const std::strin } /* If a string wasn't replaced, then we must append the new string */ - list.push_back(GRFText{ langid, text_to_add }); + list.push_back(GRFText{ langid, std::string(text_to_add) }); } /** @@ -505,7 +505,7 @@ static void AddGRFTextToList(GRFTextList &list, uint8_t langid, const std::strin * @param text_to_add The text to add to the list. * @note All text-codes will be translated. */ -void AddGRFTextToList(GRFTextList &list, uint8_t langid, uint32_t grfid, bool allow_newlines, const char *text_to_add) +void AddGRFTextToList(GRFTextList &list, uint8_t langid, uint32_t grfid, bool allow_newlines, std::string_view text_to_add) { AddGRFTextToList(list, langid, TranslateTTDPatchCodes(grfid, langid, allow_newlines, text_to_add)); } @@ -519,7 +519,7 @@ void AddGRFTextToList(GRFTextList &list, uint8_t langid, uint32_t grfid, bool al * @param text_to_add The text to add to the list. * @note All text-codes will be translated. */ -void AddGRFTextToList(GRFTextWrapper &list, uint8_t langid, uint32_t grfid, bool allow_newlines, const char *text_to_add) +void AddGRFTextToList(GRFTextWrapper &list, uint8_t langid, uint32_t grfid, bool allow_newlines, std::string_view text_to_add) { if (!list) list.reset(new GRFTextList()); AddGRFTextToList(*list, langid, grfid, allow_newlines, text_to_add); @@ -531,7 +531,7 @@ void AddGRFTextToList(GRFTextWrapper &list, uint8_t langid, uint32_t grfid, bool * @param list The list where the text should be added to. * @param text_to_add The text to add to the list. */ -void AddGRFTextToList(GRFTextWrapper &list, const std::string &text_to_add) +void AddGRFTextToList(GRFTextWrapper &list, std::string_view text_to_add) { if (!list) list.reset(new GRFTextList()); AddGRFTextToList(*list, GRFLX_UNSPECIFIED, text_to_add); @@ -540,7 +540,7 @@ void AddGRFTextToList(GRFTextWrapper &list, const std::string &text_to_add) /** * Add the new read string into our structure. */ -StringID AddGRFString(uint32_t grfid, uint16_t stringid, uint8_t langid_to_add, bool new_scheme, bool allow_newlines, const char *text_to_add, StringID def_string) +StringID AddGRFString(uint32_t grfid, uint16_t stringid, uint8_t langid_to_add, bool new_scheme, bool allow_newlines, std::string_view text_to_add, StringID def_string) { /* When working with the old language scheme (grf_version is less than 7) and * English or American is among the set bits, simply add it as English in diff --git a/src/newgrf_text.h b/src/newgrf_text.h index aad9e92cce..dfefac89ed 100644 --- a/src/newgrf_text.h +++ b/src/newgrf_text.h @@ -29,17 +29,17 @@ typedef std::vector GRFTextList; /** Reference counted wrapper around a GRFText pointer. */ typedef std::shared_ptr GRFTextWrapper; -StringID AddGRFString(uint32_t grfid, uint16_t stringid, uint8_t langid, bool new_scheme, bool allow_newlines, const char *text_to_add, StringID def_string); +StringID AddGRFString(uint32_t grfid, uint16_t stringid, uint8_t langid, bool new_scheme, bool allow_newlines, std::string_view text_to_add, StringID def_string); StringID GetGRFStringID(uint32_t grfid, StringID stringid); const char *GetGRFStringFromGRFText(const GRFTextList &text_list); const char *GetGRFStringFromGRFText(const GRFTextWrapper &text); const char *GetGRFStringPtr(uint32_t stringid); void CleanUpStrings(); void SetCurrentGrfLangID(uint8_t language_id); -std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool allow_newlines, const std::string &str, StringControlCode byte80 = SCC_NEWGRF_PRINT_WORD_STRING_ID); -void AddGRFTextToList(GRFTextList &list, uint8_t langid, uint32_t grfid, bool allow_newlines, const char *text_to_add); -void AddGRFTextToList(GRFTextWrapper &list, uint8_t langid, uint32_t grfid, bool allow_newlines, const char *text_to_add); -void AddGRFTextToList(GRFTextWrapper &list, const std::string &text_to_add); +std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool allow_newlines, std::string_view str, StringControlCode byte80 = SCC_NEWGRF_PRINT_WORD_STRING_ID); +void AddGRFTextToList(GRFTextList &list, uint8_t langid, uint32_t grfid, bool allow_newlines, std::string_view text_to_add); +void AddGRFTextToList(GRFTextWrapper &list, uint8_t langid, uint32_t grfid, bool allow_newlines, std::string_view text_to_add); +void AddGRFTextToList(GRFTextWrapper &list, std::string_view text_to_add); bool CheckGrfLangID(uint8_t lang_id, uint8_t grf_version);