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

📄 jxinifile.cpp

📁 minica2的第2个版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/************************************
  REVISION LOG ENTRY
  Written and Revision By: Zhang, Zhefu
  Contact: codetiger@hotmail
  URL: http://www.chi.c.dendai.ac.jp/~zhang/index.htm
  Revised on 2001/09/27 in FujiSoftABC Ltd. Japan
  Comment: JXINIFile Implementation File
 ************************************/
//
//
//Last Modified 2001/9/4
//Reason: NotePad add 0xFF FE to the text file header, make the first
//        section unrecognizable. 
//Fixment: Add member m_pTrueData to pass the 2 byte head

#include "stdAfx.h"
#include "JXIniFile.h"


//dwSize = -1 if szMultiByte null terminated
//dwSize not include the ending null
//return WCHARs
LPWSTR _A2W(LPSTR szMultiByte, DWORD dwSize, DWORD& dwRetSize)
{
	static WCHAR szInternalBuffer[8096];
	if(szMultiByte == NULL || (dwSize == -1 && ::strlen(szMultiByte) == 0)) 
	{ dwRetSize = 0; return NULL; }
	int nLen = MultiByteToWideChar(CP_ACP, 0,szMultiByte, dwSize, NULL, NULL);
	if(nLen > 8096) { dwRetSize = 0; return NULL; } 
	//dwRetSize in WCHARs, include null if szMultiByte nulled ended
    dwRetSize = MultiByteToWideChar(CP_ACP, 0, szMultiByte, dwSize, szInternalBuffer, 8096);
	if(dwSize == -1)
		dwRetSize--;
	else
	    szInternalBuffer[dwRetSize] = WCHAR('\0');
    return szInternalBuffer;
}

//return BYTEs
LPSTR _W2A(LPWSTR szUnicode, DWORD dwSize, DWORD& dwRetSize)
{
	static char szInternalBuffer[8096];
	if(szUnicode == NULL || (dwSize == -1 && ::wcslen(szUnicode) == 0)) 
	{ dwRetSize = 0; return NULL; }
	int nLen = WideCharToMultiByte(CP_ACP, 0,szUnicode, dwSize, NULL, 0, NULL, FALSE);
	if(nLen > 8096) { dwRetSize = 0; return NULL; } 
	//Ret: in BYTEs, The number includes the byte for the null terminator. if szUnicode null ended
	dwRetSize = WideCharToMultiByte(CP_ACP, 0, szUnicode, dwSize, szInternalBuffer, nLen, NULL, FALSE);
    if(dwSize == -1) //dwRetSize include null, szInternalBuffer null ended
		dwRetSize--;
	else
		szInternalBuffer[dwRetSize] = char('\0');
	return szInternalBuffer;
}

CJXINIFile::CJXINIFile() 
{
	m_strFilename = _T("");
	m_hFile = INVALID_HANDLE_VALUE;
	m_hMMF = NULL;
	m_dwSize = 0;
	m_pData = 0;
	m_bSectionMapDirty = TRUE; //No Section Map
	m_bSectionMapLock = FALSE;
	m_mapSection.InitHashTable(700, TRUE);
}

CJXINIFile::~CJXINIFile()
{
	UnloadIniFile();
	if(m_pData)
	{
		::UnmapViewOfFile(m_pData);
		m_pData = NULL;
	}
	if(m_hMMF != NULL)
	{
		::CloseHandle(m_hMMF);
		m_hMMF = NULL;
	}
	if(m_hFile != INVALID_HANDLE_VALUE)
	{
		::CloseHandle(m_hFile);
		m_hFile = INVALID_HANDLE_VALUE;
	}
}

//CMap m_mapSection; 
void CJXINIFile::UpdateMapA()
{
	if(m_bSectionMapLock) return;
	LPSTR pHead = (LPSTR)m_pTrueData;
	LPSTR p1 = pHead;
	LPSTR p2 = pHead;

	p1 = pHead;
    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++;
		if(p1- pHead < (int)(m_dwUseSize/sizeof(char)) &&
			p2- pHead < (int)(m_dwUseSize/sizeof(char)))
		{
			//Found, Ready To Map
			int lenSection = p2 - p1 - 1;
			//Section Name Length must >= 1
			if(lenSection >= 1)
			{
				p1++;
				CString strSection;
#ifdef _UNICODE
                DWORD dwRetSize;
				PWSTR pTemp = _A2W(p1, lenSection, dwRetSize);
				::wcsncpy(strSection.GetBuffer(dwRetSize), pTemp, dwRetSize);
                strSection.ReleaseBuffer(dwRetSize);				
#else
				::strncpy(strSection.GetBuffer(lenSection), p1, lenSection);
                strSection.ReleaseBuffer(lenSection);
#endif
				p1--; //point to [
				m_mapSection.SetAt(strSection, (LPVOID)p1);
			} 
		}
		p1 = p2 + 1;
	}
	//Debug Part
	m_bSectionMapDirty = FALSE;
    return ;
}

void CJXINIFile::UpdateMapW()
{
	if(m_bSectionMapLock) return;
	LPWSTR pHead = (LPWSTR)m_pTrueData;
	LPWSTR p1 = pHead;
	LPWSTR p2 = pHead;
    //Calculate the section number
//	int nSection = 0;
//    while(p1- pHead < (int)(m_dwUseSize/sizeof(WCHAR)) - 1)
//	{
//		if(*p1 == WCHAR('[')) nSection++;
//		p1++;
//	}
//	if(nSection < 13) nSection = 13;
//	//allow 20% margine
//	m_mapSection.InitHashTable((UINT)(1.2*nSection), TRUE);
    
	p1 = pHead;
    while(p1- pHead < (int)(m_dwUseSize/sizeof(WCHAR)) - 1)
	{
		while(p1- pHead < (int)(m_dwUseSize/sizeof(WCHAR)) - 1 &&
			*p1 != WCHAR('['))
			p1++;
		p2 = p1;
		while(p2- pHead < (int)(m_dwUseSize/sizeof(WCHAR)) - 1 &&
			*p2 != WCHAR(']'))
			p2++;
		if(p1- pHead < (int)(m_dwUseSize/sizeof(WCHAR)) &&
			p2- pHead < (int)(m_dwUseSize/sizeof(WCHAR)))
		{
			//Found, Ready To Map
			int lenSection = p2 - p1 - 1;
			//Section Name Length must >= 1
			if(lenSection >= 1)
			{
				p1++;
				CString strSection;
#ifdef _UNICODE
				::wcsncpy(strSection.GetBuffer(lenSection), p1, lenSection);
                strSection.ReleaseBuffer(lenSection);
#else
				DWORD dwRetSize;
				PSTR pTemp = _W2A(p1, lenSection, dwRetSize);
                ::strncpy(strSection.GetBuffer(dwRetSize), pTemp, dwRetSize);
                strSection.ReleaseBuffer(dwRetSize);
#endif
				p1--; //point to [
				m_mapSection.SetAt(strSection, (LPVOID)p1);
			} 
		}
		p1 = p2 + 1;
	}
	//Debug Part
	m_bSectionMapDirty = FALSE;

//  int count = m_mapSection.GetCount();
//	CString str; str.Format(_T("UpdateW %d"), count); 
//	AfxMessageBox(str);
/*
	POSITION pos = m_mapSection.GetStartPosition();
	while(pos)
	{
		CString strKey;
		LPVOID lpPos;
		m_mapSection.GetNextAssoc(pos, strKey, lpPos);
		if(AfxMessageBox(strKey, MB_YESNO | MB_ICONINFORMATION) == IDNO)
			return;
	}
*/
	return ;
}

void CJXINIFile::ResizeMap(int nNewSize)
{
	ASSERT(nNewSize > 0);
	m_mapSection.RemoveAll();
	m_mapSection.InitHashTable(nNewSize);
}

// return 0 -- no key, size too small to put value
//return -1  -- error
//return string length (of course > 1)
//Ex Version use Map
DWORD CJXINIFile::GetPrivateProfileStringExA(
         LPCSTR lpAppName,        // section name
         LPCSTR lpKeyName,        // key name
         LPCSTR lpDefault,        // default string
         LPSTR lpReturnedString,  // destination buffer
         DWORD nSize,              
		 // size of destination buffer,Specifies the size, in TCHARs, 
         LPCSTR lpFileName        // initialization file name
    )
{
	BOOL bRet = LoadIniFile(lpFileName, 1);
	if(!bRet) return (UINT)-1;
	if(lpDefault == NULL) return -1;
	if(m_dwUseSize == 0) return -1;

	//Section Map Not Available
	if(m_bSectionMapDirty && m_bSectionMapLock) //
		return GetPrivateProfileStringA(lpAppName,lpKeyName,
		   lpDefault,lpReturnedString,nSize,lpFileName);
	else if(!m_bSectionMapLock && m_bSectionMapDirty)
	{
		UpdateMapA();        
	}
 
	//AfxMessageBox(_T("Using Section Map"));
	//Now Map Info Available
	if(lpAppName == NULL) //get all section
	{
		return GetSectionsExA(lpReturnedString, nSize, lpFileName);
	}
	if(lpKeyName == NULL) //get all key in one section
	{
		return GetKeysExA(lpAppName, lpReturnedString, nSize, lpFileName);
	}

	LPSTR pHead = (LPSTR)m_pTrueData;
	UINT uSec, uKey;
	uSec = (UINT) -1;
	uKey = (UINT)-1;
	uKey = GetKeyExA(pHead, (UINT)m_dwUseSize, 
		lpAppName, lpKeyName, uSec);
    if(uKey == (UINT)-1) //not key
	{
		if(::strlen(lpDefault) > (int)nSize) return -1;
		::strncpy(lpReturnedString, lpDefault, ::strlen(lpDefault));
		//append a null
        lpReturnedString[::strlen(lpDefault)+1] = char('\0');
		return 0;
	}
	char buffer[MAX_PATH];

    LPSTR pValue = pHead + uKey;
	while(pValue - pHead < (int)((m_dwUseSize)/sizeof(char)) && 
		 *pValue != char('\r') && *pValue != char('\n'))
	{
		pValue++;  //in unicode, +2 byte
	}

	int len = pValue - pHead - uKey;
	pValue = pHead + uKey;
	::strncpy(buffer, pValue, len); 
	if(nSize <= (UINT)len)
	{
		::strncpy(lpReturnedString, pValue, nSize);
        lpReturnedString[nSize - 1] = char('\0');
		return 0;
	}
	else
	{
		::strncpy(lpReturnedString, pValue, len);
		//append null
        lpReturnedString[len] = char('\0');
		return len;			
	}
	return (UINT) -1;
}

// return 0 -- no key, size too small to put value
//return -1  -- error
//return string length (of course > 1)
//Ex Version use Map
DWORD CJXINIFile::GetPrivateProfileStringExW(
         LPCWSTR lpAppName,        // section name
         LPCWSTR lpKeyName,        // key name
         LPCWSTR lpDefault,        // default string
         LPWSTR lpReturnedString,  // destination buffer
         DWORD nSize,              
		 // size of destination buffer,Specifies the size, in TCHARs, 
         LPCWSTR lpFileName        // initialization file name
    )
{
	BOOL bRet = LoadIniFile(lpFileName, 2);
	if(!bRet) return (UINT)-1;
	if(lpDefault == NULL) return -1;
	if(m_dwUseSize == 0) return -1;

	//Section Map Not Available
	if(m_bSectionMapDirty && m_bSectionMapLock) //
		return GetPrivateProfileStringW(lpAppName,lpKeyName,
		   lpDefault,lpReturnedString,nSize,lpFileName);
	else if(!m_bSectionMapLock && m_bSectionMapDirty)
	{
		UpdateMapW();        
	}
 
	//AfxMessageBox(_T("Using Section Map"));
	//Now Map Info Available
	if(lpAppName == NULL) //get all section
	{
		return GetSectionsExW(lpReturnedString, nSize, lpFileName);
	}
	if(lpKeyName == NULL) //get all key in one section
	{
		return GetKeysExW(lpAppName, lpReturnedString, nSize, lpFileName);
	}

	LPWSTR pHead = (LPWSTR)m_pTrueData;
	UINT uSec, uKey;
	uSec = (UINT) -1;
	uKey = (UINT)-1;
	uKey = GetKeyExW(pHead, (UINT)m_dwUseSize, 
		lpAppName, lpKeyName, uSec);
    if(uKey == (UINT)-1) //not key
	{
		if(::wcslen(lpDefault) > (int)nSize) return -1;
		::wcsncpy(lpReturnedString, lpDefault, ::wcslen(lpDefault));
		//append a null
        lpReturnedString[::wcslen(lpDefault)+1] = WCHAR('\0');
		return 0;
	}
	WCHAR buffer[MAX_PATH];

    LPWSTR pValue = pHead + uKey;
	while(pValue - pHead < (int)((m_dwUseSize)/sizeof(WCHAR)) && 
		 *pValue != WCHAR('\r') && *pValue != WCHAR('\n'))
	{
		pValue++;  //in unicode, +2 byte
	}

	int len = pValue - pHead - uKey;
	pValue = pHead + uKey;
	::wcsncpy(buffer, pValue, len); 
	if(nSize <= (UINT)len)
	{
		::wcsncpy(lpReturnedString, pValue, nSize);
        lpReturnedString[nSize - 1] = WCHAR('\0');
		return 0;
	}
	else
	{
		::wcsncpy(lpReturnedString, pValue, len);
		//append null
        lpReturnedString[len] = WCHAR('\0');
		return len;			
	}
	return (UINT) -1;
}

//User Query All Section Name in INI File
DWORD CJXINIFile::GetSectionsExA(
         LPSTR lpReturnedString,  // destination buffer
         DWORD nSize, // size of destination buffer, In WCHAR
         LPCSTR lpFileName        // initialization file name
    )
{
	ASSERT(!m_bSectionMapDirty);
    BYTE wNULL = 0x00; 
	int posRet = 0;
	POSITION pos = m_mapSection.GetStartPosition();
	while(pos)
	{
		CString strKey;
		LPVOID lpPos;
		m_mapSection.GetNextAssoc(pos, strKey, lpPos);
#ifdef _UNICODE
		int lenSection = strKey.GetLength();
		DWORD dwRetSize;
		LPSTR pTemp = _W2A(strKey.GetBuffer(lenSection), lenSection, dwRetSize);
		if(dwRetSize + 1 + posRet > (int)nSize) return 0; //nSize - 1;
        ::strncpy(lpReturnedString + posRet, pTemp, dwRetSize);
        posRet += dwRetSize;
#else
		int lenSection = strKey.GetLength();
		if(lenSection + 1 + posRet > (int)nSize) return 0; //nSize - 1;
		::strncpy(lpReturnedString + posRet, (LPCSTR)strKey, lenSection);
        posRet += lenSection;
#endif
		//NULL = 0x00 , 2 Byte
		::memcpy(lpReturnedString + posRet, &wNULL, 1);
        posRet += 1;
	}
	//last NULL 
    if(1 + posRet > (int)nSize) return 0; //nSize - 1; 
    ::memcpy(lpReturnedString + posRet, &wNULL, 1);
	posRet += 1;
	return posRet;
}

//User Query All Section Name in INI File
DWORD CJXINIFile::GetSectionsExW(
         LPWSTR lpReturnedString,  // destination buffer
         DWORD nSize, // size of destination buffer, In WCHAR
         LPCWSTR lpFileName        // initialization file name
    )
{
	ASSERT(!m_bSectionMapDirty);
    WORD wNULL = 0x0000; 
	int posRet = 0;
	POSITION pos = m_mapSection.GetStartPosition();
	while(pos)
	{
		CString strKey;
		LPVOID lpPos;
		m_mapSection.GetNextAssoc(pos, strKey, lpPos);
#ifdef _UNICODE
		int lenSection = strKey.GetLength();
		if(lenSection + 1 + posRet > (int)nSize) return 0; //nSize - 1;
		::wcsncpy(lpReturnedString + posRet, (LPCWSTR)strKey, lenSection);
        posRet += lenSection;
#else
		int lenSection = strKey.GetLength();
		DWORD dwRetSize;
		PWSTR pTemp = _A2W(strKey.GetBuffer(lenSection), lenSection, dwRetSize);
		if(dwRetSize + 1 + posRet > (int)nSize) return 0; //nSize - 1;
        ::wcsncpy(lpReturnedString + posRet, pTemp, dwRetSize);
        posRet += dwRetSize;
#endif
		//NULL = 0x00 00, 2 Byte
		::memcpy(lpReturnedString + posRet, &wNULL, 2);
        posRet += 1;

	}
	//last NULL 
    if(1 + posRet > (int)nSize) return 0; //nSize - 1; 
    ::memcpy(lpReturnedString + posRet, &wNULL, 2);
	posRet += 1;
	return posRet;
}

//User Query All Keys in a Given Section
DWORD CJXINIFile::GetKeysExA(
		 LPCSTR lpAppName,        // section name
         LPSTR lpReturnedString,  // destination buffer
         DWORD nSize,              // size of destination buffer
         LPCSTR lpFileName        // initialization file name
    )
{
	int posRet = 0;
	int secLen = ::strlen(lpAppName);
	LPSTR pHead = (LPSTR)m_pTrueData;
	
	LPSTR pSecHead = NULL; //pointing to [
	//Section Map Must be Available

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -