interest: More TLV-related changes

Change-Id: I3cf300b58aaf7091cb0b27827b39bfe9e3556c78
diff --git a/src/interest.cpp b/src/interest.cpp
index 2caffb1..0a4c8d7 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -80,4 +80,167 @@
   return os;
 }
 
+const Block&
+Interest::wireEncode() const
+{
+  if (wire_.hasWire())
+    return wire_;
+
+  wire_ = Block(Tlv::Interest);
+  wire_.push_back(getName().wireEncode());
+
+  // selectors
+  {
+    Block selectors(Tlv::Selectors);
+    
+    if (getMinSuffixComponents() >= 0) {
+      OBufferStream os;
+      Tlv::writeVarNumber(os, Tlv::MinSuffixComponents);
+      Tlv::writeVarNumber(os, Tlv::sizeOfNonNegativeInteger(getMinSuffixComponents()));
+      Tlv::writeNonNegativeInteger(os, getMinSuffixComponents());
+
+      selectors.push_back(Block(os.buf()));
+    }
+    if (getMaxSuffixComponents() >= 0) {
+      OBufferStream os;
+      Tlv::writeVarNumber(os, Tlv::MaxSuffixComponents);
+      Tlv::writeVarNumber(os, Tlv::sizeOfNonNegativeInteger(getMaxSuffixComponents()));
+      Tlv::writeNonNegativeInteger(os, getMaxSuffixComponents());
+
+      selectors.push_back(Block(os.buf()));
+    }
+    if (!getExclude().empty()) {
+      selectors.push_back(getExclude().wireEncode());
+    }
+    if (getChildSelector() >= 0) {
+      OBufferStream os;
+      Tlv::writeVarNumber(os, Tlv::ChildSelector);
+      Tlv::writeVarNumber(os, Tlv::sizeOfNonNegativeInteger(getChildSelector()));
+      Tlv::writeNonNegativeInteger(os, getChildSelector());
+
+      selectors.push_back(Block(os.buf()));
+    }
+    if (getMustBeFresh()) {
+      OBufferStream os;
+      Tlv::writeVarNumber(os, Tlv::MustBeFresh);
+      Tlv::writeVarNumber(os, 0);
+
+      selectors.push_back(Block(os.buf()));
+    }
+
+    selectors.encode();
+    wire_.push_back(selectors);
+  }
+
+  // Nonce
+  {
+    OBufferStream os;
+    Tlv::writeVarNumber(os, Tlv::Nonce);
+    Tlv::writeVarNumber(os, Tlv::sizeOfNonNegativeInteger(getNonce()));
+    Tlv::writeNonNegativeInteger(os, getNonce());
+
+    wire_.push_back(Block(os.buf()));
+  }
+  
+  if (getScope() >= 0) {
+    OBufferStream os;
+    Tlv::writeVarNumber(os, Tlv::Scope);
+    Tlv::writeVarNumber(os, Tlv::sizeOfNonNegativeInteger(getScope()));
+    Tlv::writeNonNegativeInteger(os, getScope());
+
+    wire_.push_back(Block(os.buf()));
+  }
+  if (getInterestLifetime() >= 0) {
+    OBufferStream os;
+    Tlv::writeVarNumber(os, Tlv::InterestLifetime);
+    Tlv::writeVarNumber(os, Tlv::sizeOfNonNegativeInteger(getInterestLifetime()));
+    Tlv::writeNonNegativeInteger(os, getInterestLifetime());
+
+    wire_.push_back(Block(os.buf()));
+  }
+  
+  wire_.encode();
+  return wire_;
+}
+  
+void 
+Interest::wireDecode(const Block &wire) 
+{
+  wire_ = wire;
+  wire_.parse();
+
+  // Name
+  name_.wireDecode(wire_.get(Tlv::Name));
+
+  // Selectors
+  Block::element_iterator selectors = wire_.find(Tlv::Selectors);
+  if (selectors != wire_.getAll().end())
+    {
+      selectors->parse();
+
+      // MinSuffixComponents
+      Block::element_iterator val = selectors->find(Tlv::MinSuffixComponents);
+      if (val != selectors->getAll().end())
+        {
+          Buffer::const_iterator begin = val->value_begin();
+          minSuffixComponents_ = Tlv::readNonNegativeInteger(val->value_size(), begin, val->value_end());
+        }
+
+      // MaxSuffixComponents
+      val = selectors->find(Tlv::MaxSuffixComponents);
+      if (val != selectors->getAll().end())
+        {
+          Buffer::const_iterator begin = val->value_begin();
+          maxSuffixComponents_ = Tlv::readNonNegativeInteger(val->value_size(), begin, val->value_end());
+        }
+
+      // Exclude
+      val = selectors->find(Tlv::Exclude);
+      if (val != selectors->getAll().end())
+        {
+          exclude_.wireDecode(*val);
+        }
+
+      // ChildSelector
+      val = selectors->find(Tlv::ChildSelector);
+      if (val != selectors->getAll().end())
+        {
+          Buffer::const_iterator begin = val->value_begin();
+          childSelector_ = Tlv::readNonNegativeInteger(val->value_size(), begin, val->value_end());
+        }
+
+      //MustBeFresh aka AnswerOriginKind
+      val = selectors->find(Tlv::MustBeFresh);
+      if (val != selectors->getAll().end())
+        {
+          mustBeFresh_ = true;
+        }
+    }
+  
+  // Nonce
+  Block::element_iterator val = wire_.find(Tlv::Nonce);
+  if (val != wire_.getAll().end())
+    {
+      Buffer::const_iterator begin = val->value_begin();
+      nonce_ = Tlv::readNonNegativeInteger(val->value_size(), begin, val->value_end());
+    }
+
+  // Scope
+  val = wire_.find(Tlv::Scope);
+  if (val != wire_.getAll().end())
+    {
+      Buffer::const_iterator begin = val->value_begin();
+      scope_ = Tlv::readNonNegativeInteger(val->value_size(), begin, val->value_end());
+    }
+  
+  // InterestLifetime
+  val = wire_.find(Tlv::InterestLifetime);
+  if (val != wire_.getAll().end())
+    {
+      Buffer::const_iterator begin = val->value_begin();
+      interestLifetime_ = Tlv::readNonNegativeInteger(val->value_size(), begin, val->value_end());
+    } 
+}
+
+
 }