1 // This is brl/bpro/bprb/bprb_parameters.cxx
2 #include <utility>
3 #include <iostream>
4 #include "bprb_parameters.h"
5 //:
6 // \file
7
8 #ifdef _MSC_VER
9 # include "vcl_msvc_warnings.h"
10 #endif
11 #include <bxml/bxml_read.h>
12 #include <bxml/bxml_find.h>
13 #include <bxml/bxml_write.h>
14
15 //: Output stream operator for bprb_params
operator <<(std::ostream & os,const bprb_param & p)16 std::ostream& operator<<(std::ostream& os, const bprb_param& p)
17 {
18 os << "parameter{\n Description: " << p.description();
19 if (p.has_bounds())
20 os << "\n Range: " << p.min_str() << " to " << p.max_str();
21 os << "\n Default: " << p.default_str()
22 << "\n Value: " << p.value_str() << "\n}\n";
23
24 return os;
25 }
26
27 //==============================================================================
28
29 //: Constructor
30 bprb_parameters::bprb_parameters()
31 = default;
32
33
34 //: Destructor
~bprb_parameters()35 bprb_parameters::~bprb_parameters()
36 {
37 for (auto & it : param_list_) {
38 delete it;
39 }
40 }
41
42 //: Deep copy constructor
bprb_parameters(const bprb_parameters_sptr & old_params)43 bprb_parameters::bprb_parameters(const bprb_parameters_sptr& old_params)
44 {
45 for (auto & it : old_params->param_list_) {
46
47 //deep copy this param
48 bprb_param * new_param = it->clone();
49
50 param_list_.push_back( new_param );
51 name_param_map_.insert( std::pair< std::string , bprb_param* >( new_param->name() , new_param ) );
52 }
53 }
54
55
56 //: Returns true if a parameter exists with \p flag
57 bool
valid_parameter(const std::string & name) const58 bprb_parameters::valid_parameter( const std::string& name ) const
59 {
60 auto itr = name_param_map_.find( name );
61 return itr != name_param_map_.end();
62 }
63
64
65 //: reads the parameters and their values from an XML document
66 // It assumes the following XML format
67 // <ProcessName>
68 // <param1 type="" desc="" value=""/>
69 // <param2 type="" desc="" value=""/>
70 // .
71 // .
72 // </ProcessName>
parse_XML(const std::string & xml_path,const std::string & root_tag)73 bool bprb_parameters::parse_XML(const std::string& xml_path,
74 const std::string& root_tag)
75 {
76 // open the XML document
77 if (xml_path.size() == 0) {
78 std::cout << "bprb_parameters::parse_XML -- xml file path is not set" << std::endl;
79 return false;
80 }
81
82 bxml_document xml_doc_ = bxml_read(xml_path);
83 if (!xml_doc_.root_element()) {
84 std::cout << "bprb_parameters::parse_XML -- xml root not found" << std::endl;
85 return false;
86 }
87
88 if (xml_doc_.root_element()->type() != bxml_data::ELEMENT) {
89 std::cout << "bprb_parameters::parse_XML params root is not ELEMENT" << std::endl;
90 return false;
91 }
92
93 bxml_data_sptr root;
94 // if the root tag is not defined, used the document root, else find the element
95 if (root_tag.size() == 0)
96 //root = static_cast<bxml_element*> (xml_doc_.root_element().as_pointer());
97 root = xml_doc_.root_element();
98 else {
99 bxml_element query(root_tag);
100 //root = static_cast<bxml_element*> (bxml_find_by_name(xml_doc_.root_element(), query).as_pointer());
101 root = bxml_find_by_name(xml_doc_.root_element(), query);
102 if (!root) {
103 std::cout << "bprb_parameters::parse_XML root tag: " << root_tag << " is not found" << std::endl;
104 return false;
105 }
106 }
107
108 // iterate over he elements and find out their types
109 auto* h_elm = static_cast<bxml_element*>(root.ptr());
110 for (auto i = h_elm->data_begin(); i != h_elm->data_end(); ++i) {
111 bxml_data_sptr elm = *i;
112 if (elm->type() == bxml_data::ELEMENT) {
113 auto* param = static_cast<bxml_element*> (elm.as_pointer());
114 if (param) {
115 std::string value = param->attribute("value");
116 std::string type = param->attribute("type");
117 std::string desc = param->attribute("desc");
118 bprb_param* p=nullptr;
119 if (!type.compare("float")) {
120 p = new bprb_param_type<float>(param->name(), desc, 0);
121 } else if ( (!type.compare("unsigned int")) || (!type.compare("unsigned")) ) {
122 p = new bprb_param_type<unsigned>(param->name(), desc, 0);
123 } else if (!type.compare("int")) {
124 p = new bprb_param_type<int>(param->name(), desc, 0);
125 } else if (!type.compare("string")) {
126 p = new bprb_param_type<std::string>(param->name(), desc, "");
127 } else if (!type.compare("bool")) {
128 p = new bprb_param_type<bool>(param->name(), desc, false);
129 } else if (!type.compare("double")) {
130 p = new bprb_param_type<double>(param->name(), desc, false);
131 } else {
132 std::cerr << "Parsing Error: Unknown parameter type \"" << type << "\"" << std::endl;
133 continue; // maybe should abort and return false here?
134 }
135 p->parse_value_str(value);
136 param_list_.push_back(p);
137 name_param_map_[p->name()] = p;
138 }
139 }
140 }
141
142 return true;
143 }
144
145 //: prints the default parameter values to an XML document
print_def_XML(const std::string & root_tag,const std::string & xml_path)146 void bprb_parameters::print_def_XML(const std::string& root_tag,
147 const std::string& xml_path)
148 {
149 bxml_element* root = new bxml_element(root_tag);
150 root->append_text("\n");
151 // iterate over each parameter, and get the default ones
152 for (auto & it : param_list_) {
153 std::string name = it->name();
154 std::string def_value = it->default_str();
155 bxml_element* param_elem = new bxml_element(name);
156 param_elem->set_attribute("type", it->type_str());
157 param_elem->set_attribute("desc", it->description());
158 param_elem->set_attribute("value", def_value);
159 root->append_data(param_elem);
160 root->append_text("\n");
161 }
162 bxml_document doc;
163 doc.set_root_element(root);
164 bxml_write(xml_path, doc);
165 }
166
167 //: prints the currently used parameter values to an XML document
print_current_XML(const std::string & root_tag,const std::string & xml_path)168 void bprb_parameters::print_current_XML(const std::string& root_tag,
169 const std::string& xml_path)
170 {
171 bxml_element* root = new bxml_element(root_tag);
172 root->append_text("\n");
173 // iterate over each parameter, and get the default ones
174 for (auto & it : param_list_) {
175 std::string name = it->name();
176 std::string value = it->value_str();
177 bxml_element* param_elem = new bxml_element(name);
178 param_elem->set_attribute("type", it->type_str());
179 param_elem->set_attribute("desc", it->description());
180 param_elem->set_attribute("value", value);
181 root->append_data(param_elem);
182 root->append_text("\n");
183 }
184 bxml_document doc;
185 doc.set_root_element(root);
186 bxml_write(xml_path, doc);
187 }
188
189 //: Reset all parameters to their default values
190 bool
reset_all()191 bprb_parameters::reset_all()
192 {
193 for (auto & it : param_list_) {
194 it->reset();
195 }
196 return true;
197 }
198
199
200 //: Reset the parameter named \p name to its default value
201 bool
reset(const std::string & name)202 bprb_parameters::reset( const std::string& name )
203 {
204 auto it = name_param_map_.find( name );
205 if ( it == name_param_map_.end() ) {
206 return false;
207 }
208
209 it->second->reset();
210
211 return true;
212 }
213
214
215 //: Return a vector of base class pointers to the parameters
216 std::vector< bprb_param* >
get_param_list() const217 bprb_parameters::get_param_list() const
218 {
219 return param_list_;
220 }
221
222
223 //: Return the description of the parameter named \p name
224 std::string
get_desc(const std::string & name) const225 bprb_parameters::get_desc( const std::string& name ) const
226 {
227 auto it = name_param_map_.find( name );
228 if ( it == name_param_map_.end() ) {
229 return "";
230 }
231 return it->second->description();
232 }
233
234
235 //: Print all parameters to \p os
236 void
print_all(std::ostream & os) const237 bprb_parameters::print_all(std::ostream& os) const
238 {
239 for (auto it : param_list_) {
240 os << it;
241 }
242 }
243
244
245 //: Add parameter helper function
246 bool
add(bprb_param * param)247 bprb_parameters::add( bprb_param* param )
248 {
249 if ( !param )
250 return false;
251 std::string name = param->name();
252 std::string desc = param->description();
253 if ( name_param_map_.find( name ) != name_param_map_.end() ||
254 desc == "" || name == "" ) {
255 delete param;
256 return false;
257 }
258
259 param_list_.push_back( param );
260 name_param_map_.insert( std::pair< std::string , bprb_param* >( name , param ) );
261
262 return true;
263 }
264
265 //==============================================================================
266
267 //: Less than operator for bprb_filepath objects
operator <(const bprb_filepath & lhs,const bprb_filepath & rhs)268 bool operator<( const bprb_filepath& lhs, const bprb_filepath& rhs )
269 {
270 return lhs.path < rhs.path;
271 }
272
273 //: Less than or equal to operator for bprb_filepath objects
operator <=(const bprb_filepath & lhs,const bprb_filepath & rhs)274 bool operator<=( const bprb_filepath& lhs, const bprb_filepath& rhs )
275 {
276 return lhs.path <= rhs.path;
277 }
278
279 //: Output stream operator for bprb_filepath objects
operator <<(std::ostream & strm,const bprb_filepath & fp)280 std::ostream& operator<<( std::ostream& strm, const bprb_filepath& fp )
281 {
282 strm << fp.path << '\n' << fp.ext << std::ends;
283 return strm;
284 }
285
286 //: Input stream operator for bprb_filepath objects
operator >>(std::istream & strm,bprb_filepath & fp)287 std::istream& operator>>( std::istream& strm, bprb_filepath& fp )
288 {
289 strm >> fp.path >> fp.ext;
290 return strm;
291 }
292