New and improved configuration management. It now handles bool, string and number types, and all conversions happen at initialization time, so retrieval is faster. (yay)

This commit is contained in:
Marius Nita 2002-08-26 06:36:37 +00:00
parent a6d6f0118b
commit 11e643f4b8
2 changed files with 139 additions and 52 deletions

View file

@ -28,19 +28,30 @@ Config::Config() {}
Config::~Config() Config::~Config()
{ {
ItemList::const_iterator it = items.begin(), end = items.end(); // deallocate memory for the 3 lists
for (; it != end; ++it) BoolItemList::const_iterator b_it, b_end = bool_items.end();
delete *it; for (b_it = bool_items.begin(); b_it != b_end; ++b_it)
items.clear(); delete *b_it;
bool_items.clear();
NumberItemList::const_iterator n_it, n_end = number_items.end();
for (n_it = number_items.begin(); n_it != n_end; ++n_it)
delete *n_it;
number_items.clear();
StringItemList::const_iterator s_it, s_end = string_items.end();
for (s_it = string_items.begin(); s_it != s_end; ++s_it)
delete *s_it;
string_items.clear();
} }
bool Config::getStringValue(Config::ItemType type, string &ret) const bool Config::getStringValue(Config::StringType type, string &ret) const
{ {
ItemList::const_iterator it = items.begin(), end = items.end(); StringItemList::const_iterator it = string_items.begin(), end = string_items.end();
for (; it != end; ++it) { for (; it != end; ++it) {
if ((*it)->getType() == type) { if ((*it)->type == type) {
ret = (*it)->getStringValue(); ret = (*it)->value;
return true; return true;
} }
} }
@ -48,20 +59,29 @@ bool Config::getStringValue(Config::ItemType type, string &ret) const
} }
int Config::getNumberValue(Config::ItemType type) const bool Config::getNumberValue(Config::NumberType type, int &ret) const
{ {
ItemList::const_iterator it = items.begin(), end = items.end(); NumberItemList::const_iterator it = number_items.begin(), end = number_items.end();
for (; it != end; ++it) { for (; it != end; ++it) {
if ((*it)->getType() == type) if ((*it)->type == type) {
return (*it)->getNumberValue(); ret = (*it)->value;
return true;
}
} }
return 0; return false;
} }
void Config::addOption(ConfigItem *item) bool Config::getBoolValue(Config::BoolType type, bool &ret) const
{ {
items.push_back(item); BoolItemList::const_iterator it = bool_items.begin(), end = bool_items.end();
for (; it != end; ++it) {
if ((*it)->type == type) {
ret = (*it)->type;
return true;
}
}
return false;
} }
@ -69,21 +89,75 @@ void Config::addOption(const std::string &name, const std::string &value)
{ {
const struct { const struct {
const char *name; const char *name;
Config::ItemType type; Config::BoolType type;
} }
options[] = { bool_options[] = {
{ "notype", Config::noType }, { "stackedcycling", Config::stackedCycling },
{ "chaintimeout", Config::chainTimeout }, { "", NUM_BOOL_TYPES }
{ "workspacecolumns", Config::workspaceColumns },
{ "", numTypes }
}; };
const struct {
const char *name;
Config::StringType type;
}
string_options[] = {
{ "", NUM_STRING_TYPES }
};
const struct {
const char *name;
Config::NumberType type;
}
number_options[] = {
{ "chaintimeout", chainTimeout },
{ "workspacecolumns", workspaceColumns },
{ "", NUM_NUMBER_TYPES }
};
// if it's bool option, add it to the bool_items list
size_t i = 0; size_t i = 0;
while (options[i].type != numTypes) { while (bool_options[i].type != NUM_BOOL_TYPES) {
if (strcasecmp(name.c_str(), options[i].name) == 0) { if (strcasecmp(name.c_str(), bool_options[i].name) == 0) {
ConfigItem *item = new ConfigItem(options[i].type, value); BoolItem *item = new BoolItem;
items.push_back(item); const char *tmp = value.c_str();
break;
item->type = bool_options[i].type;
if (strcasecmp(tmp, "true") == 0 || strcasecmp(tmp, "1"))
item->value = true;
else
item->value = false;
bool_items.push_back(item);
return;
}
i++;
}
// if it's a string, add it to the string_items list
i = 0;
while (string_options[i].type != NUM_STRING_TYPES) {
if (strcasecmp(name.c_str(), string_options[i].name) == 0) {
StringItem *item = new StringItem;
item->type = string_options[i].type;
item->value = value;
string_items.push_back(item);
return;
}
i++;
}
// if it's a number, add it to the number_items list
i = 0;
while (number_options[i].type != NUM_NUMBER_TYPES) {
if (strcasecmp(name.c_str(), number_options[i].name) == 0) {
NumberItem *item = new NumberItem;
item->type = number_options[i].type;
item->value = atoi( value.c_str() );
number_items.push_back(item);
return;
} }
i++; i++;
} }

View file

@ -26,50 +26,63 @@
#include <string> #include <string>
#include <list> #include <list>
class ConfigItem; // forward declarations
struct BoolItem;
struct StringItem;
struct NumberItem;
class Config { class Config {
public: public:
enum ItemType { enum BoolType {
noType, NO_BOOL_TYPE,
stackedCycling,
NUM_BOOL_TYPES
};
enum StringType {
NO_STRING_TYPE,
NUM_STRING_TYPES
};
enum NumberType {
NO_NUMBER_TYPE,
chainTimeout, chainTimeout,
workspaceColumns, workspaceColumns,
numTypes NUM_NUMBER_TYPES
}; };
private: private:
typedef std::list<ConfigItem *> ItemList; typedef std::list<BoolItem *> BoolItemList;
ItemList items; typedef std::list<StringItem *> StringItemList;
typedef std::list<NumberItem *> NumberItemList;
BoolItemList bool_items;
StringItemList string_items;
NumberItemList number_items;
public: public:
Config(); Config();
~Config(); ~Config();
bool getStringValue(Config::ItemType, std::string &) const; bool getBoolValue(BoolType, bool &) const;
int getNumberValue(Config::ItemType) const; bool getStringValue(StringType, std::string &) const;
void addOption(ConfigItem *); bool getNumberValue(NumberType, int &) const;
void addOption(const std::string &, const std::string &); void addOption(const std::string &, const std::string &);
}; };
struct BoolItem {
Config::BoolType type;
bool value;
};
class ConfigItem { struct StringItem {
private: Config::StringType type;
Config::ItemType _type; std::string value;
std::string _value; };
public: struct NumberItem {
ConfigItem(Config::ItemType type, std::string value) Config::NumberType type;
: _type(type), _value(value) {} int value;
~ConfigItem() {}
inline const std::string &getStringValue() const
{ return _value; }
inline int getNumberValue() const
{ return atoi(_value.c_str()); }
inline Config::ItemType getType() const
{ return _type; }
}; };
#endif // __config_hh #endif // __config_hh