51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1725|回复: 0
打印 上一主题 下一主题

游戏编程系统2----Configuration System

[复制链接]
  • TA的每日心情
    慵懒
    2015-1-8 08:46
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]测试小兵

    跳转到指定楼层
    1#
    发表于 2007-11-23 14:48:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    不多说了,看代码吧
    头文件
    /************************************************************************/
    /*
      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也没什么区别的哈.
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-16 09:35 , Processed in 0.082352 second(s), 28 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表