Skip to content

Commit

Permalink
Merge pull request #7 from BeardedFish/cpp17
Browse files Browse the repository at this point in the history
Move source code to C++17 and add new features
  • Loading branch information
BeardedFish committed Jan 6, 2022
2 parents 2534d8e + e59c9db commit d742a2b
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 58 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# ini-rw

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

![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.")
![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.")

## Features

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

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

// Insert a pound symbol comment at the top of the loaded INI file
iniFile.insert_comment(inirw::IniCommentPrefix::Pound, "Hello, World!");
Expand Down
Binary file removed images/Banner.png
Binary file not shown.
Binary file added images/ini-rw-banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 16 additions & 16 deletions ini-rw-test/src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ int main(int argc, char* argv[])

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

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

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

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

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

iniFile.write_key_value(sectionName, keyName, keyValue);

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

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)" << ".";
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)" << ".";
}
else
{
std::cout << std::endl << "The key \"" << keyName << "\" under the section \"" << sectionName << "\" was not found in the INI file!";
std::cout << '\n' << "The key \"" << keyName << "\" under the section \"" << sectionName << "\" was not found in the INI file!";
}
}
}
else if (inirw::equals_ignore_case(userInput, "save"))
{
bool success = iniFile.save_changes();

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

if (!exitLoopFlag)
{
std::cout << std::endl << std::endl;
std::cout << '\n' << '\n';
}
}
while (!exitLoopFlag);
}
else
{
std::cout << "An error occured while trying to load the file \"" << argv[1] << "\". Program will now terminate..." << std::endl;
std::cout << "An error occured while trying to load the file \"" << argv[1] << "\". Program will now terminate..." << '\n';
}
}
51 changes: 50 additions & 1 deletion ini-rw/include/IniFile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#pragma once

#include "../include/algorithms/Search.hpp"
#include "entities/IniEntity.hpp"
#include "entities/IniKey.hpp"
#include <string>
Expand All @@ -28,6 +29,8 @@ namespace inirw

operator bool() const;

IniKey* operator[](const char globalKeyName[]);

IniKey* operator[](const std::pair<std::string, std::string>& keyPair);

bool is_loaded() const;
Expand All @@ -50,7 +53,53 @@ namespace inirw

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

void write_key_value(const std::string& sectionName, const std::string& keyName, const std::string& keyValue);
template<typename KeyValueType>
void write_key_value(const std::string& sectionName, const std::string& keyName, const KeyValueType& keyValue)
{
size_t iniKeyIndex = find_ini_key_index(m_iniContents, sectionName, keyName);
std::string keyValueString;

if constexpr (std::is_same<KeyValueType, std::string>::value)
{
keyValueString = keyValue;
}
else if constexpr (std::is_same<KeyValueType, char>::value)
{
keyValueString = std::string(1, keyValue);
}
else
{
keyValueString = std::to_string(keyValue);
}

if (iniKeyIndex != INI_NOT_FOUND)
{
static_cast<IniKey*>(m_iniContents[iniKeyIndex])->ValueCommentPair.set_value(keyValueString);
}
else
{
size_t sectionIndex = find_ini_section_index(m_iniContents, sectionName);

if (sectionIndex != INI_NOT_FOUND)
{
m_iniContents.insert(m_iniContents.begin() + sectionIndex + 1, new IniKey(static_cast<IniSection*>(m_iniContents[sectionIndex]), keyName, keyValueString));
}
else
{
if (!m_iniContents.empty())
{
m_iniContents.insert(m_iniContents.end(), new IniValueCommentPair("\n"));
}

IniSection* iniSection = new IniSection(sectionName);

m_iniContents.insert(m_iniContents.end(), iniSection);
m_iniContents.insert(m_iniContents.end(), new IniKey(iniSection, keyName, keyValueString));
}
}
}

IniKey* get_key(const std::string& keyName, bool isKeyGlobal = true);

IniKey* get_key(const std::string& sectionName, const std::string& keyName);
};
Expand Down
6 changes: 4 additions & 2 deletions ini-rw/include/algorithms/Search.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ namespace inirw
{
constexpr size_t INI_NOT_FOUND = std::numeric_limits<size_t>::max();

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

size_t get_section_location(std::vector<IniEntity*>& iniContents, const std::string& sectionName);
size_t find_ini_key_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName, const std::string& keyName);

size_t find_ini_section_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName);
}
2 changes: 2 additions & 0 deletions ini-rw/include/entities/IniSection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ namespace inirw

std::string get_name() const;

void set_name(const std::string& name);

void set_leading_whitespace(const std::string& whitespace);
private:
bool is_whitespace(const std::string& str);
Expand Down
4 changes: 4 additions & 0 deletions ini-rw/ini-rw.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -102,6 +103,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -116,6 +118,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -130,6 +133,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand Down
53 changes: 19 additions & 34 deletions ini-rw/src/IniFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ namespace inirw
return is_loaded();
}

IniKey* IniFile::operator[](const char globalKeyName[])
{
std::string globalKeyNameCppString = std::string(globalKeyName);
size_t keyIndex = find_ini_key_index(m_iniContents, globalKeyNameCppString, true);

return keyIndex != INI_NOT_FOUND
? static_cast<IniKey*>(m_iniContents[keyIndex])
: nullptr;
}

IniKey* IniFile::operator[](const std::pair<std::string, std::string>& keyPair)
{
return get_key(keyPair.first, keyPair.second);
Expand Down Expand Up @@ -204,47 +214,22 @@ namespace inirw
m_iniContents.insert(INSERT_POS, new IniValueCommentPair(COMMENT));
}

void IniFile::write_key_value(const std::string& sectionName, const std::string& keyName, const std::string& keyValue)
IniKey* IniFile::get_key(const std::string& keyName, bool isKeyGlobal)
{
size_t iniKeyIndex = find_key_index(m_iniContents, sectionName, keyName);

if (iniKeyIndex != INI_NOT_FOUND)
{
static_cast<IniKey*>(m_iniContents[iniKeyIndex])->ValueCommentPair.set_value(keyValue);
}
else
{
size_t sectionIndex = get_section_location(m_iniContents, sectionName);

if (sectionIndex != INI_NOT_FOUND)
{
m_iniContents.insert(m_iniContents.begin() + sectionIndex + 1, new IniKey(static_cast<IniSection*>(m_iniContents[sectionIndex]), keyName, keyValue));
}
else
{
if (!m_iniContents.empty())
{
m_iniContents.insert(m_iniContents.end(), new IniValueCommentPair("\n"));
}

IniSection* iniSection = new IniSection(sectionName);
size_t iniKeyIndex = find_ini_key_index(m_iniContents, keyName, isKeyGlobal);

m_iniContents.insert(m_iniContents.end(), iniSection);
m_iniContents.insert(m_iniContents.end(), new IniKey(iniSection, keyName, keyValue));
}
}
return iniKeyIndex != INI_NOT_FOUND
? static_cast<IniKey*>(m_iniContents[iniKeyIndex])
: nullptr;
}

IniKey* IniFile::get_key(const std::string& sectionName, const std::string& keyName)
{
size_t iniKeyIndex = find_key_index(m_iniContents, sectionName, keyName);

if (iniKeyIndex != INI_NOT_FOUND)
{
return static_cast<IniKey*>(m_iniContents[iniKeyIndex]);
}
size_t iniKeyIndex = find_ini_key_index(m_iniContents, sectionName, keyName);

return nullptr;
return iniKeyIndex != INI_NOT_FOUND
? static_cast<IniKey*>(m_iniContents[iniKeyIndex])
: nullptr;
}

std::ostream& operator<<(std::ostream& outputStream, const IniFile& iniFile)
Expand Down
29 changes: 27 additions & 2 deletions ini-rw/src/algorithms/Search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,32 @@
#include "../../include/algorithms/Validation.hpp"
#include "../../include/entities/IniSection.hpp"

size_t inirw::find_key_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName, const std::string& keyName)
size_t inirw::find_ini_key_index(std::vector<IniEntity*>& iniContents, const std::string& keyName, const bool& isKeyGlobal)
{
for (size_t i = 0; i < iniContents.size(); i++)
{
if (iniContents[i]->get_type() != IniEntityType::Key)
{
continue;
}

IniKey* key = static_cast<IniKey*>(iniContents[i]);

if (isKeyGlobal && key->get_section())
{
continue;
}

if (equals_ignore_case(key->get_name(), keyName))
{
return i;
}
}

return INI_NOT_FOUND;
}

size_t inirw::find_ini_key_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName, const std::string& keyName)
{
for (size_t i = 0; i < iniContents.size(); i++)
{
Expand All @@ -26,7 +51,7 @@ size_t inirw::find_key_index(std::vector<IniEntity*>& iniContents, const std::st
return INI_NOT_FOUND;
}

size_t inirw::get_section_location(std::vector<IniEntity*>& iniContents, const std::string& sectionName)
size_t inirw::find_ini_section_index(std::vector<IniEntity*>& iniContents, const std::string& sectionName)
{
for (size_t i = 0; i < iniContents.size(); i++)
{
Expand Down
5 changes: 5 additions & 0 deletions ini-rw/src/entities/IniSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ namespace inirw
return m_name;
}

void IniSection::set_name(const std::string& name)
{
m_name = name;
}

void IniSection::set_leading_whitespace(const std::string& whitespace)
{
if (!is_whitespace(whitespace))
Expand Down

0 comments on commit d742a2b

Please sign in to comment.