#pragma once #ifndef _WIN32 #include #endif #include "File.h" #include "CriticalSection.h" #include #include #include #include #include #include class CIniFileBase { public: typedef std::map KeyValueData; typedef std::set SectionList; typedef std::list strlist; typedef std::pair KeyValueItem; typedef std::vector KeyValueVector; typedef void(*SortData)(KeyValueVector &); CIniFileBase(CFileBase & FileObject, const char * FileName); virtual ~CIniFileBase(void); bool IsEmpty(); bool IsFileOpen(void); bool DeleteSection(const char * lpSectionName); bool GetString(const char * lpSectionName, const char * lpKeyName, const char * lpDefault, std::string & Value); std::string GetString(const char * lpSectionName, const char * lpKeyName, const char * lpDefault); uint32_t GetString(const char * lpSectionName, const char * lpKeyName, const char * lpDefault, char * lpReturnedString, uint32_t nSize); uint32_t GetNumber(const char * lpSectionName, const char * lpKeyName, uint32_t nDefault); bool GetNumber(const char * lpSectionName, const char * lpKeyName, uint32_t nDefault, uint32_t & Value); virtual void SaveString(const char * lpSectionName, const char * lpKeyName, const char * lpString); virtual void SaveNumber(const char * lpSectionName, const char * lpKeyName, int32_t Value); void SetAutoFlush(bool AutoFlush); void FlushChanges(void); bool EntryExists(const char * lpSectionName, const char * lpKeyName); void GetKeyList(const char * lpSectionName, strlist &List); void GetKeyValueData(const char * lpSectionName, KeyValueData & List); void SetCustomSort(SortData SortFunction); void GetVectorOfSections(SectionList & sections); const std::string &GetFileName() { return m_FileName; } protected: void OpenIniFileReadOnly(); void OpenIniFile(bool bCreate = true); void SaveCurrentSection(void); std::string FormatStr(const char * strFormat, ...); CFileBase & m_File; std::string m_FileName; private: struct insensitive_compare { bool operator() (const std::string & a, const std::string & b) const { return _stricmp(a.c_str(), b.c_str()) < 0; } }; typedef std::map FILELOC; typedef FILELOC::iterator FILELOC_ITR; typedef std::map KeyValueList; std::string m_CurrentSection; bool m_CurrentSectionDirty; int m_CurrentSectionFilePos; // Where in the file is the current section KeyValueList m_CurrentSectionData; long m_lastSectionSearch; // When scanning for a section, what was the last scanned POS bool m_ReadOnly; bool m_InstantFlush; const char * m_LineFeed; CriticalSection m_CS; FILELOC m_SectionsPos; SortData m_SortFunction; void fInsertSpaces(int Pos, int NoOfSpaces); int GetStringFromFile(char * & String, std::unique_ptr &Data, int & MaxDataSize, int & DataSize, int & ReadPos); bool MoveToSectionNameData(const char * lpSectionName, bool ChangeCurrentSection); const char * CleanLine(char * Line); void ClearSectionPosList(long FilePos); }; template class CIniFileT : public CIniFileBase { public: CIniFileT(const char * FileName) : CIniFileBase(m_FileObject, FileName) { // Try to open file for reading OpenIniFile(); } CIniFileT(const char * FileName, bool bCreate, bool bReadOnly) : CIniFileBase(m_FileObject, FileName) { if (bReadOnly) { OpenIniFileReadOnly(); } else { // Try to open file for reading OpenIniFile(bCreate); } } virtual ~CIniFileT(void) { SaveCurrentSection(); } protected: CFileStorage m_FileObject; }; typedef CIniFileT CIniFile;