File indexing completed on 2024-03-24 04:04:46
0001 /*************************************************************************** 0002 * KBlocks, a falling blocks game by KDE * 0003 * SPDX-FileCopyrightText: 2010 Zhongjie Cai <squall.leonhart.cai@gmail.com> * 0004 * * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 ***************************************************************************/ 0007 #include "KBlocksConfigManager.h" 0008 0009 #include <sys/types.h> 0010 #include <sys/stat.h> 0011 #include <fcntl.h> 0012 #include <stdlib.h> 0013 #include <cctype> 0014 #include <algorithm> 0015 0016 KBlocksConfigManager::KBlocksConfigManager() 0017 { 0018 stConfigSectionList.clear(); 0019 stConfigKeyNameList.clear(); 0020 stConfigDataTable.clear(); 0021 0022 isDebug = false; 0023 } 0024 0025 KBlocksConfigManager::~KBlocksConfigManager() 0026 { 0027 stConfigSectionList.clear(); 0028 stConfigKeyNameList.clear(); 0029 stConfigDataTable.clear(); 0030 } 0031 0032 int KBlocksConfigManager::SetDebugOutput(bool flag) 0033 { 0034 isDebug = flag; 0035 0036 return 0; 0037 } 0038 0039 int KBlocksConfigManager::LoadConfigFile(const string &filename) 0040 { 0041 FILE *fp; 0042 int result; 0043 0044 fp = fopen(filename.c_str(), "r"); 0045 0046 if (fp == NULL) { 0047 return -1; 0048 } 0049 0050 result = ParseConfigFile(fp); 0051 0052 fclose(fp); 0053 0054 return result; 0055 } 0056 0057 int KBlocksConfigManager::SaveConfigFile(const string &filename) 0058 { 0059 FILE *fp; 0060 int result; 0061 0062 fp = fopen(filename.c_str(), "w+"); 0063 0064 if (fp == NULL) { 0065 return -1; 0066 } 0067 0068 result = ConstructConfigFile(fp); 0069 0070 fclose(fp); 0071 0072 return result; 0073 } 0074 0075 int KBlocksConfigManager::GetSectionCount() 0076 { 0077 return stConfigSectionList.size(); 0078 } 0079 0080 int KBlocksConfigManager::GetKeyCount(const string &SectionName) 0081 { 0082 map< string, map<string, string> >::iterator it; 0083 0084 it = stConfigDataTable.find(SectionName); 0085 0086 if (it == stConfigDataTable.end()) { 0087 return -1; 0088 } 0089 0090 map<string, string> tmpMap = it->second; 0091 0092 return tmpMap.size(); 0093 } 0094 0095 int KBlocksConfigManager::GetKeyString(const string &SectionName, const string &KeyName, string *KeyString, const string &Default) 0096 { 0097 map< string, map<string, string> >::iterator it; 0098 0099 it = stConfigDataTable.find(SectionName); 0100 0101 if (it == stConfigDataTable.end()) { 0102 *KeyString = Default; 0103 return -1; 0104 } 0105 0106 map<string, string> tmpMap = it->second; 0107 0108 if (tmpMap.find(KeyName) == tmpMap.end()) { 0109 *KeyString = Default; 0110 return -1; 0111 } 0112 0113 *KeyString = tmpMap[KeyName]; 0114 0115 return 0; 0116 } 0117 0118 int KBlocksConfigManager::GetKeyInt(const string &SectionName, const string &KeyName, int *KeyInt, const int Default) 0119 { 0120 map< string, map<string, string> >::iterator it; 0121 0122 it = stConfigDataTable.find(SectionName); 0123 0124 if (it == stConfigDataTable.end()) { 0125 *KeyInt = Default; 0126 return -1; 0127 } 0128 0129 map<string, string> tmpMap = it->second; 0130 0131 if (tmpMap.find(KeyName) == tmpMap.end()) { 0132 *KeyInt = Default; 0133 return -1; 0134 } 0135 0136 string tmpString = tmpMap[KeyName]; 0137 char *endptr; 0138 0139 if (tmpString.find("0x") == tmpString.npos) { 0140 *KeyInt = strtol(tmpString.c_str(), &endptr, 10); 0141 } else { 0142 *KeyInt = strtol(tmpString.c_str(), &endptr, 16); 0143 } 0144 0145 return 0; 0146 } 0147 0148 int KBlocksConfigManager::GetKeyBool(const string &SectionName, const string &KeyName, bool *KeyBool, const bool Default) 0149 { 0150 string tmpValue; 0151 if (GetKeyString(SectionName, KeyName, &tmpValue, "") == -1) { 0152 *KeyBool = Default; 0153 return -1; 0154 } 0155 0156 transform(tmpValue.begin(), tmpValue.end(), tmpValue.begin(), (int(*)(int))tolower); 0157 if (tmpValue.find("true") != tmpValue.npos) { 0158 *KeyBool = true; 0159 } else if (tmpValue.find("false") != tmpValue.npos) { 0160 *KeyBool = false; 0161 } 0162 0163 return 0; 0164 } 0165 0166 int KBlocksConfigManager::SetKeyString(string SectionName, string KeyName, string KeyString) 0167 { 0168 map<int, string> tmpKeyName; 0169 map< string, map< int, string > >::iterator it_keyname; 0170 0171 map<string, string> tmpKeyMap; 0172 map< string, map<string, string> >::iterator it_data; 0173 0174 it_data = stConfigDataTable.find(SectionName); 0175 0176 if (it_data == stConfigDataTable.end()) { 0177 stConfigDataTable.insert(pair< string, map<string, string> >(SectionName, tmpKeyMap)); 0178 stConfigSectionList.insert(pair<int, string>(stConfigSectionList.size() + 1, SectionName)); 0179 stConfigKeyNameList.insert(pair< string, map<int, string> >(SectionName, tmpKeyName)); 0180 } 0181 0182 it_data = stConfigDataTable.find(SectionName); 0183 0184 tmpKeyMap = it_data->second; 0185 0186 if (tmpKeyMap.find(KeyName) == tmpKeyMap.end()) { 0187 it_keyname = stConfigKeyNameList.find(SectionName); 0188 tmpKeyName = it_keyname->second; 0189 tmpKeyName.insert(pair<int, string>(tmpKeyName.size() + 1, KeyName)); 0190 stConfigKeyNameList[SectionName] = tmpKeyName; 0191 0192 tmpKeyMap.insert(pair<string, string>(KeyName, KeyString)); 0193 } else { 0194 tmpKeyMap[KeyName] = KeyString; 0195 } 0196 0197 stConfigDataTable[SectionName] = tmpKeyMap; 0198 0199 return 0; 0200 } 0201 0202 int KBlocksConfigManager::SetKeyInt(string SectionName, string KeyName, int KeyInt) 0203 { 0204 map<int, string> tmpKeyName; 0205 map< string, map< int, string > >::iterator it_keyname; 0206 0207 map<string, string> tmpKeyMap; 0208 map< string, map<string, string> >::iterator it_data; 0209 0210 it_data = stConfigDataTable.find(SectionName); 0211 0212 if (it_data == stConfigDataTable.end()) { 0213 stConfigDataTable.insert(pair< string, map<string, string> >(SectionName, tmpKeyMap)); 0214 stConfigSectionList.insert(pair<int, string>(stConfigSectionList.size() + 1, SectionName)); 0215 stConfigKeyNameList.insert(pair< string, map<int, string> >(SectionName, tmpKeyName)); 0216 } 0217 0218 it_data = stConfigDataTable.find(SectionName); 0219 0220 tmpKeyMap = it_data->second; 0221 string tmpString = int16tostring(KeyInt); 0222 0223 if (tmpKeyMap.find(KeyName) == tmpKeyMap.end()) { 0224 it_keyname = stConfigKeyNameList.find(SectionName); 0225 tmpKeyName = it_keyname->second; 0226 tmpKeyName.insert(pair<int, string>(tmpKeyName.size() + 1, KeyName)); 0227 stConfigKeyNameList[SectionName] = tmpKeyName; 0228 0229 tmpKeyMap.insert(pair<string, string>(KeyName, tmpString)); 0230 } else { 0231 tmpKeyMap[KeyName] = tmpString; 0232 } 0233 0234 stConfigDataTable[SectionName] = tmpKeyMap; 0235 0236 return 0; 0237 } 0238 0239 int KBlocksConfigManager::SetKeyBool(const string &SectionName, const string &KeyName, bool KeyBool) 0240 { 0241 if (KeyBool) { 0242 return SetKeyString(SectionName, KeyName, "true"); 0243 } else { 0244 return SetKeyString(SectionName, KeyName, "false"); 0245 } 0246 } 0247 0248 int KBlocksConfigManager::ParseConfigFile(FILE *fp) 0249 { 0250 map< string, map< string, string > >::iterator it_section; 0251 0252 map<int, string> tmpKeyName; 0253 map< string, map< int, string > >::iterator it_keyname; 0254 0255 map<string, string> tmpKeyMap; 0256 map< string, map< string, string > >::iterator it_data; 0257 0258 stConfigSectionList.clear(); 0259 stConfigKeyNameList.clear(); 0260 stConfigDataTable.clear(); 0261 0262 string curSection = "DefaultSection"; 0263 string curKey = "DefaultKey"; 0264 string curValue = "DefaultValue"; 0265 0266 int lenth; 0267 string tmpString; 0268 char tmpBuff[1024]; 0269 while (fgets(tmpBuff, 1024, fp)) { 0270 switch (tmpBuff[0]) { 0271 case '[': 0272 tmpString = string(tmpBuff); 0273 lenth = tmpString.find(']'); 0274 curSection = tmpString.substr(1, lenth - 1); 0275 0276 it_section = stConfigDataTable.find(curSection); 0277 0278 if (it_section == stConfigDataTable.end()) { 0279 map<string, string> tmpKeyMap; 0280 stConfigDataTable.insert(pair< string, map<string, string> >(curSection, tmpKeyMap)); 0281 0282 map<int, string> tmpKeyName; 0283 stConfigKeyNameList.insert(pair< string, map<int, string> >(curSection, tmpKeyName)); 0284 0285 stConfigSectionList.insert(pair<int, string>(stConfigSectionList.size() + 1, curSection)); 0286 0287 if (isDebug) { 0288 printf("New section loaded <%s>\n", curSection.c_str()); 0289 } 0290 } else { 0291 if (isDebug) { 0292 printf("Existing section updated <%s>\n", curSection.c_str()); 0293 } 0294 } 0295 break; 0296 0297 case '#': 0298 // skip this line 0299 break; 0300 0301 case '\n': 0302 // skip this line 0303 break; 0304 0305 case '\0': 0306 // skip this line 0307 break; 0308 0309 default: 0310 tmpString = string(tmpBuff); 0311 lenth = tmpString.find('='); 0312 curKey = tmpString.substr(0, lenth); 0313 if (tmpString[tmpString.size() - 1] == '\n') { 0314 tmpString[tmpString.size() - 1] = '\0'; 0315 } 0316 curValue = tmpString.substr(lenth + 1); 0317 transform(curValue.begin(), curValue.end(), curValue.begin(), (int(*)(int))tolower); 0318 0319 it_data = stConfigDataTable.find(curSection); 0320 if (it_data == stConfigDataTable.end()) { 0321 stConfigDataTable.insert(pair< string, map<string, string> >(curSection, tmpKeyMap)); 0322 stConfigSectionList.insert(pair<int, string>(stConfigSectionList.size() + 1, curSection)); 0323 stConfigKeyNameList.insert(pair< string, map<int, string> >(curSection, tmpKeyName)); 0324 0325 if (isDebug) { 0326 printf("New section added <%s>\n", curSection.c_str()); 0327 } 0328 } else { 0329 tmpKeyMap = it_data->second; 0330 } 0331 0332 if (tmpKeyMap.find(curKey) == tmpKeyMap.end()) { 0333 it_keyname = stConfigKeyNameList.find(curSection); 0334 tmpKeyName = it_keyname->second; 0335 tmpKeyName.insert(pair<int, string>(tmpKeyName.size() + 1, curKey)); 0336 stConfigKeyNameList[curSection] = tmpKeyName; 0337 0338 if (isDebug) { 0339 printf("New Key & Value loaded <%s=%s> for section <%s>\n", curKey.c_str(), curValue.c_str(), curSection.c_str()); 0340 } 0341 tmpKeyMap.insert(pair<string, string>(curKey, curValue)); 0342 } else { 0343 if (isDebug) { 0344 printf("Existing Key & Value updated <%s=%s> for section <%s>\n", curKey.c_str(), curValue.c_str(), curSection.c_str()); 0345 } 0346 tmpKeyMap[curKey] = curValue; 0347 } 0348 stConfigDataTable[curSection] = tmpKeyMap; 0349 break; 0350 } 0351 } 0352 0353 return 0; 0354 } 0355 0356 int KBlocksConfigManager::ConstructConfigFile(FILE *fp) 0357 { 0358 for (unsigned int i = 1; i < stConfigSectionList.size() + 1; i++) { 0359 string tmpSectionName = stConfigSectionList[i]; 0360 0361 fprintf(fp, "[%s]\n", tmpSectionName.c_str()); 0362 0363 map<int, string> tmpKeyName = stConfigKeyNameList[tmpSectionName]; 0364 map<string, string> tmpKeyMap = stConfigDataTable[tmpSectionName]; 0365 0366 for (unsigned int j = 1; j < tmpKeyName.size() + 1; j++) { 0367 string tmpKeyNameStr = tmpKeyName[j]; 0368 string tmpKeyValueStr = tmpKeyMap[tmpKeyName[j]]; 0369 0370 fprintf(fp, "%s=%s\n", tmpKeyNameStr.c_str(), tmpKeyValueStr.c_str()); 0371 } 0372 } 0373 0374 return 0; 0375 } 0376 0377 string KBlocksConfigManager::int16tostring(int input) 0378 { 0379 string tmpString = ""; 0380 char tmpChar[2] = {0, 0}; 0381 0382 do { 0383 tmpChar[0] = input & 0x0F; 0384 input >>= 4; 0385 if (tmpChar[0] < 10) { 0386 tmpChar[0] += '0'; 0387 } else { 0388 tmpChar[0] += 'a' - 10; 0389 } 0390 tmpString = string(tmpChar) + tmpString; 0391 } while (input != 0); 0392 0393 tmpString = "0x" + tmpString; 0394 0395 return tmpString; 0396 }