Newer
Older
#include <Yaml_Conf.h>
#include <fstream>
#include <filesystem>
#include <algorithm>
#include <iterator>
#include <cctype>
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
using namespace inaf::oasbo::Configurators;
YamlConfigurator::YamlConfigurator(std::string path) {
this->path = path;
load(path);
}
void YamlConfigurator::load(std::string path) {
if (!std::filesystem::exists(path)) {
std::cerr << "Yaml Configurator error: file: " << path
<< " does not exits." << std::endl;
return;
}
file = YAML::LoadFile(path);
if (file.IsNull()) {
std::cerr << "Yaml Configurator error: empty file." << std::endl;
}
if (!file.IsSequence()) {
std::cerr
<< "Yaml Configurator error: file does not contains a yaml sequence."
<< std::endl;
}
}
/**
* Aggiorna il file di configurazione YAML inserendo nuove voci di configurazione per la chiave target.
* Rimuove anche le vecchie configurazioni corrispondenti alla chiave target.
*
* @param target La chiave di destinazione per la quale aggiungere e rimuovere le voci di configurazione.
*/
int YamlConfigurator::pushConfigToSource(std::string target) {
boost::to_lower(target);
// Extracrs only target entries
std::map<std::string, std::string> filteredMap;
for (const auto &pair : this->config) {
if (pair.first.compare(0, target.length(),
target) == 0) {
std::string key = pair.first.substr(target.length() + 1);
boost::to_lower(key);
filteredMap[key] = pair.second;
}
}
// save the file content in a vector
std::fstream ifile(path);
std::vector<std::string> file_content;
std::string line;
while (std::getline(ifile, line)) {
file_content.push_back(line);
}
ifile.close();
// update the file content into the vector
size_t pos = 0;
for (; pos < file_content.size(); pos++) {
if (file_content[pos].find(std::string("- ").append(target))
!= std::string::npos) {
for (auto pair : filteredMap) {
pos += 1;
std::string new_line(" " + pair.first + ": " + pair.second);
auto insertionPoint = file_content.begin() + pos;
file_content.insert(insertionPoint, new_line);
}
pos += 1;
break;
}
}
// remove the old configuration
for (; pos < file_content.size(); pos++) {
if (file_content[pos][0] != '-') {
line = file_content[pos];
// Elimina gli spazi vuoti all'inizio della stringa e Ferma l'analisi al carattere ":" escluso
line = line.erase(0, line.find_first_not_of(' ')).substr(0,
line.find(':'));
boost::to_lower(line);
bool found = false; // Controlla se la riga è stata sostituita dalla nuova conf
for (auto key : filteredMap) {
if (key.first.compare(line) == 0) {
found = true;
break;
}
}
if (found) {
file_content.erase(file_content.begin() + pos);
pos--;
}
} else
break;
}
// update the file with the content of the vector
std::ofstream ofile(path, std::ofstream::trunc); // Open the file in truncation mode
for (const auto &line : file_content) {
ofile << line << std::endl;
}
ofile.close();
load(path);
return 1;
}
int YamlConfigurator::pushConfigToSource() {
// estraggo tutti i target e li inserisco nel vector
std::vector<std::string> tagets;
for (const auto &pair : config) {
std::string key = pair.first;
size_t pos = key.find('_');
if (pos != std::string::npos) {
std::string prefix = key.substr(0, pos);
if (std::find(tagets.begin(), tagets.end(), prefix)
== tagets.end()) {
tagets.push_back(prefix);
}
}
}
// chiamo la funzione per ogni target.
for (auto target : tagets)
pushConfigToSource(target);
return 1;
}
int YamlConfigurator::readConfigFromSource(std::string target) {
boost::to_lower(target);
if (file.IsNull())
return -1;
try {
for (auto element : file) {
if (element[target]) {
YAML::Node node = element[target];
for (const auto &kvp : node) {
config[target + "_" + kvp.first.as<std::string>()] =
kvp.second.as<std::string>();
}
}
}
} catch (const YAML::Exception &e) {
std::cerr << "Yaml Configurator reading error:: " << e.what()
<< std::endl;
return -1;
}
return 1;
}
int YamlConfigurator::readConfigFromSource() {
if (file.IsNull())
return -1;
try {
// Itera sugli elementi del documento YAML
for (const auto &element : file) {
for (const auto &pair : element) {
std::string elementName = element.first.as<std::string>();
boost::to_lower(elementName);
// Se l'elemento è una mappa, estrai le chiavi e i valori
if (pair.second.IsMap()) {
for (const auto &subPair : pair.second) {
std::string key = elementName + "_"
+ subPair.first.as<std::string>();
std::string value = subPair.second.as<std::string>();
config[key] = value;
}
}
}
}
} catch (const YAML::Exception &e) {
std::cerr << "Yaml Configurator reading error:: " << e.what()
<< std::endl;
return -1;
}
return 1;
}
int YamlConfigurator::insert(std::map<std::string, std::string> conf,
std::string target) {
boost::to_lower(target);
for (const auto &kvp : conf) {
this->config[target + "_" + kvp.first] = kvp.second;
}
return 1;
}