Loading...
Searching...
No Matches
configuration_config.cpp
1/*---------------------------------------------------------------------------*\
2*
3* bitpit
4*
5* Copyright (C) 2015-2021 OPTIMAD engineering Srl
6*
7* -------------------------------------------------------------------------
8* License
9* This file is part of bitpit.
10*
11* bitpit is free software: you can redistribute it and/or modify it
12* under the terms of the GNU Lesser General Public License v3 (LGPL)
13* as published by the Free Software Foundation.
14*
15* bitpit is distributed in the hope that it will be useful, but WITHOUT
16* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18* License for more details.
19*
20* You should have received a copy of the GNU Lesser General Public License
21* along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22*
23\*---------------------------------------------------------------------------*/
24
25#include <stdexcept>
26
27#include "configuration_config.hpp"
28
29namespace bitpit {
30
46Config::Config(bool multiSections)
47 : m_multiSections(multiSections),
48 m_options(std::unique_ptr<Options>(new Options())),
49 m_sections(std::unique_ptr<Sections>(new Sections()))
50{
51}
52
59 : m_multiSections(other.m_multiSections),
60 m_options(std::unique_ptr<Options>(new Options(*(other.m_options)))),
61 m_sections(std::unique_ptr<Sections>(new Sections()))
62{
63 for (const auto &entry : *(other.m_sections)) {
64 std::unique_ptr<Config> config = std::unique_ptr<Config>(new Config(*(entry.second)));
65 m_sections->insert(std::make_pair(entry.first, std::move(config)));
66 }
67}
68
75{
76 this->swap(other);
77
78 return *this;
79}
80
87void Config::swap(Config &other)
88{
89 std::swap(m_multiSections, other.m_multiSections);
90 std::swap(m_options, other.m_options);
91 std::swap(m_sections, other.m_sections);
92}
93
94
101{
102 return m_multiSections;
103}
104
111{
112 return m_options->size();
113}
114
120Config::Options & Config::getOptions()
121{
122 return const_cast<Options &>(static_cast<const Config &>(*this).getOptions());
123}
124
130const Config::Options & Config::getOptions() const
131{
132 return *m_options;
133}
134
141bool Config::hasOption(const std::string &key) const
142{
143 return (m_options->count(key) > 0);
144}
145
154const std::string & Config::get(const std::string &key) const
155{
156 return m_options->at(key);
157}
158
170std::string Config::get(const std::string &key, const std::string &fallback) const
171{
172 if (hasOption(key)) {
173 return get(key);
174 } else {
175 return fallback;
176 }
177}
178
185void Config::set(const std::string &key, const std::string &value)
186{
187 (*m_options)[key] = value;
188}
189
196bool Config::removeOption(const std::string &key)
197{
198 return (m_options->erase(key) != 0);
199}
200
207{
208 return m_sections->size();
209}
210
217int Config::getSectionCount(const std::string &key) const
218{
219 return m_sections->count(key);
220}
221
227Config::Sections & Config::getSections()
228{
229 return const_cast<Sections &>(static_cast<const Config &>(*this).getSections());
230}
231
237const Config::Sections & Config::getSections() const
238{
239 return *m_sections;
240}
241
248Config::MultiSection Config::getSections(const std::string &key)
249{
250 MultiSection sections;
251 sections.reserve(getSectionCount(key));
252
253 auto range = m_sections->equal_range(key);
254 for (auto itr = range.first; itr != range.second; ++itr) {
255 sections.push_back(itr->second.get());
256 }
257
258 return sections;
259}
260
267Config::ConstMultiSection Config::getSections(const std::string &key) const
268{
269 ConstMultiSection sections;
270 sections.reserve(getSectionCount(key));
271
272 auto range = m_sections->equal_range(key);
273 for (auto itr = range.first; itr != range.second; ++itr) {
274 sections.push_back(const_cast<const Section *>(itr->second.get()));
275 }
276
277 return sections;
278}
279
286bool Config::hasSection(const std::string &key) const
287{
288 return (getSectionCount(key) > 0);
289}
290
299Config::Section & Config::getSection(const std::string &key)
300{
301 return const_cast<Section &>(static_cast<const Config &>(*this).getSection(key));
302}
303
312const Config::Section & Config::getSection(const std::string &key) const
313{
314 auto sectionItr = m_sections->find(key);
315 if (sectionItr == m_sections->end()) {
316 throw std::runtime_error("The section named \"" + key + "\" does not esists");
317 }
318
319 return *(sectionItr->second);
320}
321
330Config::Section & Config::addSection(const std::string &key)
331{
332 if (!m_multiSections && hasSection(key)) {
333 throw std::runtime_error("A section named \"" + key + "\" already esists");
334 }
335
336 std::unique_ptr<Section> section = std::unique_ptr<Section>(new Section(m_multiSections));
337 auto sectionItr = m_sections->insert(std::make_pair(key, std::move(section)));
338
339 return *(sectionItr->second);
340}
341
348bool Config::removeSection(const std::string &key)
349{
350 return (m_sections->erase(key) != 0);
351}
352
357{
358 m_options->clear();
359 m_sections->clear();
360}
361
370const Config::Section & Config::operator[](const std::string &key) const
371{
372 return getSection(key);
373}
374
383Config::Section & Config::operator[](const std::string &key)
384{
385 return getSection(key);
386}
387
394void Config::dump(std::ostream &out, int indentLevel) const
395{
396 const int INDENT_SIZE = 2;
397
398 std::string padding(INDENT_SIZE, ' ');
399 std::string indent(INDENT_SIZE * indentLevel, ' ');
400
401 out << std::endl;
402 out << indent << "Options..." << std::endl;
403 if (getOptionCount() > 0) {
404 for (const auto &entry : getOptions()) {
405 out << indent << padding << entry.first << " = " << entry.second << std::endl;
406 }
407 } else {
408 out << indent << padding << "No options." << std::endl;
409 }
410
411 ++indentLevel;
412 for (const auto &entry : getSections()) {
413 out << std::endl;
414 out << indent << padding << "::: Section " << entry.first << " :::" << std::endl;
415 entry.second->dump(out, indentLevel);
416 }
417}
418
419}
Configuration storage.
void dump(std::ostream &out, int indentLevel=0) const
const std::string & get(const std::string &key) const
Section & addSection(const std::string &key)
Config & operator=(Config other)
Section & operator[](const std::string &key)
Section & getSection(const std::string &key)
bool hasOption(const std::string &key) const
bool isMultiSectionsEnabled() const
bool hasSection(const std::string &key) const
void swap(Config &other)
void set(const std::string &key, const std::string &value)
bool removeSection(const std::string &key)
bool removeOption(const std::string &key)
Config(bool multiSections=false)
--- layout: doxygen_footer ---