1 #ifndef FIPA_ACL_GRAMMAR_COMMON_H
2 #define FIPA_ACL_GRAMMAR_COMMON_H
6 #include <boost/config/warning_disable.hpp>
7 #include <boost/spirit/include/qi.hpp>
9 #ifndef BOOST_SPIRIT_USE_PHOENIX_V3
10 #include <boost/spirit/home/support/context.hpp>
11 #include <boost/spirit/include/phoenix_core.hpp>
12 #include <boost/spirit/include/phoenix_operator.hpp>
13 #include <boost/spirit/include/phoenix_object.hpp>
14 #include <boost/spirit/include/phoenix_fusion.hpp>
15 #include <boost/spirit/include/phoenix_stl.hpp>
16 #include <boost/fusion/include/adapt_struct.hpp>
18 #include <boost/phoenix/phoenix.hpp>
19 #include <boost/phoenix/fusion/at.hpp>
20 #include <boost/fusion/adapted/std_pair.hpp>
23 #include <boost/foreach.hpp>
24 #include <boost/lexical_cast.hpp>
25 #include <arpa/inet.h>
28 #include <base-logging/Logging.hpp>
30 #include <fipa_acl/message_generator/acl_message.h>
32 #include <fipa_acl/message_parser/types.h>
33 #ifdef BOOST_SPIRIT_DEBUG
35 #include <fipa_acl/message_parser/debug.h>
37 #define FIPA_DEBUG_RULE(X) BOOST_SPIRIT_DEBUG_NODE(X); qi::on_error<qi::fail> ( X, std::cout << phoenix::val("Error: expecting ") << label::_4 << phoenix::val(" here: \"") << phoenix::construct<std::string>(label::_3,label::_2) << phoenix::val("\"") << std::endl);
39 #define FIPA_DEBUG_RULE(X)
43 #if BOOST_VERSION < 104500
44 #include <boost/fusion/include/adapt_class.hpp>
46 #include <boost/fusion/adapted/adt/adapt_adt.hpp>
47 #include <boost/fusion/include/adapt_adt.hpp>
50 #if BOOST_VERSION < 104500
51 #define FIPA_ACL_FUSION_ADAPT BOOST_FUSION_ADAPT_CLASS
53 #define FIPA_ACL_FUSION_ADAPT BOOST_FUSION_ADAPT_ADT
58 (
const std::string&,
const std::string&, obj.getName(), obj.setName(val))
59 (
const std::vector<std::string>&,
const std::vector<std::string>&, obj.getAddresses(), obj.setAddresses(val))
60 (
const std::vector<fipa::acl::AgentID>&,
const std::vector<fipa::acl::AgentID>&, obj.getResolvers(), obj.setResolvers(val))
61 (
const std::vector<fipa::acl::UserdefParam>&,
const std::vector<fipa::acl::UserdefParam>&, obj.getUserdefParams(), obj.setUserdefParams(val))
66 (
const std::string&,
const std::string&, obj.getName(), obj.setName(val))
67 (
const std::string&,
const std::string&, obj.getValue(), obj.setValue(val))
72 (std::string, std::string, obj.getPerformative(), obj.setPerformative(val))
75 (std::string, std::string, obj.getContent(), obj.setContent(val))
76 (std::string, std::string, obj.getReplyWith(), obj.setReplyWith(val))
77 (base::Time, base::Time, obj.getReplyBy(), obj.setReplyBy(val))
78 (std::string, std::string, obj.getInReplyTo(), obj.setInReplyTo(val))
80 (std::string, std::string, obj.getLanguage(), obj.setLanguage(val))
81 (std::string, std::string, obj.getEncoding(), obj.setEncoding(val))
82 (std::string, std::string, obj.getOntology(), obj.setOntology(val))
83 (std::string, std::string, obj.getProtocol(), obj.setProtocol(val))
84 (std::string, std::string, obj.getConversationID(), obj.setConversationID(val))
85 (
void,
void, , obj.addUserdefParam(val))
88 namespace fusion = boost::fusion;
89 namespace phoenix = boost::phoenix;
90 namespace spirit = boost::spirit;
91 namespace qi = boost::spirit::qi;
94 namespace encoding = boost::spirit::ascii;
99 (std::string, encoding)
113 (fipa::acl::Time, dateTime)
124 struct extractFromCodetableImpl
126 typedef std::string result_type;
128 template <
typename T>
134 template <
typename T>
137 if(
typeid(T) ==
typeid(
unsigned short))
146 throw std::runtime_error(
"Codetable currently unsupported");
158 template <
typename T,
typename U,
typename V>
164 template <
typename T,
typename U,
typename V>
174 extern phoenix::function<buildStringImpl>
buildString;
181 template <
typename T,
typename U,
typename V>
187 template <
typename T,
typename U,
typename V>
207 template <
typename T,
typename U>
213 template <
typename T,
typename U>
216 printf(
"%s %s\n", arg0, arg1.c_str());
221 extern phoenix::function<printImpl>
print;
227 template <
typename T>
233 template <
typename T>
236 char lastbyte = digit[0];
239 if( (lastbyte & 0x0F) == 0)
242 LOG_DEBUG(
"CodedNumber properly padded byte detected: %x", lastbyte);
245 LOG_DEBUG(
"CodedNumber with unpadded byte detected: %x", lastbyte);
258 template <
typename T>
264 template <
typename T>
270 char highbytes = arg;
271 char lowerbytes = arg;
277 std::string tmp =
convert(highbytes);
280 return std::string(tmp);
291 case 0x00:
return "";
292 case 0x01:
return "0";
293 case 0x02:
return "1";
294 case 0x03:
return "2";
295 case 0x04:
return "3";
296 case 0x05:
return "4";
297 case 0x06:
return "5";
298 case 0x07:
return "6";
299 case 0x08:
return "7";
300 case 0x09:
return "8";
301 case 0x0a:
return "9";
302 case 0x0c:
return "+";
303 case 0x0d:
return "E";
304 case 0x0e:
return "-";
305 case 0x0f:
return ".";
320 template <
typename T>
326 template <
typename T>
334 unsigned int hexNumber = atoi(arg.c_str());
337 snprintf(buffer,512,
"%#x",hexNumber);
339 return std::string(buffer);
349 template <
typename T>
356 template <
typename T>
363 extern phoenix::function<convertToNativeShortImpl>
lazy_ntohs;
369 template <
typename T>
376 template <
typename T>
383 extern phoenix::function<convertToNativeLongImpl>
lazy_ntohl;
391 template <
typename T>
398 template <
typename T>
401 return std::string(arg.begin(), arg.end());
421 template <
typename T>
430 int length = arg.size();
431 std::vector<unsigned char> tmp;
433 for(
int i = 0; i < length; i++)
435 tmp.push_back((
unsigned char) arg[i]);
449 template <
typename T>
468 template <
typename T>
477 std::string number(arg.begin(),arg.begin() + strlen(arg.c_str()));
479 return boost::lexical_cast<boost::uint32_t>(number);
480 }
catch(
const std::bad_cast& e)
482 LOG_ERROR(
"ConvertString failed: '%s'", arg.c_str());
483 LOG_ERROR(
"String_size: '%d'", arg.size());
484 LOG_ERROR(
"String_length: '%d'", strlen(arg.c_str()));
485 std::string msg =
"ConvertStringToNumber failed for '" + number +
"' " + std::string(e.what());
486 throw std::runtime_error(msg);
499 template <
typename T,
typename U>
508 #ifdef BOOST_SPIRIT_DEBUG
509 printf(
"convertToTimeImpl: %s:%s\n", arg.c_str(), msecs.c_str());
512 strptime(arg.c_str(),
"%Y-%m-%dT%H:%M:%S",&convertedTime);
513 convertedTime.
tm_msec = atoi(msecs.c_str());
515 return convertedTime;
526 template <
typename T>
532 template <
typename T>
545 std::string time = arg;
546 if ( arg.data()[0] ==
'-' || arg.data()[0] ==
'+')
550 std::string format =
"%Y%m%dT%H%M%S";
552 size_t end = time.find_last_of(
"0123456789", time.size() -1);
553 if( end < time.size() - 1)
561 std::string milliseconds = time.substr(end-2,3);
563 time +=
":" + milliseconds;
565 return base::Time::fromString(time, base::Time::Milliseconds, format);
577 namespace label = qi::labels;
579 template<
typename Iterator>
580 struct Index : qi::grammar<Iterator, uint_least16_t()>
588 | qi::byte_ [ label::_val = label::_1 ]
597 template<
typename Iterator>
598 struct Len8 : qi::grammar<Iterator, boost::uint_least8_t()>
610 template<
typename Iterator>
611 struct Len16 : qi::grammar<Iterator, boost::uint_least16_t()>
624 template<
typename Iterator>
625 struct Len32 : qi::grammar<Iterator, boost::uint_least32_t()>
638 template <
typename Iterator>
639 struct StringLiteral : qi::grammar<Iterator, fipa::acl::ByteSequence(), qi::locals<std::string> >
644 using encoding::char_;
645 using encoding::digit;
650 >> * (( char_(
"\\") >> char_(
'"') ) [ label::_a +=
"\"" ]
651 | (byte_ - char_(
'"') ) [ label::_a += label::_1 ]
654 ) [ phoenix::at_c<2>(label::_val) = label::_a ]
663 template<
typename Iterator>
679 template<
typename Iterator>
685 using encoding::char_;
686 using encoding::digit;
689 >> qi::repeat(label::_a)[byte_] [ phoenix::at_c<2>(label::_val) =
convertToCharVector(label::_1) ]
693 >> + digit [ label::_val += label::_1 ]
704 template<
typename Iterator>
710 using encoding::char_;
711 using encoding::digit;
714 >> * (byte_ - byte_(0x00)) [ label::_a += label::_1 ]
716 ) [ phoenix::at_c<2>(label::_val) = label::_a ]
720 >> + digit [ label::_val += label::_1 ]
731 template<
typename Iterator>
749 template <
typename Iterator>
750 struct Word : qi::grammar<Iterator, std::string()>
754 using encoding::char_;
770 #ifdef BOOST_SPIRIT_DEBUG
783 template<
typename Iterator>
784 struct Digits : qi::grammar<Iterator, std::string(), qi::locals<boost::uint_least8_t> >
788 using encoding::char_;
798 >> qi::eps( !(label::_val & 0x0f) )
807 qi::rule<Iterator, std::string(), qi::locals<boost::uint_least8_t> >
digits_rule;
813 template<
typename Iterator>
828 template <
typename Iterator>
829 struct DateTime : qi::grammar<Iterator, fipa::acl::Time(), qi::locals<std::string> >
857 #ifdef BOOST_SPIRIT_DEBUG
858 BOOST_SPIRIT_DEBUG_NODE(
year);
860 #endif // BOOST_SPIRIT_DEBUG
868 qi::rule<Iterator, std::string() >
year;
878 template<
typename Iterator>
879 struct String : qi::grammar<Iterator, std::string()>
901 #endif // FIPA_ACL_GRAMMAR_COMMON_H
result_type operator()(T arg) const
qi::rule< Iterator, std::string() > year
qi::rule< Iterator, std::string()> coded_number_rule
result_type operator()(T arg) const
CodedNumber< Iterator > day
phoenix::function< convertToNativeShortImpl > lazy_ntohs
CodedNumber< Iterator > month
qi::rule< Iterator, boost::uint_least8_t()> lower_bits_padding
qi::rule< Iterator, std::string(), qi::locals< boost::uint_least8_t > > digits_rule
CodedNumber< Iterator > second
std::string toRawDataString() const
qi::rule< Iterator > wordExceptionsStart
result_type operator()(T arg) const
StringLiteral< Iterator > stringLiteral
boost::uint32_t result_type
std::vector< unsigned char > result_type
phoenix::function< createAgentIDImpl > createAgentID
ByteLengthEncodedStringTerminated< Iterator > byteLengthEncodedStringTerminated
fipa::acl::AgentID operator()(T arg) const
qi::rule< Iterator, boost::uint_least32_t() > len32_rule
qi::rule< Iterator, std::string() > byteLengthEncodedStringHeader
fipa::acl::Time result_type
qi::rule< Iterator, fipa::acl::ByteSequence()> null_terminated_string_rule
result_type operator()(T arg0, U arg1) const
result_type operator()(T arg) const
qi::rule< Iterator, std::string() > byteLengthEncodedStringHeader
qi::rule< Iterator > wordExceptionsGeneral
fipa::acl::AgentID result_type
qi::rule< Iterator, std::string()> string_rule
Representation of a byte sequence. We also embed information about the encoding.
base::Time toTime() const
boost::variant< std::string, std::vector< unsigned char > > ByteString
Definition of a ByteString.
std::vector< AgentID > AgentIDList
ByteLengthEncodedString< Iterator > byteLengthEncodedString
phoenix::function< convertStringToNumberImpl > convertStringToNumber
qi::rule< Iterator, std::string()> word_rule
CodedNumber< Iterator > minute
result_type operator()(std::string arg) const
qi::rule< Iterator, fipa::acl::ByteSequence()> string_literal_terminated_rule
phoenix::function< digitPaddingBytesImpl > digitPaddingBytes
qi::rule< Iterator, fipa::acl::ByteSequence(), qi::locals< uint32_t > > byte_length_encoded_string_rule
result_type operator()(T arg0, U arg1, V arg2) const
phoenix::function< convertDigitsToHexImpl > convertDigitsToHex
BOOST_FUSION_ADAPT_STRUCT(fipa::acl::envelope::Parameter,(std::string, name)(fipa::acl::envelope::ParameterValue, data))
result_type operator()(T arg) const
result_type operator()(T arg) const
result_type operator()(fipa::acl::DateTime arg) const
ByteLengthEncodedStringTerminated()
phoenix::function< convertToCharVectorImpl > convertToCharVector
phoenix::function< concatStringsWithSeparatorImpl > concatStringsWithSeparator
StringLiteralTerminated< Iterator > stringLiteralTerminated
CodedNumber< Iterator > codedNumber
boost::variant< boost::uint_least8_t, boost::uint_least16_t, boost::uint_least32_t > LengthValue
Definition of a length - internally used by the parser.
phoenix::function< convertToBaseTimeImpl > convertToBaseTime
StringLiteral< Iterator > stringLiteral
qi::rule< Iterator, boost::uint_least8_t() > len8_rule
phoenix::function< convertToTimeImpl > convertToTime
phoenix::function< printImpl > print
qi::rule< Iterator, std::string() > millisecond
This class provides a representation of a message conforming to the FIPA specification SC00061...
phoenix::function< convertToNumberTokenImpl > convertToNumberToken
qi::rule< Iterator, fipa::acl::ByteSequence(), qi::locals< std::string > > byte_length_encoded_string_terminated_rule
ByteLengthEncodedString()
result_type operator()(std::string arg) const
boost::uint32_t operator()(T arg) const
StringLiteralTerminated()
result_type operator()(fipa::acl::ByteSequence arg) const
#define FIPA_ACL_FUSION_ADAPT
result_type operator()(const std::string &arg, const std::string &msecs) const
result_type operator()(T arg) const
result_type operator()(T arg) const
phoenix::function< extractFromCodetableImpl > extractFromCodetable
overloaded equality operator for UserdefParam class objects
qi::rule< Iterator, boost::uint_least8_t()> end_padding_marker
#define FIPA_DEBUG_RULE(X)
CodedNumber< Iterator > hour
qi::rule< Iterator, fipa::acl::Time(), qi::locals< std::string > > date_time_rule
qi::rule< Iterator, fipa::acl::ByteSequence(), qi::locals< std::string > > string_literal_rule
result_type operator()(T arg0, U arg1, V arg2) const
std::string convert(char lowerbyte) const
phoenix::function< buildStringImpl > buildString
Implements the general AgentID functionality, which is present throughout the fipa specifications(FIP...
qi::rule< Iterator, uint_least16_t() > index_rule
qi::rule< Iterator, boost::uint_least16_t() > len16_rule
phoenix::function< convertToNativeLongImpl > lazy_ntohl
phoenix::function< convertToStringImpl > convertToString
result_type operator()(T digit) const