📄 jxinifile.cpp
字号:
DWORD nSize, // size of destination buffer
LPCSTR lpFileName // initialization file name
)
{
int posRet = 0;
int secLen = ::strlen(lpAppName);
LPSTR pHead = (LPSTR)m_pTrueData;
LPSTR p1 = pHead;
LPSTR p2 = pHead;
LPSTR pSecHead = NULL; //pointing to [
LPSTR pSecTail = NULL; //point to next [
BYTE byteNULL = 0x00;
while(p1- pHead < (int)(m_dwUseSize/sizeof(char)) - 1)
{
while(p1- pHead < (int)(m_dwUseSize/sizeof(char)) - 1 &&
*p1 != char('['))
p1++;
p2 = p1;
while(p2- pHead < (int)(m_dwUseSize/sizeof(char)) - 1 &&
*p2 != char(']'))
p2++;
//p2 points to ]
if(p1- pHead < (int)(m_dwUseSize/sizeof(char)) &&
p2- pHead < (int)(m_dwUseSize/sizeof(char)))
{
//Found A Section
if(pSecHead != NULL)
{
pSecTail = p1;
break;
}
else //pSecHead == NULL
{
if(secLen == p2 - p1 - 1) //same length
{
p1++;
LPSTR p3 = p1; //p3 points to ["X"
for(int i = 0; i < secLen; i++)
{
if(*p1 != (char)(lpAppName[i])) break;
p1++;
}
if(i == secLen) //Found;
pSecHead = p3 - 1;
}
}
}
p1 = p2 + 1;
}
if(pSecHead == NULL) return -1;
if(pSecTail == NULL)
pSecTail = pHead + m_dwUseSize/sizeof(char);
pSecTail--;
//Enum Keys in Section
p1 = pSecHead;
int keyLen;
while(p1 < pSecTail - 1)
{
while(p1 < pSecTail - 1 &&
*p1 != char('\r') && *p1 != char('\n'))
p1++;
while(p1 < pSecTail - 1 &&
(*p1 == char('\r') || *p1 == char('\n')))
p1++;
p2 = p1;
while(p2 < pSecTail - 1 &&
*p2 != char('='))
p2++;
if(p1 < pSecTail - 1 && p2 < pSecTail - 1)
{
//Found A Key
keyLen = p2 - p1;
if(keyLen >= 1)
{
if(keyLen + 1 + posRet > (int)nSize) return 0; //nSize - 1;
::strncpy(lpReturnedString + posRet, p1, keyLen);
posRet += keyLen;
//NULL = 0x00 , 1 Byte
::memcpy(lpReturnedString + posRet, &byteNULL, 1);
posRet += 1;
}
}
p1 = p2 + 1;
}
//last NULL
if(1 + posRet > (int)nSize) return 0; //nSize - 1;
::memcpy(lpReturnedString + posRet, &byteNULL, 1);
posRet += 1;
return posRet;
}
BOOL CJXINIFile::LoadIniFile(CString strFilename, DWORD dwMode)
{
if(dwMode == 0 && sizeof(TCHAR) == 1) m_bUnicode = FALSE;
if(dwMode == 0 && sizeof(TCHAR) == 2) m_bUnicode = TRUE;
if(dwMode == 1) m_bUnicode = FALSE;
if(dwMode == 2) m_bUnicode = TRUE;
if(strFilename == _T("")) return FALSE;
//Already Loaded
if(m_strFilename == strFilename) return TRUE;
if(m_strFilename != _T("")) //Unload First
{
UnloadIniFile();
}
m_strFilename = strFilename;
m_bDirty = FALSE;
m_bSectionMapDirty = TRUE;
m_bSectionMapLock = FALSE;
DWORD dwHigh, dwLow;
DWORD dwTotal, dwError;
//Open File Handle
m_hFile = ::CreateFile(m_strFilename, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if(m_hFile != INVALID_HANDLE_VALUE)
{
//Measure File Size
dwLow = GetFileSize(m_hFile, &dwHigh);
dwTotal = 0;
if(dwLow == -1 && (dwError = GetLastError()) != NO_ERROR)
{
::MessageBox(NULL, _T("File Size Failure"),
_T("CJXINIFile::Load"), MB_OK | MB_ICONSTOP);
if(m_hFile != INVALID_HANDLE_VALUE)
::CloseHandle(m_hFile);
m_dwSize = 0;
m_strFilename = _T("");
return FALSE;
}
m_dwSize = dwLow; //32bit -> 4Gb
}
else
{
m_hFile = ::CreateFile(m_strFilename, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if(m_hFile == INVALID_HANDLE_VALUE)
{
::MessageBox(NULL, _T("CreateFile Failure"),
_T("CJXINIFile::Load"), MB_OK | MB_ICONSTOP);
if(m_hFile != INVALID_HANDLE_VALUE)
::CloseHandle(m_hFile);
m_dwSize = 0;
m_strFilename = _T("");
return FALSE;
}
m_dwSize = 0;
}
//Open Memory-Mapping File, maximum size = File Size + JXFlushIncrement
dwLow = m_dwSize + JXFlushIncrement;
m_hMMF = ::CreateFileMapping(m_hFile, NULL,
PAGE_READWRITE, 0 , dwLow, NULL);
if(NULL == m_hMMF)
{
::MessageBox(NULL, _T("CreateFileMapping Failure"),
_T("CJXINIFile::Load"), MB_OK | MB_ICONSTOP);
if(m_hMMF != NULL)
::CloseHandle(m_hMMF);
if(m_hFile != INVALID_HANDLE_VALUE)
::CloseHandle(m_hFile);
m_dwSize = 0;
m_strFilename = _T("");
return FALSE;
}
//Map pointer
m_pData = ::MapViewOfFile(m_hMMF, FILE_MAP_READ | FILE_MAP_WRITE,
0, 0, dwLow);
if(m_pData == NULL)
{
//ReportErr(_T(""));
if(m_hMMF != NULL)
::CloseHandle(m_hMMF);
if(m_hFile != INVALID_HANDLE_VALUE)
::CloseHandle(m_hFile);
m_dwSize = 0;
m_strFilename = _T("");
::MessageBox(NULL, _T("MapViewOfFile Failure"),
_T("CJXINIFile::Load"), MB_OK | MB_ICONSTOP);
return FALSE;
}
m_dwUseSize = m_dwSize;
CutZeroTail();
//if(sizeof(TCHAR) == 2) //UNICODE only
if(this->m_bUnicode)
//Pass Potentail 0xFF FE header if edited by MS NotePad
{
LPBYTE pByte = (LPBYTE)m_pData;
if(m_dwUseSize >= 2 && *pByte == 0xFF && *(pByte +1) == 0xFE)
{
m_pTrueData = (LPVOID)(pByte + 2);
m_dwUseSize -= 2;
}
else
{
if(m_dwUseSize == 0) //a new file, add 0xFF FE header
//for Win2k SP1 need 0xFF FE
{
*pByte = 0xFF;
*(pByte +1) = 0xFE;
//m_dwUseSize = 2;
m_pTrueData = (LPVOID)(pByte+2);
}
else //old format without 0xFF FE
{
::memmove((LPVOID)(pByte+2), (LPVOID)pByte, m_dwUseSize);
*pByte = 0xFF;
*(pByte +1) = 0xFE;
//m_dwUseSize += 2;
m_pTrueData = (LPVOID)(pByte+2);
}
}
}
else
m_pTrueData = m_pData;
return TRUE;
}
BOOL CJXINIFile::UnloadIniFile()
{
DWORD dwFileSize;
//if(sizeof(TCHAR) == 2) //UNICODE leading 0xFF FE
if(this->m_bUnicode)
dwFileSize = m_dwUseSize + 2;
else
dwFileSize = m_dwUseSize;
if(m_strFilename == _T("")) return TRUE;
if(!m_bDirty)
{
if(m_pData)
{
::UnmapViewOfFile(m_pData);
m_pData = NULL;
}
if(m_hMMF != NULL)
{
::CloseHandle(m_hMMF);
m_hMMF = NULL;
}
LONG highDist = 0;
::SetFilePointer(
m_hFile, // handle to file
dwFileSize, // bytes to move pointer
&highDist, // bytes to move pointer
FILE_BEGIN // starting point
);
::SetEndOfFile(m_hFile);
if(m_hFile != INVALID_HANDLE_VALUE)
{
::CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
m_strFilename = _T("");
return TRUE;
}
//Modified
ASSERT(m_pData);
if(!::FlushViewOfFile(m_pData, m_dwUseSize))
{
::MessageBox(NULL, _T("FlushViewMMF"), _T(""), MB_OK);
::UnmapViewOfFile(m_pData);
::CloseHandle(m_hMMF);
LONG highDist = 0;
::SetFilePointer(
m_hFile, // handle to file
dwFileSize, // bytes to move pointer
&highDist, // bytes to move pointer
FILE_BEGIN // starting point
);
::SetEndOfFile(m_hFile);
::CloseHandle(m_hFile);
m_strFilename = _T("");
m_pData = NULL;
m_hMMF = NULL;
m_hFile = INVALID_HANDLE_VALUE;
m_dwSize = 0;
return FALSE;
}
::UnmapViewOfFile(m_pData);
::CloseHandle(m_hMMF);
//Adjust File Size
LONG highDist = 0;
::SetFilePointer(
m_hFile, // handle to file
dwFileSize, // bytes to move pointer
&highDist, // bytes to move pointer
FILE_BEGIN // starting point
);
::SetEndOfFile(m_hFile);
::CloseHandle(m_hFile);
m_strFilename = _T("");
m_pData = NULL;
m_hMMF = NULL;
m_hFile = INVALID_HANDLE_VALUE;
m_dwSize = 0;
//
m_mapSection.RemoveAll();
m_bSectionMapDirty = TRUE;
m_bSectionMapLock = FALSE;
return TRUE;
}
//return -1 if not find key
//return first character of the key line
//[section name]\r\n
//keyname = valuename\r\n
//Ex Version use Map
//posSection & ret all in WCHARs
UINT CJXINIFile::GetKeyExA(LPSTR pHead, UINT uSize,
LPCSTR szSection, LPCSTR szKey, UINT& posSection)
{
//Map Must Be Ready Here
ASSERT(!m_bSectionMapDirty);
LPSTR pSecHead = NULL; //pointing to [
#ifdef _UNICODE
DWORD dwRetSize;
LPWSTR pTemp = _A2W((LPSTR)szSection, -1, dwRetSize);
if(0 == m_mapSection.Lookup(pTemp, (LPVOID&)pSecHead))
{
posSection = (UINT)-1;
return (UINT)-1;
}
#else
if(0 == m_mapSection.Lookup(szSection, (LPVOID&)pSecHead))
{
posSection = (UINT)-1;
return (UINT)-1;
}
#endif
posSection = -1;
LPSTR p1 = pSecHead;
LPSTR p2 = pSecHead;
int lenSection = ::strlen(szSection);
char szSection2[MAX_PATH];
//section --> [section]
::strncpy(szSection2+1, szSection, lenSection);
szSection2[0] = char('[');
szSection2[lenSection+1] = char(']');
szSection2[lenSection+2] = char('\0');
BOOL bSection = FALSE; //found the section
BOOL bKey = FALSE; //found the key
char buffer[MAX_PATH];
int line;
while(p1- pHead < (int)(uSize/sizeof(char)) - 1)
{
//WCHAR s1 = (WCHAR)'\r'; //13
//WCHAR s2 = (WCHAR)'\n'; //10
//WCHAR s3 = (WCHAR)0x0A; //10
//01/7/5 //avoid leak blank line
int rInc, nInc;
rInc = nInc = 0;
while(p1- pHead < (int)(uSize/sizeof(char)-1) &&
(*p1 == (char)'\r' || *p1 == (char)'\n'))
{
if(*p1 == (char)'\r') rInc++;
if(*p1 == (char)'\n') nInc++;
p1++;
}
if(rInc == 1 && nInc == 1)
{
}
else if(rInc == nInc && rInc > 1)
line += rInc - 1;
else if(rInc != nInc)
{
line += rInc > nInc ? rInc - 1 : nInc - 1;
}
p2 = p1;
while(p2- pHead < (int)(uSize/sizeof(char))-1)
{
//$$$ some file end with \n only
if(*p2 == (char)'\r' && *(p2+1) == (char)'\n')
{
break; //touch it
}
if(*p2 == (char)'\n') break;
if(*p2 == (char)'\r') break;
p2++;
}
if(p2 - pHead == (int)(uSize/sizeof(char))-1)
{
//the last sentence
while(*p2 == (char)'\r' || *p2 == (char)'\n') p2--;
int len = p2 - p1 + 1;
line++;
if(len > 1)
{
if(len > MAX_PATH)
{
p1 = p2 + 1;
continue;
}
::strncpy(buffer, p1, len);
buffer[len] = char('\0');
//a section ?
if(buffer[0] == char('[') &&
buffer[len-1] == char(']'))
{
//AfxMessageBox(buffer);
if(::strcmp(buffer,szSection2) == 0) //match
{
if(!bSection)
{
bSection = TRUE;
posSection = (UINT)(p1 - pHead);
}
}
else
{
if(bSection) return (UINT)-1;
}
}
else //a key line
{
if(!bSection)
{
}
else
{
//key name = value name
int lenKey = ::strlen(szKey);
//find =
int sam;
for(sam = 0; sam < len; sam++)
if(buffer[sam] == char('=')) break;
if(sam >= lenKey && sam < len)
{
for(int q = 0; q < sam; q++)
{
if(q < lenKey && buffer[q] != szKey[q]) break;
if(q > lenKey && buffer[q] != char(' ')) break;
}
if(q == sam) //found
{
bKey = TRUE;
return (UINT)(p1 - pHead + sam + 1);
//return (UINT)(p1 - pHead);
}
}
}
}
line++;
}
break;
}
p2--;
//now p2 points to the ending of the sentence
int l
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -