Loading...
Searching...
No Matches
configuration_tree.tpp
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#ifndef __BITPIT_CONFIGURATION_TREE_TPP__
25#define __BITPIT_CONFIGURATION_TREE_TPP__
26
27namespace bitpit {
28
29namespace config {
30
31namespace tree {
32
44template<typename Source>
45void readConfiguration(Source &source, SourceFormat format, const std::string &rootName,
46 bool checkVersion, int version, Config *rootConfig)
47{
48 if (!rootConfig) {
49 throw std::runtime_error("config::tree::readConfiguration Null Config tree structure passed");
50 }
51
52 // Read property tree
53 boost::property_tree::ptree propertyTree;
54 if (format == SOURCE_FORMAT_XML) {
55 boost::property_tree::read_xml(source, propertyTree);
56 } else if (format == SOURCE_FORMAT_JSON) {
57 boost::property_tree::read_json(source, propertyTree);
58 }
59
60 // Check if a root node exists
61 bool hasRootNode = hasRootSection(format);
62
63 // Validate root node
64 if (hasRootNode) {
65 // Get the root node
66 auto rootNode = propertyTree.begin();
67
68 // Check if the root name matches the requested one
69 if (rootNode->first != rootName) {
70 throw std::runtime_error("The name of the root element is not \"" + rootName + "\"");
71 }
72
73 // Check if the version matches the requested one
74 if (checkVersion) {
75 try {
76 int fileVersion = rootNode->second.get<int>("<xmlattr>.version");
77 if (fileVersion != version) {
78 throw std::runtime_error("The version of the configuration file is not not \"" + std::to_string(version) + "\"");
79 }
80 } catch (boost::property_tree::ptree_bad_path &error) {
81 BITPIT_UNUSED(error);
82 throw std::runtime_error("Unable to identify the version of the configuration");
83 }
84 }
85 }
86
87 // Read configuration
88 const boost::property_tree::ptree *configTree;
89 if (hasRootNode) {
90 configTree = &(propertyTree.begin()->second);
91 } else {
92 configTree = &propertyTree;
93 }
94
95 importTree(*configTree, rootConfig);
96}
97
109template<typename Destination>
110void writeConfiguration(Destination &destination, SourceFormat format, const std::string &rootName,
111 int version, const Config *rootConfig)
112{
113 if (!rootConfig) {
114 throw std::runtime_error("config::tree::writeConfiguration Null Config tree structure passed");
115 }
116
117 // Check if a root node exists
118 bool hasRootNode = hasRootSection(format);
119
120 // Create an empty property tree
121 boost::property_tree::ptree propertyTree;
122
123 // Create the root node
124 if (hasRootNode) {
125 // Create the root
126 propertyTree.put<std::string>(rootName, "");
127
128 // Get the root node
129 auto rootNode = propertyTree.begin();
130
131 // Add an attribute with version
132 rootNode->second.put<int>("<xmlattr>.version", version);
133 }
134
135 // Export the configuration into the property tree
136 boost::property_tree::ptree *configTree;
137 if (hasRootNode) {
138 configTree = &(propertyTree.begin()->second);
139 } else {
140 configTree = &propertyTree;
141 }
142
143 bool areArraysAllowed = hasArraySupport(format);
144
145 exportTree(*rootConfig, areArraysAllowed, configTree);
146
147 // Write the tree
148 writeTree(destination, format, propertyTree);
149}
150
158template<typename Destination>
159void writeTree(Destination &destination, SourceFormat format, boost::property_tree::ptree &propertyTree)
160{
161 if (format == SOURCE_FORMAT_XML) {
162 boost::property_tree::xml_writer_settings<std::string> settings(' ', 4);
163 write_xml(destination, propertyTree, settings);
164 } else if (format == SOURCE_FORMAT_JSON) {
165 write_json(destination, propertyTree, true);
166 }
167}
168
169}
170
171}
172
173}
174
175#endif
#define BITPIT_UNUSED(variable)
Definition compiler.hpp:63
bool hasArraySupport(SourceFormat format)
bool hasRootSection(SourceFormat format)
--- layout: doxygen_footer ---