/* Minetest Copyright (C) 2010-2013 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "metadata.h" #include "log.h" /* IMetadata */ bool IMetadata::operator==(const IMetadata &other) const { StringMap this_map_, other_map_; const StringMap &this_map = getStrings(&this_map_); const StringMap &other_map = other.getStrings(&other_map_); if (this_map.size() != other_map.size()) return false; for (const auto &this_pair : this_map) { const auto &other_pair = other_map.find(this_pair.first); if (other_pair == other_map.cend() || other_pair->second != this_pair.second) return false; } return true; } const std::string &IMetadata::getString(const std::string &name, std::string *place, u16 recursion) const { const std::string *raw = getStringRaw(name, place); if (!raw) { static const std::string empty_string = std::string(""); return empty_string; } return resolveString(*raw, place, recursion, true); } bool IMetadata::getStringToRef(const std::string &name, std::string &str, u16 recursion) const { const std::string *raw = getStringRaw(name, &str); if (!raw) return false; const std::string &resolved = resolveString(*raw, &str, recursion, true); if (&resolved != &str) str = resolved; return true; } const std::string &IMetadata::resolveString(const std::string &str, std::string *place, u16 recursion, bool deprecated) const { if (recursion <= 1 && str_starts_with(str, "${") && str.back() == '}') { if (deprecated) { warningstream << "Deprecated use of recursive resolution syntax in metadata: "; safe_print_string(warningstream, str); warningstream << std::endl; } // It may be the case that &str == place, but that's fine. return getString(str.substr(2, str.length() - 3), place, recursion + 1); } return str; } /* SimpleMetadata */ void SimpleMetadata::clear() { m_stringvars.clear(); m_modified = true; } bool SimpleMetadata::empty() const { return m_stringvars.empty(); } size_t SimpleMetadata::size() const { return m_stringvars.size(); } bool SimpleMetadata::contains(const std::string &name) const { return m_stringvars.find(name) != m_stringvars.end(); } const StringMap &SimpleMetadata::getStrings(StringMap *) const { return m_stringvars; } const std::vector &SimpleMetadata::getKeys(std::vector *place) const { place->clear(); place->reserve(m_stringvars.size()); for (const auto &pair : m_stringvars) place->push_back(pair.first); return *place; } const std::string *SimpleMetadata::getStringRaw(const std::string &name, std::string *) const { const auto found = m_stringvars.find(name); return found != m_stringvars.cend() ? &found->second : nullptr; } bool SimpleMetadata::setString(const std::string &name, std::string_view var) { if (var.empty()) { if (m_stringvars.erase(name) == 0) return false; } else { StringMap::iterator it = m_stringvars.find(name); if (it != m_stringvars.end() && it->second == var) return false; m_stringvars[name].assign(var); } m_modified = true; return true; }