From 3520a9bd2cfa3a4f8f76ae6cb0d4bcb310466f3b Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 26 Mar 2021 12:12:32 +0100 Subject: [PATCH] Use new helper functions ParseAsArray and ParseAsPairs of InfoStringToStructConverterBase to parse notetracksoundmap and hidetags --- .../T6/AssetLoaders/AssetLoaderWeapon.cpp | 174 +++++------------- .../InfoStringToStructConverterBase.cpp | 89 +++++++++ .../InfoStringToStructConverterBase.h | 4 + 3 files changed, 140 insertions(+), 127 deletions(-) diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderWeapon.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderWeapon.cpp index 567ac621..91ac9f66 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderWeapon.cpp +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderWeapon.cpp @@ -21,62 +21,34 @@ namespace T6 { bool ConvertHideTags(const cspField_t& field, const std::string& value) { + std::vector valueArray; + if (!ParseAsArray(value, valueArray)) + { + std::cout << "Failed to parse hide tags as array" << std::endl; + return false; + } + + if (valueArray.size() > std::extent::value) + { + std::cout << "Cannot have more than " << std::extent::value << "hide tags!" << std::endl; + return false; + } + auto* hideTags = reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); - std::ostringstream hideTag; auto currentHideTag = 0u; - auto hasHideTagText = false; - for (auto ci = 0u; ci < value.size(); ci++) - { - auto c = value[ci]; - - if (c == '\r' && ci + 1 < value.size() && value[ci + 1] == '\n') - c = value[++ci]; - - if (c == '\n') - { - if (hasHideTagText) - { - if (currentHideTag >= std::extent::value) - { - std::cout << "Cannot have more than " << std::extent::value << "hide tags!" << std::endl; - return false; - } - - auto scrString = m_zone_script_strings.AddOrGetScriptString(hideTag.str()); - hideTags[currentHideTag++] = scrString; - m_used_script_string_list.emplace(scrString); - - hasHideTagText = false; - hideTag.clear(); - hideTag.str(std::string()); - } - } - else - { - hideTag << c; - hasHideTagText = true; - } - } - - if (hasHideTagText) - { - if (currentHideTag >= std::extent::value) - { - std::cout << "Cannot have more than " << std::extent::value << "hide tags!" << std::endl; - return false; - } - - auto scrString = m_zone_script_strings.AddOrGetScriptString(hideTag.str()); - hideTags[currentHideTag++] = scrString; - m_used_script_string_list.emplace(scrString); - } - - if (currentHideTag < std::extent::value) + if (valueArray.size() < std::extent::value) { m_used_script_string_list.emplace(m_zone_script_strings.AddOrGetScriptString("")); } + for (; currentHideTag < valueArray.size(); currentHideTag++) + { + const auto scrString = m_zone_script_strings.AddOrGetScriptString(valueArray[currentHideTag]); + hideTags[currentHideTag] = scrString; + m_used_script_string_list.emplace(scrString); + } + for (; currentHideTag < std::extent::value; currentHideTag++) { hideTags[currentHideTag] = m_zone_script_strings.GetScriptString(""); @@ -106,90 +78,38 @@ namespace T6 _NODISCARD bool ConvertNotetrackSoundMap(const cspField_t& field, const std::string& value) { - auto* keys = reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); - auto* values = &keys[std::extent::value]; - - std::ostringstream str; - std::string key; - auto isKey = true; - auto currentEntryNum = 0u; - - for (auto ci = 0u; ci < value.size(); ci++) + std::vector> pairs; + if(!ParseAsPairs(value, pairs)) { - auto c = value[ci]; - - if (c == '\r' && ci + 1 < value.size() && value[ci + 1] == '\n') - c = value[++ci]; - - if (c == '\n' && !isKey) - { - std::cout << "Expected notetracksoundmap value but got new line" << std::endl; - return false; - } - - if(isspace(c)) - continue; - - int separator; - while(true) - { - str << c; - - ci++; - if(ci >= value.size()) - { - separator = EOF; - break; - } - c = value[ci]; - if (c == '\r' && ci + 1 < value.size() && value[ci + 1] == '\n') - c = value[++ci]; - if(isspace(c)) - { - separator = static_cast(static_cast(c)); - break; - } - } - - if(isKey) - { - if(separator == '\n' || separator == EOF) - { - std::cout << "Expected notetracksoundmap value but got new line" << std::endl; - return false; - } - key = str.str(); - str.clear(); - str.str(""); - } - else - { - auto parsedValue = str.str(); - str.clear(); - str.str(""); - - if(currentEntryNum >= std::extent::value) - { - std::cout << "Too many notetracksoundmap entries: Max is " << std::extent::value << std::endl; - return false; - } - - keys[currentEntryNum] = m_zone_script_strings.AddOrGetScriptString(key); - m_used_script_string_list.emplace(keys[currentEntryNum]); - - values[currentEntryNum] = m_zone_script_strings.AddOrGetScriptString(parsedValue); - m_used_script_string_list.emplace(values[currentEntryNum]); - - currentEntryNum++; - } - isKey = !isKey; + std::cout << "Failed to parse notetracksoundmap as pairs" << std::endl; + return false; } - if(currentEntryNum < std::extent::value) + if(pairs.size() > std::extent::value) + { + std::cout << "Cannot have more than " << std::extent::value << "notetracksoundmap entries!" << std::endl; + return false; + } + + auto* keys = reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); + auto* values = &keys[std::extent::value]; + auto currentEntryNum = 0u; + + if (pairs.size() < std::extent::value) { m_used_script_string_list.emplace(m_zone_script_strings.AddOrGetScriptString("")); } - for(; currentEntryNum < std::extent::value; currentEntryNum++) + + for (; currentEntryNum < pairs.size(); currentEntryNum++) + { + keys[currentEntryNum] = m_zone_script_strings.AddOrGetScriptString(pairs[currentEntryNum].first); + m_used_script_string_list.emplace(keys[currentEntryNum]); + + values[currentEntryNum] = m_zone_script_strings.AddOrGetScriptString(pairs[currentEntryNum].second); + m_used_script_string_list.emplace(values[currentEntryNum]); + } + + for (; currentEntryNum < std::extent::value; currentEntryNum++) { const auto emptyScr = m_zone_script_strings.GetScriptString(""); keys[currentEntryNum] = emptyScr; diff --git a/src/ObjLoading/InfoString/InfoStringToStructConverterBase.cpp b/src/ObjLoading/InfoString/InfoStringToStructConverterBase.cpp index 2f81d2d1..1e4fb97a 100644 --- a/src/ObjLoading/InfoString/InfoStringToStructConverterBase.cpp +++ b/src/ObjLoading/InfoString/InfoStringToStructConverterBase.cpp @@ -11,6 +11,95 @@ InfoStringToStructConverterBase::InfoStringToStructConverterBase(const InfoStrin { } +bool InfoStringToStructConverterBase::ParseAsArray(const std::string& value, std::vector& valueArray) +{ + auto startPos = 0u; + for (auto ci = 0u; ci < value.size(); ci++) + { + const auto c = value[ci]; + + if (c == '\r' && ci + 1 < value.size() && value[ci + 1] == '\n') + { + valueArray.emplace_back(value, startPos, ci - startPos); + startPos = ++ci + 1; + } + else if(c == '\n') + { + valueArray.emplace_back(value, startPos, ci - startPos); + startPos = ci + 1; + } + } + + if(startPos < value.size()) + { + valueArray.emplace_back(value, startPos, value.size() - startPos); + } + + return true; +} + +bool InfoStringToStructConverterBase::ParseAsPairs(const std::string& value, std::vector>& valueArray) const +{ + std::string key; + auto isKey = true; + + for (auto ci = 0u; ci < value.size(); ci++) + { + auto c = value[ci]; + + if (c == '\r' && ci + 1 < value.size() && value[ci + 1] == '\n') + c = value[++ci]; + + if (c == '\n' && !isKey) + { + std::cout << "Expected value but got new line" << std::endl; + return false; + } + + if (isspace(c)) + continue; + + int separator; + const auto startPos = ci; + while (true) + { + ci++; + if (ci >= value.size()) + { + separator = EOF; + break; + } + c = value[ci]; + if (c == '\r' && ci + 1 < value.size() && value[ci + 1] == '\n') + c = value[++ci]; + if (isspace(c)) + { + separator = static_cast(static_cast(c)); + break; + } + } + + if (isKey) + { + if (separator == '\n' || separator == EOF) + { + std::cout << "Expected value but got new line" << std::endl; + return false; + } + key = std::string(value, startPos, ci - startPos); + } + else + { + auto parsedValue = std::string(value, startPos, ci - startPos); + valueArray.emplace_back(std::make_pair(std::move(key), std::move(parsedValue))); + key = std::string(); + } + isKey = !isKey; + } + + return true; +} + bool InfoStringToStructConverterBase::ConvertString(const std::string& value, const size_t offset) { *reinterpret_cast(reinterpret_cast(m_structure) + offset) = m_memory->Dup(value.c_str()); diff --git a/src/ObjLoading/InfoString/InfoStringToStructConverterBase.h b/src/ObjLoading/InfoString/InfoStringToStructConverterBase.h index 8aa536a5..09380f1b 100644 --- a/src/ObjLoading/InfoString/InfoStringToStructConverterBase.h +++ b/src/ObjLoading/InfoString/InfoStringToStructConverterBase.h @@ -2,6 +2,7 @@ #include #include +#include #include "Utils/ClassUtils.h" #include "InfoString/InfoString.h" @@ -18,6 +19,9 @@ protected: std::unordered_set m_dependencies; MemoryManager* m_memory; void* m_structure; + + static bool ParseAsArray(const std::string& value, std::vector& valueArray); + bool ParseAsPairs(const std::string& value, std::vector>& valueArray) const; bool ConvertString(const std::string& value, size_t offset); bool ConvertStringBuffer(const std::string& value, size_t offset, size_t bufferSize);