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

📄 ini.cpp

📁 空调数据多线程采集
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		&& DeleteKey(lpSrcSection, lpSrcKey);
}

/////////////////////////////////////////////////////////////////////////////////
// Helper Functions
/////////////////////////////////////////////////////////////////////////////////

// Get a profile string value, return a heap pointer so we do not have to worry
// about the buffer size, however, this function requires the caller to manually
// free the memory.
// This function is the back-bone of all "Getxxx" functions of this class.
LPTSTR CIni::__GetStringDynamic(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpDefault) const
{
	TCHAR* psz = NULL;
	if (lpSection == NULL || lpKey == NULL)
	{
		// Invalid section or key name, just return the default string
		if (lpDefault == NULL)
		{
			// Empty string
			psz = new TCHAR[1];
			*psz = _T('\0');
		}
		else
		{
			psz = new TCHAR[_tcslen(lpDefault) + 1];
			_tcscpy(psz, lpDefault);
		}
		
		return psz;
	}
	
	// Keep enlarging the buffer size until being certain on that the string we
	// retrieved was original(not truncated).
	DWORD dwLen = DEF_PROFILE_THRESHOLD;
	psz = new TCHAR[dwLen + 1];
	DWORD dwCopied = ::GetPrivateProfileString(lpSection, lpKey, lpDefault == NULL ? _T("") : lpDefault, psz, dwLen, m_pszPathName);
	while (dwCopied + 1 >= dwLen)
	{		
		dwLen += DEF_PROFILE_THRESHOLD;
		delete [] psz;
		psz = new TCHAR[dwLen + 1];
		dwCopied = ::GetPrivateProfileString(lpSection, lpKey, lpDefault == NULL ? _T("") : lpDefault, psz, dwLen, m_pszPathName);
	}
	
	return psz; // !!! Requires the caller to free this memory !!!
}

// Split a string usinf a particular delimiter, split result are copied into lpBuffer
// in the "double null terminated string" format as the following figure shows:
// xxx\0xxxx\0xx\0xxx\0\0
//
// For example, if the delimiter is ",", then string "ab,cd,e" will be
// splitted into "ab\0cd\0e\0\0", this string format can be parsed into an array
// of sub strings easily using user defined functions or CIni::ParseStringArray.
DWORD CIni::__StringSplit(LPCTSTR lpString, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDelimiter, BOOL bTrimString)
{
	if (lpString == NULL || lpBuffer == NULL || dwBufSize == 0)
		return 0;	

	DWORD dwCopied = 0;
	*lpBuffer = _T('\0');
	if (*lpString == _T('\0'))
		return 0;

	// If lpDelimiter is NULL, use the default delimiter ",", if delimiter length
	// is 0, then return whole string
	if (lpDelimiter != NULL && *lpDelimiter == _T('\0'))
	{
		_tcsncpy(lpBuffer, lpString, dwBufSize - 1);
		return _tcslen(lpBuffer);
	}

	LPTSTR pszDel = (lpDelimiter == NULL) ? _tcsdup(DEF_PROFILE_DELIMITER) : _tcsdup(lpDelimiter);
	const DWORD DEL_LEN = _tcslen(pszDel);
	LPTSTR lpTarget = lpBuffer;

	// Search through lpString for delimiter matches, and extract sub strings out
	LPCTSTR lpPos = lpString;
	LPCTSTR lpEnd = _tcsstr(lpPos, pszDel);

	while (lpEnd != NULL)
	{
		LPTSTR pszSeg = __StrDupEx(lpPos, lpEnd);
		if (bTrimString)
			__TrimString(pszSeg);

		const DWORD SEG_LEN = _tcslen(pszSeg);
		const DWORD COPY_LEN = min(SEG_LEN, dwBufSize - dwCopied);

		// Need to avoid buffer overflow
		if (COPY_LEN > 0)
		{
			dwCopied += COPY_LEN + 1;
			_tcsncpy(lpTarget, pszSeg, COPY_LEN);
			lpTarget[COPY_LEN] = _T('\0');
			lpTarget = &lpTarget[SEG_LEN + 1];
		}
		delete [] pszSeg;
		lpPos = &lpEnd[DEL_LEN]; // Advance the pointer for next search		
		lpEnd = _tcsstr(lpPos, pszDel);
	}

	// The last part of string, there may not be the trailing delimiter, so we
	// need to take care of this part, too
	LPTSTR pszSeg = _tcsdup(lpPos);
	if (bTrimString)
		__TrimString(pszSeg);

	const DWORD SEG_LEN = _tcslen(pszSeg);
	const DWORD COPY_LEN = min(SEG_LEN, dwBufSize - dwCopied);

	if (COPY_LEN > 0)
	{
		dwCopied += COPY_LEN + 1;
		_tcsncpy(lpTarget, pszSeg, COPY_LEN);
		lpTarget[COPY_LEN] = _T('\0');
	}

	delete [] pszSeg;
	lpBuffer[dwCopied] = _T('\0');
	delete [] pszDel;
	return dwCopied;
}

// Parse a "double null terminated string", pass each sub string to a user-defined
// callback function
BOOL CIni::ParseDNTString(LPCTSTR lpString, SUBSTRPROC lpFnStrProc, LPVOID lpParam)
{
	if (lpString == NULL || lpFnStrProc == NULL)
		return FALSE;

	LPCTSTR p = lpString;
	DWORD dwLen = _tcslen(p);

	while (dwLen > 0)
	{
		if (!lpFnStrProc(p, lpParam))
			return FALSE;

		p = &p[dwLen + 1];
		dwLen = _tcslen(p);
	}
	return TRUE;
}

// Callback function used to compare elements inside of a 
// "double null terminated string" with a given string. Useful for
// searching in the section names list.
BOOL CALLBACK CIni::__SubStrCompare(LPCTSTR lpString1, LPVOID lpParam)
{
	assert(lpString1 != NULL);
	LPCTSTR lpString2 = (LPCTSTR)lpParam;
	assert(lpString2 != NULL);
	// if two string matches, return zero to stop the parsing
	return _tcsicmp(lpString1, lpString2) != 0;
}

// Callback function used to process a key-pair, it extracts the
// key name from the key-pair string
BOOL CALLBACK CIni:: __KeyPairProc(LPCTSTR lpString, LPVOID lpParam)
{
	STR_LIMIT* psl = (STR_LIMIT*)lpParam;
	if (lpString == NULL || psl== NULL)
		return FALSE;
	
	LPCTSTR p = _tcschr(lpString, _T('='));
	if (p == NULL || p == lpString)
		return TRUE;
	
	// extract the sub-string on left side of the '='
	LPTSTR psz = new TCHAR[_tcslen(lpString) + 1];
	for (int i = 0; &lpString[i] < p; i++)
		psz[i] = lpString[i];
	psz[i] = _T('\0');

	// trim
	__TrimString(psz);
	DWORD dwNameLen = _tcslen(psz);
	DWORD dwCopyLen = 0;
	
	//copy to the buffer
	if (psl->lpTarget != NULL)
	{
		dwCopyLen = (psl->dwRemain > 1) ? min(dwNameLen, psl->dwRemain - 1) : 0;
		_tcsncpy(psl->lpTarget, psz, dwCopyLen);
		psl->lpTarget[dwCopyLen] = _T('\0');
		psl->lpTarget = &(psl->lpTarget[dwCopyLen + 1]); 
		psl->dwRemain -= dwCopyLen + 1;
	}
	else
	{
		dwCopyLen = dwNameLen;
	}

	delete [] psz;
	psl->dwTotalCopied += dwCopyLen + 1;
	return TRUE;
}

#ifdef __AFXWIN_H__
// Callback function used to add elements that are extracted from a 
// "double null terminated string" to an MFC CStringArray.
BOOL CALLBACK CIni::__SubStrAdd(LPCTSTR lpString, LPVOID lpParam)
{
	CStringArray* pArray = (CStringArray*)lpParam;
	if (pArray == NULL || lpString == NULL)
		return FALSE;

	pArray->Add(lpString);
	return TRUE;
}
#endif

// Convert an integer into binary string format
void CIni::__ToBinaryString(UINT nNumber, LPTSTR lpBuffer, DWORD dwBufSize)
{
	if (dwBufSize == 0)
		return;
	
	DWORD dwIndex = 0;	
	do
	{
		lpBuffer[dwIndex++] = (nNumber % 2) ? _T('1') : _T('0');
		nNumber /= 2;
	} while (nNumber > 0 && dwIndex < dwBufSize);

	lpBuffer[dwIndex] = _T('\0');
	_tcsrev(lpBuffer);
}

// Make sure the base will be expected value
int CIni::__ValidateBase(int nBase)
{
	switch (nBase)
	{
	case BASE_BINARY:
	case BASE_OCTAL:
	case BASE_HEXADECIMAL:
		break;

	default:
		nBase = BASE_DECIMAL;
	}

	return nBase;
}

// Convert a signed integer into string representation, based on its base
void CIni::__IntToString(int nNumber, LPTSTR lpBuffer, int nBase)
{
	switch (nBase)
	{
	case BASE_BINARY:
	case BASE_OCTAL:
	case BASE_HEXADECIMAL:
		__UIntToString((UINT)nNumber, lpBuffer, nBase);
		break;

	default:
		_stprintf(lpBuffer, _T("%d"), nNumber);
		break;
	}	
}

// Convert an unsigned integer into string representation, based on its base
void CIni::__UIntToString(UINT nNumber, LPTSTR lpBuffer, int nBase)
{
	switch (nBase)
	{
	case BASE_BINARY:
		__ToBinaryString(nNumber, lpBuffer, DEF_PROFILE_NUM_LEN);
		break;

	case BASE_OCTAL:
		_stprintf(lpBuffer, _T("%o"), nNumber);
		break;

	case BASE_HEXADECIMAL:
		_stprintf(lpBuffer, _T("%X"), nNumber);
		break;

	default:
		_stprintf(lpBuffer, _T("%u"), nNumber);
		break;
	}	
}

BOOL CIni::StringToBool(LPCTSTR lpString, BOOL bDefault)
{
	// Default: empty string
	// TRUE: "true", "yes", non-zero decimal numner
	// FALSE: all other cases
	if (lpString == NULL || *lpString == _T('\0'))
		return bDefault;

	return (_tcsicmp(lpString, _T("true")) == 0
		|| _tcsicmp(lpString, _T("yes")) == 0
		|| _tcstol(lpString, NULL, BASE_DECIMAL) != 0);
}

BOOL CIni::__TrimString(LPTSTR lpString)
{
	if (lpString == NULL)
		return FALSE;

	BOOL bTrimmed = FALSE;
	int nLen = _tcslen(lpString);

	// '\n' and '\r' are actually not possible in this case, but anyway...
	
	// Trim right side
	while (nLen >= 0
		&& (lpString[nLen - 1] == _T(' ')
			|| lpString[nLen - 1] == _T('\t')
			|| lpString[nLen - 1] == _T('\r')
			|| lpString[nLen - 1] == _T('\n')))
	{
		lpString[--nLen] = _T('\0');
		bTrimmed = TRUE;		
	}

	// Trim left side
	LPCTSTR p = lpString; 
	while (*p == _T(' ')
			|| *p == _T('\t')
			|| *p == _T('\r')
			|| *p == _T('\n'))
	{
		p = &p[1];
		bTrimmed = TRUE;
	}

	if (p != lpString)
	{
		LPTSTR psz = _tcsdup(p);
		_tcscpy(lpString, psz);
		delete [] psz;
	}

	return bTrimmed;
}

LPTSTR CIni::__StrDupEx(LPCTSTR lpStart, LPCTSTR lpEnd)
{
	const DWORD LEN = ((DWORD)lpEnd - (DWORD)lpStart) / sizeof(TCHAR);
	LPTSTR psz = new TCHAR[LEN + 1];
	_tcsncpy(psz, lpStart, LEN);
	psz[LEN] = _T('\0');
	return psz; // !!! Requires the caller to free this memory !!!
}

/////////////////////////////////////////////////////////////////////////////////
// End of Cini Class Implementation
/////////////////////////////////////////////////////////////////////////////////

// If you are getting this error:
// ----------------------------------------------------------------------------
// "fatal error C1010: unexpected end of file while looking for precompiled
//  header directive"
//-----------------------------------------------------------------------------
// Please scroll all the way up and uncomment '#include "stdafx.h"'

⌨️ 快捷键说明

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