encoding: Optimized encoding of Interest and related data structures
Change-Id: I0609b40565835568e09c3cc0330db441fd9243b6
refs: #1172
diff --git a/src/exclude.hpp b/src/exclude.hpp
index 62ce672..22dc929 100644
--- a/src/exclude.hpp
+++ b/src/exclude.hpp
@@ -11,7 +11,7 @@
#ifndef NDN_EXCLUDE_H
#define NDN_EXCLUDE_H
-#include "name.hpp"
+#include "name-component.hpp"
namespace ndn {
@@ -24,7 +24,7 @@
struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
- typedef std::map< Name::Component, bool /*any*/, std::greater<Name::Component> > exclude_type;
+ typedef std::map< name::Component, bool /*any*/, std::greater<name::Component> > exclude_type;
typedef exclude_type::iterator iterator;
typedef exclude_type::const_iterator const_iterator;
@@ -37,11 +37,33 @@
Exclude ();
/**
+ * @brief Fast encoding or block size estimation
+ */
+ template<bool T>
+ inline size_t
+ wireEncode(EncodingImpl<T> &block) const;
+
+ /**
+ * @brief Encode to a wire format
+ */
+ inline const Block&
+ wireEncode() const;
+
+ /**
+ * @brief Decode from the wire format
+ */
+ inline void
+ wireDecode(const Block &wire);
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+
+ /**
* @brief Check if name component is excluded
* @param comp Name component to check against exclude filter
*/
bool
- isExcluded (const Name::Component &comp) const;
+ isExcluded (const name::Component &comp) const;
/**
* @brief Exclude specific name component
@@ -49,7 +71,7 @@
* @returns *this to allow chaining
*/
Exclude &
- excludeOne (const Name::Component &comp);
+ excludeOne (const name::Component &comp);
/**
* @brief Exclude components from range [from, to]
@@ -58,7 +80,7 @@
* @returns *this to allow chaining
*/
Exclude &
- excludeRange (const Name::Component &from, const Name::Component &to);
+ excludeRange (const name::Component &from, const name::Component &to);
/**
* @brief Exclude all components from range [/, to]
@@ -66,7 +88,7 @@
* @returns *this to allow chaining
*/
inline Exclude &
- excludeBefore (const Name::Component &to);
+ excludeBefore (const name::Component &to);
/**
* @brief Exclude all components from range [from, +Inf]
@@ -74,7 +96,7 @@
* @returns *this to allow chaining
*/
Exclude &
- excludeAfter (const Name::Component &from);
+ excludeAfter (const name::Component &from);
/**
* @brief Method to directly append exclude element
@@ -86,7 +108,7 @@
* If there is an error with ranges (e.g., order of components is wrong) an exception is thrown
*/
inline void
- appendExclude (const Name::Component &name, bool any);
+ appendExclude (const name::Component &name, bool any);
/**
* @brief Check if exclude filter is empty
@@ -136,20 +158,6 @@
inline std::string
toUri () const;
- /**
- * Encode this Interest for a particular wire format.
- * @return The encoded byte array.
- */
- const Block&
- wireEncode() const;
-
- /**
- * Decode the input using a particular wire format and update this Interest.
- * @param input The input byte array to be decoded.
- */
- void
- wireDecode(const Block &wire);
-
private:
Exclude &
excludeRange (iterator fromLowerBound, iterator toLowerBound);
@@ -164,13 +172,13 @@
operator << (std::ostream &os, const Exclude &name);
inline Exclude &
-Exclude::excludeBefore (const Name::Component &to)
+Exclude::excludeBefore (const name::Component &to)
{
- return excludeRange (Name::Component (), to);
+ return excludeRange (name::Component (), to);
}
inline void
-Exclude::appendExclude (const Name::Component &name, bool any)
+Exclude::appendExclude (const name::Component &name, bool any)
{
m_exclude[name] = any;
}
@@ -226,6 +234,92 @@
return os.str();
}
+template<bool T>
+inline size_t
+Exclude::wireEncode(EncodingImpl<T> &block) const
+{
+ size_t total_len = 0;
+
+ // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
+ // Any ::= ANY-TYPE TLV-LENGTH(=0)
+
+ for (Exclude::const_iterator i = m_exclude.begin (); i != m_exclude.end (); i++)
+ {
+ if (i->second)
+ {
+ total_len += prependBooleanBlock(block, Tlv::Any);
+ }
+ if (!i->first.empty())
+ {
+ total_len += i->first.wireEncode(block);
+ }
+ }
+
+ total_len += block.prependVarNumber(total_len);
+ total_len += block.prependVarNumber(Tlv::Exclude);
+ return total_len;
+}
+
+inline const Block &
+Exclude::wireEncode() const
+{
+ if (wire_.hasWire())
+ return wire_;
+
+ EncodingEstimator estimator;
+ size_t estimatedSize = wireEncode(estimator);
+
+ EncodingBuffer buffer(estimatedSize, 0);
+ wireEncode(buffer);
+
+ wire_ = buffer.block();
+ return wire_;
+}
+
+inline void
+Exclude::wireDecode(const Block &wire)
+{
+ wire_ = wire;
+ wire_.parse();
+
+ // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
+ // Any ::= ANY-TYPE TLV-LENGTH(=0)
+
+ Block::element_const_iterator i = wire_.elements_begin();
+ if (i->type() == Tlv::Any)
+ {
+ appendExclude(name::Component(), true);
+ ++i;
+ }
+
+ while (i != wire_.elements_end())
+ {
+ if (i->type() != Tlv::NameComponent)
+ throw Error("Incorrect format of Exclude filter");
+
+ name::Component excludedComponent (i->value(), i->value_size());
+ ++i;
+
+ if (i != wire_.elements_end())
+ {
+ if (i->type() == Tlv::Any)
+ {
+ appendExclude(excludedComponent, true);
+ ++i;
+ }
+ else
+ {
+ appendExclude(excludedComponent, false);
+ }
+ }
+ else
+ {
+ appendExclude(excludedComponent, false);
+ }
+ }
+}
+
+
} // ndn
#endif // NDN_EXCLUDE_H