From f60983989428881c4addc5132dbac59dfd79c6a6 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Sun, 5 Dec 2021 19:16:39 +0100 Subject: [PATCH] machineproperties: improve StrProperty class. --- machines/machineproperties.cpp | 133 +++++++++++++++++++++++++++++++++ machines/machineproperties.h | 96 ++++++++---------------- 2 files changed, 164 insertions(+), 65 deletions(-) create mode 100644 machines/machineproperties.cpp diff --git a/machines/machineproperties.cpp b/machines/machineproperties.cpp new file mode 100644 index 0000000..8139c65 --- /dev/null +++ b/machines/machineproperties.cpp @@ -0,0 +1,133 @@ +/* +DingusPPC - The Experimental PowerPC Macintosh emulator +Copyright (C) 2018-21 divingkatae and maximum + (theweirdo) spatium + +(Contact divingkatae#1017 or powermax#2286 on Discord for more info) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "machineproperties.h" + +#include +#include +#include +#include + +void StrProperty::set_string(std::string str) +{ + if (!this->check_val(str)) { + LOG_F(ERROR, "Invalid property value '%s'!", str.c_str()); + LOG_F(ERROR, "Valid values: %s!", + this->get_valid_values_as_str().c_str()); + } else { + this->val = str; + } +} + +std::string StrProperty::get_valid_values_as_str() +{ + std::stringstream ss; + + switch (this->check_type) { + case CHECK_TYPE_LIST: { + bool first = true; + for (auto it = begin(this->vec); it != end(this->vec); ++it) { + if (!first) + ss << ", "; + ss << "'" << *it << "'"; + first = false; + } + } + return ss.str(); + default: + return std::string("Any"); + } +} + +bool StrProperty::check_val(std::string str) +{ + switch (this->check_type) { + case CHECK_TYPE_LIST: + if (find(this->vec.begin(), this->vec.end(), str) != this->vec.end()) + return true; + else + return false; + default: + return true; + } +} + +uint32_t IntProperty::get_int() +{ + try { + uint32_t result = strtoul(this->get_string().c_str(), 0, 0); + + /* perform value check */ + if (!this->check_val(result)) { + LOG_F(ERROR, "Invalid property value %d!", result); + LOG_F(ERROR, "Valid values: %s!", + this->get_valid_values_as_str().c_str()); + this->set_string(to_string(this->int_val)); + } else { + this->int_val = result; + } + } catch (string bad_string) { + LOG_F(ERROR, "Could not convert string %s to an integer!", + bad_string.c_str()); + } + return this->int_val; +} + +string IntProperty::get_valid_values_as_str() +{ + std::stringstream ss; + + switch (this->check_type) { + case CHECK_TYPE_RANGE: + ss << "[" << this->min << "..." << this->max << "]"; + return ss.str(); + case CHECK_TYPE_LIST: { + bool first = true; + for (auto it = begin(this->vec); it != end(this->vec); ++it) { + if (!first) + ss << ", "; + ss << *it; + first = false; + } + return ss.str(); + } + default: + return std::string("Any"); + } +} + +bool IntProperty::check_val(uint32_t val) +{ + switch (this->check_type) { + case CHECK_TYPE_RANGE: + if (val < this->min || val > this->max) + return false; + else + return true; + case CHECK_TYPE_LIST: + if (find(this->vec.begin(), this->vec.end(), val) != this->vec.end()) + return true; + else + return false; + default: + return true; + } +} diff --git a/machines/machineproperties.h b/machines/machineproperties.h index cae1010..3ff7c14 100644 --- a/machines/machineproperties.h +++ b/machines/machineproperties.h @@ -19,16 +19,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include #include -#include #include #include #include #include #include -#include #include #include @@ -37,8 +34,6 @@ along with this program. If not, see . using namespace std; -#define ILLEGAL_DEVICE_VALUE 0x168A523B - /** Property types. */ enum PropType : int { PROP_TYPE_UNKNOWN = 0, @@ -66,15 +61,15 @@ public: /* Clone method for copying derived property objects. */ virtual BasicProperty* clone() const = 0; - string get_string() { + virtual string get_string() { return this->val; } - void set_string(string str) { + virtual void set_string(string str) { this->val = str; } - PropType get_type() { + virtual PropType get_type() { return this->type; } @@ -88,9 +83,33 @@ protected: class StrProperty : public BasicProperty { public: StrProperty(string str) - : BasicProperty(PROP_TYPE_STRING, str) {} + : BasicProperty(PROP_TYPE_STRING, str) + { + this->check_type = CHECK_TYPE_NONE; + this->vec.clear(); + } + + /* construct a string property with a list of valid values. */ + StrProperty(string str, vector vec) + : BasicProperty(PROP_TYPE_STRING, str) + { + this->check_type = CHECK_TYPE_LIST; + this->vec = vec; + } BasicProperty* clone() const { return new StrProperty(*this); } + + /* override BasicProperty::set_string() and perform checks */ + void set_string(string str); + + string get_valid_values_as_str(); + +protected: + bool check_val(string str); + +private: + CheckType check_type; + vector vec; }; /** Property class that holds an integer value. */ @@ -131,65 +150,12 @@ public: BasicProperty* clone() const { return new IntProperty(*this); } - uint32_t get_int() { - try { - uint32_t result = strtoul(this->get_string().c_str(), 0, 0); + uint32_t get_int(); - /* perform value check */ - if (!this->check_val(result)) { - LOG_F(ERROR, "Invalid property value %d!", result); - LOG_F(ERROR, "Valid values: %s!", - this->get_valid_values_as_str().c_str()); - this->set_string(to_string(this->int_val)); - } else { - this->int_val = result; - } - } catch (string bad_string) { - LOG_F(ERROR, "Could not convert string %s to an integer!", - bad_string.c_str()); - } - return this->int_val; - } - - string get_valid_values_as_str() { - stringstream ss; - - switch (this->check_type) { - case CHECK_TYPE_RANGE: - ss << "[" << this->min << "..." << this->max << "]"; - return ss.str(); - case CHECK_TYPE_LIST: { - bool first = true; - for (auto it = begin(this->vec); it != end(this->vec); ++it) { - if (!first) - ss << ", "; - ss << *it; - first = false; - } - return ss.str(); - } - default: - return string("None"); - } - } + string get_valid_values_as_str(); protected: - bool check_val(uint32_t val) { - switch (this->check_type) { - case CHECK_TYPE_RANGE: - if (val < this->min || val > this->max) - return false; - else - return true; - case CHECK_TYPE_LIST: - if (find(this->vec.begin(), this->vec.end(), val) != this->vec.end()) - return true; - else - return false; - default: - return true; - } - } + bool check_val(uint32_t val); private: uint32_t int_val;