📄 myinifile.h
字号:
// MyIniFile.h: interface for the CMyIniFile class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_MYINIFILE_H__644269B0_6129_4BAD_A1C0_E0B5458A05C3__INCLUDED_)
#define AFX_MYINIFILE_H__644269B0_6129_4BAD_A1C0_E0B5458A05C3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "MyLog.h"
#include <map>
#include <string>
#include <algorithm>
struct STRING_STRING
{
const char* pszStr1;
const char* pszStr2;
};
inline std::string GetFullPathEx(const char* path,const char* strBaseDir)
{
if(!path)
{
return "";
}
if(strBaseDir[0]==0)
{
return path;
}
if(0!=strchr(path,':'))
{
return path;
}
CString strTxt=strBaseDir;
if((strTxt.Right(1)!="\\")
&&(strTxt.Right(1)!="/"))
{
strTxt+="\\";
}
strTxt+=path;
strTxt.Replace('/','\\');
return (const char*)strTxt;
};
#define GET_FULLPATH(path) GetFullPathEx(path,m_strBaseDir).c_str()
#define TAG_OPTIONAL "OPTIONAL"
template<class T>
class CAutoDelete
{
public:
CAutoDelete(T* pT):
m_pT(pT)
{
}
operator T*() const
{
return m_pT;
}
T* operator ->() const
{
return m_pT;
}
void ClearPtr()
{
m_pT=0;
}
~CAutoDelete()
{
if(m_pT)
{
delete m_pT;
m_pT=0;
}
}
private:
T* m_pT;
};
struct INI_META_DATA_INI_FORMAT
{
std::string strIniFile;
};
struct INI_META_DATA_CHECK_RULE
{
std::string strName;
BOOL bApplyToSectionByNamingRule;
STRING_LIST ApplyToSectionList;
void SetApplyToSectionList(const char* pszApplyToSectionList)
{
strApplyToSectionList=pszApplyToSectionList;
ParseString(pszApplyToSectionList,",",ApplyToSectionList);
}
std::string strApplyToSectionList;
std::string strSectionNamingRule;
BOOL bRestrictKeySequence;
std::string strAutoCheckBegin;
STRING_LIST Keys;
STD_MAP_STRING_2_STRING MapKeysToRule;
std::string strFileRedirectToSubFolder;
};
struct INI_META_DATA
{
virtual ~INI_META_DATA()
{
};
std::string strMetaDataFilePath;
INI_META_DATA_INI_FORMAT IniFormat;
INI_META_DATA_CHECK_RULE IniCheckRule;
void SetAllKey()
{
DeleteAllKey();
IniCheckRule.Keys.push_back("ALL_KEY");
IniCheckRule.MapKeysToRule["ALL_KEY"]="";
IniCheckRule.strAutoCheckBegin="ALL_KEY";
}
void DeleteAllKey()
{
IniCheckRule.bRestrictKeySequence=FALSE;
IniCheckRule.Keys.clear();
IniCheckRule.MapKeysToRule.clear();
}
};
typedef std::vector<INI_META_DATA*> INI_META_DATA_LIST;
typedef std::map<std::string,INI_META_DATA*> MAP_NAME_2_INI_META_DATA;
class INI_META_DATA_MGR
{
public:
virtual ~INI_META_DATA_MGR()
{
ClearMetaData();
};
void ClearMetaData()
{
for(MAP_NAME_2_INI_META_DATA::iterator itr=MapName2IniMetaData.begin();itr!=MapName2IniMetaData.end();itr++)
{
delete (*itr).second;
}
MapName2IniMetaData.clear();
IniMetaDataNameList.clear();
IniFileList.clear();
MapIniFile2MetaDataNameList.clear();
}
BOOL GetRuleSectionList(const char* pszIni,STRING_LIST& RuleSectionList)
{
RuleSectionList.clear();
CString strIni=pszIni;
strIni.MakeLower();
STD_MAP_STRING_2_STRING::iterator itr=MapIniFile2MetaDataNameList.find((const char*)strIni);
if(MapIniFile2MetaDataNameList.end()==itr)
{
return FALSE;
}
if((*itr).second.empty())
{
return FALSE;
}
ParseString((*itr).second,",",RuleSectionList,true,true,true);
return TRUE;
}
INI_META_DATA* GetMetaDataByName(const char* pszName)
{
MAP_NAME_2_INI_META_DATA::iterator itr=MapName2IniMetaData.find(pszName);
if(MapName2IniMetaData.end()==itr)
{
return 0;
}
return (*itr).second;
}
BOOL GetMetaDataList(const char* pszIni,INI_META_DATA_LIST& IniMetaDataList)
{
IniMetaDataList.clear();
STRING_LIST RuleSectionList;
GetRuleSectionList(pszIni,RuleSectionList);
if(RuleSectionList.size()<1)
{
return FALSE;
}
for(long l=0;l<RuleSectionList.size();l++)
{
std::string strRuleID=RuleSectionList[l];
MAP_NAME_2_INI_META_DATA::iterator itr=MapName2IniMetaData.find(strRuleID);
if(MapName2IniMetaData.end()==itr)
{
ASSERT(false);
continue;
};
IniMetaDataList.push_back((*itr).second);
}
return TRUE;
}
void DeleteMetaData(const char *pszRuleID)
{
MAP_NAME_2_INI_META_DATA::iterator itr=MapName2IniMetaData.find(pszRuleID);
if(MapName2IniMetaData.end()==itr)
{
ASSERT(false);
}
else
{
INI_META_DATA* pIniMetaData=(*itr).second;
ASSERT(pIniMetaData);
STD_MAP_STRING_2_STRING::iterator itrIniFile2MetaDataNameList=MapIniFile2MetaDataNameList.find(pIniMetaData->IniFormat.strIniFile);
if(MapIniFile2MetaDataNameList.end()==itrIniFile2MetaDataNameList)
{
ASSERT(false);
}
else
{
CString strMetaDataNameList=(*itrIniFile2MetaDataNameList).second.c_str();
strMetaDataNameList.Replace(pszRuleID+(CString)",","");
strMetaDataNameList.Replace(pszRuleID,"");
if(strMetaDataNameList.GetLength()>0)
{
if(strMetaDataNameList.Right(1)==",")
{
strMetaDataNameList=strMetaDataNameList.Left(strMetaDataNameList.GetLength()-1);
}
}
if(strMetaDataNameList.IsEmpty())
{
MapIniFile2MetaDataNameList.erase(pIniMetaData->IniFormat.strIniFile);
STRING_LIST::iterator itrFile=std::find(IniFileList.begin(),IniFileList.end(),pIniMetaData->IniFormat.strIniFile);
if(IniFileList.end()==itrFile)
{
ASSERT(false);
}
else
{
IniFileList.erase(itrFile);
}
}
else
{
MapIniFile2MetaDataNameList[pIniMetaData->IniFormat.strIniFile]=strMetaDataNameList;
}
}
MapName2IniMetaData.erase(itr);
delete pIniMetaData;
}
STRING_LIST::iterator itrName=std::find(IniMetaDataNameList.begin(),IniMetaDataNameList.end(),pszRuleID);
if(IniMetaDataNameList.end()==itrName)
{
ASSERT(false);
}
else
{
IniMetaDataNameList.erase(itrName);
}
};
INI_META_DATA* AddNewMetaData(const char *pszFile)
{
INI_META_DATA *pIniMetaDataNew=new INI_META_DATA;
pIniMetaDataNew->IniFormat.strIniFile=pszFile;
SYSTEMTIME SystemTime={0,};
GetLocalTime(&SystemTime);
pIniMetaDataNew->IniCheckRule.strName=FormatString("%s_ruleid_%04d-%02d-%02d %02d:%02d:%02d",
(const char*)pszFile,
SystemTime.wYear,
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond
).c_str();
pIniMetaDataNew->IniFormat.strIniFile=pszFile;
MapName2IniMetaData.insert(MAP_NAME_2_INI_META_DATA::value_type(
pIniMetaDataNew->IniCheckRule.strName,pIniMetaDataNew
));
IniMetaDataNameList.push_back(pIniMetaDataNew->IniCheckRule.strName);
if(IniFileList.end()==std::find(IniFileList.begin(),IniFileList.end(),pszFile))
{
IniFileList.push_back(pszFile);
}
pIniMetaDataNew->IniCheckRule.bRestrictKeySequence=FALSE;
pIniMetaDataNew->IniCheckRule.bApplyToSectionByNamingRule=FALSE;
//
CString strMetaDataNameList;
STD_MAP_STRING_2_STRING::iterator itrMetaDataNameList=MapIniFile2MetaDataNameList.find(pszFile);
if(MapIniFile2MetaDataNameList.end()!=itrMetaDataNameList)
{
strMetaDataNameList=(*itrMetaDataNameList).second.c_str();
}
if(!strMetaDataNameList.IsEmpty())
{
strMetaDataNameList+=",";
}
strMetaDataNameList+=pIniMetaDataNew->IniCheckRule.strName.c_str();
MapIniFile2MetaDataNameList[pszFile]=strMetaDataNameList;
return pIniMetaDataNew;
}
STD_MAP_STRING_2_STRING MapIniFile2MetaDataNameList;
STRING_LIST IniFileList;
MAP_NAME_2_INI_META_DATA MapName2IniMetaData;
STRING_LIST IniMetaDataNameList;
};
typedef std::map<std::string, std::string> MAP_INI_KEY_2_VALUE;
struct INI_SECTION
{
STRING_LIST IniKeyList;
MAP_INI_KEY_2_VALUE MapIniKey2Value;
};
class IBasicMsgUI
{
public:
virtual void ShowProgressMsg(const char* pszMsg)=0;
virtual void ShowDebugMsg(const char* pszMsg)=0;
virtual void ShowErrorMsg(const char* pszMsg)=0;
};
typedef std::map<std::string, INI_SECTION*> MAP_NAME_TO_INI_SECTION;
//
//
//
class CMyIniFile
{
public:
static void CheckIniFile(
INI_META_DATA_LIST& IniMetaDataList,
const char* strFile,
const char* pszBaseDir,
IBasicMsgUI* pIBasicMsgUI
);
static void CheckIniFile(
INI_META_DATA& IniMetaData,
const char* strFile,
const char* pszBaseDir,
IBasicMsgUI* pIBasicMsgUI
);
static BOOL SaveIniMetaData(
const char * pszMetaDataFilePath,
const char* pszIniFilePath,
INI_META_DATA_MGR& IniMetaDataMgr
);
static BOOL LoadIniMetaData(
const char * pszMetaDataFilePath,
INI_META_DATA_MGR* pIniMetaDataMgr,
IBasicMsgUI* pIBasicMsgUI
);
static BOOL LoadIniMetaDataSection(
const char* pszMetaDataFilePath,
const char* strSect,
INI_META_DATA_MGR* pIniMetaDataMgr,
IBasicMsgUI* pIBasicMsgUI
);
CMyIniFile(
const char* pszBaseDir,
IBasicMsgUI* pIBasicMsgUI,
const char* pszFileRedirectSubFolder="",
const bool bDuplicatedKeyEnabled=false
);
virtual ~CMyIniFile();
static BOOL IsKeyExistesEx(
const char* pszIniFile,
const char* pszSection,
const char* pszKey
);
static BOOL IsSectionExistesEx(
const char* pszIniFile,
const char* pszSection
);
BOOL IsKeyExistes(
const char* pszSection,
const char* pszKey
);
BOOL IsSectionExistes(
const char* pszSection
);
BOOL GetKeyNameList(STRING_LIST& StrKeyList);
//
//
public:
void SetWholeLineAsValue(const BOOL bWholeLineAsValue);
void SetFileRedirectSubFolder(CString strFileRedirectSubFolder);
BOOL GetSectionList(STRING_LIST &StrList);
INI_SECTION* GetSection(const char *pszSection);
BOOL GetSectionValueList(const char* pszSection,STRING_LIST& StrListValue);
const char* GetFilePath();
BOOL SaveAs(const char* pszNewIniFilePath);
ULONG ReplaceAll(const char* pszOld,const char* pszNew,const BOOL bReplaceBackSlashWithSlash);
BOOL ReadAndParse(
const char* strFilePath
);
BOOL Read(const char* strFilePath);
protected:
static BOOL SaveIniMetaDataSection(
const char * pszMetaDataFilePath,
const char* strSect,
INI_META_DATA* pIniMetaData
);
void CheckAllIniSectionAutoCheck(INI_META_DATA_CHECK_RULE& CheckRuleAutoCheck);
void CheckIniSectionAutoCheck(
const char *pszSection,
INI_META_DATA_CHECK_RULE& CheckRuleAutoCheck
);
private:
protected:
#define NO_SECTION_FILE_SECTION_NAME "NoSection"
void Parse();
void ClearIniSection();
BOOL AutoCheckIniValue(
const char* pszSection,
INI_SECTION* pIniSection,
const char* strKeyFull,
const CString strRule,
BOOL& bKeySequenceErrorFound,
const BOOL bRestrictKeySequence,
STRING_LIST::iterator& itrValueKey
);
private:
static BOOL SimplifyExpression(
STD_MAP_STRING_2_STRING& ReplaceMapping,
const const char* strExpression,
CString& strExpressionNew,
std::string& strErr
);
static BOOL CheckStringByRule(const CString strVal,const CString strRule,const CString strContext,std::string& strErr);
private:
CMyIniFile* LoadIniIfNotFound(const char* pszIni);
void ClearMapFilePath2Ini();
private:
MAP_NAME_TO_INI_SECTION m_MapNameToIniSection;
CStringArray m_saIniStringList;
CString m_strFilePath;
CString m_strBaseDir;
IBasicMsgUI* m_pIBasicMsgUI;
bool m_bDuplicatedKeyEnabled;
CString m_strFileRedirectSubFolder;
typedef std::map<std::string,CMyIniFile*> MAP_FILE_PATH_TO_INI;
MAP_FILE_PATH_TO_INI m_MapFilePath2Ini;
BOOL m_bWholeLineAsValue;
};
BOOL OpenFileAndAutoLocate(
const char* strFilePath,
const DWORD dwLineToLocate,
const DWORD dwColumnToLocate,
const HWND hWnd
);
long FindStringInFile(
const char* pszFilePath,
const char* pszPattern,
const bool bCompareNoCase=false,
const bool bMatchPartial=true
);
void SaveIniStringList(
const char* pszIniFile,
const char* pszSection,
STRING_LIST& StringList
);
void LoadIniStringList(
const char* pszIniFile,
const char* pszSection,
STRING_LIST& StringList,
const BOOL bRemoveDuplicated=TRUE
);
//bReplaceBackSlashWithSlash:true: replace \ with / false: replace / with "\\"
CString GetRelativeFilePath(const CString strFilePath,const CString strDir,const BOOL bReplaceBackSlashWithSlash=FALSE);
void ParseRule(std::string strRule,STD_MAP_STRING_2_STRINGLIST& RulesMapping);
#endif // !defined(AFX_MYINIFILE_H__644269B0_6129_4BAD_A1C0_E0B5458A05C3__INCLUDED_)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -