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;
90 namespace spirit = boost::spirit;
91 namespace qi = boost::spirit::qi;
94 namespace encoding = boost::spirit::ascii;
99 (std::string, encoding)
124 struct extractFromCodetableImpl
126 typedef std::string result_type;
128 template <
typename T>
131 typedef result_type type;
134 template <
typename T>
135 result_type operator()(T arg)
const 137 if(
typeid(T) ==
typeid(
unsigned short))
146 throw std::runtime_error(
"Codetable currently unsupported");
154 struct buildStringImpl
156 typedef std::string result_type;
158 template <
typename T,
typename U,
typename V>
161 typedef result_type type;
164 template <
typename T,
typename U,
typename V>
165 result_type operator()(T arg0, U arg1, V arg2)
const 174 extern phoenix::function<buildStringImpl>
buildString;
177 struct concatStringsWithSeparatorImpl
179 typedef std::string result_type;
181 template <
typename T,
typename U,
typename V>
184 typedef result_type type;
187 template <
typename T,
typename U,
typename V>
188 result_type operator()(T arg0, U arg1, V arg2)
const 205 typedef void result_type;
207 template <
typename T,
typename U>
210 typedef result_type type;
213 template <
typename T,
typename U>
214 result_type operator()(T arg0, U arg1)
const 216 printf(
"%s %s\n", arg0, arg1.c_str());
221 extern phoenix::function<printImpl>
print;
223 struct digitPaddingBytesImpl
225 typedef uint32_t result_type;
227 template <
typename T>
230 typedef result_type type;
233 template <
typename T>
234 result_type operator()(T digit )
const 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);
254 struct convertToNumberTokenImpl
256 typedef std::string result_type;
258 template <
typename T>
261 typedef result_type type;
264 template <
typename T>
265 result_type operator()(T arg)
const 270 char highbytes = arg;
271 char lowerbytes = arg;
277 std::string tmp = convert(highbytes);
278 tmp += convert(lowerbytes);
280 return std::string(tmp);
283 std::string convert(
char lowerbyte)
const 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 ".";
316 struct convertDigitsToHexImpl
318 typedef std::string result_type;
320 template <
typename T>
323 typedef result_type type;
326 template <
typename T>
327 result_type operator()(T arg)
const 332 result_type operator()(std::string arg)
const 334 unsigned int hexNumber = atoi(arg.c_str());
337 snprintf(buffer,512,
"%#x",hexNumber);
339 return std::string(buffer);
345 struct convertToNativeShortImpl
347 typedef uint16_t result_type;
349 template <
typename T>
352 typedef result_type type;
356 template <
typename T>
357 result_type operator()(T arg)
const 363 extern phoenix::function<convertToNativeShortImpl>
lazy_ntohs;
365 struct convertToNativeLongImpl
367 typedef uint32_t result_type;
369 template <
typename T>
372 typedef result_type type;
376 template <
typename T>
377 result_type operator()(T arg)
const 383 extern phoenix::function<convertToNativeLongImpl>
lazy_ntohl;
387 struct convertToStringImpl
389 typedef std::string result_type;
391 template <
typename T>
394 typedef result_type type;
398 template <
typename T>
399 result_type operator()(T arg)
const 401 return std::string(arg.begin(), arg.end());
417 struct convertToCharVectorImpl
419 typedef std::vector<unsigned char> result_type;
421 template <
typename T>
424 typedef result_type type;
428 result_type operator()(T arg)
const 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]);
445 struct createAgentIDImpl
449 template <
typename T>
452 typedef result_type type;
465 struct convertStringToNumberImpl
467 typedef boost::uint32_t result_type;
468 template <
typename T>
471 typedef result_type type;
475 boost::uint32_t operator()(T arg)
const 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);
495 struct convertToTimeImpl
499 template <
typename T,
typename U>
502 typedef result_type type;
505 result_type operator()(
const std::string& arg,
const std::string& msecs)
const 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;
522 struct convertToBaseTimeImpl
524 typedef base::Time result_type;
526 template <
typename T>
529 typedef result_type type;
532 template <
typename T>
533 result_type operator()(T arg)
const 543 result_type operator()(std::string arg)
const 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()>
582 Index() : Index::base_type(index_rule,
"Index-bitefficient_grammar")
587 index_rule = qi::word [ label::_val =
lazy_ntohs(label::_1)]
588 | qi::byte_ [ label::_val = label::_1 ]
594 qi::rule<Iterator, uint_least16_t() > index_rule;
597 template<
typename Iterator>
598 struct Len8 : qi::grammar<Iterator, boost::uint_least8_t()>
600 Len8(): Len8::base_type(len8_rule,
"Len8-bitefficient_grammar")
602 len8_rule = qi::byte_;
607 qi::rule<Iterator, boost::uint_least8_t() > len8_rule;
610 template<
typename Iterator>
611 struct Len16 : qi::grammar<Iterator, boost::uint_least16_t()>
613 Len16(): Len16::base_type(len16_rule,
"Len16-bitefficient_grammar")
616 len16_rule = qi::word [ label::_val =
lazy_ntohs(label::_1) ];
621 qi::rule<Iterator, boost::uint_least16_t() > len16_rule;
624 template<
typename Iterator>
625 struct Len32 : qi::grammar<Iterator, boost::uint_least32_t()>
627 Len32(): Len32::base_type(len32_rule,
"Len32-bitefficient_grammar")
630 len32_rule = qi::dword [ label::_val =
lazy_ntohl(label::_1) ];
635 qi::rule<Iterator, boost::uint_least32_t() > len32_rule;
638 template <
typename Iterator>
639 struct StringLiteral : qi::grammar<Iterator, fipa::acl::ByteSequence(), qi::locals<std::string> >
641 StringLiteral() : StringLiteral::base_type(string_literal_rule,
"StringLiteral-bitefficient_grammar")
644 using encoding::char_;
645 using encoding::digit;
649 string_literal_rule = ( char_(
'"')
650 >> * (( char_(
"\\") >> char_(
'"') ) [ label::_a +=
"\"" ]
651 | (byte_ - char_(
'"') ) [ label::_a += label::_1 ]
654 ) [ phoenix::at_c<2>(label::_val) = label::_a ]
660 qi::rule<Iterator, fipa::acl::ByteSequence(), qi::locals<std::string> > string_literal_rule;
663 template<
typename Iterator>
664 struct StringLiteralTerminated : qi::grammar<Iterator, fipa::acl::ByteSequence() >
666 StringLiteralTerminated() : StringLiteralTerminated::base_type(string_literal_terminated_rule,
"StringLiteralTerminated-bitefficient_grammar")
668 string_literal_terminated_rule = stringLiteral [ label::_val = label::_1 ]
675 qi::rule<Iterator, fipa::acl::ByteSequence()> string_literal_terminated_rule;
676 StringLiteral<Iterator> stringLiteral;
679 template<
typename Iterator>
680 struct ByteLengthEncodedString : qi::grammar<Iterator, fipa::acl::ByteSequence(), qi::locals<uint32_t> >
682 ByteLengthEncodedString() : ByteLengthEncodedString::base_type(byte_length_encoded_string_rule,
"ByteLengthEncodedString-common_grammar")
685 using encoding::char_;
686 using encoding::digit;
688 byte_length_encoded_string_rule = byteLengthEncodedStringHeader [ label::_a =
convertStringToNumber(label::_1) ]
689 >> qi::repeat(label::_a)[byte_] [ phoenix::at_c<2>(label::_val) =
convertToCharVector(label::_1) ]
692 byteLengthEncodedStringHeader = char_(
'#')
693 >> + digit [ label::_val += label::_1 ]
700 qi::rule<Iterator, std::string() > byteLengthEncodedStringHeader;
701 qi::rule<Iterator, fipa::acl::ByteSequence(), qi::locals<uint32_t> > byte_length_encoded_string_rule;
704 template<
typename Iterator>
705 struct ByteLengthEncodedStringTerminated : qi::grammar<Iterator, fipa::acl::ByteSequence(), qi::locals<std::string> >
707 ByteLengthEncodedStringTerminated() : ByteLengthEncodedStringTerminated::base_type(byte_length_encoded_string_terminated_rule,
"ByteLengthEncodedStringTerminated-bitefficient_grammar")
710 using encoding::char_;
711 using encoding::digit;
713 byte_length_encoded_string_terminated_rule = ( byteLengthEncodedStringHeader [ phoenix::at_c<0>(label::_val) += label::_1 ]
714 >> * (byte_ - byte_(0x00)) [ label::_a += label::_1 ]
716 ) [ phoenix::at_c<2>(label::_val) = label::_a ]
719 byteLengthEncodedStringHeader = char_(
'#')
720 >> + digit [ label::_val += label::_1 ]
727 qi::rule<Iterator, std::string() > byteLengthEncodedStringHeader;
728 qi::rule<Iterator, fipa::acl::ByteSequence(), qi::locals<std::string> > byte_length_encoded_string_terminated_rule;
731 template<
typename Iterator>
732 struct NullTerminatedString : qi::grammar<Iterator, fipa::acl::ByteSequence()>
734 NullTerminatedString() : NullTerminatedString::base_type(null_terminated_string_rule,
"NullTerminatedString-bitefficient_grammar")
737 null_terminated_string_rule = stringLiteralTerminated
738 | byteLengthEncodedStringTerminated
744 qi::rule<Iterator, fipa::acl::ByteSequence()> null_terminated_string_rule;
745 StringLiteralTerminated<Iterator> stringLiteralTerminated;
746 ByteLengthEncodedStringTerminated<Iterator> byteLengthEncodedStringTerminated;
749 template <
typename Iterator>
750 struct Word : qi::grammar<Iterator, std::string()>
752 Word() : Word::base_type(word_rule,
"Word-bitefficient_grammar")
754 using encoding::char_;
756 word_rule = (char_ - wordExceptionsStart ) [ label::_val += label::_1 ]
757 >> *(char_ - wordExceptionsGeneral) [ label::_val += label::_1 ]
760 wordExceptionsStart %= wordExceptionsGeneral
766 wordExceptionsGeneral %= char_(0x00,0x20)
770 #ifdef BOOST_SPIRIT_DEBUG 771 BOOST_SPIRIT_DEBUG_NODE(wordExceptionsStart);
772 BOOST_SPIRIT_DEBUG_NODE(wordExceptionsGeneral);
778 qi::rule<Iterator, std::string()> word_rule;
779 qi::rule<Iterator> wordExceptionsStart;
780 qi::rule<Iterator> wordExceptionsGeneral;
783 template<
typename Iterator>
784 struct Digits : qi::grammar<Iterator, std::string(), qi::locals<boost::uint_least8_t> >
786 Digits() : Digits::base_type(digits_rule,
"Digits-bitefficient_grammar")
788 using encoding::char_;
796 end_padding_marker = char_(0x00) | lower_bits_padding;
797 lower_bits_padding = qi::byte_ [ label::_val = label::_1 ]
798 >> qi::eps( !(label::_val & 0x0f) )
807 qi::rule<Iterator, std::string(), qi::locals<boost::uint_least8_t> > digits_rule;
808 qi::rule<Iterator, boost::uint_least8_t()> end_padding_marker;
809 qi::rule<Iterator, boost::uint_least8_t()> lower_bits_padding;
813 template<
typename Iterator>
814 struct CodedNumber : qi::grammar<Iterator, std::string()>
816 CodedNumber() : CodedNumber::base_type(coded_number_rule,
"CodedNumber-bitefficient_grammar")
819 coded_number_rule = (qi::byte_ - qi::byte_(0x00))[ label::_val =
convertToNumberToken(label::_1)]
825 qi::rule<Iterator, std::string()> coded_number_rule;
828 template <
typename Iterator>
829 struct DateTime : qi::grammar<Iterator, fipa::acl::Time(), qi::locals<std::string> >
831 DateTime() : DateTime::base_type(date_time_rule,
"DateTime-bitefficient_grammar")
840 date_time_rule = (( ( year [ label::_a =
buildString(label::_1,
"-",
"") ])
841 >> ( month [ label::_a =
buildString(label::_a, label::_1,
"-") ])
842 >> ( day [ label::_a =
buildString(label::_a, label::_1,
"T") ])
843 >> ( hour [ label::_a =
buildString(label::_a, label::_1,
":") ])
844 >> ( minute [ label::_a =
buildString(label::_a, label::_1,
":") ])
845 >> ( second [ label::_a =
buildString(label::_a, label::_1,
"") ])
847 >> ( millisecond [ label::_val =
convertToTime(label::_a, label::_1) ])
851 year = ( codedNumber [ label::_val = label::_1] )
852 >> ( codedNumber [ label::_val += label::_1 ])
855 millisecond = year.alias();
857 #ifdef BOOST_SPIRIT_DEBUG 858 BOOST_SPIRIT_DEBUG_NODE(year);
859 BOOST_SPIRIT_DEBUG_NODE(millisecond);
860 #endif // BOOST_SPIRIT_DEBUG 865 CodedNumber<Iterator> codedNumber;
867 qi::rule<Iterator, fipa::acl::Time(), qi::locals<std::string> > date_time_rule;
868 qi::rule<Iterator, std::string() > year;
869 CodedNumber<Iterator> month;
870 CodedNumber<Iterator> day;
871 CodedNumber<Iterator> hour;
872 CodedNumber<Iterator> minute;
873 CodedNumber<Iterator> second;
874 qi::rule<Iterator, std::string() > millisecond;
878 template<
typename Iterator>
879 struct String : qi::grammar<Iterator, std::string()>
881 String() : String::base_type(string_rule,
"String-common_grammar")
883 string_rule = stringLiteral [ label::_val =
convertToString(label::_1) ]
890 StringLiteral<Iterator> stringLiteral;
891 ByteLengthEncodedString<Iterator> byteLengthEncodedString;
892 qi::rule<Iterator, std::string()> string_rule;
901 #endif // FIPA_ACL_GRAMMAR_COMMON_H phoenix::function< concatStringsWithSeparatorImpl > concatStringsWithSeparator
phoenix::function< convertToCharVectorImpl > convertToCharVector
phoenix::function< digitPaddingBytesImpl > digitPaddingBytes
phoenix::function< convertToNativeShortImpl > lazy_ntohs
phoenix::function< printImpl > print
phoenix::function< convertStringToNumberImpl > convertStringToNumber
phoenix::function< convertToStringImpl > convertToString
Representation of a byte sequence. We also embed information about the encoding.
boost::variant< std::string, std::vector< unsigned char > > ByteString
Definition of a ByteString.
std::vector< AgentID > AgentIDList
std::string toRawDataString() const
phoenix::function< createAgentIDImpl > createAgentID
BOOST_FUSION_ADAPT_STRUCT(fipa::acl::envelope::Parameter,(std::string, name)(fipa::acl::envelope::ParameterValue, data))
phoenix::function< convertToTimeImpl > convertToTime
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< convertDigitsToHexImpl > convertDigitsToHex
phoenix::function< convertToBaseTimeImpl > convertToBaseTime
This class provides a representation of a message conforming to the FIPA specification SC00061...
#define FIPA_ACL_FUSION_ADAPT
overloaded equality operator for UserdefParam class objects
#define FIPA_DEBUG_RULE(X)
phoenix::function< convertToNativeLongImpl > lazy_ntohl
base::Time toTime() const
phoenix::function< buildStringImpl > buildString
phoenix::function< convertToNumberTokenImpl > convertToNumberToken
Implements the general AgentID functionality, which is present throughout the fipa specifications(FIP...
Foundation of Physical Intelligent Agents.
phoenix::function< extractFromCodetableImpl > extractFromCodetable