std::map<String, String> CIniOptionsMgr::Load(const String& iniFilePath)
{
std::map<String, String> iniFileKeyValues = ReadIniFile(iniFilePath, lpAppName);
- std::vector<tchar_t> str(65536);
-
- // after reading the "WinMerge" section try to read the "Defaults" section; overwrite existing entries in "iniFileKeyValues" with the ones from the "Defaults" section
- if (GetPrivateProfileSection(lpDefaultSection, str.data(), static_cast<DWORD>(str.size()), iniFilePath.c_str()) > 0)
- {
- const tchar_t* p = str.data();
- while (*p)
- {
- const tchar_t* v = tc::tcschr(p, '=');
- if (!v)
- break;
- ++v;
- size_t vlen = tc::tcslen(v);
- String value{ v, v + vlen };
- String key{ p, v - 1 };
- iniFileKeyValues.insert_or_assign(key, UnescapeValue(value));
- p = v + vlen + 1;
- }
- }
+ // after reading the "WinMerge" section try to read the "Defaults" section; overwrite existing entries in "iniFileKeyValues" with the ones from the "Defaults" section
+ std::map<String, String> iniFileKeyDefaultValues = ReadIniFile(iniFilePath, lpDefaultSection);
+ for (auto& [key, strValue] : iniFileKeyDefaultValues)
+ iniFileKeyValues.insert_or_assign(key, strValue);
return iniFileKeyValues;
}
int COptionsMgr::ImportOptions(const String& filename)
{
int retVal = COption::OPT_OK;
- const int BufSize = 65536; // This should be enough for a long time..
- std::vector<tchar_t> buf(BufSize);
auto oleTranslateColor = [](unsigned color) -> unsigned { return ((color & 0xffffff00) == 0x80000000) ? GetSysColor(color & 0x000000ff) : color; };
// Query keys - returns NUL separated strings
- DWORD len = GetPrivateProfileString(_T("WinMerge"), nullptr, _T(""), buf.data(), BufSize, filename.c_str());
- if (len == 0)
+ auto iniFileKeyValues = ReadIniFile(filename, _T("WinMerge"));
+ if (iniFileKeyValues.empty())
return COption::OPT_NOTFOUND;
- tchar_t *pKey = buf.data();
- while (*pKey != '\0')
+ for (auto& [key, strValue] : iniFileKeyValues)
{
- varprop::VariantValue value = Get(pKey);
+ varprop::VariantValue value = Get(key);
if (value.GetType() == varprop::VT_BOOL)
{
- bool boolVal = GetPrivateProfileInt(_T("WinMerge"), pKey, 0, filename.c_str()) == 1;
- value.SetBool(boolVal);
+ value.SetBool(tc::ttoi(strValue.c_str()) != 0);
}
else if (value.GetType() == varprop::VT_INT)
{
- int intVal = GetPrivateProfileInt(_T("WinMerge"), pKey, 0, filename.c_str());
- if (strutils::makelower(pKey).find(String(_T("color"))) != std::string::npos)
+ tchar_t* endptr = nullptr;
+ unsigned uval = static_cast<unsigned>(tc::tcstoll(strValue.c_str(), &endptr,
+ (strValue.length() >= 2 && strValue[1] == 'x') ? 16 : 10));
+ int intVal = static_cast<int>(uval);
+ if (strutils::makelower(key).find(String(_T("color"))) != std::string::npos)
intVal = static_cast<int>(oleTranslateColor(static_cast<unsigned>(intVal)));
value.SetInt(intVal);
}
else if (value.GetType() == varprop::VT_STRING)
{
- tchar_t strVal[MAX_PATH_FULL] = {0};
- GetPrivateProfileString(_T("WinMerge"), pKey, _T(""), strVal, MAX_PATH_FULL, filename.c_str());
- String sVal = UnescapeValue(strVal);
- value.SetString(sVal);
+ value.SetString(strValue);
}
if (value.GetType() != varprop::VT_NULL)
- SaveOption(pKey, value);
-
- pKey += tc::tcslen(pKey);
-
- // Check: pointer is not past string end, and next char is not null
- // double NUL char ends the keynames string
- if ((pKey < buf.data() + len) && (*(pKey + 1) != '\0'))
- pKey++;
+ SaveOption(key, value);
}
FlushOptions();
return retVal;
value.SetBool(tc::ttoi(strValue.c_str()) != 0);
else if (tc::tcsicmp(strType.c_str(), _T("int")) == 0)
{
- auto lval = tc::tcstoll(strValue.c_str(), nullptr, 10);
- value.SetInt(static_cast<int>(lval));
+ tchar_t* endptr = nullptr;
+ unsigned uval = static_cast<unsigned>(tc::tcstoll(strValue.c_str(), &endptr,
+ (strValue.length() >= 2 && strValue[1] == 'x') ? 16 : 10));
+ value.SetInt(static_cast<int>(uval));
}
else if (tc::tcsicmp(strType.c_str(), _T("string")) == 0)
- value.SetString(UnescapeValue(strValue));
+ value.SetString(strValue);
SaveValueToReg(hKey, strValueName, value);
CloseKey(hKey, strPath);
}