All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PSet.cxx
Go to the documentation of this file.
1 #ifndef FLASHMATCHFHICL_CXX
2 #define FLASHMATCHFHICL_CXX
3 
4 #include "PSet.h"
5 #include <sstream>
6 namespace flashmatch {
7 
8  PSet::PSet(const std::string name,
9  const std::string data)
10  {
11  if(name.empty()) {
12  std::cerr << "Cannot make PSet with an empty name!" << std::endl;
13  throw std::exception();
14  }
15  _name = name;
16  if(!data.empty()) this->add(data);
17  }
18 
19  size_t PSet::size() const
20  { return (_data_value.size() + _data_pset.size()); }
21 
22  const std::vector<std::string> PSet::keys() const
23  {
24  std::vector<std::string> res;
25  res.reserve(_data_value.size() + _data_pset.size());
26  for(auto const& key_value : _data_value) res.push_back(key_value.first);
27  for(auto const& key_value : _data_pset ) res.push_back(key_value.first);
28  return res;
29  }
30 
31  const std::vector<std::string> PSet::value_keys () const
32  {
33  std::vector<std::string> res;
34  res.reserve(_data_value.size());
35  for(auto const& key_value : _data_value) res.push_back(key_value.first);
36  return res;
37  }
38  const std::vector<std::string> PSet::pset_keys () const
39  {
40  std::vector<std::string> res;
41  res.reserve(_data_pset.size());
42  for(auto const& key_value : _data_pset) res.push_back(key_value.first);
43  return res;
44  }
45  bool PSet::contains_value (const std::string& key) const
46  {
47  return (_data_value.find(key) != _data_value.end());
48  }
49  bool PSet::contains_pset (const std::string& key) const
50  {
51  return (_data_pset.find(key) != _data_pset.end());
52  }
53 
54  void PSet::strip(std::string& str, const std::string& key)
55  {
56  if(str.find(key) != 0) return;
57  while(str.find(key) == 0)
58  str = str.substr(key.size(),str.size());
59  }
60 
61  void PSet::rstrip(std::string& str, const std::string& key)
62  {
63  size_t index = str.rfind(key);
64  if(index >= str.size()) return;
65  while(key.size() == (str.size() - index)) {
66  str = str.substr(0,index);
67  index = str.rfind(key);
68  if(index >= str.size()) break;
69  }
70  }
71 
72  void PSet::trim_space(std::string& txt){
73  strip ( txt, " " );
74  strip ( txt, "\t" );
75  strip ( txt, " " );
76  rstrip ( txt, " " );
77  rstrip ( txt, "\t" );
78  rstrip ( txt, " " );
79  }
80 
81  void PSet::no_space(std::string& txt){
82  trim_space(txt);
83  if(txt.find(" ") < txt.size()) {
84  std::stringstream ss;
85  std::cerr << " Processing: " << txt.c_str() << " ... Space not allowed!" << std::endl;
86  throw std::exception();
87  }
88  if(txt.find("\t") < txt.size()) {
89  std::cerr << "Tab not allowed!" << std::endl;
90  throw std::exception();
91  }
92  }
93 
94  std::pair<PSet::KeyChar_t,size_t> PSet::search(const std::string& txt, const size_t start) const
95  {
96  std::pair<KeyChar_t,size_t> res(kNone,size_t(-1));
97  size_t index = 0;
98 
99  //
100  // kParamDef
101  //
102  index = txt.find(":",start);
103  if(index != std::string::npos && index < res.second) {
104  res.first = kParamDef;
105  res.second = index;
106  }
107  index = txt.find("{",start);
108  if(index != std::string::npos && index < res.second) {
109  res.first = kBlockStart;
110  res.second = index;
111  }
112  index = txt.find("}",start);
113  if(index != std::string::npos && index < res.second) {
114  res.first = kBlockEnd;
115  res.second = index;
116  }
117  /*
118  index = txt.find("\"",start);
119  if(index != std::string::npos && index < res.second) {
120  res.first = kString;
121  res.second = index;
122  }
123  */
124  return res;
125  }
126 
127  void PSet::add_value(std::string key,
128  std::string value)
129  {
130  //std::cout<<" "<<key<<" => "<<value<<std::endl;
131  if( _data_value.find(key) != _data_value.end() ||
132  _data_pset.find(key) != _data_pset.end() ) {
133  std::string msg;
134  std::cerr << " Duplicate key: \"" << key << "\"" << std::endl;
135  throw std::exception();
136  }
137  no_space(key);
138  if(key.empty()) {
139  std::cerr << "Empty key cannot be registered!" << std::endl;
140  throw std::exception();
141  }
142  //std::cout<<"value: @"<<value<<"@"<<std::endl;
143  trim_space(value);
144  _data_value[key]=value;
145  }
146 
147  void PSet::add_pset(const PSet& p)
148  {
149  if( _data_value.find(p.name()) != _data_value.end() ||
150  _data_pset.find(p.name()) != _data_pset.end() ) {
151  std::string msg;
152  std::cerr << " Duplicate key: \"" << p.name() << "\"" << std::endl;
153  throw std::exception();
154  }
155  _data_pset.insert(std::make_pair(p.name(),p));
156  }
157 
158  void PSet::add_pset(std::string key,
159  std::string value)
160  {
161  if( _data_value.find(key) != _data_value.end() ||
162  _data_pset.find(key) != _data_pset.end() ) {
163  std::string msg;
164  std::cerr << " Duplicate key: \"" << key << "\"" << std::endl;
165  throw std::exception();
166  }
167  no_space(key);
168  if(key.empty()) {
169  std::cerr << "Empty key cannot be registered!" << std::endl;
170  throw std::exception();
171  }
172  strip(value," ");
173  rstrip(value," ");
174  _data_pset.emplace(key,PSet(key,value));
175  }
176 
177  void PSet::add(const std::string& contents)
178  {
179  if(contents.size()<1) return;
180  size_t index=0;
181  while(contents.find(" ",index) == index)
182  index +=1;
183  if(index >= contents.size()) return;
184 
185  size_t end_index=contents.size()-1;
186  while(contents.rfind(" ",end_index) == end_index)
187  end_index -= 1;
188 
189  if(end_index <= index || end_index > contents.size()) return;
190 
191  std::string key,value,tmp;
192  KeyChar_t last_mark=kNone;
193 
194  while(index <= end_index) {
195 
196  auto next_marker = this->search(contents,index);
197 
198  if(next_marker.first == kString) {
199 
200  //std::cout<<"String found in here: "<<contents.substr(index,(next_marker.second-index))<<std::endl;
201 
202  while(next_marker.second < end_index+1) {
203 
204  next_marker = this->search(contents,next_marker.second+1);
205 
206  if(next_marker.first == kString) {
207  next_marker = this->search(contents,next_marker.second+1);
208  break;
209  }
210  }
211  //std::cout<<"String found in here: "<<contents.substr(index,next_marker.second-index)<<std::endl;
212  }
213 
214  if(next_marker.second > end_index) break;
215  if(next_marker.first == kNone) break;
216  /*
217  std::cout<<"index: "<<index<<std::endl;
218  std::cout<<"marker: "<<next_marker.second<<std::endl;
219  std::cout<<"type : "<<next_marker.first<<std::endl;
220  std::cout<<"last : "<<last_mark<<std::endl;
221  std::cout<<"Inspecting: "<<"\""<<contents.substr(index,(next_marker.second-index))<<"\""<<std::endl;
222  */
223  if(next_marker.first == kParamDef) {
224  if(last_mark == kNone || last_mark == kBlockEnd){
225  key = contents.substr(index,(next_marker.second-index));
226  no_space(key);
227  }
228  else if(last_mark == kParamDef || last_mark == kString) {
229  tmp = contents.substr(index,(next_marker.second-index));
230  //std::cout<<"Inspecting: \""<<tmp<<"\"" <<std::endl;
231  strip(tmp," ");
232  rstrip(tmp," ");
233  size_t sep_index = tmp.rfind(" ");
234  if(sep_index >= tmp.size()) {
235  std::cerr << "Invalid format (key:value)" << std::endl;
236  throw std::exception();
237  }
238  value = tmp.substr(0,sep_index);
239  // complete pair
240  this->add_value(key,value);
241  //std::cout<<"Found value: "<<value<<std::endl;
242  key = value = "";
243  key = tmp.substr(sep_index+1,(tmp.size()-sep_index-1));
244  no_space(key);
245  }
246 
247  }else if(next_marker.first == kBlockEnd) {
248  std::cerr << "Block end logic error!" << std::endl;
249  throw std::exception();
250  }
251 
252  else if(next_marker.first == kBlockStart){
253  //std::cout<<"Block start!"<<std::endl;
254  if(last_mark != kParamDef) {
255  std::cerr << "Invalid paramter set start!" << std::endl;
256  throw std::exception();
257  }
258 
259  // fast forward till this block ends
260  int start_ctr = 1;
261  index = next_marker.second + 1;
262  while(start_ctr && next_marker.second <= end_index) {
263 
264  next_marker = this->search(contents,next_marker.second+1);
265 
266  if(next_marker.first == kString) {
267 
268  while(next_marker.second < end_index+1) {
269 
270  next_marker = this->search(contents,next_marker.second+1);
271 
272  auto tmp_next_marker = this->search(contents,next_marker.second+1);
273 
274  if(next_marker.first == kString && tmp_next_marker.second != kString) {
275 
276  next_marker = tmp_next_marker;
277  break;
278  }
279 
280  }
281  //std::cout<<"Found string :"<<contents.substr(index,next_marker.second)<<std::endl;
282  }
283 
284  switch(next_marker.first){
285  case kBlockStart:
286  start_ctr +=1;
287  break;
288  case kBlockEnd:
289  start_ctr -=1;
290  break;
291  default:
292  break;
293  }
294  }
295  if(start_ctr) {
296  std::string msg;
297  std::cerr << "Invalid block:\n" << contents.substr(index,next_marker.second-index) << "\n" << std::endl;
298  throw std::exception();
299  }
300  value = contents.substr(index,next_marker.second-index);
301  //std::cout<<"PSET!\n"<<value<<"\n"<<std::endl;
302  // complete key/value
303  this->add_pset(key,value);
304 
305  key="";
306  value="";
307  }
308  else {
309  std::cerr << "Unknown error!" << std::endl;
310  throw std::exception();
311  }
312 
313  index = next_marker.second+1;
314  last_mark = next_marker.first;
315  }
316 
317  if(index <= end_index) {
318 
319  if(!value.empty()) { std::cerr << "Non-empty value @ process-end!" << std::endl; throw std::exception(); }
320  if(key.empty()) { std::cerr << "Empty key @ process-end!" << std::endl; throw std::exception(); }
321 
322  tmp = contents.substr(index+1,end_index-index);
323  //no_space(tmp);
324  trim_space(tmp);
325  if(tmp.empty()) { std::cerr << "Empty value @ end!" << std::endl; throw std::exception(); }
326  value = tmp;
327  this->add_value(key,value);
328 
329  key = "";
330  value = "";
331  }
332 
333  if(!key.empty() || !value.empty()) {
334  std::cerr << "Unpaired key:value!" << std::endl;
335  throw std::exception();
336  }
337 
338  }
339 
340  std::string PSet::dump(size_t indent_size) const
341  {
342 
343  std::string res,in_indent,out_indent;
344  for(size_t i=0; i<indent_size; ++i) out_indent += " ";
345  res = out_indent + _name + " : {\n";
346  in_indent = out_indent + " ";
347  for(auto const& key_value : _data_value)
348 
349  res += in_indent + key_value.first + " : " + key_value.second + "\n";
350 
351  for(auto const& key_value : _data_pset)
352 
353  res += key_value.second.dump(in_indent.size()) + "\n";
354 
355  res += out_indent + "}\n";
356  return res;
357  }
358 
359  std::string PSet::data_string() const
360  {
361 
362  std::string res;
363  res = _name + ": {";
364  for(auto const& key_value : _data_value)
365 
366  res += key_value.first + ": " + key_value.second + " ";
367 
368  for(auto const& key_value : _data_pset)
369 
370  res += key_value.second.data_string();
371 
372  res += "} ";
373  return res;
374  }
375 
376  const PSet& PSet::get_pset(const std::string& key) const
377  {
378  auto iter = _data_pset.find(key);
379  if( iter == _data_pset.end() ) {
380  std::string msg;
381  std::cerr << "Key does not exist: \"" << key << "\"" << std::endl;
382  throw std::exception();
383  }
384  return (*iter).second;
385 
386  }
387 
388  template<>
389  PSet PSet::get<flashmatch::PSet>(const std::string& key) const
390  { return this->get_pset(key); }
391 
392 }
393 
394 #endif
bool contains_pset(const std::string &key) const
Check if a specified key exists for key-PSet pairs.
Definition: PSet.cxx:49
std::map< std::string, std::string > _data_value
Key-Value pairs.
Definition: PSet.h:158
const std::vector< std::string > pset_keys() const
Returns a vector of keys for key-PSet pairs.
Definition: PSet.cxx:38
BEGIN_PROLOG could also be cerr
void no_space(std::string &txt)
Definition: PSet.cxx:81
void add_pset(const PSet &p)
Insert method for a PSet rep.
Definition: PSet.cxx:147
pdgs p
Definition: selectors.fcl:22
const std::vector< std::string > keys() const
Returns a vector of all parameter keys.
Definition: PSet.cxx:22
void add_value(std::string key, std::string value)
Insert method for a simple param.
Definition: PSet.cxx:127
const std::string & name() const
name getter
Definition: PSet.h:44
std::map< std::string,::flashmatch::PSet > _data_pset
Key-PSet pairs.
Definition: PSet.h:160
const std::vector< std::string > value_keys() const
Returns a vector of keys for key-value pairs.
Definition: PSet.cxx:31
void rstrip(std::string &str, const std::string &key)
Definition: PSet.cxx:61
void trim_space(std::string &txt)
Definition: PSet.cxx:72
std::string _name
The name of this flashmatch::PSet.
Definition: PSet.h:156
bool contains_value(const std::string &key) const
Check if a specified key exists for key-value pairs.
Definition: PSet.cxx:45
std::string data_string() const
Dump data string.
Definition: PSet.cxx:359
std::string dump(size_t indent_size=0) const
Dump into a text format.
Definition: PSet.cxx:340
void add(const std::string &data)
Set data contents.
Definition: PSet.cxx:177
std::pair< PSet::KeyChar_t, size_t > search(const std::string &txt, const size_t start) const
Definition: PSet.cxx:94
PSet(const std::string name="", const std::string data="")
Default constructor.
Definition: PSet.cxx:8
then echo fcl name
temporary value
size_t size() const
Returns # of parameters.
Definition: PSet.cxx:19
void strip(std::string &str, const std::string &key)
Definition: PSet.cxx:54
Class def header for a class flashmatch::PSet.
const PSet & get_pset(const std::string &key) const
None-template function to retrieve parameter set (deprecated)
Definition: PSet.cxx:376
A nested configuration parameter set holder for flashmatch framework.
Definition: PSet.h:26