bool TMDTextUnserializer::Unserialize(StringView str) { Array 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; }