25 #include <boost/bind.hpp> 26 #include <boost/mpl/for_each.hpp> 27 #include <boost/range/adaptor/reversed.hpp> 34 template<
typename TAG>
36 getLocationSortOrder();
40 getLocationSortOrder<field_location_tags::Header>()
47 getLocationSortOrder<field_location_tags::Fragment>()
58 FieldInfo(uint64_t tlv);
68 class ExtractFieldInfo
71 using result_type = void;
75 operator()(FieldInfo* info, T)
const 77 if (T::TlvType::value != info->tlvType) {
80 info->isRecognized =
true;
81 info->canIgnore =
false;
82 info->isRepeatable = T::IsRepeatable::value;
83 info->locationSortOrder = getLocationSortOrder<typename T::FieldLocation>();
87 FieldInfo::FieldInfo()
96 FieldInfo::FieldInfo(uint64_t tlv)
103 boost::mpl::for_each<FieldSet>(boost::bind(ExtractFieldInfo(),
this, _1));
107 (tlvType & 0x03) == 0x00;
112 compareFieldSortOrder(
const FieldInfo& first,
const FieldInfo& second)
114 return (first.locationSortOrder < second.locationSortOrder) ||
115 (first.locationSortOrder == second.locationSortOrder && first.tlvType < second.tlvType);
135 if (elements.size() == 1 && elements.front().type() == FragmentField::TlvType::value) {
136 elements.front().parse();
137 return elements.front().elements().front();
149 add<FragmentField>(make_pair(wire.
begin(), wire.
end()));
162 FieldInfo info(element.type());
164 if (!info.isRecognized && !info.canIgnore) {
165 BOOST_THROW_EXCEPTION(
Error(
"unrecognized field " +
to_string(element.type()) +
" cannot be ignored"));
169 if (info.tlvType == prev.tlvType && !info.isRepeatable) {
170 BOOST_THROW_EXCEPTION(
Error(
"non-repeatable field " +
to_string(element.type()) +
" cannot be repeated"));
173 else if (info.tlvType != prev.tlvType && !compareFieldSortOrder(prev, info)) {
174 BOOST_THROW_EXCEPTION(
Error(
"fields are not in correct sort order"));
186 Packet::comparePos(uint64_t first,
const Block& second)
188 FieldInfo firstInfo(first);
189 FieldInfo secondInfo(second.
type());
190 return compareFieldSortOrder(firstInfo, secondInfo);
Copyright (c) 2013-2017 Regents of the University of California.
const element_container & elements() const
Get container of sub elements.
Buffer::const_iterator end() const
Get end iterator of encoded wire.
bool canIgnore
can this unknown field be ignored
Represents a TLV element of NDN packet format.
void wireDecode(const Block &wire)
decode packet from wire format
bool isRecognized
is this field known
upper bound of 3-octet header field
bool isRepeatable
is the field repeatable
Block wireEncode() const
encode packet into wire format
void parse() const
Parse TLV-VALUE into sub elements.
uint32_t type() const
Get TLV-TYPE.
uint64_t tlvType
TLV-TYPE of the field; 0 if field does not exist.
void encode()
Encode sub elements into TLV-VALUE.
std::string to_string(const V &v)
int locationSortOrder
sort order of field_location_tag
lower bound of 3-octet header field
std::vector< Block > element_container
Buffer::const_iterator begin() const
Get begin iterator of encoded wire.