1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-24 00:03:11 +01:00

Fix strings by std::string-ing LanguagePack

This commit is contained in:
Ted John
2017-12-05 17:42:04 +00:00
committed by Michael Steenbeek
parent 31e112cf3b
commit 2ea20552c4
3 changed files with 41 additions and 108 deletions

View File

@@ -245,7 +245,7 @@ void language_free_object_string(rct_string_id stringId)
{ {
if (_languageCurrent != nullptr) if (_languageCurrent != nullptr)
{ {
_languageCurrent->SetString(stringId, nullptr); _languageCurrent->RemoveString(stringId);
} }
_availableObjectStringIds.push(stringId); _availableObjectStringIds.push(stringId);
} }
@@ -275,6 +275,6 @@ rct_string_id language_allocate_object_string(const std::string &target)
rct_string_id stringId = _availableObjectStringIds.top(); rct_string_id stringId = _availableObjectStringIds.top();
_availableObjectStringIds.pop(); _availableObjectStringIds.pop();
_languageCurrent->SetString(stringId, target.c_str()); _languageCurrent->SetString(stringId, target);
return stringId; return stringId;
} }

View File

@@ -41,40 +41,30 @@ constexpr sint32 ScenarioOverrideMaxStringCount = 3;
struct ObjectOverride struct ObjectOverride
{ {
char name[8]; char name[8] = { 0 };
const utf8 * strings[4]; std::string strings[4];
}; };
struct ScenarioOverride struct ScenarioOverride
{ {
std::string filename; std::string filename;
union { std::string strings[3];
const utf8 * strings[3];
struct {
const utf8 * name;
const utf8 * park;
const utf8 * details;
};
};
}; };
class LanguagePack final : public ILanguagePack class LanguagePack final : public ILanguagePack
{ {
private: private:
uint16 _id; uint16 const _id;
utf8 * _stringData; std::vector<std::string> _strings;
std::vector<const utf8*> _strings;
std::vector<ObjectOverride> _objectOverrides; std::vector<ObjectOverride> _objectOverrides;
std::vector<ScenarioOverride> _scenarioOverrides; std::vector<ScenarioOverride> _scenarioOverrides;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Parsing work data // Parsing work data
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
StringBuilder _stringDataSB; std::string _currentGroup;
utf8 * _currentGroup; ObjectOverride * _currentObjectOverride = nullptr;
ObjectOverride * _currentObjectOverride; ScenarioOverride * _currentScenarioOverride = nullptr;
ScenarioOverride * _currentScenarioOverride;
public: public:
static LanguagePack * FromFile(uint16 id, const utf8 * path) static LanguagePack * FromFile(uint16 id, const utf8 * path)
@@ -117,69 +107,22 @@ public:
} }
LanguagePack(uint16 id, const utf8 * text) LanguagePack(uint16 id, const utf8 * text)
: _id(id)
{ {
Guard::ArgumentNotNull(text); Guard::ArgumentNotNull(text);
_id = id;
_stringData = nullptr;
_currentGroup = nullptr;
_currentObjectOverride = nullptr;
_currentScenarioOverride = nullptr;
auto reader = UTF8StringReader(text); auto reader = UTF8StringReader(text);
while (reader.CanRead()) while (reader.CanRead())
{ {
ParseLine(&reader); ParseLine(&reader);
} }
_stringData = _stringDataSB.GetString();
size_t stringDataBaseAddress = (size_t)_stringData;
for (auto &string : _strings)
{
if (string != nullptr)
{
string = (utf8*)(stringDataBaseAddress + (size_t)string);
}
}
for (auto &objectOverride : _objectOverrides)
{
for (sint32 j = 0; j < ObjectOverrideMaxStringCount; j++)
{
const utf8 * * strPtr = &(objectOverride.strings[j]);
if (*strPtr != nullptr)
{
*strPtr = (utf8*)(stringDataBaseAddress + (size_t)*strPtr);
}
}
}
for (auto &scenarioOverride : _scenarioOverrides)
{
for (sint32 j = 0; j < ScenarioOverrideMaxStringCount; j++)
{
const utf8 * * strPtr = &(scenarioOverride.strings[j]);
if (*strPtr != nullptr)
{
*strPtr = (utf8*)(stringDataBaseAddress + (size_t)*strPtr);
}
}
}
// Clean up the parsing work data // Clean up the parsing work data
Memory::Free(_currentGroup); _currentGroup = std::string();
// Reset the string builder to free memory
_stringDataSB.Reset();
_currentGroup = nullptr;
_currentObjectOverride = nullptr; _currentObjectOverride = nullptr;
_currentScenarioOverride = nullptr; _currentScenarioOverride = nullptr;
} }
~LanguagePack()
{
Memory::Free(_stringData);
Memory::Free(_currentGroup);
}
uint16 GetId() const override uint16 GetId() const override
{ {
return _id; return _id;
@@ -190,7 +133,15 @@ public:
return (uint32)_strings.size(); return (uint32)_strings.size();
} }
void SetString(rct_string_id stringId, const utf8 * str) override void RemoveString(rct_string_id stringId) override
{
if (_strings.size() >= (size_t)stringId)
{
_strings[stringId] = std::string();
}
}
void SetString(rct_string_id stringId, const std::string &str) override
{ {
if (_strings.size() >= (size_t)stringId) if (_strings.size() >= (size_t)stringId)
{ {
@@ -208,7 +159,7 @@ public:
if (_scenarioOverrides.size() > (size_t)ooIndex) if (_scenarioOverrides.size() > (size_t)ooIndex)
{ {
return _scenarioOverrides[ooIndex].strings[ooStringIndex]; return _scenarioOverrides[ooIndex].strings[ooStringIndex].c_str();
} }
else else
{ {
@@ -223,7 +174,7 @@ public:
if (_objectOverrides.size() > (size_t)ooIndex) if (_objectOverrides.size() > (size_t)ooIndex)
{ {
return _objectOverrides[ooIndex].strings[ooStringIndex]; return _objectOverrides[ooIndex].strings[ooStringIndex].c_str();
} }
else else
{ {
@@ -234,7 +185,7 @@ public:
{ {
if (_strings.size() > (size_t)stringId) if (_strings.size() > (size_t)stringId)
{ {
return _strings[stringId]; return _strings[stringId].c_str();
} }
else else
{ {
@@ -253,7 +204,7 @@ public:
{ {
if (strncmp(objectOverride.name, objectIdentifier, 8) == 0) if (strncmp(objectOverride.name, objectIdentifier, 8) == 0)
{ {
if (objectOverride.strings[index] == nullptr) if (objectOverride.strings[index].empty())
{ {
return STR_NONE; return STR_NONE;
} }
@@ -275,7 +226,7 @@ public:
{ {
if (String::Equals(scenarioOverride.filename.c_str(), scenarioFilename, true)) if (String::Equals(scenarioOverride.filename.c_str(), scenarioFilename, true))
{ {
if (scenarioOverride.strings[index] == nullptr) if (scenarioOverride.strings[index].empty())
{ {
return STR_NONE; return STR_NONE;
} }
@@ -287,13 +238,12 @@ public:
return STR_NONE; return STR_NONE;
} }
ObjectOverride * GetObjectOverride(const char * objectIdentifier) private:
ObjectOverride * GetObjectOverride(const std::string &objectIdentifier)
{ {
Guard::ArgumentNotNull(objectIdentifier);
for (auto &oo : _objectOverrides) for (auto &oo : _objectOverrides)
{ {
if (strncmp(oo.name, objectIdentifier, 8) == 0) if (strncmp(oo.name, objectIdentifier.c_str(), 8) == 0)
{ {
return &oo; return &oo;
} }
@@ -301,16 +251,11 @@ public:
return nullptr; return nullptr;
} }
ScenarioOverride * GetScenarioOverride(const utf8 * scenarioIdentifier) ScenarioOverride * GetScenarioOverride(const std::string &scenarioIdentifier)
{ {
Guard::ArgumentNotNull(scenarioIdentifier);
for (auto &so : _scenarioOverrides) for (auto &so : _scenarioOverrides)
{ {
// At this point ScenarioOverrides were not yet rewritten to point at if (String::Equals(so.strings[0], scenarioIdentifier.c_str(), true))
// strings, but rather still hold offsets from base.
const utf8 *name = _stringDataSB.GetBuffer() + (size_t)so.name;
if (_stricmp(name, scenarioIdentifier) == 0)
{ {
return &so; return &so;
} }
@@ -444,8 +389,6 @@ public:
if (closedCorrectly) if (closedCorrectly)
{ {
SafeFree(_currentGroup);
while (sb.GetLength() < 8) while (sb.GetLength() < 8)
{ {
sb.Append(' '); sb.Append(' ');
@@ -464,8 +407,7 @@ public:
_objectOverrides.push_back(ObjectOverride()); _objectOverrides.push_back(ObjectOverride());
_currentObjectOverride = &_objectOverrides[_objectOverrides.size() - 1]; _currentObjectOverride = &_objectOverrides[_objectOverrides.size() - 1];
Memory::Set(_currentObjectOverride, 0, sizeof(ObjectOverride)); Memory::Copy(_currentObjectOverride->name, _currentGroup.c_str(), 8);
Memory::Copy(_currentObjectOverride->name, _currentGroup, 8);
} }
} }
} }
@@ -496,8 +438,6 @@ public:
if (closedCorrectly) if (closedCorrectly)
{ {
SafeFree(_currentGroup);
_currentGroup = sb.GetString(); _currentGroup = sb.GetString();
_currentObjectOverride = nullptr; _currentObjectOverride = nullptr;
_currentScenarioOverride = GetScenarioOverride(_currentGroup); _currentScenarioOverride = GetScenarioOverride(_currentGroup);
@@ -511,7 +451,6 @@ public:
_scenarioOverrides.push_back(ScenarioOverride()); _scenarioOverrides.push_back(ScenarioOverride());
_currentScenarioOverride = &_scenarioOverrides[_scenarioOverrides.size() - 1]; _currentScenarioOverride = &_scenarioOverrides[_scenarioOverrides.size() - 1];
_currentScenarioOverride->filename = std::string(sb.GetBuffer()); _currentScenarioOverride->filename = std::string(sb.GetBuffer());
Memory::Set(_currentScenarioOverride->strings, 0, sizeof(_currentScenarioOverride->strings));
} }
} }
} }
@@ -554,7 +493,7 @@ public:
const utf8 * identifier = sb.GetBuffer(); const utf8 * identifier = sb.GetBuffer();
sint32 stringId; sint32 stringId;
if (_currentGroup == nullptr) if (_currentGroup.empty())
{ {
if (sscanf(identifier, "STR_%4d", &stringId) != 1) if (sscanf(identifier, "STR_%4d", &stringId) != 1)
{ {
@@ -610,35 +549,27 @@ public:
} }
} }
// Append a null terminator for the benefit of the last string auto s = std::string(sb.GetBuffer());
_stringDataSB.Append('\0'); if (_currentGroup.empty())
// Get the relative offset to the string (add the base offset when we extract the string properly)
utf8 * relativeOffset = (utf8*)_stringDataSB.GetLength();
if (_currentGroup == nullptr)
{ {
// Make sure the list is big enough to contain this string id // Make sure the list is big enough to contain this string id
if ((size_t)stringId >= _strings.size()) if ((size_t)stringId >= _strings.size())
{ {
_strings.resize(stringId + 1); _strings.resize(stringId + 1);
} }
_strings[stringId] = s;
_strings[stringId] = relativeOffset;
} }
else else
{ {
if (_currentObjectOverride != nullptr) if (_currentObjectOverride != nullptr)
{ {
_currentObjectOverride->strings[stringId] = relativeOffset; _currentObjectOverride->strings[stringId] = s;
} }
else else
{ {
_currentScenarioOverride->strings[stringId] = relativeOffset; _currentScenarioOverride->strings[stringId] = s;
} }
} }
_stringDataSB.Append(&sb);
} }
bool ParseToken(IStringReader * reader, uint32 * token, bool * isByte) bool ParseToken(IStringReader * reader, uint32 * token, bool * isByte)

View File

@@ -18,6 +18,7 @@
#ifdef __cplusplus #ifdef __cplusplus
#include <string>
#include "../common.h" #include "../common.h"
interface ILanguagePack interface ILanguagePack
@@ -27,7 +28,8 @@ interface ILanguagePack
virtual uint16 GetId() const abstract; virtual uint16 GetId() const abstract;
virtual uint32 GetCount() const abstract; virtual uint32 GetCount() const abstract;
virtual void SetString(rct_string_id stringId, const utf8 * str) abstract; virtual void RemoveString(rct_string_id stringId) abstract;
virtual void SetString(rct_string_id stringId, const std::string &str) abstract;
virtual const utf8 * GetString(rct_string_id stringId) const abstract; virtual const utf8 * GetString(rct_string_id stringId) const abstract;
virtual rct_string_id GetObjectOverrideStringId(const char * objectIdentifier, uint8 index) abstract; virtual rct_string_id GetObjectOverrideStringId(const char * objectIdentifier, uint8 index) abstract;
virtual rct_string_id GetScenarioOverrideStringId(const utf8 * scenarioFilename, uint8 index) abstract; virtual rct_string_id GetScenarioOverrideStringId(const utf8 * scenarioFilename, uint8 index) abstract;