metadata.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. Minetest
  3. Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "metadata.h"
  17. #include "log.h"
  18. /*
  19. IMetadata
  20. */
  21. bool IMetadata::operator==(const IMetadata &other) const
  22. {
  23. StringMap this_map_, other_map_;
  24. const StringMap &this_map = getStrings(&this_map_);
  25. const StringMap &other_map = other.getStrings(&other_map_);
  26. if (this_map.size() != other_map.size())
  27. return false;
  28. for (const auto &this_pair : this_map) {
  29. const auto &other_pair = other_map.find(this_pair.first);
  30. if (other_pair == other_map.cend() || other_pair->second != this_pair.second)
  31. return false;
  32. }
  33. return true;
  34. }
  35. const std::string &IMetadata::getString(const std::string &name, std::string *place,
  36. u16 recursion) const
  37. {
  38. const std::string *raw = getStringRaw(name, place);
  39. if (!raw) {
  40. static const std::string empty_string = std::string("");
  41. return empty_string;
  42. }
  43. return resolveString(*raw, place, recursion, true);
  44. }
  45. bool IMetadata::getStringToRef(const std::string &name,
  46. std::string &str, u16 recursion) const
  47. {
  48. const std::string *raw = getStringRaw(name, &str);
  49. if (!raw)
  50. return false;
  51. const std::string &resolved = resolveString(*raw, &str, recursion, true);
  52. if (&resolved != &str)
  53. str = resolved;
  54. return true;
  55. }
  56. const std::string &IMetadata::resolveString(const std::string &str, std::string *place,
  57. u16 recursion, bool deprecated) const
  58. {
  59. if (recursion <= 1 && str_starts_with(str, "${") && str.back() == '}') {
  60. if (deprecated) {
  61. warningstream << "Deprecated use of recursive resolution syntax in metadata: ";
  62. safe_print_string(warningstream, str);
  63. warningstream << std::endl;
  64. }
  65. // It may be the case that &str == place, but that's fine.
  66. return getString(str.substr(2, str.length() - 3), place, recursion + 1);
  67. }
  68. return str;
  69. }
  70. /*
  71. SimpleMetadata
  72. */
  73. void SimpleMetadata::clear()
  74. {
  75. m_stringvars.clear();
  76. m_modified = true;
  77. }
  78. bool SimpleMetadata::empty() const
  79. {
  80. return m_stringvars.empty();
  81. }
  82. size_t SimpleMetadata::size() const
  83. {
  84. return m_stringvars.size();
  85. }
  86. bool SimpleMetadata::contains(const std::string &name) const
  87. {
  88. return m_stringvars.find(name) != m_stringvars.end();
  89. }
  90. const StringMap &SimpleMetadata::getStrings(StringMap *) const
  91. {
  92. return m_stringvars;
  93. }
  94. const std::vector<std::string> &SimpleMetadata::getKeys(std::vector<std::string> *place) const
  95. {
  96. place->clear();
  97. place->reserve(m_stringvars.size());
  98. for (const auto &pair : m_stringvars)
  99. place->push_back(pair.first);
  100. return *place;
  101. }
  102. const std::string *SimpleMetadata::getStringRaw(const std::string &name, std::string *) const
  103. {
  104. const auto found = m_stringvars.find(name);
  105. return found != m_stringvars.cend() ? &found->second : nullptr;
  106. }
  107. bool SimpleMetadata::setString(const std::string &name, std::string_view var)
  108. {
  109. if (var.empty()) {
  110. if (m_stringvars.erase(name) == 0)
  111. return false;
  112. } else {
  113. StringMap::iterator it = m_stringvars.find(name);
  114. if (it != m_stringvars.end() && it->second == var)
  115. return false;
  116. m_stringvars[name].assign(var);
  117. }
  118. m_modified = true;
  119. return true;
  120. }