command.cpp
Go to the documentation of this file.
1 
8 
10 
11 Command::Command(const CommandParams& cmdParams, const std::shared_ptr<Syntax> syntax,
12  const std::unordered_map<std::string,
13  std::shared_ptr<CommandOptions>>& options)
14 {
15  name = cmdParams.name;
16  cmdHasParams = cmdParams.cmdHasParams;
17  cmdHasResponse = cmdParams.cmdHasResponse;
18  respHasParams = cmdParams.respHasParams;
19  this->options = options;
20 
21  parameterTypes = std::unordered_map<std::string, std::string>();
22  if (cmdParams.cmdHasParams || cmdParams.respHasParams)
23  {
24  for (std::pair<std::string, std::string> param : cmdParams.params)
25  {
26  parameterTypes.insert(param);
27  }
28  }
29 
30  commandTemplate = std::vector<std::pair<int, insertInstruction>>();
31  cmdKeyWords = std::vector<std::string>();
32  cmdParameter = std::vector<std::string>();
33  cmdParameterSet = std::unordered_set<std::string>();
34 
35  std::vector<std::string> split;
36  boost::split(split, cmdParams.cmd, boost::is_any_of(" "));
37  int keyWordCounter = 0;
38  int paramCounter = 0;
39  for (std::string s : split)
40  {
41  if (s.find('$') != std::string::npos)
42  {
43  commandTemplate.push_back(
44  std::make_pair(paramCounter, &Command::insertCmdParameter));
45  std::string param = s.substr(1, std::string::npos);
46  cmdParameter.push_back(param);
47  cmdParameterSet.insert(param);
48  paramCounter++;
49  }
50  else
51  {
52  commandTemplate.push_back(
53  std::make_pair(keyWordCounter, &Command::insertCmdKeyword));
54  cmdKeyWords.push_back(s);
55  keyWordCounter++;
56  }
57  }
58  responseTemplate = std::vector<std::pair<std::string, bool>>();
59  if (cmdParams.cmdHasResponse)
60  {
61  simpleResponse = "";
62  if (!cmdParams.respHasParams)
63  {
64  simpleResponse = cmdParams.response;
65  }
66  else
67  {
68  std::vector<std::string> split2;
69  boost::split(split2, cmdParams.response, boost::is_any_of(" "));
70  keyWordCounter = 0;
71  paramCounter = 0;
72  for (std::string s : split2)
73  {
74  if (s.find('$') != std::string::npos)
75  {
76  std::string param = s.substr(1, std::string::npos);
77  responseTemplate.push_back(std::make_pair(param, true));
78  }
79  else
80  {
81  responseTemplate.push_back(std::make_pair(s, false));
82  }
83  }
84  }
85  }
86 }
87 
89  std::string& out)
90 {
91  std::stringstream ss = std::stringstream();
92  std::string s;
93  for (auto component : commandTemplate)
94  {
95  s = "";
96  (this->*component.second)(component.first, inputParams, s);
97  ss << " " << s;
98  }
99  out = ss.str().substr(1, std::string::npos);
100 }
101 
103  const std::vector<std::string>& optionsList,
104  std::string& out)
105 {
106  std::string cmd = "";
107  generateCommand(inputParams, cmd);
108  std::stringstream ss = std::stringstream();
109  ss << cmd;
110  for (std::string s : optionsList)
111  {
112  const CommandOptions& cmdopt = *options[s];
113  if(cmdopt.opt.size()<1) break;
114  std::vector<std::string> split;
115  boost::split(split, cmdopt.opt, boost::is_any_of(" ="));
116  for (std::string s1 : split)
117  {
118  if (s1.at(0) == '$')
119  {
120  std::string value = "";
121  inputParams.getParameterValueAsString(s1.substr(1, std::string::npos),
122  value);
123  ss << "=" << value;
124  }
125  else
126  {
127  ss << " " << syntax->optionsPrefix << s1;
128  }
129  }
130  }
131  out = ss.str();
132 }
133 
134 const bool Command::verifyResponse(const Parameter::ParameterMap& inputParams,
135  const std::string& responseOrig,
136  Parameter::ParameterMap& outputParams)
137 {
138  // preprocessing
139  std::string response = responseOrig;
140  response.erase(boost::remove_if(response, boost::is_any_of(syntax->answerOnCmdPrefix +
141  syntax->endOfFrame + syntax->endOfMessage)),
142  response.end());
143  boost::trim(response);
144  // start
145  outputParams = Parameter::ParameterMap();
146  // first case -> no response
147  if (!cmdHasResponse)
148  return true;
149  // second case -> static response
150  if (!respHasParams)
151  {
152  return response.compare(simpleResponse) == 0;
153  }
154  // third case -> response contains any amount of parameter
155  std::vector<std::string> split;
156  boost::split(split, response, boost::is_any_of(" ="));
157  // response contains not enough tokens/params
158  if (split.size() < responseTemplate.size())
159  return false;
160  // continue
161  for (int i = 0; i < split.size(); i++)
162  {
163  // exit if the response contains more elements than expected
164  if (i >= responseTemplate.size())
165  return false;
166  // check if this component is a variable
167  const std::string& param = responseTemplate[i].first;
168  if (responseTemplate[i].second)
169  {
170  // if the param appears in cmd. and resp. -> indicates reply on cmd
171  if (cmdParameterSet.find(param) != cmdParameterSet.end())
172  {
173  std::string expectedValue = "";
174  inputParams.getParameterValueAsString(responseTemplate[i].first,
175  expectedValue);
176  if (split[i].compare(expectedValue) != 0)
177  return false;
178  }
179  // if param doesn't appear in cmd. -> indicates request for data
180  else
181  {
182  // special treatment for string types
183  if(parameterTypes[param].compare("string_t")==0){
184  std::stringstream ss = std::stringstream();
185  for(int n = i; n<split.size(); n++){
186  ss<<" "<<split[n];
187  }
188  std::string out = ss.str().substr(1,std::string::npos);
189  outputParams.insertParameter(param, parameterTypes[param], out);
190  return true;
191  }
192  //standard case
193  outputParams.insertParameter(param, parameterTypes[param]);
194  outputParams.setParameterValueAsString(param, split[i]);
195  }
196  }
197  // check if keyWord equals the expected response keyWord
198  else
199  {
200  if (split[i].compare(param) != 0)
201  return false;
202  }
203  }
204 
205  return true;
206 }
207 
208 const bool Command::verifyResponse(const Parameter::ParameterMap& inputParams,
209  const std::vector<std::string>& options,
210  const std::string& responseOrig,
211  Parameter::ParameterMap& outputParams)
212 {
213  // preprocessing
214  std::string response = responseOrig;
215  response.erase(
216  boost::remove_if(response, boost::is_any_of(syntax->answerOnCmdPrefix)),
217  response.end());
218  boost::trim(response);
219  // start
220  outputParams = Parameter::ParameterMap();
221  // first case -> no response
222  if (!cmdHasResponse)
223  return true;
224  // second case -> there may be a response of some kind
225  std::vector<std::shared_ptr<CommandOptions>> optWithResponse = std::vector<std::shared_ptr<CommandOptions>>();
226  for (std::string opt : options)
227  {
228  if (this->options[opt]->optReturnsParams)
229  {
230  // gather all options that provoke an additional parameter in the response
231  optWithResponse.push_back(this->options[opt]);
232  }
233  }
234  std::vector<std::string> split;
235  int splitIndex = 0;
236  // second case a) -> static response with opt. parameters
237  if (!respHasParams)
238  {
239  // exit if the static response w.o. options doesn't match
240  if (simpleResponse.compare(response.substr(0, simpleResponse.size())) != 0)
241  return false;
242  // extract rest of response and separate on whitespaces
243  std::string restResponse =
244  response.substr(simpleResponse.size(), std::string::npos);
245  boost::split(split, restResponse, boost::is_any_of(" "));
246  }
247  else
248  {
249  // second case b) case -> response with params and opt. parameters
250  // check every key word and param of the unmodified response
251  boost::split(split, response, boost::is_any_of(" "));
252  for (int i = 0; i < split.size(); i++)
253  {
254  // break if the response contains more elements than expected
255  if (i >= responseTemplate.size())
256  {
257  splitIndex = i;
258  break;
259  }
260  // check if this component is a variable
261  const std::string& param = responseTemplate[i].first;
262  if (responseTemplate[i].second)
263  {
264  // if the param appears in cmd. and resp. -> indicates reply on cmd
265  if (cmdParameterSet.find(param) != cmdParameterSet.end())
266  {
267  std::string expectedValue = "";
268  inputParams.getParameterValueAsString(responseTemplate[i].first,
269  expectedValue);
270  if (split[i].compare(expectedValue) != 0)
271  return false;
272  }
273  // if param doesn't appear in cmd. -> indicates request for data
274  else
275  {
276  outputParams.setParameterValueAsString(param, split[i]);
277  }
278  }
279  // check if keyWord equals the expected response keyWord
280  else
281  {
282  if (split[i].compare(param) != 0)
283  return false;
284  }
285  }
286  }
287  // at last, check every key word and parameter of the modified response
288  for (std::shared_ptr<CommandOptions> opt : optWithResponse)
289  {
290  // if there are more tokens in the response than expected -> exit
291  if (splitIndex >= split.size())
292  return false;
293  // separate expected option response into tokens at white spaces
294  std::vector<std::string> optionSplit;
295  boost::split(optionSplit, opt->response, boost::is_any_of(" "));
296  for (std::string s : optionSplit)
297  {
298  // if there are more tokens in the response than expected -> exit
299  if (splitIndex >= split.size())
300  return false;
301  // case: token expected as a parameter
302  int dollarIdx = s.find('$');
303  int assignIdx = s.find('=');
304  if (dollarIdx != std::string::npos && dollarIdx == 0)
305  {
306  // if the parameter is expected in out and input -> check for equality
307  std::string param = s.substr(1, std::string::npos);
308  // check if param is string type -> special treatment required
309  std::string paramType = "";
310  for(auto params : opt->params){
311  if(params.first.compare(param)==0){
312  paramType = params.second;
313  break;
314  }
315  }
316  if(paramType.size()<1) return false;
317  if(paramType.compare("string_t")==0){
318  std::stringstream ss = std::stringstream();
319  for(int n = splitIndex; n<split.size(); n++){
320  ss<<" "<<split[n];
321  }
322  std::string out = ss.str().substr(1,std::string::npos);
323  outputParams.insertParameter(param, paramType, out);
324  return true;
325  }
326  // continue with standard case
327  if (outputParams.isParamInMap(param) && inputParams.isParamInMap(param))
328  {
329  std::string paramValue = "";
330  inputParams.getParameterValueAsString(param, paramValue);
331  if (split[splitIndex].compare(paramValue) != 0)
332  return false;
333  }
334  // if the parameter is only expected in the output -> insert in output
335  else
336  {
337  outputParams.setParameterValueAsString(param, split[splitIndex]);
338  }
339  }
340  else if(dollarIdx!=std::string::npos && assignIdx!=std::string::npos){
341  std::vector<std::string> asignSplit;
342  boost::split(asignSplit, s, boost::is_any_of("="));
343  if(split[splitIndex].find('=')==std::string::npos) return false;
344  std::vector<std::string> responseSplit;
345  boost::split(responseSplit, split[splitIndex], boost::is_any_of("="));
346 
347  if(asignSplit.size()!=2) return false;
348  if(responseSplit.size()!=2) return false;
349  std::string optParam = asignSplit[1].substr(1, std::string::npos);
350  std::string optKey = asignSplit[0].substr(0, std::string::npos);
351  std::string respParam = responseSplit[1].substr(0, std::string::npos);
352  std::string respKey = responseSplit[0].substr(0, std::string::npos);
353  if(optKey.compare(respKey)!=0) return false;
354  std::string optParamValue;
355  if(!inputParams.isParamInMap(optParam)) return false;
356  inputParams.getParameterValueAsString(optParam, optParamValue);
357  if(respParam.compare(optParamValue)!=0) return false;
358 
359  }
360  // case: token expected as key word
361  else
362  {
363  if (s.compare(split[splitIndex]) != 0)
364  return false;
365  }
366  splitIndex++;
367  }
368  }
369 
370  return true;
371 }
372 
373 const std::string& Command::getName() const { return name; }
374 
375 void Command::insertCmdKeyword(const int& index,
376  const Parameter::ParameterMap& input,
377  std::string& out)
378 {
379  if (index >= cmdKeyWords.size())
380  throw std::out_of_range("Command keyword index out of bounds! Size: " +
381  std::to_string(cmdKeyWords.size()) + " Index: " +
382  std::to_string(index));
383  out = cmdKeyWords[index];
384 }
385 
386 void Command::insertCmdParameter(const int& index,
387  const Parameter::ParameterMap& input,
388  std::string& out)
389 {
390  if (index >= cmdParameter.size())
391  throw std::out_of_range("Command parameter index out of bounds! Size: " +
392  std::to_string(cmdParameter.size()) + " Index: " +
393  std::to_string(index));
394  const std::string& param = cmdParameter[index];
395  if (!input.isParamInMap(param))
396  throw std::out_of_range("Command parameter" + param + "not in map.");
397  input.getParameterValueAsString(param, out);
398 }
std::vector< std::string > cmdKeyWords
Definition: command.h:206
std::vector< std::string > cmdParameter
Definition: command.h:208
Header file for the Command class.
std::string name
Definition: command.h:33
bool cmdHasParams
Definition: command.h:34
Command()
Command default constructor.
Definition: command.cpp:9
std::unordered_set< std::string > cmdParameterSet
Definition: command.h:204
std::string cmd
Definition: command.h:38
bool respHasParams
Definition: command.h:195
void getParameterValueAsString(const std::string &name, std::string &out) const
Get the string representation of a value from a parameter in this map with the given name...
Definition: parameter.h:271
The Parameter::ParameterMap class provides a map functionality for Parameter::Parameter objects conta...
Definition: parameter.h:163
const bool isParamInMap(const std::string &name) const
Is a parameter with the given name contained within this map?.
Definition: parameter.h:178
void insertCmdKeyword(const int &index, const Parameter::ParameterMap &input, std::string &out)
Command template building function for a keyword token.
Definition: command.cpp:375
bool cmdHasResponse
Definition: command.h:40
bool respHasParams
Definition: command.h:41
bool cmdHasParams
Definition: command.h:193
const bool verifyResponse(const Parameter::ParameterMap &inputParams, const std::string &responseOrig, Parameter::ParameterMap &outputParams)
Verifies a given response based on the internal template given all necessary input parameter values...
Definition: command.cpp:134
std::string name
Definition: command.h:192
The CommandOptions class serves as a data struct to inform Command objects about all modifiers that c...
Definition: command.h:55
std::string opt
Definition: command.h:62
std::string simpleResponse
Definition: command.h:217
std::unordered_map< std::string, std::string > parameterTypes
Definition: command.h:200
std::unordered_map< std::string, std::shared_ptr< CommandOptions > > options
Definition: command.h:197
std::vector< std::pair< int, insertInstruction > > commandTemplate
Definition: command.h:212
void insertParameter(const std::string &name, const std::string &type, const T &value, const bool isValid=true)
Insert a new parameter in this map, with the given name, type and value.
Definition: parameter.h:219
std::vector< std::pair< std::string, bool > > responseTemplate
Definition: command.h:220
std::shared_ptr< Syntax > syntax
Definition: command.h:196
std::vector< std::pair< std::string, std::string > > params
Definition: command.h:36
void setParameterValueAsString(const std::string &name, const std::string &input, const bool isValid=true)
Set the value of a parameter in this map with the given name from a string.
Definition: parameter.h:406
std::string response
Definition: command.h:42
The CommandParams class serves as a data struct to configure Command objects.
Definition: command.h:31
void insertCmdParameter(const int &index, const Parameter::ParameterMap &input, std::string &out)
Command template building function for a parameter token.
Definition: command.cpp:386
const std::string & getName() const
Getter for the unique name attribute.
Definition: command.cpp:373
void generateCommand(const Parameter::ParameterMap &inputParams, std::string &out)
Generates a command string from the internal template given all necessary parameter values...
Definition: command.cpp:88
bool cmdHasResponse
Definition: command.h:194


pses_ucbridge
Author(s): Sebastian Ehmes
autogenerated on Sat Oct 28 2017 19:16:13