Skip to content

Commit d742a2b

Browse files
authored
Merge pull request #7 from BeardedFish/cpp17
Move source code to C++17 and add new features
2 parents 2534d8e + e59c9db commit d742a2b

File tree

11 files changed

+132
-58
lines changed

11 files changed

+132
-58
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# ini-rw
22

3-
![Programming language](https://img.shields.io/badge/programming%20language-c%2B%2B11-blue)
3+
![Programming language](https://img.shields.io/badge/programming%20language-c%2B%2B17-blue)
44
![Licence](https://img.shields.io/github/license/BeardedFish/ini-rw)
55
![Code size](https://img.shields.io/github/languages/code-size/BeardedFish/ini-rw)
66
![Contributors](https://img.shields.io/github/contributors/BeardedFish/ini-rw)
77

8-
![ini-rw: A .ini reader/writer library programmed in C++11.](images/Banner.png "ini-rw: A .ini reader/writer library programmed in C++11.")
8+
![ini-rw: A .ini file reader and writer library programmed in C++17.](images/ini-rw-banner.png "ini-rw: A .ini file reader and writer library programmed in C++17.")
99

1010
## Features
1111

@@ -43,7 +43,9 @@ int main()
4343
std::cout << "The INI key was not found.\n";
4444
}
4545

46-
iniFile.write_key_value("App", "library_name", "ini-rw");
46+
iniFile.write_key_value<std::string>("library", "name", "ini-rw");
47+
iniFile.write_key_value<int>("library", "cpp_standard", 17);
48+
iniFile.write_key_value<bool>("library", "is_open_source", true);
4749

4850
// Insert a pound symbol comment at the top of the loaded INI file
4951
iniFile.insert_comment(inirw::IniCommentPrefix::Pound, "Hello, World!");

images/Banner.png

-413 KB
Binary file not shown.

images/ini-rw-banner.png

69.5 KB
Loading

ini-rw-test/src/Main.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ int main(int argc, char* argv[])
2424

2525
if (argc <= 1)
2626
{
27-
std::cerr << "Invalid amount of parameters." << std::endl;
28-
std::cerr << "Usage: " << (argc == 0 ? "[EXECUTABLE_NAME]" : argv[0]) << " [INI_FILE_PATH]" << std::endl;
27+
std::cerr << "Invalid amount of parameters." << '\n';
28+
std::cerr << "Usage: " << (argc == 0 ? "[EXECUTABLE_NAME]" : argv[0]) << " [INI_FILE_PATH]" << '\n';
2929

3030
return EXIT_FAILURE;
3131
}
@@ -34,8 +34,8 @@ int main(int argc, char* argv[])
3434

3535
if (iniFile) // Alternatively, you could do "iniFile.is_loaded()"
3636
{
37-
std::cout << "The INI file \"" << argv[1] << "\" was loaded successfully!" << std::endl << std::endl;
38-
std::cout << "Type \"help\" for a list of commands." << std::endl << std::endl;
37+
std::cout << "The INI file \"" << argv[1] << "\" was loaded successfully!" << '\n' << '\n';
38+
std::cout << "Type \"help\" for a list of commands." << '\n' << '\n';
3939

4040
bool exitLoopFlag = false;
4141
std::string userInput;
@@ -55,7 +55,7 @@ int main(int argc, char* argv[])
5555
{
5656
iniFile.clear();
5757

58-
std::cout << "The INI file contents were cleared succesfully!";
58+
std::cout << "The INI file contents were cleared successfully!";
5959
}
6060
else if (inirw::equals_ignore_case(userInput, "contents"))
6161
{
@@ -65,11 +65,11 @@ int main(int argc, char* argv[])
6565
}
6666
else if (inirw::equals_ignore_case(userInput, "help"))
6767
{
68-
std::cout << "clrini - Clears the loaded INI file contents." << std::endl;
69-
std::cout << "contents - Prints the contents of the loaded INI file." << std::endl;
70-
std::cout << "help - Prints a list of valid commands for this program." << std::endl;
71-
std::cout << "iv - Inserts a value to the INI file." << std::endl;
72-
std::cout << "rs - Reads a string from the loaded INI file." << std::endl;
68+
std::cout << "clrini - Clears the loaded INI file contents." << '\n';
69+
std::cout << "contents - Prints the contents of the loaded INI file." << '\n';
70+
std::cout << "help - Prints a list of valid commands for this program." << '\n';
71+
std::cout << "iv - Inserts a value to the INI file." << '\n';
72+
std::cout << "rs - Reads a string from the loaded INI file." << '\n';
7373
std::cout << "save - Saves the contents of the INI file to the location it was loaded from.";
7474
}
7575
else if (inirw::equals_ignore_case(userInput, "iv") || inirw::equals_ignore_case(userInput, "rs"))
@@ -89,7 +89,7 @@ int main(int argc, char* argv[])
8989

9090
iniFile.write_key_value(sectionName, keyName, keyValue);
9191

92-
std::cout << std::endl << "Value written succesfully!";
92+
std::cout << '\n' << "Value written succesfully!";
9393
}
9494
else // Read string value from INI file
9595
{
@@ -99,19 +99,19 @@ int main(int argc, char* argv[])
9999
{
100100
const inirw::IniValueCommentPair VALUE_COMMENT_PAIR = key->ValueCommentPair;
101101

102-
std::cout << std::endl << "The extracted value for the key \"" << keyName << "\" under the section \"" << sectionName << "\" is: \"" << VALUE_COMMENT_PAIR.get_value(true) << "\" (\"" << VALUE_COMMENT_PAIR.get_value() << "\" with leading and trailing whitespace)" << ".";
102+
std::cout << '\n' << "The extracted value for the key \"" << keyName << "\" under the section \"" << sectionName << "\" is: \"" << VALUE_COMMENT_PAIR.get_value(true) << "\" (\"" << VALUE_COMMENT_PAIR.get_value() << "\" with leading and trailing whitespace)" << ".";
103103
}
104104
else
105105
{
106-
std::cout << std::endl << "The key \"" << keyName << "\" under the section \"" << sectionName << "\" was not found in the INI file!";
106+
std::cout << '\n' << "The key \"" << keyName << "\" under the section \"" << sectionName << "\" was not found in the INI file!";
107107
}
108108
}
109109
}
110110
else if (inirw::equals_ignore_case(userInput, "save"))
111111
{
112112
bool success = iniFile.save_changes();
113113

114-
std::cout << (success ? "The INI file was saved succesfully!" : "An error occured while trying to save the INI file.");
114+
std::cout << (success ? "The INI file was saved successfully!" : "An error occured while trying to save the INI file.");
115115
}
116116
else
117117
{
@@ -126,13 +126,13 @@ int main(int argc, char* argv[])
126126

127127
if (!exitLoopFlag)
128128
{
129-
std::cout << std::endl << std::endl;
129+
std::cout << '\n' << '\n';
130130
}
131131
}
132132
while (!exitLoopFlag);
133133
}
134134
else
135135
{
136-
std::cout << "An error occured while trying to load the file \"" << argv[1] << "\". Program will now terminate..." << std::endl;
136+
std::cout << "An error occured while trying to load the file \"" << argv[1] << "\". Program will now terminate..." << '\n';
137137
}
138138
}

ini-rw/include/IniFile.hpp

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#pragma once
66

7+
#include "../include/algorithms/Search.hpp"
78
#include "entities/IniEntity.hpp"
89
#include "entities/IniKey.hpp"
910
#include <string>
@@ -28,6 +29,8 @@ namespace inirw
2829

2930
operator bool() const;
3031

32+
IniKey* operator[](const char globalKeyName[]);
33+
3134
IniKey* operator[](const std::pair<std::string, std::string>& keyPair);
3235

3336
bool is_loaded() const;
@@ -50,7 +53,53 @@ namespace inirw
5053

5154
void insert_comment(const size_t& index, const IniCommentPrefix& prefix, const std::string& text);
5255

53-
void write_key_value(const std::string& sectionName, const std::string& keyName, const std::string& keyValue);
56+
template<typename KeyValueType>
57+
void write_key_value(const std::string& sectionName, const std::string& keyName, const KeyValueType& keyValue)
58+
{
59+
size_t iniKeyIndex = find_ini_key_index(m_iniContents, sectionName, keyName);
60+
std::string keyValueString;
61+
62+
if constexpr (std::is_same<KeyValueType, std::string>::value)
63+
{
64+
keyValueString = keyValue;
65+
}
66+
else if constexpr (std::is_same<KeyValueType, char>::value)
67+
{
68+
keyValueString = std::string(1, keyValue);
69+
}
70+
else
71+
{
72+
keyValueString = std::to_string(keyValue);
73+
}
74+
75+
if (iniKeyIndex != INI_NOT_FOUND)
76+
{
77+
static_cast<IniKey*>(m_iniContents[iniKeyIndex])->ValueCommentPair.set_value(keyValueString);
78+
}
79+
else
80+
{
81+
size_t sectionIndex = find_ini_section_index(m_iniContents, sectionName);
82+
83+
if (sectionIndex != INI_NOT_FOUND)
84+
{
85+
m_iniContents.insert(m_iniContents.begin() + sectionIndex + 1, new IniKey(static_cast<IniSection*>(m_iniContents[sectionIndex]), keyName, keyValueString));
86+
}
87+
else
88+
{
89+
if (!m_iniContents.empty())
90+
{
91+
m_iniContents.insert(m_iniContents.end(), new IniValueCommentPair("\n"));
92+
}
93+
94+
IniSection* iniSection = new IniSection(sectionName);
95+
96+
m_iniContents.insert(m_iniContents.end(), iniSection);
97+
m_iniContents.insert(m_iniContents.end(), new IniKey(iniSection, keyName, keyValueString));
98+
}
99+
}
100+
}
101+
102+
IniKey* get_key(const std::string& keyName, bool isKeyGlobal = true);
54103

55104
IniKey* get_key(const std::string& sectionName, const std::string& keyName);
56105
};

ini-rw/include/algorithms/Search.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ namespace inirw
1414
{
1515
constexpr size_t INI_NOT_FOUND = std::numeric_limits<size_t>::max();
1616

17-
size_t find_key_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName, const std::string& keyName);
17+
size_t find_ini_key_index(std::vector<IniEntity*>& iniContents, const std::string& keyName, const bool& isKeyGlobal);
1818

19-
size_t get_section_location(std::vector<IniEntity*>& iniContents, const std::string& sectionName);
19+
size_t find_ini_key_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName, const std::string& keyName);
20+
21+
size_t find_ini_section_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName);
2022
}

ini-rw/include/entities/IniSection.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ namespace inirw
2929

3030
std::string get_name() const;
3131

32+
void set_name(const std::string& name);
33+
3234
void set_leading_whitespace(const std::string& whitespace);
3335
private:
3436
bool is_whitespace(const std::string& str);

ini-rw/ini-rw.vcxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
<SDLCheck>true</SDLCheck>
8989
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
9090
<ConformanceMode>true</ConformanceMode>
91+
<LanguageStandard>stdcpp17</LanguageStandard>
9192
</ClCompile>
9293
<Link>
9394
<SubSystem>Console</SubSystem>
@@ -102,6 +103,7 @@
102103
<SDLCheck>true</SDLCheck>
103104
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
104105
<ConformanceMode>true</ConformanceMode>
106+
<LanguageStandard>stdcpp17</LanguageStandard>
105107
</ClCompile>
106108
<Link>
107109
<SubSystem>Console</SubSystem>
@@ -116,6 +118,7 @@
116118
<SDLCheck>true</SDLCheck>
117119
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
118120
<ConformanceMode>true</ConformanceMode>
121+
<LanguageStandard>stdcpp17</LanguageStandard>
119122
</ClCompile>
120123
<Link>
121124
<SubSystem>Console</SubSystem>
@@ -130,6 +133,7 @@
130133
<SDLCheck>true</SDLCheck>
131134
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
132135
<ConformanceMode>true</ConformanceMode>
136+
<LanguageStandard>stdcpp17</LanguageStandard>
133137
</ClCompile>
134138
<Link>
135139
<SubSystem>Console</SubSystem>

ini-rw/src/IniFile.cpp

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ namespace inirw
6363
return is_loaded();
6464
}
6565

66+
IniKey* IniFile::operator[](const char globalKeyName[])
67+
{
68+
std::string globalKeyNameCppString = std::string(globalKeyName);
69+
size_t keyIndex = find_ini_key_index(m_iniContents, globalKeyNameCppString, true);
70+
71+
return keyIndex != INI_NOT_FOUND
72+
? static_cast<IniKey*>(m_iniContents[keyIndex])
73+
: nullptr;
74+
}
75+
6676
IniKey* IniFile::operator[](const std::pair<std::string, std::string>& keyPair)
6777
{
6878
return get_key(keyPair.first, keyPair.second);
@@ -204,47 +214,22 @@ namespace inirw
204214
m_iniContents.insert(INSERT_POS, new IniValueCommentPair(COMMENT));
205215
}
206216

207-
void IniFile::write_key_value(const std::string& sectionName, const std::string& keyName, const std::string& keyValue)
217+
IniKey* IniFile::get_key(const std::string& keyName, bool isKeyGlobal)
208218
{
209-
size_t iniKeyIndex = find_key_index(m_iniContents, sectionName, keyName);
210-
211-
if (iniKeyIndex != INI_NOT_FOUND)
212-
{
213-
static_cast<IniKey*>(m_iniContents[iniKeyIndex])->ValueCommentPair.set_value(keyValue);
214-
}
215-
else
216-
{
217-
size_t sectionIndex = get_section_location(m_iniContents, sectionName);
218-
219-
if (sectionIndex != INI_NOT_FOUND)
220-
{
221-
m_iniContents.insert(m_iniContents.begin() + sectionIndex + 1, new IniKey(static_cast<IniSection*>(m_iniContents[sectionIndex]), keyName, keyValue));
222-
}
223-
else
224-
{
225-
if (!m_iniContents.empty())
226-
{
227-
m_iniContents.insert(m_iniContents.end(), new IniValueCommentPair("\n"));
228-
}
229-
230-
IniSection* iniSection = new IniSection(sectionName);
219+
size_t iniKeyIndex = find_ini_key_index(m_iniContents, keyName, isKeyGlobal);
231220

232-
m_iniContents.insert(m_iniContents.end(), iniSection);
233-
m_iniContents.insert(m_iniContents.end(), new IniKey(iniSection, keyName, keyValue));
234-
}
235-
}
221+
return iniKeyIndex != INI_NOT_FOUND
222+
? static_cast<IniKey*>(m_iniContents[iniKeyIndex])
223+
: nullptr;
236224
}
237225

238226
IniKey* IniFile::get_key(const std::string& sectionName, const std::string& keyName)
239227
{
240-
size_t iniKeyIndex = find_key_index(m_iniContents, sectionName, keyName);
241-
242-
if (iniKeyIndex != INI_NOT_FOUND)
243-
{
244-
return static_cast<IniKey*>(m_iniContents[iniKeyIndex]);
245-
}
228+
size_t iniKeyIndex = find_ini_key_index(m_iniContents, sectionName, keyName);
246229

247-
return nullptr;
230+
return iniKeyIndex != INI_NOT_FOUND
231+
? static_cast<IniKey*>(m_iniContents[iniKeyIndex])
232+
: nullptr;
248233
}
249234

250235
std::ostream& operator<<(std::ostream& outputStream, const IniFile& iniFile)

ini-rw/src/algorithms/Search.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,32 @@
66
#include "../../include/algorithms/Validation.hpp"
77
#include "../../include/entities/IniSection.hpp"
88

9-
size_t inirw::find_key_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName, const std::string& keyName)
9+
size_t inirw::find_ini_key_index(std::vector<IniEntity*>& iniContents, const std::string& keyName, const bool& isKeyGlobal)
10+
{
11+
for (size_t i = 0; i < iniContents.size(); i++)
12+
{
13+
if (iniContents[i]->get_type() != IniEntityType::Key)
14+
{
15+
continue;
16+
}
17+
18+
IniKey* key = static_cast<IniKey*>(iniContents[i]);
19+
20+
if (isKeyGlobal && key->get_section())
21+
{
22+
continue;
23+
}
24+
25+
if (equals_ignore_case(key->get_name(), keyName))
26+
{
27+
return i;
28+
}
29+
}
30+
31+
return INI_NOT_FOUND;
32+
}
33+
34+
size_t inirw::find_ini_key_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName, const std::string& keyName)
1035
{
1136
for (size_t i = 0; i < iniContents.size(); i++)
1237
{
@@ -26,7 +51,7 @@ size_t inirw::find_key_index(std::vector<IniEntity*>& iniContents, const std::st
2651
return INI_NOT_FOUND;
2752
}
2853

29-
size_t inirw::get_section_location(std::vector<IniEntity*>& iniContents, const std::string& sectionName)
54+
size_t inirw::find_ini_section_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName)
3055
{
3156
for (size_t i = 0; i < iniContents.size(); i++)
3257
{

0 commit comments

Comments
 (0)