32 #define iniEOL '\r' << endl 42 m_IsCaseInsensitive(true)
59 AString keyname, valuename, value;
60 AString::size_type pLeft, pRight;
61 bool IsFromExampleRedirect =
false;
68 if (a_AllowExampleRedirect)
71 AString ExPath(a_FileName.substr(0, a_FileName.length() - 4));
72 ExPath.append(
".example.ini");
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);
150 AddValue(keyname, valuename, value);
177 if (IsFromExampleRedirect)
203 for (
size_t commentID = 0; commentID < NumComments; ++commentID)
213 for (
size_t keyID = 0; keyID <
m_Keys.size(); ++keyID)
218 for (
size_t commentID = 0; commentID <
m_Keys[keyID].m_Comments.size(); ++commentID)
220 f <<
';' <<
m_Keys[keyID].m_Comments[commentID] <<
iniEOL;
224 for (
size_t valueID = 0; valueID <
m_Keys[keyID].m_Names.size(); ++valueID)
226 f <<
m_Keys[keyID].m_Names[valueID] <<
'=' <<
m_Keys[keyID].m_Values[valueID] <<
iniEOL;
242 for (
size_t keyID = 0; keyID <
m_Names.size(); ++keyID)
246 return static_cast<int>(keyID);
258 if (!
m_Keys.size() || (keyID >=
static_cast<int>(
m_Keys.size())))
264 for (
size_t valueID = 0; valueID < m_Keys[static_cast<size_t>(keyID)].
m_Names.size(); ++valueID)
282 return static_cast<int>(
m_Names.size()) - 1;
291 if (keyID < static_cast<int>(
m_Names.size()))
293 return m_Names[
static_cast<size_t>(keyID)];
307 if (keyID < static_cast<int>(
m_Keys.size()))
309 return static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Names.size());
325 return static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Names.size());
334 if ((keyID < static_cast<int>(
m_Keys.size())) && (valueID < static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Names.size())))
336 return m_Keys[
static_cast<size_t>(keyID)].
m_Names[static_cast<size_t>(valueID)];
361 int keyID =
FindKey(a_KeyName);
367 m_Keys[
static_cast<size_t>(keyID)].
m_Names.push_back(a_ValueName);
368 m_Keys[
static_cast<size_t>(keyID)].m_Values.push_back(a_Value);
395 if ((static_cast<size_t>(keyID) >=
m_Keys.size()) || (static_cast<size_t>(valueID) >=
m_Keys[
static_cast<size_t>(keyID)].
m_Names.size()))
399 m_Keys[
static_cast<size_t>(keyID)].m_Values[static_cast<size_t>(valueID)] = value;
409 int keyID =
FindKey(a_KeyName);
412 if (!a_CreateIfNotExists)
419 int valueID =
FindValue(keyID, a_ValueName);
422 if (!a_CreateIfNotExists)
426 m_Keys[
static_cast<size_t>(keyID)].
m_Names.push_back(a_ValueName);
427 m_Keys[
static_cast<size_t>(keyID)].m_Values.push_back(a_Value);
431 m_Keys[
static_cast<size_t>(keyID)].m_Values[static_cast<size_t>(valueID)] = a_Value;
443 return SetValue(a_KeyName, a_ValueName,
Printf(
"%d", a_Value), a_CreateIfNotExists);
452 return SetValue(a_Keyname, a_ValueName,
Printf(
"%lld", a_Value), a_CreateIfNotExists);
461 return SetValue(a_KeyName, a_ValueName,
Printf(
"%f", a_Value), a_CreateIfNotExists);
470 if ((keyID < static_cast<int>(
m_Keys.size())) && (valueID < static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Names.size())))
472 return m_Keys[
static_cast<size_t>(keyID)].m_Values[static_cast<size_t>(valueID)];
489 int valueID =
FindValue(
int(keyID), valuename);
495 return m_Keys[
static_cast<size_t>(keyID)].m_Values[static_cast<size_t>(valueID)];
505 Printf(Data,
"%d", defValue);
506 return atoi(
GetValue(keyname, valuename, Data).c_str());
516 Printf(Data,
"%f", defValue);
517 return atof(
GetValue(keyname, valuename, Data).c_str());
529 SetValue(keyname, valuename, defValue);
533 int valueID =
FindValue(
int(keyID), valuename);
536 SetValue(keyname, valuename, defValue);
540 return m_Keys[
static_cast<size_t>(keyID)].m_Values[static_cast<size_t>(valueID)];
550 Printf(Data,
"%f", defValue);
551 return atof(
GetValueSet(keyname, valuename, Data).c_str());
561 Printf(Data,
"%d", defValue);
562 return atoi(
GetValueSet(keyname, valuename, Data).c_str());
572 Printf(Data,
"%lld", defValue);
574 Int64 result = defValue;
576 sscanf_s(resultstring.c_str(),
"%lld", &result);
578 sscanf(resultstring.c_str(),
"%lld", &result);
589 if ((keyID < static_cast<int>(
m_Keys.size())) && (valueID < static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Names.size())))
592 vector<AString>::iterator npos =
m_Keys[
static_cast<size_t>(keyID)].
m_Names.begin() + valueID;
593 vector<AString>::iterator vpos =
m_Keys[
static_cast<size_t>(keyID)].m_Values.begin() + valueID;
594 m_Keys[
static_cast<size_t>(keyID)].
m_Names.erase(npos, npos + 1);
595 m_Keys[
static_cast<size_t>(keyID)].m_Values.erase(vpos, vpos + 1);
613 int valueID =
FindValue(
int(keyID), valuename);
634 vector<AString>::iterator npos =
m_Names.begin() + keyID;
635 vector<key>::iterator kpos =
m_Keys.begin() + keyID;
637 m_Keys.erase(kpos, kpos + 1);
660 int keyID =
FindKey(a_KeyName);
667 int valueID =
FindValue(keyID, a_ValueName);
668 return (valueID !=
noID);
687 if (commentID < static_cast<int>(
m_Comments.size()))
689 return m_Comments[
static_cast<size_t>(commentID)];
700 if (commentID < static_cast<int>(
m_Comments.size()))
702 vector<AString>::iterator cpos =
m_Comments.begin() + commentID;
715 if (keyID < static_cast<int>(
m_Keys.size()))
717 return static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Comments.size());
733 return static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Comments.size());
742 if (keyID < static_cast<int>(
m_Keys.size()))
744 m_Keys[
static_cast<size_t>(keyID)].
m_Comments.resize(
m_Keys[static_cast<size_t>(keyID)].m_Comments.size() + 1, comment);
770 if ((keyID < static_cast<int>(
m_Keys.size())) && (commentID < static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Comments.size())))
772 return m_Keys[
static_cast<size_t>(keyID)].
m_Comments[static_cast<size_t>(commentID)];
797 if ((keyID < static_cast<int>(
m_Keys.size())) && (commentID < static_cast<int>(
m_Keys[
static_cast<size_t>(keyID)].
m_Comments.size())))
799 vector<AString>::iterator cpos =
m_Keys[
static_cast<size_t>(keyID)].
m_Comments.begin() + commentID;
826 if (keyID < static_cast<int>(
m_Keys.size()))
859 size_t len = res.length();
860 for (
size_t i = 0; i < len; i++)
862 res[i] =
static_cast<char>(tolower(res[i]));
874 static unsigned const char BOM[] = { 0xEF, 0xBB, 0xBF };
877 const AString ref = a_line.substr(0, 3);
880 for (
size_t i = 0; i < 3; ++i)
882 if (static_cast<unsigned char>(ref[i]) != BOM[i])
907 std::vector<std::pair<AString, AString>> ret;
908 int keyID =
FindKey(a_keyName);
913 for (
size_t valueID = 0; valueID < m_Keys[static_cast<size_t>(keyID)].
m_Names.size(); ++valueID)
915 ret.emplace_back(
m_Keys[static_cast<size_t>(keyID)].
m_Names[valueID],
m_Keys[static_cast<size_t>(keyID)].m_Values[valueID]);
927 const AString & a_PortsValueName,
928 const AString & a_OldIPv4ValueName,
929 const AString & a_OldIPv6ValueName,
937 for (
auto pair : a_Settings.
GetValues(a_KeyName))
939 if (pair.first != a_PortsValueName)
944 Ports.insert(Ports.end(), temp.begin(), temp.end());
950 AString Ports4 = a_Settings.
GetValue(a_KeyName, a_OldIPv4ValueName, a_DefaultValue);
953 a_Settings.
DeleteValue(a_KeyName, a_OldIPv4ValueName);
954 a_Settings.
DeleteValue(a_KeyName, a_OldIPv6ValueName);
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...
bool DeleteKeyComments(const int keyID)
double GetValueSetF(const AString &keyname, const AString &valuename, const double defValue=0.0)
void AddValueI(const AString &a_KeyName, const AString &a_ValueName, const int a_Value)
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 StringsConcat(const AStringVector &a_Strings, char a_Separator)
Concatenates the specified strings into a single string, separated by the specified separator charact...
virtual bool DeleteValue(const AString &keyname, const AString &valuename)=0
Deletes the specified key, value pair.
int GetValueI(const AString &keyname, const AString &valuename, const int defValue=0) const
int GetNumValues(const AString &keyname) const
bool DeleteKey(const AString &keyname)
void AddValueF(const AString &a_KeyName, const AString &a_ValueName, const double a_Value)
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 DeleteKeyComment(const int keyID, const int commentID)
virtual bool KeyExists(const AString a_keyName) const override
Returns true iff the specified key exists.
std::vector< AString > m_Names
std::vector< AString > AStringVector
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.
int FindKey(const AString &keyname) const
Returns index of specified key, or noID if not found.
AString GetKeyComment(const int keyID, const int commentID) const
Return a key comment.
bool WriteFile(const AString &a_FileName) const
Writes data stored in class to the specified ini file.
bool SetValue(const int keyID, const int valueID, const AString &value)
AStringVector StringSplitAndTrim(const AString &str, const AString &delim)
Split the string at any of the listed delimiters and trim each value.
bool DeleteValue(const AString &keyname, const AString &valuename) override
Deletes the specified key, value pair.
bool SetValueF(const AString &a_KeyName, const AString &a_ValueName, const double a_Value, const bool a_CreateIfNotExists=true)
AString & Printf(AString &str, const char *format, fmt::ArgList args)
Output the formatted text into the string.
void AddHeaderComment(const AString &comment)
Adds a header comment.
void Clear(void)
Deletes all stored ini data (but doesn't touch the file)
AString GetHeaderComment(const int commentID) const
Returns a header comment, or empty string if out of range.
AString GetValueName(const AString &keyname, const int valueID) const
std::vector< AString > m_Comments
AString GetKeyName(const int keyID) const
int GetNumKeyComments(const int keyID) const
Get number of key comments.
int FindValue(const int keyID, const AString &valuename) const
Returns index of specified value, in the specified key, or noID if not found.
AString CheckCase(const AString &s) const
If the object is case-insensitive, returns s as lowercase; otherwise returns s as-is.
int AddKeyName(const AString &keyname) override
Add a key name.
AString TrimString(const AString &str)
Trims whitespace at both ends of the string.
bool DeleteValueByID(const int keyID, const int valueID)
double GetValueF(const AString &keyname, const AString &valuename, const double defValue=0) const
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
bool SetValueI(const AString &a_KeyName, const AString &a_ValueName, const int a_Value, const bool a_CreateIfNotExists=true) override
void AddValue(const AString &a_KeyName, const AString &a_ValueName, const AString &a_Value) override
Adds a new value to the specified key.
int GetValueSetI(const AString &keyname, const AString &valuename, const int defValue=0) override
bool DeleteHeaderComment(int commentID)
Deletes a header comment.
void RemoveBom(AString &a_line) const
Removes the UTF-8 BOMs (Byte order makers), if present.
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...
std::vector< key > m_Keys
bool HasValue(const AString &a_KeyName, const AString &a_ValueName) const override
Returns true iff the specified value exists.
AStringVector MergeStringVectors(const AStringVector &a_Strings1, const AStringVector &a_Strings2)
Merges the two vectors of strings, removing duplicate entries from the second vector.
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 AddKeyComment(const int keyID, const AString &comment)
Add a key comment.
cIniFile(void)
Creates a new instance with no data.
AString GetValueSet(const AString &keyname, const AString &valuename, const AString &defValue="") override
Gets the value; if not found, write the default to the repository.