📄 iniwr.cpp
字号:
#include "StdAfx.h"
#include "IniWR.h"
//////////////////////////////////////////////////////////////////////////
// 全局变量
LPWSTR g_pData = NULL; // 存储整个INI文件数据的缓冲区
CIniWR::CIniWR(void)
{
}
CIniWR::~CIniWR(void)
{
}
///////////////////////////////////////////////////////
//名称:ReadIniFile
//描述:打开文件,并将文件数据拷贝到一缓冲区g_pData中
//输入:lpFileName
//输出:nReturn
//日期:2008-07-09
//备注:
// 1). 判断一个文本文件是不是UNICODE文件:读取文件前两个字节,如果是0XFF和0XFE
// 则为UNICODE文件,否则为ASCII文件(注意根据CPU是大端还是小端格式),这里默
// 认为小端格式.如果是UNICODE文件,则丢去前两个字节.
// 2). 先将INI整个文件数据读到BYTE型缓冲区中,再转为WCHAR型,为什么?还没弄明白
///////////////////////////////////////////////////////
int CIniWR::ReadIniFile(LPCWSTR lpFileName)
{
int nReturn = 0;
WCHAR szFileName[MAX_PATH] ={0} ;
BY_HANDLE_FILE_INFORMATION fi = {0};
HANDLE hfile;
DWORD dwSize , dwIO;
BOOL bUnicode = FALSE, bRet = FALSE; // bUnicode - 标志INI文件是不是Unicode文件
BYTE* pData = NULL;
if (!lpFileName)
{
nReturn = 0;
goto exit;
}
if (wcschr(lpFileName, '\\'))
wcscpy(szFileName, lpFileName);
else
wsprintf(szFileName, _T("\\windows\\%s"), lpFileName);
// ReadIniFile the file.
hfile = CreateFile(szFileName, GENERIC_READ,
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES)0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, (HANDLE)0);
if (hfile == INVALID_HANDLE_VALUE)
{
ERRORMSG(1, (_T("ReadIniFile, CreateFile failed on INI file: %s, err %d\n"), szFileName, GetLastError()));
nReturn = 0;
goto exit;
}
// Get its size.
if (!GetFileInformationByHandle(hfile, &fi))
{
CloseHandle(hfile);
ERRORMSG(1, (_T("ReadIniFile, GetFileInformationByHandle failed on INI file: %s\n"), szFileName));
nReturn = 0;
goto exit;
}
dwSize = (fi.nFileSizeLow + 1) & ~0x1; //keep it word aligned
// Now check if the file is unicode.
dwIO = 0;
if (sizeof(WORD) <= dwSize)
{
WORD wByteOrderMark = 0;
// See comment at the bottom of the file.
if ((ReadFile(hfile, &wByteOrderMark, sizeof(WORD), &dwIO, NULL)) &&
(dwIO == sizeof(WORD)) &&
(0xfeff == wByteOrderMark))
{
dwSize -= sizeof(WORD);
bUnicode = TRUE;
}
else
SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
}
// Next, load the data.
//RETAILMSG(1, (_T("ReadIniFile, the size of ini file [%s] is [%d]\n"), szFileName, dwSize));
if (0 < dwSize)
{
pData = (BYTE *)malloc( dwSize + sizeof(WCHAR) );
if (!pData)
{
RETAILMSG(1, (_T("ReadIniFile, no enough memory\n")));
nReturn = 0;
goto exit;
}
memset(pData,0,dwSize + sizeof(WCHAR));
bRet = ReadFile(hfile, pData, dwSize, &dwIO, NULL);
CloseHandle(hfile);
if (!bRet)
{
RETAILMSG(1, (_T("ReadIniFile, ReadFile fail, err = [%d]\n"),GetLastError()));
nReturn = 0;
goto exit;
}
// Create the buffer.
if( g_pData )
{
free(g_pData);
g_pData = NULL;
}
dwSize = MultiByteToWideChar( CP_ACP,0, (char *)pData ,-1,NULL,0);
g_pData = (TCHAR *)malloc(dwSize*sizeof(WCHAR));
if(!g_pData)
{
RETAILMSG(1, (_T("ReadIniFile, no enough momery\n")));
nReturn = 0;
goto exit;
}
MultiByteToWideChar(CP_ACP,0,(char *)pData,-1,g_pData,dwSize);
dwSize--; // includes the NULL termination character
nReturn = dwSize;
}
exit:
if(pData)
{
free(pData);
pData = NULL;
}
if(hfile)
{
CloseHandle(hfile);
hfile = NULL;
}
return nReturn;
}
///////////////////////////////////////////////////////
//名称:GetLine
//描述:获取在g_pData中从dwOffset位置开始的一行数据并保存到pLine,同时把偏移量dwOffset
// 移到下一行行首
//输入:pLine[out] - 接收一行数据(不包括\r\n)
// dwOffset[in] - 要读取的那一行的开始位置
// dwSize[in] - INI文件大小
//输出:
// 正确 - 下一行行首的位置
// 错误 - 0
//日期:2008-07-09
//备注:作者XZP,封装类Mercury Xu
///////////////////////////////////////////////////////
DWORD CIniWR::GetLine(LPWSTR pLine, DWORD dwOffset, DWORD dwSize)
{
DWORD len = 0;
DWORD len2 = 0;
// Look for the end of the line.
while ( dwOffset + len < dwSize
&& '\r' != g_pData[dwOffset+len] && '\n' != g_pData[dwOffset+len])
{
if( g_pData[dwOffset+len]==0 )
break;
pLine[len] = g_pData[dwOffset+len] ;
++len;
}
pLine[len] = 0 ;
// Now push the internal offset past the newline.
// (We assume \r\n pairs are always in this order)
if (dwOffset + len + len2 < dwSize && '\r' == g_pData[dwOffset+len+len2])
++len2;
if (dwOffset + len + len2+1 < dwSize && '\n' == g_pData[dwOffset+len+len2])
++len2;
if (2 >= len + len2 && (dwOffset +2 >=dwSize) )
return 0;
dwOffset += len + len2;
return dwOffset;
}
///////////////////////////////////////////////////////
//名称:IsComment
//描述:判断是不是注释行
//输入:pLine[in] - INI的一行数据
//输出:1 - 注释行 0 - 不是注释行
//日期:2008-07-09
//备注:1). 空行也视为注释行 类封装 Mercury Xu
///////////////////////////////////////////////////////
bool CIniWR::IsComment(LPCWSTR pLine)
{
if (!pLine || 0 == wcslen(pLine) || ';' == *pLine)
return TRUE;
return FALSE;
}
///////////////////////////////////////////////////////
//名称:IsSection
//描述:判断是不是段名
//输入:pLine[in] - INI的一行数据
//输出:1 - 是段名 0 - 不是
//日期:2008-07-09
//备注:类封装Mercury Xu
///////////////////////////////////////////////////////
bool CIniWR::IsSection(LPCWSTR pLine)
{
if (pLine && '[' == *pLine)
return TRUE;
return FALSE;
}
///////////////////////////////////////////////////////
//名称:IsSectionName
//描述:判断是INI文件的一行(pLine)是不是我们要找的段名(pSection)
//输入:pLine[in] - INI文件的一行数据 pSection[in] - 要找的段名
//输出:1 - 是 0 - 不是
//日期:2008-07-09
//备注:类封装 2008-07-09
///////////////////////////////////////////////////////
bool CIniWR::IsSectionName(LPCWSTR pLine, LPCWSTR pSection)
{
if (IsSection(pLine))
{
DWORD len = wcslen(pSection);
if (wcslen(pLine) - 2 == len && 0 == _wcsnicmp(pLine+1, pSection, len))
return TRUE;
}
return FALSE;
}
///////////////////////////////////////////////////////
//名称:IsKey
//描述:判断INI文件中一行的数据是不是我们要找的键名,如果是并读取键值
//输入:pLine[in] - INI文件某行数据
// pKeyName[in] - 要寻找的键名
// pValue[out] - 键值
// dwValLen[out] - 键值pValue大小(in bytes)
//输出:1 - 是,同时pValue返回键值
// 0 - 不是,pValue为NULL
//日期:2008-07-09
//备注:类封装
///////////////////////////////////////////////////////
bool CIniWR::IsKey(LPCWSTR pLine, LPCWSTR pKeyName, LPWSTR* pValue , DWORD* dwValLen)
{
LPCWSTR pEqual = NULL;
DWORD length = 0, len = 0;
if(!pLine || !pKeyName)
return FALSE;
// pLine是不是注释行
if (IsComment( pLine ))
return FALSE;
// 寻找"="号
pEqual = wcschr(pLine, L'=' );
if (!pEqual)
return FALSE;
// 寻找键名最后一字符的位置
while (pEqual - 1 >= pLine && iswspace(*(pEqual-1)))
--pEqual;
// Badly formed file.
if (pEqual - 1 < pLine)
return FALSE;
// 键名长度
length = pEqual - pLine;
len = wcslen(pKeyName);
//if (len == length && 0 == _wcsnicmp(pLine, pKeyName, len))
if ( 0 == _wcsnicmp(pLine, pKeyName, len))
{
*pValue = wcschr(pLine, '=' );
++(*pValue);
*dwValLen = wcslen(pLine) - ((*pValue) - pLine);
// 去掉紧跟在"="号后的所有空格
while (0 < *dwValLen && iswspace(**pValue))
{
++(*pValue);
--(*dwValLen);
}
while (0 < *dwValLen && iswspace((*pValue)[*dwValLen-1]))
{
--(*dwValLen);
}
// If the string is surrounded by quotes, remove them.
if ('"' == (**pValue))
{
++(*pValue);
--(*dwValLen);
if ('"' == (*pValue)[*dwValLen-1])
{
--(*dwValLen);
}
}
return TRUE;
}
else
{
*pValue = NULL;
return FALSE;
}
}
///////////////////////////////////////////////////////
//名称:WriteValue
//描述:向指定INI文件中写入段名、键名和键值
//输入:
// m_hOutput[in]
// pointer to the handle of ini file.
// pAppName[in]
// Pointer to a null-terminated string containing the name of the section
// in which data is written. If this parameter is NULL, the WriteValue
// function just wirte the pKeyName and pString.
// pKeyName[in]
// Pointer to a null-terminated string containing the name of the key in
// which data is writtern.
// pString[in]
// Pointer to a null-terminated string to be written to the file.
//输出:无
//日期:2008-07-09
//备注:作者 XZP 类封装 Mercury Xu
// 1). 要成功写入INI文件,键名pKeyName和键值pString都不能为NULL。
// 2). 如果段名pAppName为NULL,则只写入键名pKeyName和键值pString。
// 3). 注意往INI文件写入字符串时,不要写入结束符。
///////////////////////////////////////////////////////
void CIniWR::WriteValue(HANDLE m_hOutput, LPCWSTR pAppName, LPCWSTR pKeyName, LPCWSTR pString)
{
char buffer[MAX_PATH] = {0} ;
DWORD dwWrote;
BOOL m_bUnicode = FALSE ;
if (pKeyName && pString)
{
//RETAILMSG( 1 , (TEXT("pKeyName : %s , pString : %s"), pKeyName , pString) ) ;
if (pAppName) // 写入段名
{
if (m_bUnicode)
{
WriteFile(m_hOutput, L"[", sizeof(WCHAR), &dwWrote, NULL);
WriteFile(m_hOutput, pAppName, wcslen(pAppName)*sizeof(WCHAR), &dwWrote, NULL);
WriteFile(m_hOutput, L"]\r\n", 3*sizeof(WCHAR), &dwWrote, NULL);
}
else
{
int bsize , iRetLen;
TCHAR szTempLine[256] ={0} ;
wcscpy( szTempLine , TEXT("[") ) ;
wcscat( szTempLine , pAppName ) ;
wcscat( szTempLine , TEXT("]") ) ;
bsize=WideCharToMultiByte(CP_ACP,0,szTempLine,-1,NULL,0,NULL,NULL);
iRetLen = WideCharToMultiByte(CP_ACP,0,szTempLine,-1,buffer, bsize,NULL,NULL);
buffer[bsize] = 0 ;
WriteFile(m_hOutput, buffer , bsize-1 , &dwWrote, NULL);
WriteFile(m_hOutput, "\r\n", 2, &dwWrote, NULL);
}
}
if (m_bUnicode) // 写入健名和键值
{
WriteFile(m_hOutput, pKeyName, wcslen(pKeyName)*sizeof(WCHAR), &dwWrote, NULL);
WriteFile(m_hOutput, L"=", sizeof(WCHAR), &dwWrote, NULL);
WriteFile(m_hOutput, pString, wcslen(pString)*sizeof(WCHAR), &dwWrote, NULL);
WriteFile(m_hOutput, L"\r\n", 2*sizeof(WCHAR), &dwWrote, NULL);
}
else
{
int bsize , iRetLen;
TCHAR szTempLine[256] ={0} ;
wcscpy( szTempLine , pKeyName ) ;
wcscat( szTempLine , TEXT("=") ) ;
wcscat( szTempLine , pString ) ;
bsize=WideCharToMultiByte(CP_ACP,0,szTempLine,-1,NULL,0,NULL,NULL);
iRetLen = WideCharToMultiByte(CP_ACP,0,szTempLine,-1,buffer, bsize,NULL,NULL);
buffer[bsize] = 0 ;
WriteFile(m_hOutput, buffer, bsize-1 , &dwWrote, NULL);
WriteFile(m_hOutput, "\r\n", 2, &dwWrote, NULL);
}
}
}
///////////////////////////////////////////////////////
//名称:GetString
//描述:读INI文件
//输入:lpAppName[in] - 字段名
// lpKeyName[in] - 键名
// lpReturnedString[out] - 键值
// nSize[in] - 键值缓冲区大小(in characters )
// lpFileName[in] - 完整的INI文件名
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -