rtop
fileio.h
Go to the documentation of this file.
1 #include <vector>
2 #include <sstream>
3 #include <string>
4 #include <stdexcept>
5 #include "pugixml.hpp"
6 
7 #ifndef _XML_H_
8 #define _XML_H_
9 #include "rtop_logger.h"
10 #include "columns.h"
11 
12 extern src::severity_logger<severity_level> lg;
13 //TODO: poorly written, make more understandabl by documentation and cleaning up logical flow
14 namespace rtop
15 {
16  extern MapOfKeyDicts mapKeyDict;
17  extern MemFuncPDict funcPDict;
18 
20 
28  class XMLTree
29  {
30  private:
31  pugi::xml_document doc;
32  void createTreeFirstPass(pugi::xml_node node);
33  void createPanel(int, int, std::string);
34  pugi::xml_attribute getAttribute(pugi::xml_node, std::string);
35  pugi::xml_node findNode(pugi::xml_node, int uuid);
36  pugi::xml_node findNode(pugi::xml_node, std::string);
37 
38  void parseKeyDictionaries(pugi::xml_node);
39  void parseCallbacks(pugi::xml_node);
40  void parseColors(pugi::xml_node);
41  void parseDatabase(pugi::xml_node);
42  void parseProcInfo(pugi::xml_node);
43  void parseColumn(pugi::xml_node);
44 
50 
51  void updateObjFromAttrib(int, std::string, View*&);
52  void updateObjFromAttrib(int, std::string, StateMachine&);
53  void updateObjFromAttrib(int, std::string, SimplePanelData*&);
54  void updateObjFromAttrib(int, std::string, int&, std::string, int&);
55 
56  void updateObjFromNodeVal(int, std::string, std::vector<InfoProc<std::string>*>&);
57  void updateObjFromNodeVal(int, std::string, std::vector<InfoProc<int>*>&);
58  void updateObjFromNodeVal(int, std::string, std::vector<InfoProc<float>*>&);
59  void updateObjFromNodeVal(int, std::string, std::vector<Info*>&);
60  void updateObjFromNodeVal(int, std::string, std::string, std::string, StateMachine&);
61  void updateObjFromNodeVal(int, std::string, std::map<SimplePanelData*, std::pair<SimplePanelData*,SimplePanelData*>>&);
62  void updateObjFromNodeVal(int, std::string, std::map<std::string, int>&, SimplePanelData*);
63 
64  void updateViewPanelColors(int, std::string, View*);
65  //void updateCallbacks(pugi::xml_node, ScreenManager*);
66  void updateChildren(int, std::string, std::vector<View*> &);
67  void updateChildren(int, std::string, std::vector<SimplePanelData*> &);
68  void updateChildren(int, std::string, std::string, std::string, std::vector<std::pair<int, int>>&);
69 
70  //TODO: add dictionaries for data structures
71  public:
72  XMLTree(std::string);
74  };
75 
76  XMLTree::XMLTree(std::string xmlfile)
77  {
78  doc.load_file(xmlfile.c_str());
79  pugi::xml_node root_node;
80 
81  root_node = doc.child("Callbacks");
82  parseCallbacks(root_node);
83 
84  root_node = doc.child("KeyDictionaries");
85  parseKeyDictionaries(root_node);
86 
87  root_node = doc.child("Colors");
88  parseColors(root_node);
89 
90  root_node = doc.child("ProcDb");
91  parseDatabase(root_node);
92 
93  root_node = doc.child("Screen");
94  createTreeFirstPass(root_node);
95 
96  root_node = doc.child("ProcInfo");
97  parseProcInfo(root_node);
98 
99  root_node = doc.child("Column");
100  parseColumn(root_node);
101  }
102 
104  {
105  ScreenManager* p_screen = funcPDict.getScreen(1); // beware of constant, TODO: fix this
106  updateObjFromAttrib(p_screen->uUid(), "currView", p_screen->currView);
107  updateObjFromNodeVal(p_screen->uUid(), "StateMachine", "Type", "View", p_screen->smViews);
108  updateObjFromNodeVal(p_screen->uUid(), "StateMachine", "Type", "KeyDict", p_screen->smKeys);
109  updateChildren(p_screen->uUid(), "View", p_screen->views);
110  return p_screen;
111  }
112 
113  void XMLTree::parseColors(pugi::xml_node node)
114  {
115  StringParser parser{'\n'};
116  pugi::xml_text txt_obj = node.text();
117  parser<<txt_obj.get();
118  std::vector<std::string> words = parser.Words();
119  words.erase(words.begin());
120  words.erase(words.end()-1);
121  parser.setSeparator(',');
122  for(auto word: words)
123  {
124  parser.clear();
125  parser<<word;
126  std::vector<std::string> colorstring = parser.Words();
127  colors[std::stoi(colorstring[0])] = std::make_pair(color_map[colorstring[1]], color_map[colorstring[2]]);
128  }
129  }
130 
131  void XMLTree::parseDatabase(pugi::xml_node node)
132  {
133  pugi::xml_attribute attr = getAttribute(node, "Uuid");
134  int uuid = std::stoi(attr.value());
135  ProcDb* database = new ProcDb(uuid);
136  funcPDict.addDatabase(uuid, database);
137  pugi::xml_node child_node = findNode(doc.child("ProcDb"), "FieldProperties");
138  pugi::xml_text txt_obj = child_node.text();
139  StringParser parser{'\n'};
140  parser<<txt_obj.get();
141  std::vector<std::string> words = parser.Words();
142  words.erase(words.begin());
143  words.erase(words.end()-1);
144  parser.clear();
145  parser.setSeparator(',');
146  for(auto line: words)
147  {
148  parser<<line;
149  int field = std::stoi((parser.Words()[0]));
150  std::string prop = (parser.Words()[1]);
151  std::string type = (parser.Words()[2]);
152  database->field_prop_dict[field] = std::make_pair(prop, type);
153  database->prop_type_dict[prop] = type;
154  parser.clear();
155  }
156  /*
157  parser.clear();
158  parser.setSeparator('\n');
159  child_node = findNode(doc.child("ProcDb"), "PropType");
160  txt_obj = child_node.text();
161  parser<<txt_obj.get();
162  words.clear();
163  words = parser.Words();
164  words.erase(words.begin());
165  words.erase(words.end()-1);
166  parser.clear();
167  parser.setSeparator(',');
168  for(auto line: words)
169  {
170  parser<<line;
171  std::string prop = (parser.Words()[0]);
172  std::string type = (parser.Words()[1]);
173  database->prop_type_dict[prop] = type;
174  parser.clear();
175  }
176  */
177  }
178 
179  void XMLTree::parseProcInfo(pugi::xml_node node)
180  {
181  pugi::xml_attribute attr = getAttribute(node, "Uuid");
182  int uuid = std::stoi(attr.value());
183  ProcInfo* pinfo = new ProcInfo(uuid);
184  funcPDict.addProcInfo(uuid, pinfo);
185  pinfo->sortkey = (getAttribute(node, "SortKey")).value();
186  int db_uuid = std::stoi((getAttribute(node, "ProcDb")).value());
187  pinfo->proc_database = funcPDict.getDatabase(db_uuid);
188  }
189 
190  void XMLTree::parseColumn(pugi::xml_node node)
191  {
192  pugi::xml_attribute attr = getAttribute(node, "Uuid");
193  int uuid = std::stoi(attr.value());
194  Columns* pclms = new Columns(uuid);
195  funcPDict.addColumn(uuid, pclms);
196  attr = getAttribute(node, "ProcInfo");
197  int pinfo_uuid = std::stoi(attr.value());
198  pclms->p_procinfo = funcPDict.getProcInfo(pinfo_uuid);
199  attr = getAttribute(node, "ProcViewPanel");
200  int viewp_uuid = std::stoi(attr.value());
201  pclms->proc_view = dynamic_cast<ProcViewPanel*>(funcPDict.getPanel(viewp_uuid));
202  pugi::xml_node child_node = findNode(node, "ProcViews");
203  pugi::xml_text txt_obj = child_node.text();
204  StringParser parser{','};
205  parser<<txt_obj.get();
206  std::vector<std::string> words;
207  words = parser.Words();
208  for(auto view_id: words)
209  pclms->proc_views.push_back(std::stoi(view_id));
210  pclms->pscreen = funcPDict.getScreen(1);
211  }
212 
213 
214  pugi::xml_attribute XMLTree::getAttribute(pugi::xml_node node, std::string attr_name)
215  {
216  pugi::xml_attribute attr;
217  for(attr=node.first_attribute(); attr; attr = attr.next_attribute())
218  {
219  if (strcmp(attr.name(), attr_name.c_str()) == 0)
220  break;
221  }
222  return attr;
223  }
224 
225  void XMLTree::parseKeyDictionaries(pugi::xml_node root)
226  {
227  for(pugi::xml_node node_keydict=root.first_child(); node_keydict; node_keydict = node_keydict.next_sibling()) // iterate over key dicts
228  {
229  int uuid = std::stoi((getAttribute(node_keydict, "Uuid").value()));
230  KeyDict key_dict{uuid};
231  StringParser parser{','};
232  for(pugi::xml_node node_keyacts=node_keydict.first_child(); node_keyacts; node_keyacts = node_keyacts.next_sibling()) // iterate over key-actions
233  {
234  int key = std::stol((getAttribute(node_keyacts,"Key").value()), NULL, 0);
235  std::vector<Action> vec_actions;
236  for(pugi::xml_node node_act=node_keyacts.first_child(); node_act; node_act = node_act.next_sibling()) // iterate over actions
237  {
238 
239  parser<<(node_act.text()).get();
240  std::vector<std::string> words = parser.Words();
241  vec_actions.push_back(Action{std::stoi(words[0]), words[1]});
242  parser.clear();
243  }
244  key_dict.addKeyActions(key, vec_actions);
245  vec_actions.clear();
246  }
247  mapKeyDict.addKeyDict(uuid, key_dict);
248  }
249  }
250 
251  void XMLTree::parseCallbacks(pugi::xml_node root)
252  {
253  StringParser parser{'\n'};
254  pugi::xml_text txt_obj = root.text();
255  parser<<txt_obj.get();
256  std::vector<std::string> words = parser.Words();
257  words.erase(words.begin());
258  words.erase(words.end()-1);
259 
260  parser.clear();
261  parser.setSeparator(',');
262  for(auto word: words)
263  {
264  parser<<word;
265  std::vector<std::string> obj_func_pair = parser.Words();
266  if (obj_func_pair[0] == "Screen")
267  {
268  if (obj_func_pair[1] == "refresh")
269  funcPDict.registerFunc(obj_func_pair[1],&ScreenManager::refresh);
270  }
271  else if (obj_func_pair[0] == "View")
272  {
273  }
274  else if (obj_func_pair[0] == "SimplePanelData")
275  {
276  if (obj_func_pair[1] == "Down")
277  funcPDict.registerFunc(obj_func_pair[1],&SimplePanelData::Down);
278  if (obj_func_pair[1] == "Up")
279  funcPDict.registerFunc(obj_func_pair[1],&SimplePanelData::Up);
280  if (obj_func_pair[1] == "editModeOn")
282  if (obj_func_pair[1] == "editModeOff")
284  if (obj_func_pair[1] == "insertIntoLeftNbr")
286  if (obj_func_pair[1] == "insertIntoRightNbr")
288  if (obj_func_pair[1] == "addIntoLeftNbr")
290  if (obj_func_pair[1] == "addIntoRightNbr")
292  if (obj_func_pair[1] == "moveIntoLeftNbr")
294  if (obj_func_pair[1] == "moveIntoRightNbr")
296  if (obj_func_pair[1] == "toggleEditMode")
298  if (obj_func_pair[1] == "deleteColumn")
300  if (obj_func_pair[1] == "insertColumn")
302  if (obj_func_pair[1] == "moveLeft")
304  if (obj_func_pair[1] == "moveRight")
306  if (obj_func_pair[1] == "refresh")
308  if (obj_func_pair[1] == "remove")
310 
311  }
312  else if (obj_func_pair[0] == "Columns")
313  {
314  if(obj_func_pair[1] == "markPid")
315  funcPDict.registerFunc(obj_func_pair[1], &Columns::markPid);
316  if(obj_func_pair[1] == "read")
317  funcPDict.registerFunc(obj_func_pair[1], &Columns::read);
318  }
319  else if(obj_func_pair[0] == "ProcInfo")
320  {
321  if(obj_func_pair[1] == "kill")
322  funcPDict.registerFunc(obj_func_pair[1], &ProcInfo::kill);
323  }
324  else // statemachine
325  {
326  if (obj_func_pair[1] == "next")
327  funcPDict.registerFunc(obj_func_pair[1],&StateMachine::next);
328  if (obj_func_pair[1] == "stale")
329  funcPDict.registerFunc(obj_func_pair[1],&StateMachine::stale);
330 
331  }
332  parser.clear();
333  }
334  }
335 
336  void XMLTree::createPanel(int uuid, int type, std::string container_type)
337  {
338  if(funcPDict.getPanel(uuid) == NULL)
339  {
340  switch(type)
341  {
342  case 0:
343  funcPDict.addPanel(uuid, new SimplePanelData(uuid));
344  break;
345  case 1:
346  if (container_type == "inf_int")
348  else if (container_type == "inf_float")
350  else if (container_type == "inf_string")
352  else
353  funcPDict.addPanel(uuid, new BrowsePanelData<Info>(uuid));
354  break;
355  case 2:
356  if (container_type == "inf_int")
357  funcPDict.addPanel(uuid, new EditPanelData<InfoProc<int>>(uuid));
358  else if (container_type == "inf_float")
360  else if (container_type == "inf_string")
362  else
363  funcPDict.addPanel(uuid, new EditPanelData<Info>(uuid));
364  break;
365  case 3:
366  funcPDict.addPanel(uuid, new ProcViewPanel(uuid));
367  break;
368  default:
369  break;
370  }
371  //funcPDict.addPanel(uuid, panel_dict[uuid]);
372  }
373  }
374 
375  /*
376  depending on node type generate attributes. if node type is not one of screen, view or panel, do not create a new one,
377  instead treat them as properties. iterate over any child nodes and create each one recursively
378  */
379  void XMLTree::createTreeFirstPass(pugi::xml_node node)
380  {
381  // based on node's name, create a specific type and add to dictionary
382  if (strcmp(node.name(), "Screen") == 0) // Create Screen
383  {
384  if(pugi::xml_attribute attr = getAttribute(node, "Uuid"))
385  {
386  int uuid = std::stoi(attr.value());
387  if (funcPDict.getScreen(uuid) == NULL) // if object corresponding to uuid not already instantiated, proceed, else skip
388  {
389  funcPDict.addScreen(uuid, new ScreenManager(uuid));
390  }
391  }
392  else
393  {
394  std::stringstream ss;
395  ss<<"createTreeFirstPass: failed to find attribute Uuid in "<<node.name()<<"\n";
396  throw std::runtime_error(ss.str());
397  }
398  }
399  else if (strcmp((char*)node.name(), "View")==0) // Create View
400  {
401  if(pugi::xml_attribute attr = getAttribute(node, "Uuid"))
402  {
403  int uuid = std::stoi(attr.value());
404  if (funcPDict.getView(uuid) == NULL) // if object corresponding to uuid not already instantiated, proceed, else skip
405  {
406  funcPDict.addView(uuid, new View(uuid));
407  }
408  }
409  else
410  {
411  std::stringstream ss;
412  ss<<"createTreeFirstPass: failed to find attribute Uuid in "<<node.name()<<"\n";
413  throw std::runtime_error(ss.str());
414  }
415  }
416  else if (strcmp(node.name(), "Panel") == 0) // Create Panel
417  {
418  if(pugi::xml_attribute attr = getAttribute(node, "Uuid"))
419  {
420  int uuid = std::stoi(attr.value());
421  if(pugi::xml_attribute attr = getAttribute(node, "Type"))
422  {
423  int type = std::stoi(attr.value());
424  if(pugi::xml_attribute attr = getAttribute(node, "ContainerData"))
425  createPanel(uuid, type, attr.value());
426  else
427  throw std::runtime_error("failed to find ContainerData in Panel\n");
428  }
429  else
430  throw std::runtime_error("failed to find Type in Panel\n");
431  }
432  else
433  throw std::runtime_error("failed to find UUID in Screen \n");
434  }
435  else if (strcmp(node.name(), "ColumnsPanelData") == 0) // Create Columns Panel
436  {
437  //TODO
438  }
439  else // Base case
440  {
441  return; // ignore nodes carrying attribute values
442  }
443 
444  // create all child node
445  for(pugi::xml_node child_node = node.first_child(); child_node; child_node = child_node.next_sibling())
446  createTreeFirstPass(child_node);
447  }
448 
449  pugi::xml_node XMLTree::findNode(pugi::xml_node node, int uuid)
450  {
451 
452  if (pugi::xml_attribute attr=getAttribute(node, "Uuid"))
453  {
454  if(std::stoi(attr.value()) == uuid)
455  return node;
456  else
457  {
458  for(pugi::xml_node child=node.first_child(); child; child=child.next_sibling())
459  {
460  if (pugi::xml_node return_node = findNode(child, uuid))
461  return return_node;
462  else
463  continue;
464  }
465  }
466  }
467  return pugi::xml_node();
468  }
469 
470  pugi::xml_node XMLTree::findNode(pugi::xml_node node, std::string name)
471  {
472  if (strcmp(name.c_str(), node.name()) == 0)
473  return node;
474  else
475  {
476  for(pugi::xml_node child=node.first_child(); child; child=child.next_sibling())
477  {
478  if (pugi::xml_node return_node = findNode(child, name))
479  return return_node;
480  else
481  continue;
482  }
483  }
484  return pugi::xml_node();
485  }
486 
487  void XMLTree::updateObjFromAttrib(int uuid, std::string attr_name, View*& currView)
488  {
489  pugi::xml_node node = findNode(doc.child("Screen"), uuid); // find node corresponding to the uuid
490  if (!node) // if node not found, throw exception with message
491  {
492  std::stringstream ss;
493  ss<<"updateObjFromAttrib: node corresponding to uuid "<<uuid<<" not found \n";
494  throw std::runtime_error(ss.str());
495  }
496  if(pugi::xml_attribute attr=getAttribute(node, attr_name)) // find atttribute in the node and set the parameter after appropriate conversion
497  currView = funcPDict.getView(std::stoi(attr.value()));
498  //currView = view_dict[std::stoi(attr.value())];
499  else
500  {
501  std::stringstream ss;
502  ss<<"failed to find "<<attr_name<<" in object "<<uuid<<"\n";
503  throw std::runtime_error(ss.str());
504  }
505  }
506 
507  void XMLTree::updateObjFromAttrib(int uuid, std::string attr_name, SimplePanelData*& currPanel)
508  {
509  pugi::xml_node node = findNode(doc.child("Screen"), uuid); // find node corresponding to the uuid
510  if (!node) // if node not found, throw exception with message
511  {
512  std::stringstream ss;
513  ss<<"updateObjFromAttrib: node corresponding to uuid "<<uuid<<" not found \n";
514  throw std::runtime_error(ss.str());
515  }
516  if(pugi::xml_attribute attr=getAttribute(node, attr_name)) // find atttribute in the node and set the parameter after appropriate conversion
517  //currPanel = panel_dict[std::stoi(attr.value())];
518  currPanel = funcPDict.getPanel(std::stoi(attr.value()));
519  else
520  {
521  std::stringstream ss;
522  ss<<"failed to find "<<attr_name<<" in object "<<uuid<<"\n";
523  throw std::runtime_error(ss.str());
524  }
525  }
526 
527  void XMLTree::updateObjFromAttrib(int uuid, std::string attr1, int& attr1_val, std::string attr2, int& attr2_val)
528  {
529  pugi::xml_node node = findNode(doc.child("Screen"), uuid); // find node corresponding to the uuid
530  if (!node) // if node not found, throw exception with message
531  {
532  std::stringstream ss;
533  ss<<"updateObjFromAttrib: node corresponding to uuid "<<uuid<<" not found \n";
534  throw std::runtime_error(ss.str());
535  }
536 
537  if(pugi::xml_attribute attr=getAttribute(node, attr1)) // find atttribute in the node and set the parameter after appropriate conversion
538  attr1_val = std::stoi(attr.value());
539  else
540  {
541  std::stringstream ss;
542  ss<<"failed to find "<<attr1<<" in object "<<uuid<<"\n";
543  throw std::runtime_error(ss.str());
544  }
545 
546  if(pugi::xml_attribute attr=getAttribute(node, attr2)) // find atttribute in the node and set the parameter after appropriate conversion
547  attr2_val = std::stoi(attr.value());
548  else
549  {
550  std::stringstream ss;
551  ss<<"failed to find "<<attr2<<" in object "<<uuid<<"\n";
552  throw std::runtime_error(ss.str());
553  }
554 
555  }
556 
557  void XMLTree::updateObjFromNodeVal(int uuid, std::string child_name, std::vector<InfoProc<std::string>*>& object_list)
558  {
559  pugi::xml_node root = findNode(doc.child("Screen"), uuid);
560  pugi::xml_node child = findNode(root, child_name);
561  pugi::xml_text txt_obj = child.text();
562  if (txt_obj.empty())
563  {
564  std::stringstream ss;
565  ss<<"failure to read object list from panel "<<uuid<<", empty list\n";
566  throw std::runtime_error(ss.str());
567  }
568  pugi::xml_attribute attr = getAttribute(child, "Separator");
569  int capacity = std::stoi((getAttribute(child, "Capacity").value()));
570  StringParser parser{toChar(attr.value())};
571  parser<<txt_obj.get();
572  object_list.reserve(capacity);
573  for(auto word: parser.Words())
574  object_list.push_back(new InfoProc<std::string>(word));
575 
576  }
577 
578  void XMLTree::updateObjFromNodeVal(int uuid, std::string child_name, std::vector<InfoProc<float>*>& object_list)
579  {
580  }
581 
582  void XMLTree::updateObjFromNodeVal(int uuid, std::string child_name, std::vector<InfoProc<int>*>& object_list)
583  {
584  }
585 
586  void XMLTree::updateObjFromNodeVal(int uuid, std::string child_name, std::vector<Info*>& object_list)
587  {
588  pugi::xml_node root = findNode(doc.child("Screen"), uuid);
589  pugi::xml_node child = findNode(root, child_name);
590  pugi::xml_text txt_obj = child.text();
591  if (txt_obj.empty())
592  {
593  std::stringstream ss;
594  ss<<"failure to read object list from panel "<<uuid<<", empty list\n";
595  throw std::runtime_error(ss.str());
596  }
597  pugi::xml_attribute attr = getAttribute(child, "Separator");
598  int capacity = std::stoi((getAttribute(child, "Capacity").value()));
599 
600  StringParser parser{toChar(attr.value())};
601  parser<<txt_obj.get();
602  std::vector<std::string> words = parser.Words();
603  words.erase(words.begin());
604  words.erase(words.end()-1);
605  parser.clear();
606  parser.setSeparator(',');
607  object_list.reserve(capacity);
608  for(auto word: words)
609  {
610  parser<<word;
611  std::vector<std::string> info = parser.Words();
612  object_list.push_back(new Info(info[0], info[1], info[2]));
613  parser.clear();
614  }
615  }
616 
617  void XMLTree::updateObjFromNodeVal(int uuid, std::string child_name, std::string child_attr, std::string child_attr_val, StateMachine& sm)
618  {
619  pugi::xml_node root = findNode(doc.child("Screen"), uuid);
620  pugi::xml_node_iterator it;
621  for(it=root.begin(); it != root.end(); it++)
622  {
623  if (strcmp(it->name(), child_name.c_str()) == 0) // if child is a state machine node
624  {
625  pugi::xml_attribute attr = getAttribute(*it, child_attr);
626  if (strcmp(attr.value(), child_attr_val.c_str())==0)
627  break;
628  }
629  }
630  if (it == root.end())
631  return;
632  // register State Machine with funcPDict
633  pugi::xml_attribute attr = getAttribute(*it, "Uuid");
634  int sm_uuid = std::stoi(attr.value());
635  funcPDict.addSm(sm_uuid, &sm);
636  // populate state machine
637  attr = getAttribute(*it, "CurrState");
638  sm.setCurrState(std::stoi(attr.value()));
639  attr = getAttribute(*it, "Separator");
640  StringParser parser{toChar(attr.value())};
641 
642  pugi::xml_node child = findNode(*it, "Transitions");
643  pugi::xml_text txt_obj = child.text();
644  if (txt_obj.empty())
645  {
646  std::stringstream ss;
647  ss<<"failure to read object list from panel "<<uuid<<", empty list\n";
648  throw std::runtime_error(ss.str());
649  }
650  parser<<txt_obj.get();
651  std::vector<std::string> words = parser.Words();
652  words.erase(words.begin());
653  words.erase(words.end()-1);
654  parser.clear();
655  parser.setSeparator(',');
656  for(auto word: words)
657  {
658  parser<<word;
659  std::vector<std::string> transn = parser.Words();
660  sm.addTransition(std::stol(transn[1],NULL,0),std::stoi(transn[0],NULL,0),std::stoi(transn[2],NULL,0));
661  parser.clear();
662  }
663 
664  }
665 
666  void XMLTree::updateObjFromNodeVal(int uuid, std::string child_name, std::map<SimplePanelData*, std::pair<SimplePanelData*, SimplePanelData*>>& nbrs)
667  {
668  pugi::xml_node view_node = findNode(doc.child("Screen"), uuid);
669  pugi::xml_node child_node;
670  for(child_node = view_node.first_child(); child_node; child_node=child_node.next_sibling())
671  {
672  if(strcmp(child_node.name(), (child_name).c_str())==0)
673  break;
674  }
675  if (!child_node)
676  return;
677  pugi::xml_text txt_obj = child_node.text();
678  StringParser parser{'\n'};
679  parser<<txt_obj.get();
680  std::vector<std::string> nbr_lines = parser.Words();
681  nbr_lines.erase(nbr_lines.begin());
682  nbr_lines.erase(nbr_lines.end()-1);
683  parser.setSeparator(',');
684  parser.clear();
685  //parse each line of neighbourhood
686  std::vector<std::string> panels_uuids;
687  SimplePanelData* leftNbr, *rightNbr;
688  for(auto word: nbr_lines)
689  {
690  parser<<word;
691  panels_uuids = parser.Words();
692  // if panel id for left/right nbr is 0, nbr will be set as NULL
693  leftNbr = funcPDict.getPanel(std::stoi(panels_uuids[1]));
694  rightNbr = funcPDict.getPanel(std::stoi(panels_uuids[2]));
695  nbrs[funcPDict.getPanel(std::stoi(panels_uuids[0]))] = std::make_pair(leftNbr, rightNbr);
696  panels_uuids.clear();
697  parser.clear();
698  }
699  }
700 
701  void XMLTree::updateViewPanelColors(int uuid, std::string child_name, View* view)
702  {
703  pugi::xml_node view_node = findNode(doc.child("Screen"), uuid);
704  pugi::xml_node child_node;
705  for(child_node = view_node.first_child(); child_node; child_node = child_node.next_sibling())
706  {
707  if (strcmp(child_node.name(), (child_name).c_str()) == 0)
708  break;
709  }
710  if (!child_node)
711  return;
712 
713  // now parse child node (PanelColors), for color pairs
714  for(pugi::xml_node color_node = child_node.first_child(); color_node; color_node = color_node.next_sibling())
715  {
716  if (strcmp(color_node.name(), "Editing") == 0)
717  view->editing_color_pair = std::stoi((color_node.text()).get());
718  if (strcmp(color_node.name(), "Selection") == 0)
719  view->selection_color_pair = std::stoi((color_node.text()).get());
720  if (strcmp(color_node.name(), "Header") == 0)
721  view->header_color_pair = std::stoi((color_node.text()).get());
722  }
723  }
724 
725 
726  void XMLTree::updateChildren(int uuid,std::string main_attrib, std::string sub_attrib1, std::string sub_attrib2, std::vector<std::pair<int, int>>& panels_yx)
727  {
728  pugi::xml_node view_node = findNode(doc.child("Screen"), uuid);
729  pugi::xml_node positions_node = findNode(view_node, main_attrib);
730  int n_children = 0;
731  for(pugi::xml_node pos_node=positions_node.first_child(); pos_node; pos_node=pos_node.next_sibling())
732  n_children++;
733  panels_yx.reserve(n_children);
734  for(pugi::xml_node pos_node=positions_node.first_child(); pos_node; pos_node=pos_node.next_sibling())
735  {
736  std::pair<int, int> temp;
737  temp.first = std::stoi((getAttribute(pos_node,sub_attrib1)).value());
738  temp.second = std::stoi((getAttribute(pos_node,sub_attrib2)).value());
739  panels_yx.push_back(temp);
740  }
741  }
742 
743  void XMLTree::updateChildren(int uuid, std::string child_name, std::vector<View*> & views)
744  {
745  pugi::xml_node root = findNode(doc.child("Screen"), uuid); //find the root node for the sub-tree corresponding to uuid
746  int n_children = 0;
747  for(pugi::xml_node child=root.first_child(); child; child = child.next_sibling()) // count the number of children
748  n_children++;
749  views.reserve(n_children); // reserve vector capacity to proprely store pointers
750 
751  View* pview;
752  for(pugi::xml_node child=root.first_child(); child; child = child.next_sibling()) //
753  {
754  if (strcmp((char*)child.name(), "View") != 0) // only if child node is view, continue, else remaining body of loop
755  continue;
756  pugi::xml_attribute attr=getAttribute(child, "Uuid");
757 
758  int uuid = std::stoi(attr.value()); // view's uuid
759  pview = funcPDict.getView(uuid);
760  pview->win = newwin(40, 140, 0, 0);
761  // populate view state machines
762  updateObjFromNodeVal(uuid, "StateMachine", "Type", "Panel",pview->smPanels);
763  updateObjFromNodeVal(uuid, "StateMachine", "Type", "KeyDict",pview->smKeys);
764  updateObjFromNodeVal(uuid, "Neighbourhood", pview->neighbourhood);
765  // populate view's color pairs
766  updateViewPanelColors(uuid, "PanelColors", pview);
767 
768 
769  updateObjFromAttrib(uuid, "currPanel", pview->curr_panel);
770  updateChildren(uuid, "PanelPositions", "YPos", "XPos", pview->panels_yx);
771  updateChildren(uuid, "Panel", pview->panels);
772  // set panel colors
773  for(auto panel: pview->panels)
774  {
775  panel->setBasicColor(pview->basic_color_pair);
776  panel->setSelectionColor(pview->selection_color_pair);
777  panel->setEditingColor(pview->editing_color_pair);
778  panel->setHeaderColor(pview->header_color_pair);
779  }
780  for(auto panel:pview->panels)
781  panel->syncColors();
782  for(int i=0; i<pview->panels_yx.size(); i++)
783  pview->panels[i]->moveTo(pview->panels_yx[i].first, pview->panels_yx[i].second); // can be optimized
784  views.push_back(pview);
785  }
786  }
787 
788  void XMLTree::updateChildren(int uuid, std::string child_name, std::vector<SimplePanelData*> & panels)
789  {
790  int root_uuid = uuid;
791  pugi::xml_node root = findNode(doc.child("Screen"), uuid); //find the root node for the sub-tree corresponding to uuid
792  int n_children = 0;
793  for(pugi::xml_node child=root.first_child(); child; child = child.next_sibling()) // count the number of children
794  n_children++;
795  panels.reserve(n_children); // reserve vector capacity to proprely store pointers
796  int count = 0;
797  SimplePanelData* ppanel;
798  View* pview;
799  for(pugi::xml_node child=root.first_child(); child; child = child.next_sibling()) //
800  {
801  if (strcmp((char*)child.name(), "Panel") != 0)
802  continue;
803  pugi::xml_attribute attr=getAttribute(child, "Uuid");
804  int uuid = std::stoi(attr.value());
805  pugi::xml_attribute container=getAttribute(child, "ContainerData");
806  ppanel = funcPDict.getPanel(uuid);
807 
808  // base class initialization
809  pview = funcPDict.getView(root_uuid);
810  updateObjFromAttrib(uuid, "Width", ppanel->width, "Height",ppanel->height);
811  // set header
812  ppanel->setHeader((getAttribute(child, "Header")).value());
813 
814  BOOST_LOG_SEV(lg, info)<<"Panel: "<<uuid<<" Ht: "<<ppanel->height<<" Wd: "<<ppanel->width;
815  ppanel->win = derwin(pview->win, ppanel->height, ppanel->width, pview->panels_yx[count].first, pview->panels_yx[count].second);
816  ppanel->panel = new_panel(ppanel->win);
817  updateObjFromNodeVal(uuid, "StateMachine", "Type", "KeyDict",ppanel->smKeys);
818 
819  if (container.value() == "info_int")
820  updatePolymorphicPanel(dynamic_cast<BrowsePanelData<InfoProc<int>>*>(ppanel));
821  else if (container.value() == "info_float")
823  else if (container.value() == "info_string")
825  else if (strcmp(container.value(),"panels")==0)
826  updatePolymorphicPanel(dynamic_cast<ProcViewPanel*>(ppanel));
827  else
828  updatePolymorphicPanel(dynamic_cast<BrowsePanelData<Info>*>(ppanel));
829  panels.push_back(ppanel);
830  count++;
831  }
832  }
833 
834 void XMLTree::updateObjFromNodeVal(int uuid, std::string child_name, std::map<std::string, int>& dict, SimplePanelData* main_panel)
835 {
836  pugi::xml_node child_node = findNode(doc.child("Screen"), uuid);
837  pugi::xml_node prop_node = findNode(child_node, "Columns");
838  StringParser parser{'\n'};
839  pugi::xml_text txt_obj = prop_node.text();
840  parser<<txt_obj.get();
841  std::vector<std::string> lines = parser.Words();
842  lines.erase(lines.begin());
843  lines.erase(lines.end()-1);
844  parser.clear();
845  parser.setSeparator(',');
846  int panel_xpos = 0;
847  for(auto line: lines)
848  {
849  parser<<line;
850  std::string clm_prop_name = (parser.Words())[0];
851  int clm_width = std::stoi((parser.Words())[1]);
852  dict[clm_prop_name] = clm_width;
853  parser.clear();
854  }
855 }
856 
858 {
859  updateObjFromNodeVal(pPanel->uuid, "Columns", pPanel->prop_wid_dict, pPanel);
860  pugi::xml_node proc_node = findNode(doc.child("Screen"), pPanel->uuid);
861  for(pugi::xml_node child_node = proc_node.first_child(); child_node; child_node = child_node.next_sibling())
862  {
863  if(strcmp(child_node.name(), "ActiveProc") == 0)
864  {
865  pugi::xml_text txt_obj = child_node.text();
866  pPanel->active_proc_panel = funcPDict.getPanel(std::stoi(txt_obj.get()));
867 
868  }
869  if(strcmp(child_node.name(), "ProcDb") == 0)
870  {
871  pugi::xml_text txt_obj = child_node.text();
872  pPanel->proc_database = funcPDict.getDatabase(std::stoi(txt_obj.get()));
873  }
874  if(strcmp(child_node.name(), "SortKey") == 0)
875  {
876  pugi::xml_text txt_obj = child_node.text();
877  pPanel->sort_key= txt_obj.get();
878  }
879  }
880 }
881 
883  {
884 
885  if (dynamic_cast<BrowsePanelData<InfoProc<int>>*>(pPanel) != NULL)
886  updateObjFromNodeVal(pPanel->uuid, "ObjectList", pPanel->object_list);
887 
888  if (dynamic_cast<EditPanelData<InfoProc<int>>*>(pPanel))
889  (dynamic_cast<EditPanelData<InfoProc<int>>*>(pPanel))->editing = false;
890  }
891 
893  {
894 
895  if (dynamic_cast<BrowsePanelData<InfoProc<float>>*>(pPanel) != NULL)
896  updateObjFromNodeVal(pPanel->uuid, "ObjectList", pPanel->object_list);
897 
898  if (dynamic_cast<EditPanelData<InfoProc<float>>*>(pPanel))
899  (dynamic_cast<EditPanelData<InfoProc<float>>*>(pPanel))->editing = false;
900  }
901 
903  {
904 
905  // If edit panel can be cast as
906  if (dynamic_cast<BrowsePanelData<InfoProc<std::string>>*>(pPanel) != NULL)
907  {
908  BOOST_LOG_SEV(lg, debug)<<"--> XMLTree::updatePoly-Browse-InfoPorc-string";
909  updateObjFromNodeVal(pPanel->uuid, "ObjectList", pPanel->object_list);
910  pPanel->selected = pPanel->object_list.size();
911  pPanel->refreshItemList();
912  }
913 
914  if (dynamic_cast<EditPanelData<InfoProc<std::string>>*>(pPanel))
915  (dynamic_cast<EditPanelData<InfoProc<std::string>>*>(pPanel))->editing = false;
916 
917  }
918 
920  {
921  if (dynamic_cast<BrowsePanelData<Info>*>(pPanel))
922  {
923  updateObjFromNodeVal(pPanel->uuid, "ObjectList", pPanel->object_list);
924  pPanel->selected = pPanel->object_list.size();
925  pPanel->refreshItemList();
926  }
927  if (dynamic_cast<EditPanelData<Info>*>(pPanel))
928  (dynamic_cast<EditPanelData<Info>*>(pPanel))->editing = false;
929  }
930 
931 
932 } // namespace rtop
933 
934 #endif // _XML_H_
int width
width and height in panel window in ncurses units.
Definition: panel2.h:39
responsible for parsing strings in a line, specfied by some character separator
Definition: rtop_utils.h:55
void kill()
Definition: proc_info.h:44
XMLTree(std::string)
Definition: fileio.h:76
virtual void insertColumn()
mock
Definition: panel2.h:136
void updateViewPanelColors(int, std::string, View *)
Definition: fileio.h:701
void addProcInfo(int, ProcInfo *)
adds ProcInfo object pointer to private object_type dictionary
Definition: mem_func.h:247
void read()
invokes ProcDb update based on properties currently on display in ProcViewPanel
Definition: columns.h:65
void setCurrState(int state)
sets current state
Definition: sm.h:46
ProcInfo * getProcInfo(int)
returns pointer to ProcInfo object of given uuid
Definition: mem_func.h:181
ScreenManager * getScreen(int)
returns pointer to ScreenManager object of given uuid
Definition: mem_func.h:154
void updateObjFromAttrib(int, std::string, View *&)
Definition: fileio.h:487
int editing_color_pair
index of color_pair used for selected menu item in edit mode
Definition: view2.h:49
virtual void toggleEditMode()
mock
Definition: panel2.h:87
MapOfKeyDicts mapKeyDict
global variable for accessing key dictionaries by their uuid
Definition: key_dict.h:175
void addTransition(int, int, int)
add a single transition i.e. tuple (key_input, curr_state, next_state)
Definition: sm.h:150
derived from BrowsePanelData. capable of editing items in ncurses menu list.
Definition: panel2.h:242
void parseCallbacks(pugi::xml_node)
Definition: fileio.h:251
void updateObjFromNodeVal(int, std::string, std::vector< InfoProc< std::string > * > &)
Definition: fileio.h:557
pugi::xml_document doc
Definition: fileio.h:31
void parseProcInfo(pugi::xml_node)
Definition: fileio.h:179
void parseColors(pugi::xml_node)
Definition: fileio.h:113
WINDOW * win
pointer to window associated with the view, contained panels' windows are derived from it
Definition: view2.h:35
void addColumn(int, Columns *)
adds Columns object pointer to private object_type dictionary
Definition: mem_func.h:241
char toChar(std::string str1)
converts string to its equivalent char value.
Definition: rtop_utils.h:37
virtual void insertIntoLeftNbr()
mock
Definition: panel2.h:119
void parseDatabase(pugi::xml_node)
Definition: fileio.h:131
void refreshItemList() override
intended to be used with browse panels. tears down menu and re-initializes with items in object_list
Definition: panel2.h:417
std::vector< std::pair< int, int > > panels_yx
vector of contained panels' window positions within view window
Definition: view2.h:41
void createTreeFirstPass(pugi::xml_node node)
Definition: fileio.h:379
Action object.
Definition: action.h:16
StateMachine smKeys
Keys statemachine.
Definition: panel2.h:47
std::vector< View * > views
collection of view object pointers
Definition: screen2.h:49
std::map< std::string, int > prop_wid_dict
dictionary of column width assigned to each process property
Definition: panel2.h:928
virtual void insertIntoRightNbr()
mock
Definition: panel2.h:121
void parseKeyDictionaries(pugi::xml_node)
Definition: fileio.h:225
virtual void Up()
mock
Definition: panel2.h:105
int selected
item selected in menu, 0 being header item
Definition: panel2.h:267
void addDatabase(int, ProcDb *)
adds ProcDb object pointer to private object_type dictionary
Definition: mem_func.h:253
WINDOW * win
window attached to the panel
Definition: panel2.h:43
data structure that hold property values for processes. contains facilities to enable their proper ac...
Definition: info.h:109
ScreenManager * instantiate()
Definition: fileio.h:103
StateMachine smViews
Views statemachine.
Definition: screen2.h:53
std::string sort_key
sorting key - some process's properties name
Definition: panel2.h:926
virtual void addIntoRightNbr()
mock
Definition: panel2.h:125
std::vector< T * > object_list
vector of pointers to generic type containing value that goes into menu item.
Definition: panel2.h:257
MemFuncPDict funcPDict
Definition: key_dict.h:20
int uUid() const
Definition: screen2.h:43
virtual void moveIntoLeftNbr()
mock
Definition: panel2.h:115
2nd level UI object. Responsible for switching between panels and resolving key input
Definition: view2.h:30
void addSm(int, StateMachine *)
adds StateMachine object pointer to private object_type dictionary
Definition: mem_func.h:235
SimplePanelData * getPanel(int)
returns pointer to SimplePanelData object of given uuid
Definition: mem_func.h:199
pugi::xml_attribute getAttribute(pugi::xml_node, std::string)
Definition: fileio.h:214
panel data structure responsible for displaying of property values for all live processes.
Definition: panel2.h:915
void updatePolymorphicPanel(BrowsePanelData< InfoProc< int >> *)
Definition: fileio.h:882
int header_color_pair
index of color_pair used for panel header
Definition: view2.h:55
virtual void editModeOff()
mock
Definition: panel2.h:91
virtual void editModeOn()
mock
Definition: panel2.h:89
std::map< int, std::pair< int, int > > colors
Definition: params.h:11
std::vector< std::string > Words() const
returns a vector of parsed strings stored in StringParser::words
Definition: rtop_utils.h:70
virtual void setHeader(std::string)
mock
Definition: panel2.h:101
virtual void remove()
mock
Definition: panel2.h:127
src::severity_logger< severity_level > lg
Definition: rtop_logger.h:108
void updateChildren(int, std::string, std::vector< View * > &)
Definition: fileio.h:743
void addScreen(int, ScreenManager *)
adds ScreenManager object pointer to private object_type dictionary
Definition: mem_func.h:217
data structure that defines type of entry from which panel menu entrires obtain their c-string data
Definition: info.h:25
Top Level UI object. Responsible to switching between views and capturing key input.
Definition: screen2.h:34
derived from SimplePanelData. capable of storing list of item in a ncurses menu object.
Definition: panel2.h:253
holds a dictionary of key values and corresponding Action list. Provides API to resolve the keys
Definition: key_dict.h:25
ProcDb * proc_database
pointer reference to ProcDb object
Definition: panel2.h:924
virtual void addIntoLeftNbr()
mock
Definition: panel2.h:123
SimplePanelData * active_proc_panel
reference to panel data structure containing property names to be displayed. clm_names,...
Definition: panel2.h:934
pugi::xml_node findNode(pugi::xml_node, int uuid)
Definition: fileio.h:449
View * currView
pointer to current view object
Definition: screen2.h:47
int selection_color_pair
index of color_pair used for selected menu item in non-edit mode
Definition: view2.h:51
virtual void moveLeft()
mock
Definition: panel2.h:140
void registerFunc(std::string func_name, void(ScreenManager::*)())
registers ScreenManager class member methods
Definition: mem_func.h:88
data structure that defines type of entry from which panel menu entries obtain their c-string data
Definition: info.h:71
StateMachine smKeys
Keys statemachine.
Definition: screen2.h:51
Base class in heirarchy of UI objects responsible to storing the content associated with a panel and ...
Definition: panel2.h:34
void addView(int, View *)
adds ScreenManager object pointer to private object_type dictionary
Definition: mem_func.h:223
interfaces with linux API to read process information and update ProcDb with it
Definition: proc_info.h:24
void addKeyDict(int, KeyDict)
adds key dictionary corresponding to the supplied key_dict_uuid
Definition: key_dict.h:145
void refresh()
refreshes screen
Definition: screen2.h:135
ProcDb * getDatabase(int)
returns pointer to ProcDb object of given uuid
Definition: mem_func.h:163
void addPanel(int, SimplePanelData *)
adds SimplePanelData object pointer to private object_type dictionary
Definition: mem_func.h:229
statemachine that uses integer corresponding to object uuids to represent states
Definition: sm.h:20
PANEL * panel
panel to which the data structure is associated
Definition: panel2.h:41
void next()
same as StateMachine::next(int) except that reads key input from global
Definition: sm.h:114
parses config file
Definition: fileio.h:28
virtual void moveIntoRightNbr()
mock
Definition: panel2.h:117
virtual void refresh()
mock
Definition: panel2.h:138
void stale()
sets changed to false
Definition: sm.h:59
View * getView(int)
returns pointer to View object of given uuid
Definition: mem_func.h:190
std::map< std::string, int > color_map
dictionary containing color_pair number corresponding to each color_name
Definition: rtop_utils.h:190
virtual void deleteColumn()
mock
Definition: panel2.h:134
Definition: action.h:7
void createPanel(int, int, std::string)
Definition: fileio.h:336
void markPid()
Definition: columns.h:45
virtual void Down()
mock
Definition: panel2.h:103
void parseColumn(pugi::xml_node)
Definition: fileio.h:190
responsible for managing the flow of information between ProcViewPanel, ProcDb and ProcInfo
Definition: columns.h:16
virtual void moveRight()
mock
Definition: panel2.h:142