StormByte is a comprehensive, cross-platform C++ library aimed at easing system programming, configuration management, logging, and database handling tasks. This library provides a unified API that abstracts away the complexities and inconsistencies of different platforms (Windows, Linux).
Features
- Configuration Management: Provides an intuitive API for reading and writing configuration files.
- Serialization: Specializations of
StormByte::Util::Serializable
for all items to enable serialization to raw buffers for network sending or binary writing.
Table of Contents
- Repository
- Installation
- Modules
- Contributing
- License
Repository
You can visit the code repository at GitHub
Installation
Prerequisites
Ensure you have the following installed:
- C++23 compatible compiler
- CMake 3.12 or higher
Building
To build the library, follow these steps:
git clone https://github.com/StormBytePP/StormByte-Config.git
cd StormByte-Config
mkdir build
cd build
cmake ..
make
Modules
StormByte Library is composed by several modules:
Config
Overview
The Config
module of StormByte provides a flexible and human-readable way to manage configuration files. It supports initialization from any std::istream
, setting pre and post read hooks using std::function
, handling different data types and managing operation modes when items already exist before addition.
Initialization from <tt>std::istream</tt>
You can initialize the configuration from any std::istream
, including std::fstream
, std::cin
, or even another Config
object.
Example
#include <StormByte/config/config.hxx>
#include <fstream>
#include <iostream>
using namespace StormByte::Config;
int main() {
std::ifstream file("config.cfg");
file >> config;
file.close();
std::cin >> config2;
config2 >> config3;
return 0;
}
Contains type aliases and utilities for configuration handling.
Hooks: Pre and Post Read
You can set pre and post read hooks using std::function
. These hooks allow you to perform actions before and after reading the configuration, with the Config
object passed as a reference argument.
Example
#include <StormByte/config/config.hxx>
#include <iostream>
using namespace StormByte::Config;
std::cout <<
"Pre-read hook executed. Current config has " << root.
Size() <<
" items." << std::endl;
}
std::cout <<
"Post-read hook executed. Current config has " << root.
Size() <<
" items." << std::endl;
}
int main() {
std::ifstream file("config.cfg");
file >> config;
file.close();
return 0;
}
constexpr void AddHookAfterRead(HookFunction hook)
Definition config.hxx:278
constexpr void AddHookBeforeRead(HookFunction hook)
Definition config.hxx:270
constexpr size_t Size() const noexcept
Definition container.hxx:253
Represents a group in a configuration file that can hold other items, subgroups, and sublists recursi...
Definition group.hxx:20
Operation Modes for Existing Items
You can set the operation mode when an item already exists before adding a new one. Operation modes can include replace, ignore, or throw an exception (the default).
Example
#include <StormByte/config/config.hxx>
#include <iostream>
using namespace StormByte::Config;
int main() {
std::ifstream file("config.cfg");
file >> config;
file.close();
return 0;
}
constexpr void OnExistingAction(const OnExistingAction &on_existing)
Definition config.hxx:254
Data Types
The configuration supports various data types, including string, integer, double, comments (singleline and multiline), and containers (list and group).
String
username = "example_user"
Example
#include <StormByte/config/config.hxx>
#include <iostream>
using namespace StormByte::Config;
int main() {
std::ifstream file("config.cfg");
file >> config;
file.close();
std::cout <<
"Username: " << username.
Value<std::string>() << std::endl;
return 0;
}
The base class for all configuration items.
Definition base.hxx:29
const T & Value() const
Definition base.hxx:148
Integer
Example
#include <StormByte/config/config.hxx>
#include <iostream>
using namespace StormByte::Config;
int main() {
std::ifstream file("config.cfg");
file >> config;
file.close();
std::cout <<
"Timeout: " << timeout.
Value<
int>() << std::endl;
return 0;
}
Double
Example
#include <StormByte/config/config.hxx>
#include <iostream>
using namespace StormByte::Config;
int main() {
std::ifstream file("config.cfg");
file >> config;
file.close();
const Item::Base& feature_timeout = config[
"feature_timeout"];
std::cout <<
"Feature Timeout: " << feature_timeout.
Value<
double>() << std::endl;
return 0;
}
Comments
Configuration files can have comments!
Singleline
# Bash like
Bash like comments start with #
until the rest of the line
# C/C++ like
C/C++ like comments start with //
until the rest of the line
Multiline
Multiline comments are enclosed between /*
and */
(like C/C++ style comments)
# This is a single-line comment
/**
* This is a multiline comment
*/
// int = 66; # Which is disabled
Containers
Configuration can have containers with subitems and also subcontainers
List
Lists are sequences of values enclosed in square brackets []
separated by spaces and can contain any other item (including nested lists and groups).
favorite_numbers = [3 14 42 "pi constant"]
# Example
#include <StormByte/config/config.hxx>
#include <iostream>
using namespace StormByte::Config;
int main() {
std::ifstream file("config.cfg");
file >> config;
file.close();
const Item::List& favorite_numbers = config[
"favorite_numbers"].Value<List>();
std::cout << "Favorite Numbers: ";
for (const auto& number : favorite_numbers)
std::cout << (std::string)number << " ";
std::cout << std::endl;
return 0;
}
Represents a list in a configuration file that can hold other items, subgroups, and sublists recursiv...
Definition list.hxx:20
Group
Groups are nested configurations that can contain other key-value pairs, groups, or lists.
settings = {
username = "example_user"
timeout = 30
}
# Example
#include <StormByte/config/config.hxx>
#include <iostream>
using namespace StormByte::Config;
int main() {
std::ifstream file("config.cfg");
file >> config;
file.close();
const Item::Base& username = config[
"settings/username"];
const Item::Base& timeout = config[
"settings/timeout"];
std::cout <<
"Username: " << username.
Value<std::string>() << std::endl;
std::cout <<
"Timeout: " << timeout.
Value<
int>() << std::endl;
return 0;
}
Serialization
The Config
module supports serialization of configuration items to raw buffers, which can be useful for network transmission or binary storage. This is achieved through specializations of StormByte::Util::Serializable
.
Example: Serialize and Deserialize a Configuration
#include <StormByte/config/config.hxx>
#include <StormByte/util/serializable.hxx>
#include <fstream>
#include <iostream>
using namespace StormByte::Config;
int main() {
StormByte::Util::Serializable<Config> serializable(config);
StormByte::Util::Buffer buffer = serializable.Serialize();
auto deserialized_config = StormByte::Util::Serializable<Config>::Deserialize(buffer);
if (!deserialized_config) {
std::cerr << "Failed to deserialize configuration: " << deserialized_config.error()->what() << std::endl;
return 1;
}
const Item::Base& username = deserialized_config.value()[
"username"];
const Item::Base& timeout = deserialized_config.value()[
"timeout"];
std::cout <<
"Username: " << username.
Value<std::string>() << std::endl;
std::cout <<
"Timeout: " << timeout.
Value<
int>() << std::endl;
return 0;
}
Represents a configuration item with a value.
Definition value.hxx:16
Sharing Configuration
There are two options for sharing the configuration:
- Human-readable: Share the configuration as a human-readable text file.
- Binary serialized: Serialize the configuration to a binary format for network transmission or binary storage.
Contributing
Contributions are welcome! Please fork the repository and submit pull requests for any enhancements or bug fixes.
License
This project is licensed under GPL v3 License - see the [LICENSE](LICENSE) file for details.