param_package.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright 2017 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <array>
  5. #include <vector>
  6. #include "common/logging/log.h"
  7. #include "common/param_package.h"
  8. #include "common/string_util.h"
  9. namespace Common {
  10. constexpr char KEY_VALUE_SEPARATOR = ':';
  11. constexpr char PARAM_SEPARATOR = ',';
  12. constexpr char ESCAPE_CHARACTER = '$';
  13. const std::string KEY_VALUE_SEPARATOR_ESCAPE{ESCAPE_CHARACTER, '0'};
  14. const std::string PARAM_SEPARATOR_ESCAPE{ESCAPE_CHARACTER, '1'};
  15. const std::string ESCAPE_CHARACTER_ESCAPE{ESCAPE_CHARACTER, '2'};
  16. ParamPackage::ParamPackage(const std::string& serialized) {
  17. std::vector<std::string> pairs;
  18. Common::SplitString(serialized, PARAM_SEPARATOR, pairs);
  19. for (const std::string& pair : pairs) {
  20. std::vector<std::string> key_value;
  21. Common::SplitString(pair, KEY_VALUE_SEPARATOR, key_value);
  22. if (key_value.size() != 2) {
  23. LOG_ERROR(Common, "invalid key pair {}", pair);
  24. continue;
  25. }
  26. for (std::string& part : key_value) {
  27. part = Common::ReplaceAll(part, KEY_VALUE_SEPARATOR_ESCAPE, {KEY_VALUE_SEPARATOR});
  28. part = Common::ReplaceAll(part, PARAM_SEPARATOR_ESCAPE, {PARAM_SEPARATOR});
  29. part = Common::ReplaceAll(part, ESCAPE_CHARACTER_ESCAPE, {ESCAPE_CHARACTER});
  30. }
  31. Set(key_value[0], key_value[1]);
  32. }
  33. }
  34. ParamPackage::ParamPackage(std::initializer_list<DataType::value_type> list) : data(list) {}
  35. std::string ParamPackage::Serialize() const {
  36. if (data.empty())
  37. return "";
  38. std::string result;
  39. for (const auto& pair : data) {
  40. std::array<std::string, 2> key_value{{pair.first, pair.second}};
  41. for (std::string& part : key_value) {
  42. part = Common::ReplaceAll(part, {ESCAPE_CHARACTER}, ESCAPE_CHARACTER_ESCAPE);
  43. part = Common::ReplaceAll(part, {PARAM_SEPARATOR}, PARAM_SEPARATOR_ESCAPE);
  44. part = Common::ReplaceAll(part, {KEY_VALUE_SEPARATOR}, KEY_VALUE_SEPARATOR_ESCAPE);
  45. }
  46. result += key_value[0] + KEY_VALUE_SEPARATOR + key_value[1] + PARAM_SEPARATOR;
  47. }
  48. result.pop_back(); // discard the trailing PARAM_SEPARATOR
  49. return result;
  50. }
  51. std::string ParamPackage::Get(const std::string& key, const std::string& default_value) const {
  52. auto pair = data.find(key);
  53. if (pair == data.end()) {
  54. LOG_DEBUG(Common, "key '{}' not found", key);
  55. return default_value;
  56. }
  57. return pair->second;
  58. }
  59. int ParamPackage::Get(const std::string& key, int default_value) const {
  60. auto pair = data.find(key);
  61. if (pair == data.end()) {
  62. LOG_DEBUG(Common, "key '{}' not found", key);
  63. return default_value;
  64. }
  65. try {
  66. return std::stoi(pair->second);
  67. } catch (const std::logic_error&) {
  68. LOG_ERROR(Common, "failed to convert {} to int", pair->second);
  69. return default_value;
  70. }
  71. }
  72. float ParamPackage::Get(const std::string& key, float default_value) const {
  73. auto pair = data.find(key);
  74. if (pair == data.end()) {
  75. LOG_DEBUG(Common, "key {} not found", key);
  76. return default_value;
  77. }
  78. try {
  79. return std::stof(pair->second);
  80. } catch (const std::logic_error&) {
  81. LOG_ERROR(Common, "failed to convert {} to float", pair->second);
  82. return default_value;
  83. }
  84. }
  85. void ParamPackage::Set(const std::string& key, const std::string& value) {
  86. data[key] = value;
  87. }
  88. void ParamPackage::Set(const std::string& key, int value) {
  89. data[key] = std::to_string(value);
  90. }
  91. void ParamPackage::Set(const std::string& key, float value) {
  92. data[key] = std::to_string(value);
  93. }
  94. bool ParamPackage::Has(const std::string& key) const {
  95. return data.find(key) != data.end();
  96. }
  97. } // namespace Common