⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inireader.cpp

📁 该项目是为PPC(PocketPc)使用者提供方便的理财事务.如,现金的借贷,债务处理,证券买卖,以及物品管 理等等。该项目的主要用户群是:PPC使用者.
💻 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 + -