📄 inireader.cpp
字号:
#include "StdAfx.h"
#include "inireader.h"
////////////////////////////////////////////////////////
//
// CSection 的实现
//
///////////////////////////////////////////////////////
CSection::CSection(void)
{
}
CSection::~CSection(void)
{
}
CSection::CSection(CSection & sec)
{
this->m_SectionName = sec.m_SectionName;
POSITION pos = sec.m_item.GetStartPosition();
while( pos != NULL )
{
String key;
String value;
// Get key ( string ) and value ( string )
sec.m_item.GetNextAssoc(pos, key, value);
// Use string and pPerson
this->m_item.SetAt(key, value);
}
}
CSection CSection::operator =(CSection & sec)
{
this->m_SectionName = sec.m_SectionName;
POSITION pos = sec.m_item.GetStartPosition();
while( pos != NULL )
{
String key;
String value;
// Get key ( string ) and value ( string )
sec.m_item.GetNextAssoc(pos, key, value);
// Use string and pPerson
this->m_item.SetAt(key, value);
}
return *this;
}
String CSection::operator [](String key) const
{
String tmp;
// look up for the key
m_item.Lookup(key, tmp);
return tmp;
}
String CSection::ToString() const
{
// 没有实现
return String(L"");
}
////////////////////////////////////////////////////////
//
// CIni 的实现
//
////////////////////////////////////////////////////////
CIni::CIni()
{
}
CIni::~CIni()
{
}
String CIni::GetFilePath() const
{
return this->m_FileName;
}
#ifdef _DEBUG
VOID CIni::Dump()
{
String tmp;
String total;
tmp.Format(L"There are %d sections\n", this->m_Sections.GetSize());
total += tmp;
for(int i = 0; i < m_Sections.GetSize(); i++)
{
tmp.Format(L"Section : %s\n", m_Sections[i].m_SectionName);
total += tmp;
POSITION pos = m_Sections[i].m_item.GetStartPosition();
while( pos != NULL )
{
String key;
String value;
// Get key ( string ) and value ( string )
m_Sections[i].m_item.GetNextAssoc(pos, key, value);
tmp.Format(L"%s = %s\n", key, value);
total += tmp;
}
}
::AfxMessageBox(total);
}
#endif // _DEBUG
////////////////////////////////////////////////////////
//
// CIniReader 的实现
//
///////////////////////////////////////////////////////
CIniReader::CIniReader(String strFileName)
{
this->m_FileName = strFileName;
}
CIniReader::~CIniReader(void)
{
}
// 添加一个key, value的pair.
BOOL CIniReader::AddPair(String key, String val, String secName)
{
// 检测section是否已经存在
for(int i = 0; i < this->m_Sections.GetSize(); i++)
{
if(secName == m_Sections[i].m_SectionName)
{
m_Sections[i].m_item.SetAt(key, val);
return TRUE;
}
}
// 执行到这里,必然没有存在,创建新的Section
CSection sTmp;
sTmp.m_SectionName = secName;
sTmp.m_item.SetAt(key, val);
this->m_Sections.Add(sTmp);
return TRUE;
}
// 此函数的作用是把strFileName指明的文件的所有内容读到m_Buffer中
INT CIniReader::Load()
{
DWORD dwSize; // File size
DWORD dwRead; // size that has been read
TCHAR * pBuf;
if(! this->Probe())
{
return FALSE;
}
// Open the file and read it to a string
HANDLE hFile =
CreateFile((LPCTSTR)m_FileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
return -1;
}
// Get file size
dwSize = GetFileSize(hFile, NULL);
if( dwSize <=0 )
{
CloseHandle(hFile);
return -1;
}
pBuf = (USHORT*)new BYTE[dwSize + 2];
memset(pBuf, 0, dwSize + 2);
// Read the whole file
BOOL bResult = ReadFile(
hFile,
pBuf,
dwSize,
&dwRead,
NULL);
if (! bResult && (dwRead =! dwSize) )
{
delete [] pBuf;
pBuf = NULL;
CloseHandle(hFile);
return -1;
}
this->m_Buffer = pBuf;
delete [] pBuf;
CloseHandle(hFile);
return 1;
}
// 读取文件到m_Buffer
INT CIniReader::Store()
{
if(! this->ParseWriter())
{
return FALSE;
}
CFile * file = new CFile(this->m_FileName, CFile::modeWrite | CFile::modeCreate);
if (! file)
{
return FALSE;
}
file->Write((LPCTSTR)m_Buffer, m_Buffer.GetLength() * sizeof(TCHAR));
file->Close();
delete file;
return TRUE;
}
INT CIniReader::ParseWriter()
{
String tmp;
String total;
for(int i = 0; i < m_Sections.GetSize(); i++)
{
// 输出section头
tmp.Format(L"\r\n[%s]\r\n\r\n", m_Sections[i].m_SectionName);
total += tmp;
POSITION pos = m_Sections[i].m_item.GetStartPosition();
while( pos != NULL )
{
String key;
String value;
// Get key ( string ) and value ( string )
m_Sections[i].m_item.GetNextAssoc(pos, key, value);
tmp.Format(L"%s = %s\r\n", key, value);
total += tmp;
}
}
this->m_Buffer = total;
return TRUE;
}
// 用来简化操作的宏定义
#define TRIMRETURN if ( cur == 13 || cur == 10) \
{ \
i += 2; \
continue; \
}
#define TRIMSPACE if ( cur == L' ' || cur == L'\t') \
{ \
i++; \
continue; \
}
#define ISRETURN (cur == 13 && m_Buffer[i + 1] == 10) ? TRUE : FALSE
// 此函数做作用是解析m_Buffer的内容,然后建立相应的Section和map
INT CIniReader::Parse()
{
String strSec; // section buffer
String strKey; // key
String strValue; // value
CSection secTmp; // temporary section
INT nErrCode = 0;
INT nPrevState = 0;
// state defination
const INT STATE_INIT = 0; // Inital value
const INT STATE_COMMENT = 1; // the machine is reading comment
const INT STATE_KEY = 2; // the machine is reading the key
const INT STATE_VALUE = 3; // reading value
const INT STATE_SECTION = 4; // reading section
const INT STATE_INSECTION = 5; // in certain section
// Error defination
const INT ERR_INVALIDFORMAT = -1;
const INT ERR_UNKNOWN = -10;
// machine's current state
INT state = STATE_INIT;
// to skip the "0xFF 0xFE" at the beginning of the unicode file.
int i = 0;
if (m_Buffer[i] == 0xFEFF)
{
i++;
}
int nBufLen = m_Buffer.GetLength();
while(i < nBufLen)
{
TCHAR cur = m_Buffer[i];
switch(state)
{
case STATE_INIT:
TRIMSPACE
TRIMRETURN
if(cur == L';') // comment
{
nPrevState = state;
state = STATE_COMMENT;
}
else if(L'[' == cur) // '[' is the start flag of key
{
state = STATE_SECTION;
}
else if( _istprint(cur)) // printable word, NOT allowed.
{
nErrCode = ERR_INVALIDFORMAT;
goto ErrorHandle;
}
i++;
break;
case STATE_COMMENT:
if ( ISRETURN ) // line end
{
i += 2;
state = nPrevState;
}
else // ignore the comment
{
i++;
}
break;
case STATE_SECTION:
if(cur == L']') // end section
{
secTmp.m_SectionName = strSec;
strSec.Empty();
state = STATE_INSECTION;
}
else if( _istprint(cur)) // printable word
{
strSec += cur;
}
else if( ISRETURN ) //CRLF, not allowed
{
nErrCode = ERR_INVALIDFORMAT;
goto ErrorHandle;
}
i++;
break;
case STATE_INSECTION:
TRIMSPACE
TRIMRETURN
if(cur == L';') // comment
{
nPrevState = state;
state = STATE_COMMENT;
}
else if(L'[' == cur) // '[' is the start flag of key
{
// a section has been parsed, add it to sections.
this->m_Sections.Add(secTmp);
state = STATE_SECTION;
// Clear the item section
secTmp.m_item.RemoveAll();
secTmp.m_SectionName.Empty();
i++;
}
else if( _istprint(cur)) // printable word, new item
{
state = STATE_KEY;
strKey.Empty();
}
break;
case STATE_KEY:
TRIMSPACE
if (cur == L'=') // encounter = , key end;
{
state = STATE_VALUE;
strValue.Empty(); // clear for stroe new value
}
else
{
strKey += cur;
}
i++;
break;
case STATE_VALUE:
TRIMSPACE
if ( ISRETURN ) // line end
{
// add item
secTmp.m_item.SetAt(strKey, strValue);
// do clean job
i++;
strSec.Empty();
strKey.Empty();
state = STATE_INSECTION;
}
else
{
strValue += cur;
}
i++;
break;
default:
// error handling here
return FALSE;
break;
}
}
// Add the last section
this->m_Sections.Add(secTmp);
return TRUE;
ErrorHandle:
return nErrCode;
}
// 运算符重载,根据SecName,返回相应的Section
CSection CIniReader::operator [](String SecName) const
{
CSection sec;
for(int i = 0; i < m_Sections.GetSize(); i++)
{
if(m_Sections[i].m_SectionName == SecName)
{
sec = m_Sections[i];
break;
}
}
return sec;
}
// 添加一个Section
BOOL CIniReader::AddSection(CSection sec)
{
// 检测该section是否存在
for(int i = 0; i < this->m_Sections.GetSize(); i++)
{
if(m_Sections[i].m_SectionName == sec.m_SectionName)
{
return FALSE;
}
}
// 增加element
m_Sections.Add(sec);
return TRUE;
}
/////////////////////////////////////////////////////////////////
//
// 从某些固定的目录中搜索文件名指定的INI,包括:
// 1) 当前目录
// 2) 根目录
// 3) Storage Card
//
/////////////////////////////////////////////////////////////////
BOOL CIniReader::Probe()
{
CString str[3];
TCHAR buf[MAX_PATH];
HANDLE hFile;
str[0] = m_FileName; // 不指定,默认根目录和Windows目录
// 存储卡
str[1].Format(L"\\Storage Card\\%s", this->m_FileName);
// 由于windows CE不支持当前目录,只能采用这个函数得到当前目录,
// 然后做相应处理
GetModuleFileName(NULL, buf, MAX_PATH);
// 倒序查找'\'
TCHAR * pPos = _tcsrchr(buf, L'\\');
*(pPos) = L'\0';
str[2].Format(L"%s\\%s", buf, this->m_FileName);
for (int i = 0; i < 3; i++)
{
hFile = CreateFile(
(LPCTSTR)str[i],
GENERIC_READ,
FILE_SHARE_READ,
NULL, //security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if( hFile == INVALID_HANDLE_VALUE)
{
continue;
}
else // we have found the file
{
CloseHandle(hFile);
this->m_FileName = str[i];
return TRUE;
}
}
// Not found
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -