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