編寫一個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;
}