mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-11-07 01:01:59 +00:00
150 lines
4.9 KiB
C++
150 lines
4.9 KiB
C++
#include "CommandsParserState.h"
|
|
|
|
namespace
|
|
{
|
|
MemberInformation* GetMemberWithName(const std::string& memberName, const StructureInformation* type)
|
|
{
|
|
for (const auto& member : type->m_ordered_members)
|
|
{
|
|
if (member->m_member->m_name == memberName)
|
|
{
|
|
return member.get();
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool GetNextTypenameSeparatorPos(const std::string& typeNameValue, const size_t startPos, size_t& separatorPos)
|
|
{
|
|
const auto typeNameValueSize = typeNameValue.size();
|
|
for (auto currentHead = startPos + 1; currentHead < typeNameValueSize; currentHead++)
|
|
{
|
|
if (typeNameValue[currentHead] == ':' && typeNameValue[currentHead - 1] == ':')
|
|
{
|
|
separatorPos = currentHead - 1;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool ExtractMembersFromTypenameInternal(const std::string& typeNameValue,
|
|
size_t typeNameOffset,
|
|
const StructureInformation* type,
|
|
std::vector<MemberInformation*>& members)
|
|
{
|
|
auto startOffset = typeNameOffset;
|
|
while (GetNextTypenameSeparatorPos(typeNameValue, typeNameOffset, typeNameOffset))
|
|
{
|
|
auto* foundMember = GetMemberWithName(std::string(typeNameValue, startOffset, typeNameOffset - startOffset), type);
|
|
|
|
if (foundMember == nullptr)
|
|
return false;
|
|
|
|
members.push_back(foundMember);
|
|
type = foundMember->m_type;
|
|
typeNameOffset += 2;
|
|
startOffset = typeNameOffset;
|
|
}
|
|
|
|
auto* foundMember = GetMemberWithName(std::string(typeNameValue, startOffset, typeNameValue.size() - startOffset), type);
|
|
if (foundMember == nullptr)
|
|
return false;
|
|
|
|
members.push_back(foundMember);
|
|
return true;
|
|
}
|
|
} // namespace
|
|
|
|
CommandsParserState::CommandsParserState(IDataRepository* repository)
|
|
: m_repository(repository),
|
|
m_in_use(nullptr)
|
|
{
|
|
}
|
|
|
|
const IDataRepository* CommandsParserState::GetRepository() const
|
|
{
|
|
return m_repository;
|
|
}
|
|
|
|
void CommandsParserState::AddBlock(std::unique_ptr<FastFileBlock> block) const
|
|
{
|
|
m_repository->Add(std::move(block));
|
|
}
|
|
|
|
void CommandsParserState::AddGameVariant(std::string variantName, const WordSize wordSize, const std::endian endianness) const
|
|
{
|
|
m_repository->AddGameVariant(std::make_unique<GameVariant>(std::move(variantName), wordSize, endianness));
|
|
}
|
|
|
|
void CommandsParserState::SetGame(std::string gameName) const
|
|
{
|
|
m_repository->SetGame(std::move(gameName));
|
|
}
|
|
|
|
StructureInformation* CommandsParserState::GetInUse() const
|
|
{
|
|
return m_in_use;
|
|
}
|
|
|
|
void CommandsParserState::SetInUse(StructureInformation* structure)
|
|
{
|
|
m_in_use = structure;
|
|
}
|
|
|
|
bool CommandsParserState::GetMembersFromTypename(const std::string& typeNameValue,
|
|
const StructureInformation* baseType,
|
|
std::vector<MemberInformation*>& members) const
|
|
{
|
|
return m_in_use != nullptr && ExtractMembersFromTypenameInternal(typeNameValue, 0, m_in_use, members)
|
|
|| ExtractMembersFromTypenameInternal(typeNameValue, 0, baseType, members);
|
|
}
|
|
|
|
bool CommandsParserState::GetTypenameAndMembersFromTypename(const std::string& typeNameValue,
|
|
StructureInformation*& structure,
|
|
std::vector<MemberInformation*>& members) const
|
|
{
|
|
if (m_in_use != nullptr)
|
|
{
|
|
if (ExtractMembersFromTypenameInternal(typeNameValue, 0, m_in_use, members))
|
|
{
|
|
structure = m_in_use;
|
|
return true;
|
|
}
|
|
members.clear();
|
|
}
|
|
|
|
DataDefinition* foundDefinition = nullptr;
|
|
auto currentSeparatorPos = 0uz;
|
|
while (GetNextTypenameSeparatorPos(typeNameValue, currentSeparatorPos, currentSeparatorPos))
|
|
{
|
|
std::string currentTypename(typeNameValue, 0, currentSeparatorPos);
|
|
currentSeparatorPos += 2;
|
|
|
|
foundDefinition = m_repository->GetDataDefinitionByName(currentTypename);
|
|
if (foundDefinition != nullptr)
|
|
break;
|
|
}
|
|
|
|
if (foundDefinition == nullptr)
|
|
{
|
|
currentSeparatorPos = static_cast<unsigned>(typeNameValue.size());
|
|
foundDefinition = m_repository->GetDataDefinitionByName(typeNameValue);
|
|
}
|
|
|
|
if (foundDefinition == nullptr)
|
|
return false;
|
|
|
|
const auto* definitionWithMembers = dynamic_cast<DefinitionWithMembers*>(foundDefinition);
|
|
if (definitionWithMembers == nullptr)
|
|
return false;
|
|
|
|
structure = m_repository->GetInformationFor(definitionWithMembers);
|
|
if (currentSeparatorPos >= typeNameValue.size())
|
|
return true;
|
|
|
|
return ExtractMembersFromTypenameInternal(typeNameValue, currentSeparatorPos, structure, members);
|
|
}
|