51Testing软件测试论坛

标题: 游戏编程系统2----Configuration System [打印本页]

作者: 51testing    时间: 2007-11-23 14:48
标题: 游戏编程系统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:pen_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:perator ()(const TCHAR *name, int col /* = 1 */)
{
return value(name, col);
}

const TCHAR* Config:perator ()(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[str.length() - 1] == '\\')
  {
   size_t last = str.length() - 1;
   str.replace(last, 1, "");
   append = 1;
   continue;
  }

  if (str.length() <= 2 || str[0] == '\r')
   continue;

  if (str[0] == '[' && str[str.length() - 1] == ']')
  {
   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[0] == 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 - 1]))
{
  pos--;
  count++;
}
str.replace(pos, count, "");

count = 0;
pos = 0;
while (iswspace(str[pos]))
{
  pos++;
  count++;
}
str.replace(0, count, "");

if (str[0] == '"' && str[str.length() - 1] == '"')
{
  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也没什么区别的哈.




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2