bool TMDTextUnserializer::Unserialize(StringView str)
{
Array<size_t> indexStack;
auto FixupEntries = [this,&indexStack](int level)
{
size_t end = _entries.size();
while (indexStack.size() > size_t(level + 1))
{
_entries[indexStack.last()].off2next = end - indexStack.last();
indexStack.pop_back();
}
};
_entries.clear();
_data = str;
str = _data;
int prevLevel = -1;
while (str.not_empty())
{
StringView line = str.until("\n");
str.skip(line.size() + 1);
// detect level
int level = 0;
while (line.ch() == ' ' || line.ch() == '\t')
{
line.skip(1);
level++;
}
// whitespace only, skip line
if (line.empty())
continue;
if (level > prevLevel + 1)
{
LOG_WARNING << "TMDTextUnserializer failed: missing entries/excessive indenting";
return false;
}
if (level == prevLevel + 1)
{
indexStack.push_back(_entries.size());
}
else
{
if (level < prevLevel)
FixupEntries(level);
_entries[indexStack[level]].off2next = _entries.size() - indexStack[level];
indexStack[level] = _entries.size();
}
prevLevel = level;
StringView nametype = line.until("=");
StringView value = line.part(nametype.size() + 1);
StringView name = nametype.until(":");
StringView type = nametype.part(name.size() + 1);
name.trim(SPACE_CHARS);
type.trim(SPACE_CHARS);
value.trim(SPACE_CHARS);
_entries.push_back({ level, 0, name, type, value });
}
FixupEntries(-1);
return true;
}
Comments