1 /* 2 * Copyright (C) 2004-2020 ZNC, see the NOTICE file for details. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ZNC_CONFIG_H 18 #define ZNC_CONFIG_H 19 20 #include <znc/zncconfig.h> 21 #include <znc/ZNCString.h> 22 23 class CFile; 24 class CConfig; 25 26 struct CConfigEntry { 27 CConfigEntry(); 28 CConfigEntry(const CConfig& Config); 29 CConfigEntry(const CConfigEntry& other); 30 ~CConfigEntry(); 31 CConfigEntry& operator=(const CConfigEntry& other); 32 33 CConfig* m_pSubConfig; 34 }; 35 36 class CConfig { 37 public: CConfig()38 CConfig() : m_ConfigEntries(), m_SubConfigs() {} 39 40 typedef std::map<CString, VCString> EntryMap; 41 typedef std::map<CString, CConfigEntry> SubConfig; 42 typedef std::map<CString, SubConfig> SubConfigMap; 43 44 typedef EntryMap::const_iterator EntryMapIterator; 45 typedef SubConfigMap::const_iterator SubConfigMapIterator; 46 BeginEntries()47 EntryMapIterator BeginEntries() const { return m_ConfigEntries.begin(); } EndEntries()48 EntryMapIterator EndEntries() const { return m_ConfigEntries.end(); } 49 BeginSubConfigs()50 SubConfigMapIterator BeginSubConfigs() const { 51 return m_SubConfigs.begin(); 52 } EndSubConfigs()53 SubConfigMapIterator EndSubConfigs() const { return m_SubConfigs.end(); } 54 AddKeyValuePair(const CString & sName,const CString & sValue)55 void AddKeyValuePair(const CString& sName, const CString& sValue) { 56 if (sName.empty() || sValue.empty()) { 57 return; 58 } 59 60 m_ConfigEntries[sName].push_back(sValue); 61 } 62 AddSubConfig(const CString & sTag,const CString & sName,CConfig Config)63 bool AddSubConfig(const CString& sTag, const CString& sName, 64 CConfig Config) { 65 SubConfig& conf = m_SubConfigs[sTag]; 66 SubConfig::const_iterator it = conf.find(sName); 67 68 if (it != conf.end()) { 69 return false; 70 } 71 72 conf[sName] = Config; 73 return true; 74 } 75 76 bool FindStringVector(const CString& sName, VCString& vsList, 77 bool bErase = true) { 78 EntryMap::iterator it = m_ConfigEntries.find(sName); 79 vsList.clear(); 80 if (it == m_ConfigEntries.end()) return false; 81 vsList = it->second; 82 83 if (bErase) { 84 m_ConfigEntries.erase(it); 85 } 86 87 return true; 88 } 89 90 bool FindStringEntry(const CString& sName, CString& sRes, 91 const CString& sDefault = "") { 92 EntryMap::iterator it = m_ConfigEntries.find(sName); 93 sRes = sDefault; 94 if (it == m_ConfigEntries.end() || it->second.empty()) return false; 95 sRes = it->second.front(); 96 it->second.erase(it->second.begin()); 97 if (it->second.empty()) m_ConfigEntries.erase(it); 98 return true; 99 } 100 101 bool FindBoolEntry(const CString& sName, bool& bRes, 102 bool bDefault = false) { 103 CString s; 104 if (FindStringEntry(sName, s)) { 105 bRes = s.ToBool(); 106 return true; 107 } 108 bRes = bDefault; 109 return false; 110 } 111 112 bool FindUIntEntry(const CString& sName, unsigned int& uRes, 113 unsigned int uDefault = 0) { 114 CString s; 115 if (FindStringEntry(sName, s)) { 116 uRes = s.ToUInt(); 117 return true; 118 } 119 uRes = uDefault; 120 return false; 121 } 122 123 bool FindUShortEntry(const CString& sName, unsigned short& uRes, 124 unsigned short uDefault = 0) { 125 CString s; 126 if (FindStringEntry(sName, s)) { 127 uRes = s.ToUShort(); 128 return true; 129 } 130 uRes = uDefault; 131 return false; 132 } 133 134 bool FindDoubleEntry(const CString& sName, double& fRes, 135 double fDefault = 0) { 136 CString s; 137 if (FindStringEntry(sName, s)) { 138 fRes = s.ToDouble(); 139 return true; 140 } 141 fRes = fDefault; 142 return false; 143 } 144 145 bool FindSubConfig(const CString& sName, SubConfig& Config, 146 bool bErase = true) { 147 SubConfigMap::iterator it = m_SubConfigs.find(sName); 148 if (it == m_SubConfigs.end()) { 149 Config.clear(); 150 return false; 151 } 152 Config = it->second; 153 154 if (bErase) { 155 m_SubConfigs.erase(it); 156 } 157 158 return true; 159 } 160 empty()161 bool empty() const { 162 return m_ConfigEntries.empty() && m_SubConfigs.empty(); 163 } 164 165 bool Parse(CFile& file, CString& sErrorMsg); 166 void Write(CFile& file, unsigned int iIndentation = 0); 167 168 private: 169 EntryMap m_ConfigEntries; 170 SubConfigMap m_SubConfigs; 171 }; 172 173 #endif // !ZNC_CONFIG_H 174