游戏编程系统2----Configuration System
不多说了,看代码吧头文件
/************************************************************************/
/*
Config System
*/
/************************************************************************/
// Default config file
#define DEF_CONFIG _T("D:\\myc\\dllSystem\\debug\\Config.cfg")
enum ValType
{
TYPE_EMPTY,
TYPE_VARIABLE,
TYPE_KEYWORD,
TYPE_BLOCK
};
class Value
{
std::string value;
int type;
int block;
public:
Value* next;
Value();
void set(std::string str, int bl, int key = TYPE_VARIABLE);
std::string& get();
const TCHAR* sget();
int is_keyword();
int is_block();
int get_block_id();
int get_type();
};
class Config
{
std::ifstream file;
TCHAR delimiter;
int vcol;
Value* svalue, *vstart;
int open_config_file(const TCHAR* name);
int close_config_file();
int read_config_file();
void S_trunc(std::string& str);
int search_block(const TCHAR* block);
const TCHAR* search_value(int col);
public:
Config();
Config(const TCHAR* name, int col = 1);
Config(TCHAR delim, int col = 1);
Config(const TCHAR* name, TCHAR delim, int col = 1);
int init(const TCHAR* name, TCHAR delim, int col);
~Config();
const TCHAR* value(const TCHAR* name, int col = 1);
const TCHAR* value(const TCHAR* block, const TCHAR* name, int col = 1);
const TCHAR* operator()(const TCHAR* name, int col = 1);
const TCHAR* operator()(const TCHAR* block, const TCHAR* name, int col = 1);
const TCHAR* _ivalue(const TCHAR* block, const TCHAR* name, int index, int col);
const TCHAR* ivalue(int index, int col = 1);
const TCHAR* ivalue(const TCHAR* block, int index, int col = 1);
const TCHAR* ivalue(const TCHAR* block, const TCHAR* name, int index, int col = 1);
const TCHAR* keyword(int index);
};
cpp文件
//////////////////////////////////////////////////////////////////////////
//Config System
//////////////////////////////////////////////////////////////////////////
int S_count(const std::string& s, TCHAR c);
Value::Value(void)
{
next = 0;
type = TYPE_EMPTY;
}
void Value::set(std::string str, int bl, int key /* = TYPE_VARIABLE */)
{
value = str;
type = key;
block = bl;
}
std::string& Value::get()
{
return value;
}
const TCHAR* Value::sget()
{
return value.c_str();
}
int Value::is_keyword()
{
return (type == TYPE_KEYWORD) ? 1 : 0;
}
int Value::is_block()
{
return (type == TYPE_BLOCK) ? 1 : 0;
}
int Value::get_block_id()
{
return block;
}
int Value::get_type()
{
return type;
}
Config::Config()
{
init(DEF_CONFIG, '=', 1);
}
Config::Config(const TCHAR* name, int col /* = 1 */)
{
init(name, '=', col);
}
Config::Config(TCHAR delim, int col /* = 1 */)
{
init(DEF_CONFIG, delim, col);
}
Config::Config(const TCHAR* name, TCHAR delim, int col /* = 1 */)
{
init(name, delim, col);
}
int Config::init(const TCHAR* name, TCHAR delim, int col)
{
delimiter = delim;
vcol = col;
if (vcol < 1)
vcol = 1;
svalue = 0;
open_config_file(name);
read_config_file();
close_config_file();
return 0;
}
Config::~Config()
{
if (vstart != 0)
{
while (vstart->next)
{
svalue = vstart->next;
delete vstart;
vstart = svalue;
}
}
}
int Config::open_config_file(const TCHAR* name)
{
file.open(name);
if (!file)
MessageBox(NULL, "File Open Error!", "Error", MB_OK | MB_ICONSTOP);
return 0;
}
int Config::close_config_file()
{
file.close();
return 0;
}
const TCHAR* Config::operator ()(const TCHAR *name, int col /* = 1 */)
{
return value(name, col);
}
const TCHAR* Config::operator ()(const TCHAR *block, const TCHAR *name, int col /* = 1 */)
{
return value(block, name, col);
}
const TCHAR* Config::value(const TCHAR* block, const TCHAR* name, int col /* = 1 */)
{
if (name == NULL || col < 1)
return NULL;
svalue = vstart;
int block_id = 0;
block_id = search_block(block);
while (svalue->next)
{
if (block_id != svalue->get_block_id())
break;
if (!(svalue->get()).compare(name) && svalue->is_keyword())
return search_value(col);
svalue = svalue->next;
}
return NULL;
}
const TCHAR* Config::value(const TCHAR* name, int col /* = 1 */)
{
if (name == NULL || col < 1)
return NULL;
svalue = vstart;
while (svalue->next)
{
if (!(svalue->get()).compare(name) && svalue->is_keyword())
return search_value(col);
svalue = svalue->next;
}
return NULL;
}
const TCHAR* Config::search_value(int col)
{
for (int i = 0; i < col; i++)
{
svalue = svalue->next;
if (svalue->next == NULL || svalue->is_keyword())
return NULL;
}
return svalue->sget();
}
const TCHAR* Config::_ivalue(const TCHAR* block, const TCHAR* name, int index, int col)
{
if (index < 1 || col < 1)
return NULL;
svalue = vstart;
int block_id = 0;
if (block)
block_id = search_block(block);
int count = 0;
while (svalue->next)
{
if (block)
if (block_id != svalue->get_block_id())
break;
if (name)
{
if (svalue->is_keyword() && !(svalue->get()).compare(name))
count++;
}
else
{
if (svalue->is_keyword())
count++;
}
if (count == index)
return search_value(col);
svalue = svalue->next;
}
return NULL;
}
int Config::search_block(const TCHAR* block)
{
int block_id = 0;
while (svalue->next)
{
if (!(svalue->get()).compare(block) && svalue->is_block())
{
block_id = svalue->get_block_id();
break;
}
svalue = svalue->next;
}
return block_id;
}
const TCHAR* Config::ivalue(int index, int col /* = 1 */)
{
return _ivalue(NULL, NULL, index, col);
}
const TCHAR* Config::ivalue(const TCHAR* block, int index, int col /* = 1 */)
{
return _ivalue(block, NULL, index, col);
}
const TCHAR* Config::ivalue(const TCHAR* block, const TCHAR* name, int index, int col /* = 1 */)
{
return _ivalue(block, name, index, col);
}
const TCHAR* Config::keyword(int index)
{
if (index < 1)
return NULL;
svalue = vstart;
int count = 0;
while (svalue->next)
{
if (svalue->is_keyword())
count++;
if (count == index)
return svalue->sget();
svalue = svalue->next;
}
return NULL;
}
int Config::read_config_file()
{
//std::string temp_buf;
std::string str, str_buf;
int block_no = 0;
int append = 0;
while (true)
{
if (svalue == 0)
{
svalue = new Value;
vstart = svalue;
}
else if (svalue->get_type() != TYPE_EMPTY)
{
svalue->next = new Value;
svalue = svalue->next;
}
if (getline(file, str_buf) == 0)
break;
//str_buf = CA2W(temp_buf.c_str());
str_buf += '#';
str_buf = str_buf.substr(0, str_buf.find('#'));
S_trunc(str_buf);
if (append)
str += str_buf;
else
str = str_buf;
append = 0;
size_t pos = str.length();
if (pos <= 2)
continue;
S_trunc(str);
if (str == '\\')
{
size_t last = str.length() - 1;
str.replace(last, 1, "");
append = 1;
continue;
}
if (str.length() <= 2 || str == '\r')
continue;
if (str == '[' && str == ']')
{
pos = str.length() - 1;
str.replace(pos, 1, "");
str.replace(0, 1, "");
block_no++;
svalue->set(str, block_no, TYPE_BLOCK);
continue;
}
size_t is_delim = str.find(delimiter);
if (is_delim == -1)
continue;
if (str == delimiter)
continue;
str_buf = str.substr(0, str.find(delimiter));
S_trunc(str_buf);
svalue->set(str_buf, block_no, TYPE_KEYWORD);
int col = S_count(str, delimiter);
if (col > vcol)
col = vcol;
pos = 0;
for (int i = 0; i < col; i++)
{
svalue->next = new Value;
svalue = svalue->next;
pos = str.find(delimiter, pos + 1);
str_buf = str.substr(pos + 1);
if (i < col - 1)
{
str_buf += ':';
str_buf = str_buf.substr(0, str_buf.find(delimiter));
}
S_trunc(str_buf);
svalue->set(str_buf, block_no);
}
}
return 0;
}
int S_count(const std::string& s, TCHAR c)
{
int n = 0;
std::string::const_iterator i = find(s.begin(), s.end(), c);
while (i != s.end())
{
++n;
i = find(i + 1, s.end(), c);
}
return n;
}
void Config::S_trunc(std::string& str)
{
size_t pos = str.length();
if (pos <= 0)
return;
int count = 0;
while (iswspace(str))
{
pos--;
count++;
}
str.replace(pos, count, "");
count = 0;
pos = 0;
while (iswspace(str))
{
pos++;
count++;
}
str.replace(0, count, "");
if (str == '"' && str == '"')
{
pos = str.length() - 1;
str.replace(pos, 1, "");
str.replace(0, 1, "");
}
}
用的时候这样
Config g_Config;
g_Config.value(........);
比较郁闷的是在UNICODE里面,你处理的都是UNICODE的字符,但是读入和写入的时候必须要转换成ASCII,因为你在windows下面新建个文本文件默认存储格式还是ANSI...
UNICODE是趋势啊...vs.net 2005 默认工程全是 UNICODE了,strcpy也不让用了,不过strcpy_s也没什么区别的哈.
页:
[1]