artdaq_mfextensions  v1_06_02
ma_richmsg.cpp
1 #include "ErrorHandler/MessageAnalyzer/ma_richmsg.h"
2 #include "ErrorHandler/MessageAnalyzer/ma_rule.h"
3 
4 using namespace novadaq::errorhandler;
5 
6 namespace {
7 
8 bool parse_msg_ref(std::string const& s, ma_rule const* rule, std::vector<cond_arg_t>& symbols)
9 {
10  size_t pos = s.find('.');
11 
12  if (pos == std::string::npos) return false; // no .
13 
14  cond_idx_t cond_idx = rule->get_cond_idx(s.substr(0, pos));
15 
16  ++pos;
17 
18  if (pos == s.size() || s[pos] != '$') return false; // no $
19 
20  ++pos;
21 
22  if (pos == s.size() || std::string("stmg").find(s[pos]) == std::string::npos) return false;
23 
24  switch (s[pos])
25  {
26  case 's': // $s, source
27  if (pos == s.size() - 1)
28  {
29  symbols.push_back(cond_arg_t(cond_idx, SOURCE));
30  return true;
31  }
32  return false;
33 
34  case 't': // $t, target
35  if (pos == s.size() - 1)
36  {
37  symbols.push_back(cond_arg_t(cond_idx, TARGET));
38  return true;
39  }
40  return false;
41 
42  case 'm': // $m, message
43  if (pos == s.size() - 1)
44  {
45  symbols.push_back(cond_arg_t(cond_idx, MESSAGE));
46  return true;
47  }
48  return false;
49 
50  case 'g': // $gn, group-n
51  if (pos == s.size() - 2 && s[pos + 1] >= '1' && s[pos + 1] <= '9')
52  {
53  symbols.push_back(cond_arg_t(cond_idx, (arg_t)(GROUP1 + s[pos + 1] - '1')));
54  return true;
55  }
56  return false;
57 
58  default:
59  return false;
60  }
61 }
62 
63 bool parse_msg(std::string const& s, ma_rule const* rule, std::string& stripped_msg, std::vector<size_t>& insert_pos, std::vector<cond_arg_t>& symbols)
64 {
65  size_t old = 0;
66  size_t pos = s.find("${");
67  size_t ins = 0;
68 
69  while (pos != std::string::npos)
70  {
71  ins += (pos - old);
72  insert_pos.push_back(ins);
73  stripped_msg.append(s, old, pos - old);
74 
75  size_t close = s.find('}', pos);
76 
77  if (close == std::string::npos)
78  return false; // no close '}'
79 
80  if (!parse_msg_ref(s.substr(pos + 2, close - pos - 2), rule, symbols))
81  return false;
82 
83  old = close + 1;
84  pos = s.find("${", old);
85  }
86 
87  if (old < s.size())
88  stripped_msg.append(s.substr(old));
89 
90  return true;
91 }
92 
93 } // end of anonymous namespace
94 
95 ma_richmsg::ma_richmsg()
96  : rule(NULL)
97  , plain_msg()
98  , stripped_msg()
99  , insert_pos()
100  , symbols()
101 {
102 }
103 
104 ma_richmsg::ma_richmsg(std::string const& s, ma_rule const* parent)
105  : rule(NULL)
106  , plain_msg()
107  , stripped_msg()
108  , insert_pos()
109  , symbols()
110 {
111  init(parent, s);
112 }
113 
114 void ma_richmsg::init(ma_rule const* parent, std::string const& s)
115 {
116  rule = parent;
117  plain_msg = s;
118 
119  if (!parse_msg(plain_msg, rule, stripped_msg, insert_pos, symbols))
120  throw std::runtime_error("Error parsing rule messages!");
121 }
122 
123 const std::string& ma_richmsg::plain_message() const
124 {
125  return plain_msg;
126 }
127 
128 std::string ma_richmsg::message() const
129 {
130  std::string result = stripped_msg;
131  ma_domain const& alarm = rule->get_alarm();
132 
133  for (int i = symbols.size() - 1; i >= 0; --i)
134  {
135  ma_condition* cond_ptr = symbols[i].first.first;
136  size_t cond_idx = symbols[i].first.second;
137  arg_t cond_arg = symbols[i].second;
138 
139  result.insert(insert_pos[i], cond_ptr->get_arg(alarm[cond_idx], cond_arg));
140  }
141 
142  return result;
143 }