Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/Rookfighter/inifile-cpp

A header-only and easy to use Ini file parser for C++.
https://github.com/Rookfighter/inifile-cpp

cpp cpp-library ini-parser inifile

Last synced: 3 months ago
JSON representation

A header-only and easy to use Ini file parser for C++.

Awesome Lists containing this project

README

        

# inifile-cpp
![License](https://img.shields.io/packagist/l/doctrine/orm.svg)
[![CMake](https://github.com/Rookfighter/inifile-cpp/workflows/CMake/badge.svg)](https://github.com/Rookfighter/inifile-cpp/actions/workflows/cmake.yml)
[![codecov](https://codecov.io/gh/Rookfighter/inifile-cpp/graph/badge.svg?token=39FL0C8NRK)](https://codecov.io/gh/Rookfighter/inifile-cpp)

```inifile-cpp``` is a simple and easy to use single header-only ini file en- and decoder for C++.

## Install

Install the headers using the CMake build system:

```sh
cd
mkdir build
cd build
cmake ..
make install
```

or simply copy the header file into your project and include it directly.

## Usage

For examples on how to use and extend ```inifile-cpp``` for your custom needs, please have a look at the ```examples/``` directory.

```inifile-cpp``` allows loading data from any ```std::istream``` and requires a
single function call or use the overloaded constructor.

```cpp
#include

int main()
{
// create istream object "is" ...

// use function
ini::IniFile myFirstIni;
myFirstIni.decode(is);

// or use the constructor
ini::IniFile mySecondIni(is);
}
```

You can directly load ini-data from files by using the ```load()``` function. It requires a file path
and automatically parses its contents:

```cpp
#include

int main()
{
// load an ini file
ini::IniFile myIni;
myIni.load("some/ini/path");
}
```

You can enable decoding of multi-line values using the ```setMultiLineValues(true)``` function. If you do this, field values may be continued on the next line, after indentation. Each line will be separated by the `\n` character in the final value, and the indentation will be removed.

```cpp
#include

int main()
{
// load an ini file
ini::IniFile myIni;
myIni.setMultiLineValues(true);
myIni.load("some/ini/path");
}
```

When duplicate fields are decoded the previous value is simply overwritten by default. You can disallow duplicate fields from being overwritten by using the ```allowOverwriteDuplicateFields(false)``` function. If you do this, an exception will be thrown if a duplicate field is found inside a section.

```cpp
#include

int main()
{
// load an ini file
ini::IniFile myIni;
myIni.allowOverwriteDuplicateFields(false);
// throws an exception if the ini file has duplicate fields
myIni.load("some/ini/path");
}
```

Sections and fields can be accessed using the index operator ```[]```.
The values can be converted to various native types:

```cpp
bool myBool = myIni["Foo"]["myBool"].as();
char myChar = myIni["Foo"]["myChar"].as();
unsigned char myUChar = myIni["Foo"]["myUChar"].as();
int myInt = myIni["Foo"]["myInt"].as();
unsigned int myUInt = myIni["Foo"]["myUInt"].as();
long myLong = myIni["Foo"]["myLong"].as();
unsigned long myULong = myIni["Foo"]["myULong"].as();
float myFloat = myIni["Foo"]["myFloat"].as();
double myDouble = myIni["Foo"]["myDouble"].as();
std::string myStr = myIni["Foo"]["myStr"].as();
const char *myStr2 = myIni["Foo"]["myStr"].as();
```

Natively supported types are:

* ```bool```
* ```char```
* ```unsigned char```
* ```short```
* ```unsigned short```
* ```int```
* ```unsigned int```
* ```long```
* ```unsigned long```
* ```float```
* ```double```
* ```std::string```
* ```const char *```
* ```std::string_view```

Custom type conversions can be added by implementing specialized template of the ```ini::Convert``` functor (see examples).

Values can be assigned to ini fileds just by using the assignment operator.
The content of the inifile can then be written to any ```std::ostream``` object.

```cpp
#include

int main()
{
// create ostream object "os" ...

ini::IniFile myIni;

myIni["Foo"]["myInt"] = 1;
myIni["Foo"]["myStr"] = "Hello world";
myIni["Foo"]["myBool"] = true;
myIni["Bar"]["myDouble"] = 1.2;

myIni.encode(os);
}
```

You can directly save ini-data to files by using the ```save()``` function. It requires a file path
and automatically stores the ini file contents:

```cpp
#include

int main()
{
ini::IniFile myIni;

myIni["Foo"]["myInt"] = 1;
myIni["Foo"]["myStr"] = "Hello world";
myIni["Foo"]["myBool"] = true;
myIni["Bar"]["myDouble"] = 1.2;

myIni.save("some/ini/path");
}
```

You can define custom type conversions for inifile-cpp which will be automatically used by the assignment operator and the ```as()``` method of ini fields, e.g. you can add support for ```std::vector``` (see also examples):

```cpp
// the conversion functor must live in the "ini" namespace
namespace ini
{
/** Conversion functor to parse std::vectors from an ini field-
* The generic template can be passed down to the vector. */
template
struct Convert>
{
/** Decodes a std::vector from a string. */
void decode(const std::string &value, std::vector &result)
{
result.clear();

// variable to store the decoded value of each element
T decoded;
// maintain a start and end pos within the string
size_t startPos = 0;
size_t endPos = 0;
size_t cnt;

while(endPos != std::string::npos)
{
if(endPos != 0)
startPos = endPos + 1;
// search for the next comma as separator
endPos = value.find(',', startPos);

// if no comma was found use the rest of the string
// as input
if(endPos == std::string::npos)
cnt = value.size() - startPos;
else
cnt = endPos - startPos;

std::string tmp = value.substr(startPos, cnt);
// use the conversion functor for the type contained in
// the vector, so the vector can use any type that
// is compatible with inifile-cpp
Convert conv;
conv.decode(tmp, decoded);
result.push_back(decoded);

}
}

/** Encodes a std::vector to a string. */
void encode(const std::vector &value, std::string &result)
{
// variable to store the encoded element value
std::string encoded;
// string stream to build the result stream
std::stringstream ss;
for(size_t i = 0; i < value.size(); ++i)
{
// use the conversion functor for the type contained in
// the vector, so the vector can use any type that
// is compatible with inifile-cp
Convert conv;
conv.encode(value[i], encoded);
ss << encoded;

// if this is not the last element add a comma as separator
if(i != value.size() - 1)
ss << ',';
}
// store the created string in the result
result = ss.str();
}
};
}
```

## Contributing

If you want to contribute new features or bug fixes, simply file a pull request.
Make sure all CI checks pass, otherwise PRs will not be merged.

## License

`inifile-cpp` is licensed under the [MIT license](https://github.com/Rookfighter/inifile-cpp/blob/main/LICENSE.txt)