編寫一個簡單的license文件控制器


編寫一個file-drive的軟件權限控制器:

文件內容可以如下:


#註釋

Car.IsPrivate True


轉載請註明出處 : http://blog.csdn.net/elfprincexu



關於文件的讀寫,是一個循環,每讀取一行,就會去解析每一行的license,分理出裏面的key value對,並且把它們放入我們的 KVPair存儲起來

bool Params::readFileParams (const Str& filename)
{
    
    _filename = filename;
    ifstream ifs (filename.c_str(), ios::in);
    if (!ifs.good())
    {
        return false;
    }

    Str key, value;
    while (getFileEntry(ifs, key, value))
        this->set(key, value);
 
    return true;
}


通過閱讀以上的文件來獲得軟件所有的權限控制。


1. 先編輯一個存儲 key/value 對的數據結構 KVPair

struct KVPair 
{
KVPair(void) : _key(), _value(), _readonly(false) { return ;}
KVPair(const KVPair& src) {*this=src;}
KVPair& operator= (const KVPair& src) 
{
if ( this != &src) 
{
_key = src._key;
_value = src._value;
_readonly = src._readonly;
}
return *this;
}

Str _key;
Str _value;
Str _readonly;
}


然後定義一個控制器, Params, 當然,我們不止一個KVPair,所以在Params類中,我們有一連串的KVPair

class Params 
{
   public :
           ...

           bool getFileEntry(ifstream& ifs, Str& key, Str& value)  const                                                                                                                bool set(Str key,Str value,bool readonly = true)                                                                                                                             ...
     private:

           struct KVPair 
          {
               ...
          }

           std::vector<KVPair> _kvpList;
}


關於文件的讀寫,是一個循環,每讀取一行,就會去解析每一行的license,分理出裏面的key value對,並且把它們放入我們的 KVPair存儲起來

bool Params::readFileParams (const Str& filename)
{
    
    _filename = filename;
    ifstream ifs (filename.c_str(), ios::in);
    if (!ifs.good())
    {
        return false;
    }

    Str key, value;
    while (getFileEntry(ifs, key, value))
        this->set(key, value);
 
    return true;
}


其中關鍵是去讀去文件中每一行的key/value 值,我們允許註釋行的加入,所以在解析的時候要去忽略註釋行,好在我們可以統一規定#開頭的爲註釋行。

bool Params::getFileEntry (ifstream& ifs, Str& key, Str& value) const
{
    char line[StringMax];
    bool result = false;
    do
    {
        memset(line, 0, StringMax);
        if (ifs.getline (line, StringMax).good())
        {
            char* c = line;

            //
            // ignore comment lines...
            //
            if (*c != '#')
            {

                //
                // find first Whitespace...
                //
                for (c=line; *c && (*c != ' ') && (*c != '\t'); ++c) ;

                //
                // before the end?
                //
                if (*c)
                {
                    *c = '\0';                // split line into key and value, at first whitespace
                    while (*++c && ((*c == ' ') || (*c == '\t'))) ;
                    key = line;
                    value = Str(c).stripBlanks();
                    result = true;
                }
            }
        }
        else return false;

    } while (!result);

    return result;
}

還有一個設置key/value的函數, set

 		// set a "key"
    bool set (const Str& key, const Str& value); //            { (*this)[key] = value; }
    bool set (const Str& key, int value);        //            { (*this)[key] = Str (value); }
    bool setBool(const Str& key, bool value);    //            { (*this)[key] = Str (value ? "True" : "False"); }
    bool set (const Str& key, double value);     //            { (*this)[key] = Str (value); }
    bool set (const Str& key, Point value);      //            { (*this)[key] = Str (value); }
    bool Params::set (const Str& key, const Str& value, bool readOnlyFlag = false) ;   //


所有的set函數都會用到以下的set函數

// Functions to set a "key".
//
bool Params::set (const Str& key, const Str& value, bool readOnlyFlag)
{

    vector<Params::KVPair>::iterator p = _kvpList.begin();
    for (p = _kvpList.begin(); p<_kvpList.end(); p++)
    {
        if (p->_key == key) // key existing, so replace the value.
        {
            if(p->_readOnly == false) //replace value only if key is not read only
            {
               p->_value = value;
               p->_readOnly = readOnlyFlag;
               return true;
            }
            //key is read only
            return false;
        }
    }

    //
    // A new key, so add to the list.
    //
    struct Params::KVPair kvp;
    kvp._key = key;
    kvp._value = value;
    kvp._readOnly = readOnlyFlag;
    _kvpList.push_back(kvp);
    return true;
}

當然,我們在覈對license的時候,也會去從KVPair中去獲取相應的key value對

bool Params::getStr (const Str& key, Str& value) const
{
    //now look for key in this object
    vector<Params::KVPair>::const_iterator p = _kvpList.begin();
    while (p < _kvpList.end())
    {
        if (p->_key == key)  // found the key, so get the value.
        {
            value = p->_value;
            return true;
        }
        else
            ++p;
    }

    // Key not found.
    return false;
}



總結:

    1. 上面的file-drive方式在軟件開發當中十分普遍,通過改變文件的方式來改變軟件的整體控制也是十分普遍。

    2. 上面的案例是一個簡單的權限控制器,當然我們還需當心多線程間的同時讀取,加以鎖的保護來進行處理,當然涉及到文件的不同進程讀取,也要加file-lock進行保護。








關於文件的讀寫,是一個循環,每讀取一行,就會去解析每一行的license,分理出裏面的key value對,並且把它們放入我們的 KVPair存儲起來

bool Params::readFileParams (const Str& filename)
{
    
    _filename = filename;
    ifstream ifs (filename.c_str(), ios::in);
    if (!ifs.good())
    {
        return false;
    }

    Str key, value;
    while (getFileEntry(ifs, key, value))
        this->set(key, value);
 
    return true;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章