fipa_acl  1.4
bitefficient_message_format.cpp
Go to the documentation of this file.
2 
3 #include <iostream>
4 #include <fstream>
5 #include <sstream>
6 #include <string>
7 #include <cstring>
8 #include <iterator>
9 #include <stdexcept>
10 #include <arpa/inet.h>
11 #include <limits>
12 
13 #include<boost/algorithm/string/erase.hpp>
14 
15 #include <base-logging/Logging.hpp>
16 
17 #include <fipa_acl/message_generator/acl_message.h>
18 #include <fipa_acl/message_generator/message_format.h>
19 
20 #include "bitefficient_format.h"
21 
22 namespace fipa {
23 namespace acl {
24 
25 std::string BitefficientMessageFormat::apply(const ACLMessage& msg) const
26 {
27  std::string mes = getBitHeader() + getBitMessageType(msg) + getBitMessageParameters(msg);
28 
29  // Since content can be of arbitrary sicne add content here
30  // to avoid copying around large content object
31  const std::string* content = msg.getContentPtr();
32  if (!content->empty())
33  {
34  uint32_t digit = content->size();
35  mes += 0x04;
36 
37  // Check if there is binary content to be set
38  // add choose encoding based on the respective content size
39  if(strlen(content->c_str()) != digit)
40  {
41  if(digit <= std::numeric_limits<uint8_t>::max())
42  {
43  uint8_t dataSize = digit;
44  mes += 0x16;
45  mes.append(reinterpret_cast<const char*>(&dataSize), sizeof(uint8_t));
46  mes += *content;
47  } else if (digit <= std::numeric_limits<uint16_t>::max())
48  {
49  uint16_t dataSize = digit;
50  dataSize = htons(dataSize);
51  mes += 0x17;
52  mes.append(reinterpret_cast<const char*>(&dataSize),sizeof(uint16_t));
53  mes += *content;
54  } else {
55  digit = htonl(digit);
56  mes += 0x19;
57  mes.append(reinterpret_cast<const char*>(&digit),sizeof(uint32_t));
58  mes += *content;
59  }
60  } else { // use string with null terminated (more efficient)
61  char digitString[100];
62  snprintf(digitString,100, "%c#%d%c",0x14,digit,'\"');
63  mes += digitString;
64  mes += *content;
65  mes += char(0x00);
66  }
67  }
68 
70  return mes;
71 }
72 
74 {
75  std::string retstr;
76 
77  char id = getBitMessageID();
78  char version = getBitMessageVersion();
79 
80  return retstr.append(1,id).append(1,version);
81 }
82 
84 {
85  if (!getUseCodeTables())
86  {
87  return 0xfa;
88  }
89  if (getUpdateCodeTables())
90  {
91  return 0xfb;
92  }
93  return 0xfc;
94 }
95 
97 {
98  std::string version = getVersion();
99  return char(((int) version[0]-48)*16 + ((int)version[2]-48));
100 }
101 
103 {
104  std::string performative = msg.getPerformative();
105  // Check if we have one of the predefined performatives
106  for (int i = (int) ACLMessage::ACCEPT_PROPOSAL; i < (int) ACLMessage::END_PERFORMATIVE; ++i)
107  {
108  if (PerformativeTxt[(ACLMessage::Performative) i] == performative)
109  {
110  char a[2];
111  a[0] = char(i+1);
112  a[1] = '\0';
113  return std::string(a);
114  }
115  }
116 
117  // actually we will have user defined performative here
118  if(performative.empty())
119  throw MessageGeneratorException("Performative cannot be empty");
120 
121  return (char(0x00) + getBitBinWord(performative));
122 }
123 
124 std::string BitefficientMessageFormat::getBitBinWord(const std::string& sword) const
125 {
126  if (!getUseCodeTables())
127  {
128  return (char(0x10) + sword + char(0x00));
129  }
130 
131  throw std::runtime_error("BitefficientMessageFormat does not support codetables");
132 }
133 
135 {
137 }
138 
139 
140 
142 {
143  std::string retstr;
144 
145  // Check if entries exists for the predefined message parameters
146  // sender is not always required,
147  AgentID sender = msg.getSender();
148  if ( !sender.empty())
149  {
150  LOG_DEBUG("Writing sender: %s", getBitAID(sender, getResolverDepth()).c_str());
151  retstr = retstr + char(0x02) + getBitAID(sender, getResolverDepth());
152  }
153 
154  std::vector<AgentID> receivers = msg.getAllReceivers();
155  if (!receivers.empty())
156  {
157  retstr = retstr + char(0x03) + getBitAIDColl(receivers,getResolverDepth());
158  }
159 
161 
162  std::string replyWith = msg.getReplyWith();
163  if (!replyWith.empty())
164  retstr = retstr + char(0x05) + getBitBinExpression(replyWith,'s');
165 
166  if (!msg.getReplyBy().isNull())
167  {
168  retstr = retstr + char(0x06) + BitefficientFormat::getBinDateTimeToken(msg.getReplyBy());
169  }
170 
171  std::string inReplyTo = msg.getInReplyTo();
172  if (!inReplyTo.empty())
173  {
174  retstr = retstr + char(0x07) + getBitBinExpression(inReplyTo,'s');
175  }
176 
177  std::vector<AgentID> replyTo = msg.getAllReplyTo();
178  if (!replyTo.empty())
179  {
180  retstr = retstr + char(0x08) + getBitAIDColl(replyTo,getResolverDepth());
181  }
182 
183  std::string language = msg.getLanguage();
184  if (!language.empty())
185  {
186  retstr = retstr + char(0x09) + getBitBinExpression(language,'s');
187  }
188 
189  std::string encoding = msg.getEncoding();
190  if (!encoding.empty())
191  {
192  retstr = retstr + char(0x0a) + getBitBinExpression(encoding,'s');
193  }
194 
195  std::string ontology = msg.getOntology();
196  if (!ontology.empty())
197  retstr = retstr + char(0x0b) + getBitBinExpression(ontology,'s');
198 
199  std::string protocol = msg.getProtocol();
200  if (!protocol.empty())
201  {
202  retstr = retstr + char(0x0c) + getBitBinWord(protocol);
203  }
204 
205  std::string conversationID = msg.getConversationID();
206  if (!conversationID.empty())
207  retstr = retstr + char(0x0d) + getBitBinExpression(conversationID,'s');
208 
209  return retstr;
210 }
211 
213 {
214  std::string retstr;
215 
216  std::vector<UserdefParam> s = msg.getUserdefParams();
217  if( s.empty() )
218  {
219  return retstr;
220  }
221 
222  LOG_WARN("Userdefined parameters: %d", (int) s.size());
223 
224  std::vector<UserdefParam>::iterator it;
225  it = s.begin();
226  for (; it != s.end(); ++it)
227  {
228  retstr = retstr + char(0x00) + bitParseParam(*it);
229  }
230 
231  return retstr;
232 }
233 
234 std::string BitefficientMessageFormat::getBitUserdefParams(const std::vector<UserdefParam>& params) const
235 {
236  std::string retstr;
237  std::vector<UserdefParam>::const_iterator it = params.begin();
238  for (; it != params.end(); ++it)
239  retstr = retstr + char(0x04) + bitParseParam(*it);
240 
241  return retstr;
242 }
243 
245 {
246  return getBitBinWord(p.getName()) + getBitBinExpression(p.getValue(),'s');
247 }
248 
249 
250 std::string BitefficientMessageFormat::getBitAID(const AgentID& aid, int depth) const
251 {
252  if (depth > 0)
253  return char(0x02) + getBitBinWord(aid.getName())+
254  (( aid.getAddresses().empty() == true)? "" : (char(0x02) + getBinURLCol(aid.getAddresses()))) +
255  (( aid.getResolvers().empty() == true)? "" : getBitResolvers(aid.getResolvers(),depth-1)) +
256  (( aid.getUserdefParams().empty() == true)? "" : getBitUserdefParams(aid.getUserdefParams())) +
258 
259 
260  return char(0x02) + getBitBinWord(aid.getName())+
261  (( aid.getAddresses().empty() == true)? "" : (char(0x02) + getBinURLCol(aid.getAddresses()))) +
262  (( aid.getUserdefParams().empty() == true)? "" : getBitUserdefParams(aid.getUserdefParams())) +
264 }
265 
266 
267 std::string BitefficientMessageFormat::getBinURLCol(const std::vector<std::string>& adrr) const
268 {
269  std::string retstr;
270  std::vector<std::string>::const_iterator it = adrr.begin();
271  for (; it != adrr.end(); ++it)
272  retstr = retstr + getBitBinWord(*it);
273 
274  retstr = retstr + BitefficientFormat::getEOFCollection();
275  return retstr;
276 }
277 
278 std::string BitefficientMessageFormat::getBitResolvers(const std::vector<AgentID>& aids,int depth) const
279 {
280  return (char(0x03) + getBitAIDColl(aids,depth));
281 }
282 
283 std::string BitefficientMessageFormat::getBitAIDColl(const std::vector<AgentID>& aids, int depth) const
284 {
285  std::string retstr;
286  std::vector<AgentID>::const_iterator it = aids.begin();
287  for (; it != aids.end(); ++it)
288  retstr = retstr + getBitAID(*it, depth);
289  return retstr + BitefficientFormat::getEOFCollection();
290 }
291 
292 std::string BitefficientMessageFormat::getByteLengthEncodedString(const std::string& sword) const
293 {
294  return char(0x14) + BitefficientFormat::getByteLengthEncodedString(sword) + char(0x00);
295 }
296 
297 std::string BitefficientMessageFormat::getBitBinExpression(const std::string& sword,char c) const
298 {
299  //if (!sword.compare(msg.getContent()))
300  //{
301  // return char(0xff) + getBitBinString(sword);
302  //}
303 
304  if (c == 's')
305  return getBitBinString(sword);
306 
307  if (c == 'w')
308  return getBitBinWord(sword);
309 
310  throw std::runtime_error("BitefficientMessageFormat: getBitBinExpression called with wrong base character");
311 }
312 
313 std::string BitefficientMessageFormat::getBitBinExpression(double n,char base) const
314 {
315  return getBitBinNumber(n,base);
316 }
317 
318 std::string BitefficientMessageFormat::getBitBinNumber(double n,char base) const
319 {
320  std::stringstream ss (std::stringstream::in | std::stringstream::out);
321  ss << n;
322  std::string test = ss.str();
323 
324  if(base == 'h')
325  return char(0x13) + BitefficientFormat::getDigits(test);
326  if(base == 'o' || base == 'd')
327  return char(0x12) + BitefficientFormat::getDigits(test);
328 
329  throw std::runtime_error("BitefficientMessageFormat: getBitBinNumber called with wrong base character");
330 }
331 
332 std::string BitefficientMessageFormat::getBitBinString(const std::string& sword) const
333 {
334  if (!getUseCodeTables())
335  {
336  return char(0x14) + ( '\"' + sword + '\"') + char(0x00);
337  }
338  // char(0x15) + return getCTIndex(sword);
339  throw std::runtime_error("BitefficientMessageFormat does not support codetables");
340 
341 }
342 
343 } // end namespace acl
344 } // end namespace fipa
std::string getBitBinString(const std::string &sword) const
implements the binary string production; functionality not complete as code tables are not yet implem...
std::string getEncoding() const
Definition: acl_message.h:258
std::string apply(const ACLMessage &msg) const
int getResolverDepth() const
const Resolvers & getResolvers() const
Get list of resolvers.
Definition: agent_id.h:127
bool empty() const
Check if AgentId is empty, i.e. does not contain a name.
Definition: agent_id.cpp:210
char getBitMessageID() const
depending on the flags it sets the ID
std::vector< UserdefParam > getUserdefParams() const
Definition: acl_message.h:323
const std::string & getName() const
setter and getter methods for all fields; they do not result in deep-copies assignments/retreivals, but this can be easily changed if needed through the overloaded operator which do
Definition: agent_id.h:90
base::Time getReplyBy() const
Definition: acl_message.h:334
static std::string getDigits(const std::string &numberString)
std::string getPerformative() const
Definition: acl_message.h:139
bool getUseCodeTables() const
std::string bitParseParam(const UserdefParam &) const
parses one user defined parameter the specification does not differentiate at this level between mess...
std::string getReplyWith() const
Definition: acl_message.h:217
std::string getOntology() const
Definition: acl_message.h:248
AgentIDList getAllReplyTo() const
Definition: acl_message.h:192
const std::string & getValue() const
Definition: userdef_param.h:65
const std::vector< std::string > & getAddresses() const
Retrieve list of addresses.
Definition: agent_id.h:110
Performative
an enum of all the predefined fipa message performatives so far, presented in the order used in the m...
Definition: acl_message.h:64
const std::string * getContentPtr() const
Definition: acl_message.h:299
std::string getBitUserdefParams(const std::vector< UserdefParam > &params) const
parses a set of user defined parameters; different from the getBitUserdefMessageParams() method in th...
std::string getVersion() const
char getBitMessageVersion() const
gets the message version in one byte the message version has a very specific format: digit+dot+digit ...
std::string getLanguage() const
Definition: acl_message.h:268
static std::string getByteLengthEncodedString(const std::string &sword)
std::string getBitBinWord(const std::string &sword) const
quite frequently used production; currently it does not have complete functionality: the code tables ...
std::string getInReplyTo() const
Definition: acl_message.h:207
std::string getBitMessageParameters(const ACLMessage &msg) const
puts together all the message parameters
std::map< ACLMessage::Performative, std::string > PerformativeTxt
Definition: acl_message.cpp:15
const std::string & getName() const
Definition: userdef_param.h:77
std::string getBitResolvers(const std::vector< AgentID > &aids, int depth) const
basically a wrapper function of the getBitAIDColl(), to add the required specific flag ...
std::string getBitBinNumber(double n, char base) const
parses a number according to the specification(see comment 9 of the specification) for ease it is tur...
AgentID getSender() const
Definition: acl_message.h:311
std::string getBinURLCol(const std::vector< std::string > &) const
currently used to encode the addresses of the AgentID instances(strings)
std::string getProtocol() const
Definition: acl_message.h:238
static char getEOFCollection()
returns the very used end-of-collection marker
This class provides a representation of a message conforming to the FIPA specification SC00061...
Definition: acl_message.h:55
std::string getBitAIDColl(const std::vector< AgentID > &aids, int depth) const
parses a set of AgentID instances the resolvers depth variable that is being passed around is not mod...
std::string getBitPredefMessageParams(const ACLMessage &msg) const
checks all predefined message parameters whether they are set or not and it encodes them accordingly ...
std::string getBitAID(const AgentID &aid, int depth) const
encodes an AgentID instance
overloaded equality operator for UserdefParam class objects
Definition: userdef_param.h:25
bool getUpdateCodeTables() const
std::string getBitHeader() const
puts the header toghether
std::string getByteLengthEncodedString(const std::string &sword) const
const std::vector< UserdefParam > & getUserdefParams() const
Get the all userdefined parameter.
Definition: agent_id.h:150
std::string getBitUserdefMessageParams(const ACLMessage &msg) const
Implements the general AgentID functionality, which is present throughout the fipa specifications(FIP...
Definition: agent_id.h:37
std::string getBitBinExpression(const std::string &sword, char c) const
implements the binary expression production of the grammar; not complete(w.r.t. the specification) in...
static std::string getBinDateTimeToken(const std::string &date1)
implements the date time token production of the grammar; not complete(w.r.t. the specification) in f...
AgentIDList getAllReceivers() const
Definition: acl_message.h:166
std::string getConversationID() const
Definition: acl_message.h:227
std::string getBitMessageType(const ACLMessage &msg) const
encodes the message performative; it compares the string of the message performative to all the prede...