CCSDSPack
C++ Library for CCSDS Space Packet manipulation. i.e. generation, extraction, analisys and more
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Private Member Functions | Private Attributes | List of all members
Config Class Reference

Parses and stores config values from custom file format. More...

#include <CCSDSConfig.h>

Public Types

using ConfigValue = std::variant< std::string, int, float, bool, std::vector< uint8_t > >
 

Public Member Functions

CCSDS::ResultBool load (const std::string &filename)
 Load config file.
 
template<typename T >
CCSDS::Result< T > get (const std::string &key) const
 Get value by key and type.
 
bool isKey (const std::string &key) const
 

Static Private Member Functions

static std::tuple< std::string, std::string, std::string > parseLine (const std::string &line)
 Parse a single line from config.
 
static CCSDS::ResultBuffer parseBytes (const std::string &valueStr)
 Parse string "[1,2,3]" into vector<uint8_t>
 

Private Attributes

std::unordered_map< std::string, ConfigValuevalues
 

Detailed Description

Parses and stores config values from custom file format.

Definition at line 11 of file CCSDSConfig.h.

Member Typedef Documentation

◆ ConfigValue

using Config::ConfigValue = std::variant<std::string, int, float, bool, std::vector<uint8_t> >

Definition at line 13 of file CCSDSConfig.h.

Member Function Documentation

◆ get()

template<typename T >
CCSDS::Result< T > Config::get ( const std::string &  key) const
inline

Get value by key and type.

Definition at line 20 of file CCSDSConfig.h.

20 {
21 auto it = values.find(key);
22 RET_IF_ERR_MSG(it == values.end(), CCSDS::ErrorCode::NO_DATA,"Config: No data found for key: " + key);
23
24 if (const auto* p = std::get_if<T>(&it->second)) {
25 return *p;
26 }
27 return CCSDS::Error{ CCSDS::ErrorCode::INVALID_DATA, "Config: Wrong type for key: " + key};
28 }
#define RET_IF_ERR_MSG(condition, errorCode, message)
Macro to return an error with an error message if a condition is met.
Represents an error with both an error code and a message.
Definition CCSDSResult.h:44
std::unordered_map< std::string, ConfigValue > values
Definition CCSDSConfig.h:33
CCSDS::Result< T > get(const std::string &key) const
Get value by key and type.
Definition CCSDSConfig.h:20
@ NO_DATA
No data available.
Definition CCSDSResult.h:23
@ INVALID_DATA
Data is invalid.
Definition CCSDSResult.h:24
Here is the caller graph for this function:

◆ isKey()

bool Config::isKey ( const std::string &  key) const

Definition at line 48 of file CCSDSConfig.cpp.

48 {
49 if (values.find(key) != values.end()) {
50 return true;
51 }
52 return false;
53}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ load()

CCSDS::ResultBool Config::load ( const std::string &  filename)

Load config file.

Definition at line 12 of file CCSDSConfig.cpp.

12 {
13 std::ifstream file(filename);
14 RET_IF_ERR_MSG(!file.is_open(),CCSDS::ErrorCode::CONFIG_FILE_ERROR, "Failed to open configuration file");
15
16 std::string line;
17 while (std::getline(file, line)) {
18 if (line.empty() || line.front() == '#') continue;
19
20 auto [key, type, valueStr] = parseLine(line);
21 RET_IF_ERR_MSG(key.empty() || type.empty(),CCSDS::ErrorCode::CONFIG_FILE_ERROR, "Failed to parse configuration file");
22 ConfigValue value;
23 if (type == "string") {
24 value = valueStr;
25 } else if (type == "int") {
26 std::uint8_t base = 10;
27 if (valueStr.size() > 2 && valueStr.substr(0, 2) == "0x") {
28 valueStr = valueStr.substr(2);
29 base = 16;
30 }
31 value = std::stoi(valueStr, nullptr, base);
32 } else if (type == "float") {
33 value = std::stof(valueStr);
34 } else if (type == "bool") {
35 value = (valueStr == "true" || valueStr == "1");
36 } else if (type == "bytes") {
37 ASSIGN_CP( value, parseBytes(valueStr) );
38 } else {
39 return CCSDS::Error{CCSDS::ErrorCode::CONFIG_FILE_ERROR, " unknown type: " + type};
40 }
41
42 values[key] = value;
43 }
44
45 return true;
46}
#define ASSIGN_CP(var, result)
Macro to assign a result value to a variable or return an error by copy.
std::variant< std::string, int, float, bool, std::vector< uint8_t > > ConfigValue
Definition CCSDSConfig.h:13
static CCSDS::ResultBuffer parseBytes(const std::string &valueStr)
Parse string "[1,2,3]" into vector<uint8_t>
static std::tuple< std::string, std::string, std::string > parseLine(const std::string &line)
Parse a single line from config.
@ CONFIG_FILE_ERROR
Configuration file error.
Definition CCSDSResult.h:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseBytes()

CCSDS::ResultBuffer Config::parseBytes ( const std::string &  valueStr)
staticprivate

Parse string "[1,2,3]" into vector<uint8_t>

Definition at line 72 of file CCSDSConfig.cpp.

72 {
73 std::vector<uint8_t> result{};
74 RET_IF_ERR_MSG(valueStr.empty() || valueStr.front() != '[' || valueStr.back() != ']',
76 "Config: Invalid buffer formatting []");
77
78 if (valueStr == "[]" || valueStr == "[ ]") {
79 return result;
80 }
81
82 // Strip surrounding [ ... ]
83 std::string inner = valueStr.substr(1, valueStr.size() - 2);
84 std::stringstream ss(inner);
85 std::string token;
86
87 while (std::getline(ss, token, ',')) {
88 // Remove all spaces inside each token
89 token.erase(std::remove_if(token.begin(), token.end(),
90 [](unsigned char c){ return std::isspace(c); }),
91 token.end());
92
93 // Empty token after trimming is invalid (e.g., "[12, ,34]")
94 if (token.empty()) {
95 return CCSDS::Error{CCSDS::ErrorCode::CONFIG_FILE_ERROR, "Invalid byte value: <empty>"};
96 }
97
98 std::uint8_t base = 10;
99 std::string_view sv{token};
100
101 // Allow 0x / 0X prefix for hex
102 if (sv.size() > 2 && sv[0] == '0' && (sv[1] == 'x' || sv[1] == 'X')) {
103 sv.remove_prefix(2);
104 base = 16;
105 if (sv.empty()) {
106 return CCSDS::Error{CCSDS::ErrorCode::CONFIG_FILE_ERROR, "Invalid byte value: 0x"};
107 }
108 }
109
110 // Parse without exceptions
111 std::uint8_t tmp = 0;
112 const char* first = sv.data();
113 const char* last = sv.data() + sv.size();
114 auto res = std::from_chars(first, last, tmp, base);
115
116 // Valid if parsed ok, consumed all characters, and fits in a byte
117 if (res.ec != std::errc{} || res.ptr != last || tmp > 0xFFu) {
119 std::string("Invalid byte value: ") + std::string(token)};
120 }
121 result.push_back(static_cast<uint8_t>(tmp));
122 }
123
124 return result;
125}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseLine()

std::tuple< std::string, std::string, std::string > Config::parseLine ( const std::string &  line)
staticprivate

Parse a single line from config.

Definition at line 55 of file CCSDSConfig.cpp.

55 {
56 auto colonPos = line.find(':');
57 auto equalPos = line.find('=');
58
59 if (colonPos == std::string::npos || equalPos == std::string::npos || equalPos < colonPos)
60 return {"", "", ""};
61
62 std::string key = line.substr(0, colonPos);
63 std::string type = line.substr(colonPos + 1, equalPos - colonPos - 1);
64 std::string value = line.substr(equalPos + 1);
65
66 if (!value.empty() && value.front() == '"' && value.back() == '"')
67 value = value.substr(1, value.size() - 2);
68
69 return {key, type, value};
70}
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ values

std::unordered_map<std::string, ConfigValue> Config::values
private

Definition at line 33 of file CCSDSConfig.h.


The documentation for this class was generated from the following files: