memory_settings_interface.cpp (8987B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #include "memory_settings_interface.h" 5 6 #include "common/assert.h" 7 #include "common/error.h" 8 #include "common/string_util.h" 9 10 MemorySettingsInterface::MemorySettingsInterface() = default; 11 12 MemorySettingsInterface::~MemorySettingsInterface() = default; 13 14 bool MemorySettingsInterface::Save(Error* error /* = nullptr */) 15 { 16 Error::SetStringView(error, "Memory settings cannot be saved."); 17 return false; 18 } 19 20 void MemorySettingsInterface::Clear() 21 { 22 m_sections.clear(); 23 } 24 25 bool MemorySettingsInterface::IsEmpty() 26 { 27 return m_sections.empty(); 28 } 29 30 bool MemorySettingsInterface::GetIntValue(const char* section, const char* key, s32* value) const 31 { 32 const auto sit = m_sections.find(section); 33 if (sit == m_sections.end()) 34 return false; 35 36 const auto iter = sit->second.find(key); 37 if (iter == sit->second.end()) 38 return false; 39 40 std::optional<s32> parsed = StringUtil::FromChars<s32>(iter->second, 10); 41 if (!parsed.has_value()) 42 return false; 43 44 *value = parsed.value(); 45 return true; 46 } 47 48 bool MemorySettingsInterface::GetUIntValue(const char* section, const char* key, u32* value) const 49 { 50 const auto sit = m_sections.find(section); 51 if (sit == m_sections.end()) 52 return false; 53 54 const auto iter = sit->second.find(key); 55 if (iter == sit->second.end()) 56 return false; 57 58 std::optional<u32> parsed = StringUtil::FromChars<u32>(iter->second, 10); 59 if (!parsed.has_value()) 60 return false; 61 62 *value = parsed.value(); 63 return true; 64 } 65 66 bool MemorySettingsInterface::GetFloatValue(const char* section, const char* key, float* value) const 67 { 68 const auto sit = m_sections.find(section); 69 if (sit == m_sections.end()) 70 return false; 71 72 const auto iter = sit->second.find(key); 73 if (iter == sit->second.end()) 74 return false; 75 76 std::optional<float> parsed = StringUtil::FromChars<float>(iter->second); 77 if (!parsed.has_value()) 78 return false; 79 80 *value = parsed.value(); 81 return true; 82 } 83 84 bool MemorySettingsInterface::GetDoubleValue(const char* section, const char* key, double* value) const 85 { 86 const auto sit = m_sections.find(section); 87 if (sit == m_sections.end()) 88 return false; 89 90 const auto iter = sit->second.find(key); 91 if (iter == sit->second.end()) 92 return false; 93 94 std::optional<double> parsed = StringUtil::FromChars<double>(iter->second); 95 if (!parsed.has_value()) 96 return false; 97 98 *value = parsed.value(); 99 return true; 100 } 101 102 bool MemorySettingsInterface::GetBoolValue(const char* section, const char* key, bool* value) const 103 { 104 const auto sit = m_sections.find(section); 105 if (sit == m_sections.end()) 106 return false; 107 108 const auto iter = sit->second.find(key); 109 if (iter == sit->second.end()) 110 return false; 111 112 std::optional<bool> parsed = StringUtil::FromChars<bool>(iter->second); 113 if (!parsed.has_value()) 114 return false; 115 116 *value = parsed.value(); 117 return true; 118 } 119 120 bool MemorySettingsInterface::GetStringValue(const char* section, const char* key, std::string* value) const 121 { 122 const auto sit = m_sections.find(section); 123 if (sit == m_sections.end()) 124 return false; 125 126 const auto iter = sit->second.find(key); 127 if (iter == sit->second.end()) 128 return false; 129 130 *value = iter->second; 131 return true; 132 } 133 134 bool MemorySettingsInterface::GetStringValue(const char* section, const char* key, SmallStringBase* value) const 135 { 136 const auto sit = m_sections.find(section); 137 if (sit == m_sections.end()) 138 return false; 139 140 const auto iter = sit->second.find(key); 141 if (iter == sit->second.end()) 142 return false; 143 144 value->assign(iter->second); 145 return true; 146 } 147 148 void MemorySettingsInterface::SetIntValue(const char* section, const char* key, s32 value) 149 { 150 SetValue(section, key, std::to_string(value)); 151 } 152 153 void MemorySettingsInterface::SetUIntValue(const char* section, const char* key, u32 value) 154 { 155 SetValue(section, key, std::to_string(value)); 156 } 157 158 void MemorySettingsInterface::SetFloatValue(const char* section, const char* key, float value) 159 { 160 SetValue(section, key, std::to_string(value)); 161 } 162 163 void MemorySettingsInterface::SetDoubleValue(const char* section, const char* key, double value) 164 { 165 SetValue(section, key, std::to_string(value)); 166 } 167 168 void MemorySettingsInterface::SetBoolValue(const char* section, const char* key, bool value) 169 { 170 SetValue(section, key, value ? "true" : "false"); 171 } 172 173 void MemorySettingsInterface::SetStringValue(const char* section, const char* key, const char* value) 174 { 175 SetValue(section, key, value); 176 } 177 178 std::vector<std::pair<std::string, std::string>> MemorySettingsInterface::GetKeyValueList(const char* section) const 179 { 180 std::vector<std::pair<std::string, std::string>> output; 181 auto sit = m_sections.find(section); 182 if (sit != m_sections.end()) 183 { 184 for (const auto& it : sit->second) 185 output.emplace_back(it.first, it.second); 186 } 187 return output; 188 } 189 190 void MemorySettingsInterface::SetKeyValueList(const char* section, 191 const std::vector<std::pair<std::string, std::string>>& items) 192 { 193 auto sit = m_sections.find(section); 194 sit->second.clear(); 195 for (const auto& [key, value] : items) 196 sit->second.emplace(key, value); 197 } 198 199 void MemorySettingsInterface::SetValue(const char* section, const char* key, std::string value) 200 { 201 auto sit = m_sections.find(section); 202 if (sit == m_sections.end()) 203 sit = m_sections.emplace(std::make_pair(std::string(section), KeyMap())).first; 204 205 const auto range = sit->second.equal_range(key); 206 if (range.first == range.second) 207 { 208 sit->second.emplace(std::string(key), std::move(value)); 209 return; 210 } 211 212 auto iter = range.first; 213 iter->second = std::move(value); 214 ++iter; 215 216 // remove other values 217 while (iter != range.second) 218 { 219 auto remove = iter++; 220 sit->second.erase(remove); 221 } 222 } 223 224 std::vector<std::string> MemorySettingsInterface::GetStringList(const char* section, const char* key) const 225 { 226 std::vector<std::string> ret; 227 228 const auto sit = m_sections.find(section); 229 if (sit != m_sections.end()) 230 { 231 const auto range = sit->second.equal_range(key); 232 for (auto iter = range.first; iter != range.second; ++iter) 233 ret.emplace_back(iter->second); 234 } 235 236 return ret; 237 } 238 239 void MemorySettingsInterface::SetStringList(const char* section, const char* key, const std::vector<std::string>& items) 240 { 241 auto sit = m_sections.find(section); 242 if (sit == m_sections.end()) 243 sit = m_sections.emplace(std::make_pair(std::string(section), KeyMap())).first; 244 245 const auto range = sit->second.equal_range(key); 246 for (auto iter = range.first; iter != range.second;) 247 sit->second.erase(iter++); 248 249 std::string_view keysv(key); 250 for (const std::string& value : items) 251 sit->second.emplace(keysv, value); 252 } 253 254 bool MemorySettingsInterface::RemoveFromStringList(const char* section, const char* key, const char* item) 255 { 256 auto sit = m_sections.find(section); 257 if (sit == m_sections.end()) 258 sit = m_sections.emplace(std::make_pair(std::string(section), KeyMap())).first; 259 260 const auto range = sit->second.equal_range(key); 261 bool result = false; 262 for (auto iter = range.first; iter != range.second;) 263 { 264 if (iter->second == item) 265 { 266 sit->second.erase(iter++); 267 result = true; 268 } 269 else 270 { 271 ++iter; 272 } 273 } 274 275 return result; 276 } 277 278 bool MemorySettingsInterface::AddToStringList(const char* section, const char* key, const char* item) 279 { 280 auto sit = m_sections.find(section); 281 if (sit == m_sections.end()) 282 sit = m_sections.emplace(std::make_pair(std::string(section), KeyMap())).first; 283 284 const auto range = sit->second.equal_range(key); 285 for (auto iter = range.first; iter != range.second; ++iter) 286 { 287 if (iter->second == item) 288 return false; 289 } 290 291 sit->second.emplace(std::string(key), std::string(item)); 292 return true; 293 } 294 295 bool MemorySettingsInterface::ContainsValue(const char* section, const char* key) const 296 { 297 const auto sit = m_sections.find(section); 298 if (sit == m_sections.end()) 299 return false; 300 301 return (sit->second.find(key) != sit->second.end()); 302 } 303 304 void MemorySettingsInterface::DeleteValue(const char* section, const char* key) 305 { 306 auto sit = m_sections.find(section); 307 if (sit == m_sections.end()) 308 return; 309 310 const auto range = sit->second.equal_range(key); 311 for (auto iter = range.first; iter != range.second;) 312 sit->second.erase(iter++); 313 } 314 315 void MemorySettingsInterface::ClearSection(const char* section) 316 { 317 auto sit = m_sections.find(section); 318 if (sit == m_sections.end()) 319 return; 320 321 m_sections.erase(sit); 322 } 323 324 void MemorySettingsInterface::RemoveSection(const char* section) 325 { 326 auto sit = m_sections.find(section); 327 if (sit == m_sections.end()) 328 return; 329 330 m_sections.erase(sit); 331 } 332 333 void MemorySettingsInterface::RemoveEmptySections() 334 { 335 for (auto sit = m_sections.begin(); sit != m_sections.end();) 336 { 337 if (sit->second.size() > 0) 338 { 339 ++sit; 340 continue; 341 } 342 343 sit = m_sections.erase(sit); 344 } 345 }