interest: setNonce resets wire buffer

Prior to this commit, Interest::setNonce overwrote part of the wire
buffer, which could lead to unexpected behavior: when two Interest
instances are sharing the same wire buffer, setting the Nonce on one
instance affects the other instance.

refs #4168

Change-Id: Ia90ed54d91845575504ca53071ea356e3854eba5
diff --git a/src/interest.cpp b/src/interest.cpp
index 05951be..d618475 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -94,8 +94,10 @@
   }
 
   // Nonce
-  getNonce(); // to ensure that Nonce is properly set
-  totalLength += encoder.prependBlock(m_nonce);
+  uint32_t nonce = this->getNonce(); // assigns random Nonce if needed
+  totalLength += encoder.prependByteArray(reinterpret_cast<uint8_t*>(&nonce), sizeof(nonce));
+  totalLength += encoder.prependVarNumber(sizeof(nonce));
+  totalLength += encoder.prependVarNumber(tlv::Nonce);
 
   // Selectors
   if (hasSelectors()) {
@@ -128,7 +130,7 @@
   EncodingBuffer buffer(estimatedSize, 0);
   wireEncode(buffer);
 
-  // to ensure that Nonce block points to the right memory location
+  // to ensure that Link block points to the right memory location
   const_cast<Interest*>(this)->wireDecode(buffer.block());
 
   return m_wire;
@@ -155,7 +157,16 @@
     m_selectors = Selectors();
 
   // Nonce
-  m_nonce = m_wire.get(tlv::Nonce);
+  val = m_wire.find(tlv::Nonce);
+  if (val == m_wire.elements_end()) {
+    BOOST_THROW_EXCEPTION(Error("Nonce element is missing"));
+  }
+  uint32_t nonce = 0;
+  if (val->value_size() != sizeof(nonce)) {
+    BOOST_THROW_EXCEPTION(Error("Nonce element is malformed"));
+  }
+  std::memcpy(&nonce, val->value(), sizeof(nonce));
+  m_nonce = nonce;
 
   // InterestLifetime
   val = m_wire.find(tlv::InterestLifetime);
@@ -320,7 +331,7 @@
 bool
 Interest::matchesInterest(const Interest& other) const
 {
-  /// @todo #3162 match Link field
+  /// @todo #3162 match ForwardingHint field
   return (this->getName() == other.getName() &&
           this->getSelectors() == other.getSelectors());
 }
@@ -330,32 +341,17 @@
 uint32_t
 Interest::getNonce() const
 {
-  if (!m_nonce.hasWire())
-    const_cast<Interest*>(this)->setNonce(random::generateWord32());
-
-  if (m_nonce.value_size() == sizeof(uint32_t)) {
-    uint32_t nonce = 0;
-    std::memcpy(&nonce, m_nonce.value(), sizeof(uint32_t));
-    return nonce;
+  if (!m_nonce) {
+    m_nonce = random::generateWord32();
   }
-  else {
-    // for compatibility reasons.  Should be removed eventually
-    return readNonNegativeInteger(m_nonce);
-  }
+  return *m_nonce;
 }
 
 Interest&
 Interest::setNonce(uint32_t nonce)
 {
-  if (m_wire.hasWire() && m_nonce.value_size() == sizeof(uint32_t)) {
-    std::memcpy(const_cast<uint8_t*>(m_nonce.value()), &nonce, sizeof(nonce));
-  }
-  else {
-    m_nonce = makeBinaryBlock(tlv::Nonce,
-                              reinterpret_cast<const uint8_t*>(&nonce),
-                              sizeof(nonce));
-    m_wire.reset();
-  }
+  m_nonce = nonce;
+  m_wire.reset();
   return *this;
 }