📄 stm32+i
字号:
/////////////////////////////////////////////////////////////////////////////////
// Cini Class Implementation
/////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h" // include if you got "fatal error C1010: unexpected end of file..."
#include "Ini.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#define DEF_PROFILE_NUM_LEN 64 // numeric string length, could be quite long for binary format
#define DEF_PROFILE_THRESHOLD 512 // temporary string length
#define DEF_PROFILE_DELIMITER _T(",") // default string delimiter
#define DEF_PROFILE_TESTSTRING _T("{63788286-AE30-4D6B-95DF-3B451C1C79F9}") // Uuid for internal use
// struct used to be passed to __KeyPairProc as a LPVOID parameter
struct STR_LIMIT
{
LPTSTR lpTarget;
DWORD dwRemain;
DWORD dwTotalCopied;
};
/////////////////////////////////////////////////////////////////////////////////
// Constructors & Destructor
/////////////////////////////////////////////////////////////////////////////////
CIni::CIni()
{
m_pszPathName = NULL;
}
CIni::CIni(LPCTSTR lpPathName)
{
m_pszPathName = NULL;
SetPathName(lpPathName);
}
CIni::~CIni()
{
if (m_pszPathName != NULL)
delete [] m_pszPathName;
}
/////////////////////////////////////////////////////////////////////////////////
// Ini File Path Access
/////////////////////////////////////////////////////////////////////////////////
// Assign ini file path name
void CIni::SetPathName(LPCTSTR lpPathName)
{
if (lpPathName == NULL)
{
if (m_pszPathName != NULL)
*m_pszPathName = _T('\0');
}
else
{
if (m_pszPathName != NULL)
delete [] m_pszPathName;
m_pszPathName = _tcsdup(lpPathName);
}
}
// Retrieve ini file path name
DWORD CIni::GetPathName(LPTSTR lpBuffer, DWORD dwBufSize) const
{
*lpBuffer = _T('\0');
DWORD dwLen = 0;
if (lpBuffer != NULL)
{
_tcsncpy(lpBuffer, m_pszPathName, dwBufSize);
dwLen = _tcslen(lpBuffer);
}
else
{
// just calculate the required buffer size
dwLen = _tcslen(m_pszPathName);
}
return dwLen;
}
#ifdef __AFXWIN_H__
CString CIni::GetPathName() const
{
return CString(m_pszPathName);
}
#endif
/////////////////////////////////////////////////////////////////////////////////
// Raw String Access
/////////////////////////////////////////////////////////////////////////////////
// Get a profile string value, if the buffer size is not large enough, the result
// may be truncated.
DWORD CIni::GetString(LPCTSTR lpSection, LPCTSTR lpKey, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDefault) const
{
if (lpBuffer != NULL)
*lpBuffer = _T('\0');
LPTSTR psz = __GetStringDynamic(lpSection, lpKey, lpDefault);
DWORD dwLen = _tcslen(psz);
if (lpBuffer != NULL)
{
_tcsncpy(lpBuffer, psz, dwBufSize);
dwLen = min(dwLen, dwBufSize);
}
delete [] psz;
return dwLen;
}
#ifdef __AFXWIN_H__
CString CIni::GetString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpDefault) const
{
LPTSTR psz = __GetStringDynamic(lpSection, lpKey, lpDefault);
CString str(psz);
delete [] psz;
return str;
}
#endif
// Write a string value to the ini file
BOOL CIni::WriteString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue) const
{
if (lpSection == NULL || lpKey == NULL)
return FALSE;
return ::WritePrivateProfileString(lpSection, lpKey, lpValue == NULL ? _T("") : lpValue, m_pszPathName);
}
// Read a string value from the ini file, append another string after it and then write it
// back to the ini file
BOOL CIni::AppendString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpString) const
{
if (lpString == NULL)
return FALSE;
TCHAR* psz = __GetStringDynamic(lpSection, lpKey);
TCHAR* pNewString = new TCHAR[_tcslen(psz) + _tcslen(lpString) + 1];
_stprintf(pNewString, _T("%s%s"), psz, lpString);
const BOOL RES = WriteString(lpSection, lpKey, pNewString);
delete [] pNewString;
delete [] psz;
return RES;
}
/////////////////////////////////////////////////////////////////////////////////
// Ini File String Array Access
/////////////////////////////////////////////////////////////////////////////////
// Get an array of string
DWORD CIni::GetArray(LPCTSTR lpSection, LPCTSTR lpKey, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDelimiter, BOOL bTrimString) const
{
if (lpBuffer != NULL)
*lpBuffer = _T('\0');
if (lpSection == NULL || lpKey == NULL)
return 0;
LPTSTR psz = __GetStringDynamic(lpSection, lpKey);
DWORD dwCopied = 0;
if (*psz != _T('\0'))
{
if (lpBuffer == NULL)
{
// just calculate the required buffer size
const DWORD MAX_LEN = _tcslen(psz) + 2;
LPTSTR p = new TCHAR[MAX_LEN + 1];
dwCopied = __StringSplit(psz, p, MAX_LEN, lpDelimiter, bTrimString);
delete [] p;
}
else
{
dwCopied = __StringSplit(psz, lpBuffer, dwBufSize, lpDelimiter, bTrimString);
}
}
delete [] psz;
return dwCopied;
}
#ifdef __AFXWIN_H__
void CIni::GetArray(LPCTSTR lpSection, LPCTSTR lpKey, CStringArray *pArray, LPCTSTR lpDelimiter, BOOL bTrimString) const
{
if (pArray != NULL)
pArray->RemoveAll();
const DWORD LEN = GetArray(lpSection, lpKey, NULL, 0, lpDelimiter);
if (LEN == 0)
return;
LPTSTR psz = new TCHAR[LEN + 3];
GetArray(lpSection, lpKey, psz, LEN + 2, lpDelimiter);
ParseDNTString(psz, __SubStrAdd, (LPVOID)pArray);
delete [] psz;
}
#endif
#ifdef __AFXWIN_H__
BOOL CIni::WriteArray(LPCTSTR lpSection, LPCTSTR lpKey, const CStringArray *pArray, int nWriteCount, LPCTSTR lpDelimiter) const
{
if (pArray == NULL)
return FALSE;
if (nWriteCount < 0)
nWriteCount = pArray->GetSize();
else
nWriteCount = min(nWriteCount, pArray->GetSize());
const CString DELIMITER = (lpDelimiter == NULL || *lpDelimiter == _T('\0')) ? _T(",") : lpDelimiter;
CString sLine;
for (int i = 0; i < nWriteCount; i++)
{
sLine += pArray->GetAt(i);
if (i != nWriteCount - 1)
sLine += DELIMITER;
}
return WriteString(lpSection, lpKey, sLine);
}
#endif
/////////////////////////////////////////////////////////////////////////////////
// Primitive Data Type Access
/////////////////////////////////////////////////////////////////////////////////
// Get a signed integral value
int CIni::GetInt(LPCTSTR lpSection, LPCTSTR lpKey, int nDefault, int nBase) const
{
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T("");
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN);
return *sz == _T('\0') ? nDefault : int(_tcstoul(sz, NULL, __ValidateBase(nBase)));
}
// Get an unsigned integral value
UINT CIni::GetUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nDefault, int nBase) const
{
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T("");
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN);
return *sz == _T('\0') ? nDefault : UINT(_tcstoul(sz, NULL, __ValidateBase(nBase)));
}
// Get a boolean value
BOOL CIni::GetBool(LPCTSTR lpSection, LPCTSTR lpKey, BOOL bDefault) const
{
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T("");
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN);
return StringToBool(sz, bDefault);
}
// Get a double floating value
double CIni::GetDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fDefault) const
{
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T("");
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN);
return *sz == _T('\0') ? fDefault : _tcstod(sz, NULL);
}
// Write a signed integral value to the ini file
BOOL CIni::WriteInt(LPCTSTR lpSection, LPCTSTR lpKey, int nValue, int nBase) const
{
TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T("");
__IntToString(nValue, szValue, nBase);
return WriteString(lpSection, lpKey, szValue);
}
// Write an unsigned value to the ini file
BOOL CIni::WriteUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nValue, int nBase) const
{
TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T("");
__UIntToString(nValue, szValue, nBase);
return WriteString(lpSection, lpKey, szValue);
}
// Write a double floating value to the ini file
BOOL CIni::WriteDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fValue, int nPrecision) const
{
TCHAR szFmt[16] = _T("%f");
if (nPrecision > 0)
_stprintf(szFmt, _T("%%.%df"), nPrecision);
TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T("");
_stprintf(szValue, szFmt, fValue);
return WriteString(lpSection, lpKey, szValue);
}
// Read a double value from the ini file, increase it then write it back
BOOL CIni::IncreaseDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fIncrease, int nPrecision) const
{
double f = GetDouble(lpSection, lpKey, 0.0);
f += fIncrease;
return WriteDouble(lpSection, lpKey, f, nPrecision);
}
// Write a boolean value to the ini file
BOOL CIni::WriteBool(LPCTSTR lpSection, LPCTSTR lpKey, BOOL bValue) const
{
return WriteInt(lpSection, lpKey, bValue ? 1 : 0, BASE_DECIMAL);
}
// Read a boolean value from the ini file, invert it(true becomes false, false becomes true),
// then write it back
BOOL CIni::InvertBool(LPCTSTR lpSection, LPCTSTR lpKey) const
{
return WriteBool(lpSection, lpKey, !GetBool(lpSection, lpKey, FALSE));
}
// Read a int from the ini file, increase it and then write it back to the ini file
BOOL CIni::IncreaseInt(LPCTSTR lpSection, LPCTSTR lpKey, int nIncrease, int nBase) const
{
int nVal = GetInt(lpSection, lpKey, 0, nBase);
nVal += nIncrease;
return WriteInt(lpSection, lpKey, nVal, nBase);
}
// Read an UINT from the ini file, increase it and then write it back to the ini file
BOOL CIni::IncreaseUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nIncrease, int nBase) const
{
UINT nVal = GetUInt(lpSection, lpKey, 0, nBase);
nVal += nIncrease;
return WriteUInt(lpSection, lpKey, nVal, nBase);
}
TCHAR CIni::GetChar(LPCTSTR lpSection, LPCTSTR lpKey, TCHAR cDefault) const
{
TCHAR sz[2] = _T("");
GetString(lpSection, lpKey, sz, 1);
return *sz == _T('\0') ? cDefault : sz[0];
}
BOOL CIni::WriteChar(LPCTSTR lpSection, LPCTSTR lpKey, TCHAR c) const
{
TCHAR sz[2] = { c, _T('\0') };
return WriteString(lpSection, lpKey, sz);
}
/////////////////////////////////////////////////////////////////////////////////
// User-Defined Data Type Access
/////////////////////////////////////////////////////////////////////////////////
// Get a block of raw data from the ini file
DWORD CIni::GetDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPVOID lpBuffer, DWORD dwBufSize, DWORD dwOffset) const
{
LPTSTR psz = __GetStringDynamic(lpSection, lpKey);
DWORD dwLen = _tcslen(psz) / 2;
if (dwLen <= dwOffset)
{
delete [] psz;
return 0;
}
// verify psz, must be all in hex format
for (int i = 0; psz[i] != _T('\0'); i++)
{
TCHAR c = psz[i];
if ((c >= _T('0') && c <= _T('9'))
|| (c >= _T('a') && c <= _T('f'))
|| (c >= _T('A') && c <= _T('F')))
{
// valid
}
else
{
delete [] psz;
return 0;
}
}
DWORD dwProcLen = 0;
LPBYTE lpb = (LPBYTE)lpBuffer;
if (lpb != NULL)
{
dwProcLen = min(dwLen - dwOffset, dwBufSize);
LPCTSTR p = &psz[dwOffset * 2];
for (DWORD i = 0; i < dwProcLen; i++)
{
TCHAR sz[3] = _T("");
_tcsncpy(sz, p, 2);
lpb[i] = BYTE(_tcstoul(sz, NULL, 16));
p = &p[2];
}
}
else
{
dwProcLen = dwLen - dwOffset;
}
delete [] psz;
return dwProcLen;
}
// Write a block of raw data to the ini file
BOOL CIni::WriteDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPCVOID lpData, DWORD dwDataSize) const
{
const BYTE* lpb = (const BYTE*)lpData;
if (lpb == NULL)
return FALSE;
LPTSTR psz = new TCHAR[dwDataSize * 2 + 1];
for (DWORD i = 0, j = 0; i < dwDataSize; i++, j += 2)
_stprintf(&psz[j], _T("%02X"), lpb[i]);
const BOOL RES = WriteString(lpSection, lpKey, psz);
delete [] psz;
return RES;
}
// Append a block of raw data to a specified key in the ini file
BOOL CIni::AppendDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPCVOID lpData, DWORD dwDataSize) const
{
const BYTE* lpb = (const BYTE*)lpData;
if (lpb == NULL)
return FALSE;
LPTSTR psz = new TCHAR[dwDataSize * 2 + 1];
for (DWORD i = 0, j = 0; i < dwDataSize; i++, j += 2)
_stprintf(&psz[j], _T("%02X"), lpb[i]);
const BOOL RES = AppendString(lpSection, lpKey, psz);
delete [] psz;
return RES;
}
// Get a POINT value
POINT CIni::GetPoint(LPCTSTR lpSection, LPCTSTR lpKey, POINT ptDefault) const
{
POINT pt;
if (GetDataBlock(lpSection, lpKey, &pt, sizeof(POINT)) != sizeof(POINT))
pt = ptDefault;
return pt;
}
// Get a RECT value
RECT CIni::GetRect(LPCTSTR lpSection, LPCTSTR lpKey, RECT rcDefault) const
{
RECT rc;
if (GetDataBlock(lpSection, lpKey, &rc, sizeof(RECT)) != sizeof(RECT))
rc = rcDefault;
return rc;
}
// Write a POINT to the ini file
BOOL CIni::WritePoint(LPCTSTR lpSection, LPCTSTR lpKey, POINT pt) const
{
return WriteDataBlock(lpSection, lpKey, &pt, sizeof(POINT));
}
// Write a RECT to the ini file
BOOL CIni::WriteRect(LPCTSTR lpSection, LPCTSTR lpKey, RECT rc) const
{
return WriteDataBlock(lpSection, lpKey, &rc, sizeof(RECT));
}
/////////////////////////////////////////////////////////////////////////////////
// Sections & Keys Access
/////////////////////////////////////////////////////////////////////////////////
// Retrieve a list of key-lines(key-pairs) of the specified section
DWORD CIni::GetKeyLines(LPCTSTR lpSection, LPTSTR lpBuffer, DWORD dwBufSize) const
{
if (lpBuffer != NULL)
*lpBuffer = _T('\0');
if (lpSection == NULL)
return 0;
if (lpBuffer == NULL)
{
// just calculate the required buffer size
DWORD dwLen = DEF_PROFILE_THRESHOLD;
LPTSTR psz = new TCHAR[dwLen + 1];
DWORD dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_pszPathName);
while (dwCopied + 2 >= dwLen)
{
dwLen += DEF_PROFILE_THRESHOLD;
delete [] psz;
psz = new TCHAR[dwLen + 1];
dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_pszPathName);
}
delete [] psz;
return dwCopied + 2;
}
else
{
return ::GetPrivateProfileSection(lpSection, lpBuffer, dwBufSize, m_pszPathName);
}
}
// Retrieve a list of key names of the specified section
DWORD CIni::GetKeyNames(LPCTSTR lpSection, LPTSTR lpBuffer, DWORD dwBufSize) const
{
if (lpBuffer != NULL)
*lpBuffer = _T('\0');
if (lpSection == NULL)
return 0;
STR_LIMIT sl;
sl.lpTarget = lpBuffer;
sl.dwRemain = dwBufSize;
sl.dwTotalCopied = 0;
const DWORD LEN = GetKeyLines(lpSection, NULL, 0);
if (LEN == 0)
return 0;
LPTSTR psz = new TCHAR[LEN + 1];
GetKeyLines(lpSection, psz, LEN);
ParseDNTString(psz, __KeyPairProc, (LPVOID)(&sl));
delete [] psz;
if (lpBuffer != NULL)
lpBuffer[sl.dwTotalCopied] = _T('\0');
return sl.dwTotalCopied;
}
// Get all section names from an ini file
DWORD CIni::GetSectionNames(LPTSTR lpBuffer, DWORD dwBufSize) const
{
if (lpBuffer == NULL)
{
// just calculate the required buffer size
DWORD dwLen = DEF_PROFILE_THRESHOLD;
LPTSTR psz = new TCHAR[dwLen + 1];
DWORD dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_pszPathName);
while (dwCopied + 2 >= dwLen)
{
dwLen += DEF_PROFILE_THRESHOLD;
delete [] psz;
psz = new TCHAR[dwLen + 1];
dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_pszPathName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -