32 #define iniEOL '\r' << endl
42 m_IsCaseInsensitive(true)
59 AString keyname, valuename, value;
60 AString::size_type pLeft, pRight;
61 bool IsFromExampleRedirect =
false;
64 f.open((a_FileName).c_str(), ios::in);
68 if (a_AllowExampleRedirect)
71 AString ExPath(a_FileName.substr(0, a_FileName.length() - 4));
72 ExPath.append(
".example.ini");
73 f.open((ExPath).c_str(), ios::in);
78 IsFromExampleRedirect =
true;
86 bool IsFirstLine =
true;
88 while (getline(f, line))
103 size_t lineLength = line.length();
108 if (line[lineLength - 1] ==
'\r')
110 line = line.substr(0, lineLength - 1);
113 if (line.length() == 0)
120 if (!isprint(line[0]))
122 printf(
"%s: Binary-check failed on char %d\n", __FUNCTION__, line[0]);
126 if ((pLeft = line.find_first_of(
";#[=")) == AString::npos)
136 ((pRight = line.find_last_of(
"]")) != AString::npos) &&
140 keyname = line.substr(pLeft + 1, pRight - pLeft - 1);
148 valuename = line.substr(0, pLeft);
151 AddValue(keyname, valuename, value);
178 if (IsFromExampleRedirect)
197 f.open((a_FileName).c_str(), ios::out);
205 for (
size_t commentID = 0; commentID < NumComments; ++commentID)
215 for (
size_t keyID = 0; keyID <
m_Keys.size(); ++keyID)
220 for (
size_t commentID = 0; commentID <
m_Keys[keyID].m_Comments.size(); ++commentID)
222 f <<
';' <<
m_Keys[keyID].m_Comments[commentID] <<
iniEOL;
226 for (
size_t valueID = 0; valueID <
m_Keys[keyID].m_Names.size(); ++valueID)
228 writevalue =
m_Keys[keyID].m_Values[valueID];
230 f <<
m_Keys[keyID].m_Names[valueID] <<
'=' << writevalue <<
iniEOL;
246 for (
size_t keyID = 0; keyID <
m_Names.size(); ++keyID)
250 return static_cast<int>(keyID);
262 if (!
m_Keys.size() || (keyID >=
static_cast<int>(
m_Keys.size())))
268 for (
size_t valueID = 0; valueID < m_Keys[static_cast<size_t>(keyID)].m_Names.size(); ++valueID)
286 return static_cast<int>(
m_Names.size()) - 1;
295 if (keyID <
static_cast<int>(
m_Names.size()))
297 return m_Names[
static_cast<size_t>(keyID)];
311 if (keyID <
static_cast<int>(
m_Keys.size()))
313 return static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Names.size());
329 return static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Names.size());
338 if ((keyID <
static_cast<int>(
m_Keys.size())) && (valueID <
static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].m_Names.size())))
340 return m_Keys[
static_cast<size_t>(keyID)].
m_Names[
static_cast<size_t>(valueID)];
365 int keyID =
FindKey(a_KeyName);
371 m_Keys[
static_cast<size_t>(keyID)].
m_Names.push_back(a_ValueName);
372 m_Keys[
static_cast<size_t>(keyID)].m_Values.push_back(a_Value);
381 AddValue(a_KeyName, a_ValueName, fmt::format(FMT_STRING(
"{}"), a_Value));
390 AddValue(a_KeyName, a_ValueName, fmt::format(FMT_STRING(
"{}"), a_Value));
399 if ((
static_cast<size_t>(keyID) >=
m_Keys.size()) || (
static_cast<size_t>(valueID) >=
m_Keys[
static_cast<size_t>(keyID)].m_Names.size()))
403 m_Keys[
static_cast<size_t>(keyID)].m_Values[
static_cast<size_t>(valueID)] = value;
413 int keyID =
FindKey(a_KeyName);
416 if (!a_CreateIfNotExists)
423 int valueID =
FindValue(keyID, a_ValueName);
426 if (!a_CreateIfNotExists)
430 m_Keys[
static_cast<size_t>(keyID)].
m_Names.push_back(a_ValueName);
431 m_Keys[
static_cast<size_t>(keyID)].m_Values.push_back(a_Value);
435 m_Keys[
static_cast<size_t>(keyID)].m_Values[
static_cast<size_t>(valueID)] = a_Value;
447 return SetValue(a_KeyName, a_ValueName, fmt::format(FMT_STRING(
"{}"), a_Value), a_CreateIfNotExists);
456 return SetValue(a_Keyname, a_ValueName, fmt::format(FMT_STRING(
"{}"), a_Value), a_CreateIfNotExists);
465 return SetValue(a_KeyName, a_ValueName, fmt::format(FMT_STRING(
"{}"), a_Value), a_CreateIfNotExists);
474 if ((keyID <
static_cast<int>(
m_Keys.size())) && (valueID <
static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].m_Names.size())))
476 return m_Keys[
static_cast<size_t>(keyID)].m_Values[
static_cast<size_t>(valueID)];
493 int valueID =
FindValue(
int(keyID), valuename);
499 return m_Keys[
static_cast<size_t>(keyID)].m_Values[
static_cast<size_t>(valueID)];
508 auto Data = fmt::format(FMT_STRING(
"{}"), defValue);
509 return atoi(
GetValue(keyname, valuename, Data).c_str());
518 auto Data = fmt::format(FMT_STRING(
"{}"), defValue);
519 return atof(
GetValue(keyname, valuename, Data).c_str());
531 SetValue(keyname, valuename, defValue);
535 int valueID =
FindValue(
int(keyID), valuename);
538 SetValue(keyname, valuename, defValue);
542 return m_Keys[
static_cast<size_t>(keyID)].m_Values[
static_cast<size_t>(valueID)];
551 auto Data = fmt::format(FMT_STRING(
"{}"), defValue);
552 return atof(
GetValueSet(keyname, valuename, Data).c_str());
561 auto Data = fmt::format(FMT_STRING(
"{}"), defValue);
562 return atoi(
GetValueSet(keyname, valuename, Data).c_str());
571 auto Data = fmt::format(FMT_STRING(
"{}"), defValue);
573 Int64 result = defValue;
575 sscanf_s(resultstring.c_str(),
"%lld", &result);
577 sscanf(resultstring.c_str(),
"%lld", &result);
588 if ((keyID <
static_cast<int>(
m_Keys.size())) && (valueID <
static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].m_Names.size())))
591 vector<AString>::iterator npos =
m_Keys[
static_cast<size_t>(keyID)].
m_Names.begin() + valueID;
592 vector<AString>::iterator vpos =
m_Keys[
static_cast<size_t>(keyID)].m_Values.begin() + valueID;
593 m_Keys[
static_cast<size_t>(keyID)].
m_Names.erase(npos, npos + 1);
594 m_Keys[
static_cast<size_t>(keyID)].m_Values.erase(vpos, vpos + 1);
612 int valueID =
FindValue(
int(keyID), valuename);
633 vector<AString>::iterator npos =
m_Names.begin() + keyID;
634 vector<key>::iterator kpos =
m_Keys.begin() + keyID;
636 m_Keys.erase(kpos, kpos + 1);
659 int keyID =
FindKey(a_KeyName);
666 int valueID =
FindValue(keyID, a_ValueName);
667 return (valueID !=
noID);
686 if (commentID <
static_cast<int>(
m_Comments.size()))
688 return m_Comments[
static_cast<size_t>(commentID)];
699 if (commentID <
static_cast<int>(
m_Comments.size()))
701 vector<AString>::iterator cpos =
m_Comments.begin() + commentID;
714 if (keyID <
static_cast<int>(
m_Keys.size()))
716 return static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Comments.size());
732 return static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Comments.size());
741 if (keyID <
static_cast<int>(
m_Keys.size()))
743 m_Keys[
static_cast<size_t>(keyID)].
m_Comments.resize(
m_Keys[
static_cast<size_t>(keyID)].m_Comments.size() + 1, comment);
769 if ((keyID <
static_cast<int>(
m_Keys.size())) && (commentID <
static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].m_Comments.size())))
771 return m_Keys[
static_cast<size_t>(keyID)].
m_Comments[
static_cast<size_t>(commentID)];
796 if ((keyID <
static_cast<int>(
m_Keys.size())) && (commentID <
static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].m_Comments.size())))
798 vector<AString>::iterator cpos =
m_Keys[
static_cast<size_t>(keyID)].
m_Comments.begin() + commentID;
825 if (keyID <
static_cast<int>(
m_Keys.size()))
858 size_t len = res.length();
859 for (
size_t i = 0; i < len; i++)
861 res[i] =
static_cast<char>(tolower(res[i]));
873 static unsigned const char BOM[] = { 0xEF, 0xBB, 0xBF };
876 const AString ref = a_line.substr(0, 3);
879 for (
size_t i = 0; i < 3; ++i)
881 if (
static_cast<unsigned char>(ref[i]) != BOM[i])
906 std::vector<std::pair<AString, AString>> ret;
907 int keyID =
FindKey(a_keyName);
912 for (
size_t valueID = 0; valueID < m_Keys[static_cast<size_t>(keyID)].m_Names.size(); ++valueID)
914 ret.emplace_back(
m_Keys[
static_cast<size_t>(keyID)].m_Names[valueID],
m_Keys[
static_cast<size_t>(keyID)].m_Values[valueID]);
926 const AString & a_PortsValueName,
927 const AString & a_OldIPv4ValueName,
928 const AString & a_OldIPv6ValueName,
936 for (
const auto & pair : a_Settings.
GetValues(a_KeyName))
938 if (pair.first != a_PortsValueName)
943 Ports.insert(Ports.end(), temp.begin(), temp.end());
949 AString Ports4 = a_Settings.
GetValue(a_KeyName, a_OldIPv4ValueName, a_DefaultValue);
952 a_Settings.
DeleteValue(a_KeyName, a_OldIPv4ValueName);
953 a_Settings.
DeleteValue(a_KeyName, a_OldIPv6ValueName);
AStringVector ReadUpgradeIniPorts(cSettingsRepositoryInterface &a_Settings, const AString &a_KeyName, const AString &a_PortsValueName, const AString &a_OldIPv4ValueName, const AString &a_OldIPv6ValueName, const AString &a_DefaultValue)
Reads the list of ports from the INI file, possibly upgrading from IPv4 / IPv6-specific values into n...
AStringVector StringSplitAndTrim(const AString &str, const AString &delim)
Split the string at any of the listed delimiters and trim each value.
AString TrimString(const AString &str)
Trims whitespace at both ends of the string.
void ReplaceString(AString &iHayStack, const AString &iNeedle, const AString &iReplaceWith)
Replaces each occurence of iNeedle in iHayStack with iReplaceWith.
AString StringsConcat(const AStringVector &a_Strings, char a_Separator)
Concatenates the specified strings into a single string, separated by the specified separator charact...
AStringVector MergeStringVectors(const AStringVector &a_Strings1, const AStringVector &a_Strings2)
Merges the two vectors of strings, removing duplicate entries from the second vector.
std::vector< AString > AStringVector
AString GetHeaderComment(const int commentID) const
Returns a header comment, or empty string if out of range.
void RemoveBom(AString &a_line) const
Removes the UTF-8 BOMs (Byte order makers), if present.
bool DeleteValueByID(const int keyID, const int valueID)
bool HasValue(const AString &a_KeyName, const AString &a_ValueName) const override
Returns true iff the specified value exists.
int AddKeyName(const AString &keyname) override
Add a key name.
AString GetKeyName(const int keyID) const
bool DeleteKeyComments(const int keyID)
int FindKey(const AString &keyname) const
Returns index of specified key, or noID if not found.
AString GetValue(const AString &keyname, const AString &valuename, const AString &defValue="") const override
Get the value at the specified key and value, returns defValue on failure.
bool WriteFile(const AString &a_FileName) const
Writes data stored in class to the specified ini file.
bool AddKeyComment(const int keyID, const AString &comment)
Add a key comment.
std::vector< AString > m_Comments
int GetNumValues(const AString &keyname) const
bool DeleteValue(const AString &keyname, const AString &valuename) override
Deletes the specified key, value pair.
bool ReadFile(const AString &a_FileName, bool a_AllowExampleRedirect=true)
Reads the contents of the specified ini file If the file doesn't exist and a_AllowExampleRedirect is ...
bool SetValueF(const AString &a_KeyName, const AString &a_ValueName, const double a_Value, const bool a_CreateIfNotExists=true)
virtual bool KeyExists(const AString a_keyName) const override
Returns true iff the specified key exists.
void Clear(void)
Deletes all stored ini data (but doesn't touch the file)
virtual std::vector< std::pair< AString, AString > > GetValues(AString a_keyName) override
returns a vector containing a name, value pair for each value under the key
AString GetValueName(const AString &keyname, const int valueID) const
void AddValue(const AString &a_KeyName, const AString &a_ValueName, const AString &a_Value) override
Adds a new value to the specified key.
int GetValueI(const AString &keyname, const AString &valuename, const int defValue=0) const
bool DeleteKeyComment(const int keyID, const int commentID)
void AddHeaderComment(const AString &comment)
Adds a header comment.
int GetValueSetI(const AString &keyname, const AString &valuename, const int defValue=0) override
bool DeleteKey(const AString &keyname)
cIniFile(void)
Creates a new instance with no data.
void AddValueF(const AString &a_KeyName, const AString &a_ValueName, const double a_Value)
bool SetValueI(const AString &a_KeyName, const AString &a_ValueName, const int a_Value, const bool a_CreateIfNotExists=true) override
bool SetValue(const int keyID, const int valueID, const AString &value)
AString GetValueSet(const AString &keyname, const AString &valuename, const AString &defValue="") override
Gets the value; if not found, write the default to the repository.
std::vector< AString > m_Names
bool DeleteHeaderComment(int commentID)
Deletes a header comment.
void AddValueI(const AString &a_KeyName, const AString &a_ValueName, const int a_Value)
int GetNumKeyComments(const int keyID) const
Get number of key comments.
double GetValueSetF(const AString &keyname, const AString &valuename, const double defValue=0.0)
double GetValueF(const AString &keyname, const AString &valuename, const double defValue=0) const
std::vector< key > m_Keys
AString CheckCase(const AString &s) const
If the object is case-insensitive, returns s as lowercase; otherwise returns s as-is.
int FindValue(const int keyID, const AString &valuename) const
Returns index of specified value, in the specified key, or noID if not found.
AString GetKeyComment(const int keyID, const int commentID) const
Return a key comment.
virtual bool DeleteValue(const AString &keyname, const AString &valuename)=0
Deletes the specified key, value pair.
virtual std::vector< std::pair< AString, AString > > GetValues(AString a_keyName)=0
returns a vector containing a name, value pair for each value under the key
virtual AString GetValue(const AString &keyname, const AString &valuename, const AString &defValue="") const =0
Get the value at the specified key and value, returns defValue on failure.
virtual bool SetValue(const AString &a_KeyName, const AString &a_ValueName, const AString &a_Value, const bool a_CreateIfNotExists=true)=0
Overwrites the value of the key, value pair Specify the optional parameter as false if you do not wan...