data: Optimize Data signing

As of this commit, KeyChain::sign pre-allocates EncodingBuffer, requests
unsigned portion of Data using Data::wireEncode(EncodingBuffer, true),
and then appends the resulting signature and prepends Data packet
header.  This way there is no extra memory allocation after Data packet
is signed.

Change-Id: I670e9a2f1d6f5e9b049f41b47f011af384f32c95
diff --git a/src/data.cpp b/src/data.cpp
new file mode 100644
index 0000000..8ce8f4c
--- /dev/null
+++ b/src/data.cpp
@@ -0,0 +1,308 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "data.hpp"
+#include "util/crypto.hpp"
+
+namespace ndn {
+
+Data::Data()
+  : m_content(Tlv::Content) // empty content
+{
+}
+
+Data::Data(const Name& name)
+  : m_name(name)
+{
+}
+
+Data::Data(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+template<bool T>
+size_t
+Data::wireEncode(EncodingImpl<T>& block, bool unsignedPortion/* = false*/) const
+{
+  size_t totalLength = 0;
+
+  // Data ::= DATA-TLV TLV-LENGTH
+  //            Name
+  //            MetaInfo
+  //            Content
+  //            Signature
+
+  // (reverse encoding)
+
+  if (!unsignedPortion && !m_signature)
+    {
+      throw Error("Requested wire format, but data packet has not been signed yet");
+    }
+
+  if (!unsignedPortion)
+    {
+      // SignatureValue
+      totalLength += prependBlock(block, m_signature.getValue());
+    }
+
+  // SignatureInfo
+  totalLength += prependBlock(block, m_signature.getInfo());
+
+  // Content
+  totalLength += prependBlock(block, getContent());
+
+  // MetaInfo
+  totalLength += getMetaInfo().wireEncode(block);
+
+  // Name
+  totalLength += getName().wireEncode(block);
+
+  if (!unsignedPortion)
+    {
+      totalLength += block.prependVarNumber(totalLength);
+      totalLength += block.prependVarNumber(Tlv::Data);
+    }
+  return totalLength;
+}
+
+const Block&
+Data::wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const
+{
+  size_t totalLength = encoder.size();
+  totalLength += encoder.appendBlock(signatureValue);
+
+  totalLength += encoder.prependVarNumber(totalLength);
+  encoder.prependVarNumber(Tlv::Data);
+
+  const_cast<Data*>(this)->wireDecode(encoder.block());
+  return m_wire;
+}
+
+const Block&
+Data::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  const_cast<Data*>(this)->wireDecode(buffer.block());
+  return m_wire;
+}
+
+void
+Data::wireDecode(const Block& wire)
+{
+  m_wire = wire;
+  m_wire.parse();
+
+  // Data ::= DATA-TLV TLV-LENGTH
+  //            Name
+  //            MetaInfo
+  //            Content
+  //            Signature
+
+  // Name
+  m_name.wireDecode(m_wire.get(Tlv::Name));
+
+  // MetaInfo
+  m_metaInfo.wireDecode(m_wire.get(Tlv::MetaInfo));
+
+  // Content
+  m_content = m_wire.get(Tlv::Content);
+
+  ///////////////
+  // Signature //
+  ///////////////
+
+  // SignatureInfo
+  m_signature.setInfo(m_wire.get(Tlv::SignatureInfo));
+
+  // SignatureValue
+  Block::element_const_iterator val = m_wire.find(Tlv::SignatureValue);
+  if (val != m_wire.elements_end())
+    m_signature.setValue(*val);
+}
+
+Data&
+Data::setName(const Name& name)
+{
+  onChanged();
+  m_name = name;
+
+  return *this;
+}
+
+Data&
+Data::setMetaInfo(const MetaInfo& metaInfo)
+{
+  onChanged();
+  m_metaInfo = metaInfo;
+
+  return *this;
+}
+
+Data&
+Data::setContentType(uint32_t type)
+{
+  onChanged();
+  m_metaInfo.setType(type);
+
+  return *this;
+}
+
+Data&
+Data::setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
+{
+  onChanged();
+  m_metaInfo.setFreshnessPeriod(freshnessPeriod);
+
+  return *this;
+}
+
+Data&
+Data::setFinalBlockId(const name::Component& finalBlockId)
+{
+  onChanged();
+  m_metaInfo.setFinalBlockId(finalBlockId);
+
+  return *this;
+}
+
+const Block&
+Data::getContent() const
+{
+  if (m_content.empty())
+    m_content = dataBlock(Tlv::Content, reinterpret_cast<const uint8_t*>(0), 0);
+
+  if (!m_content.hasWire())
+      m_content.encode();
+  return m_content;
+}
+
+Data&
+Data::setContent(const uint8_t* content, size_t contentLength)
+{
+  onChanged();
+
+  m_content = dataBlock(Tlv::Content, content, contentLength);
+
+  return *this;
+}
+
+Data&
+Data::setContent(const ConstBufferPtr& contentValue)
+{
+  onChanged();
+
+  m_content = Block(Tlv::Content, contentValue); // not a real wire encoding yet
+
+  return *this;
+}
+
+Data&
+Data::setContent(const Block& content)
+{
+  onChanged();
+
+  if (content.type() == Tlv::Content)
+    m_content = content;
+  else {
+    m_content = Block(Tlv::Content, content);
+  }
+
+  return *this;
+}
+
+Data&
+Data::setSignature(const Signature& signature)
+{
+  onChanged();
+  m_signature = signature;
+
+  return *this;
+}
+
+Data&
+Data::setSignatureValue(const Block& value)
+{
+  onChanged();
+  m_signature.setValue(value);
+
+  return *this;
+}
+
+//
+
+Data&
+Data::setIncomingFaceId(uint64_t incomingFaceId)
+{
+  getLocalControlHeader().setIncomingFaceId(incomingFaceId);
+  // ! do not reset Data's wire !
+
+  return *this;
+}
+
+void
+Data::onChanged()
+{
+  // The values have changed, so the wire format is invalidated
+
+  // !!!Note!!! Signature is not invalidated and it is responsibility of
+  // the application to do proper re-signing if necessary
+
+  m_wire.reset();
+}
+
+bool
+Data::operator==(const Data& other) const
+{
+  return getName() == other.getName() &&
+    getMetaInfo() == other.getMetaInfo() &&
+    getContent() == other.getContent() &&
+    getSignature() == other.getSignature();
+}
+
+bool
+Data::operator!=(const Data& other) const
+{
+  return !(*this == other);
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Data& data)
+{
+  os << "Name: " << data.getName() << "\n";
+  os << "MetaInfo: " << data.getMetaInfo() << "\n";
+  os << "Content: (size: " << data.getContent().value_size() << ")\n";
+  os << "Signature: (type: " << data.getSignature().getType() <<
+    ", value_length: "<< data.getSignature().getValue().value_size() << ")";
+  os << std::endl;
+
+  return os;
+}
+
+} // namespace ndn
diff --git a/src/data.hpp b/src/data.hpp
index b82533a..9338258 100644
--- a/src/data.hpp
+++ b/src/data.hpp
@@ -83,17 +83,20 @@
    * Otherwise, Data::shared_from_this() will throw an exception.
    */
   explicit
-  Data(const Block& wire)
-  {
-    wireDecode(wire);
-  }
+  Data(const Block& wire);
 
   /**
    * @brief Fast encoding or block size estimation
+   *
+   * @param block                   EncodingEstimator or EncodingBuffer instance
+   * @param wantUnsignedPortionOnly Request only unsigned portion to be encoded in block.
+   *                                If true, only Name, MetaInfo, Content, and SignatureInfo
+   *                                blocks will be encoded into the block. Note that there
+   *                                will be no outer TLV header of the Data packet.
    */
   template<bool T>
   size_t
-  wireEncode(EncodingImpl<T>& block, bool unsignedPortion = false) const;
+  wireEncode(EncodingImpl<T>& block, bool wantUnsignedPortionOnly = false) const;
 
   /**
    * @brief Encode to a wire format
@@ -102,6 +105,28 @@
   wireEncode() const;
 
   /**
+   * @brief Finalize Data packet encoding with the specified SignatureValue
+   *
+   * @param encoder        EncodingBuffer instance, containing Name, MetaInfo, Content, and
+   *                       SignatureInfo (without outer TLV header of the Data packet).
+   * @param signatureValue SignatureValue block to be added to Data packet to finalize
+   *                       the wire encoding
+   *
+   * This method is intended to be used in concert with Data::wireEncode(EncodingBuffer&, true)
+   * method to optimize Data packet wire format creation:
+   *
+   *     Data data;
+   *     ...
+   *     EncodingBuffer encoder;
+   *     data.wireEncode(encoder, true);
+   *     ...
+   *     Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
+   *     data.wireEncode(encoder, signatureValue)
+   */
+  const Block&
+  wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
+
+  /**
    * @brief Decode from the wire format
    */
   void
@@ -286,112 +311,6 @@
   friend class nfd::LocalControlHeader;
 };
 
-inline
-Data::Data()
-  : m_content(Tlv::Content) // empty content
-{
-}
-
-inline
-Data::Data(const Name& name)
-  : m_name(name)
-{
-}
-
-template<bool T>
-inline size_t
-Data::wireEncode(EncodingImpl<T>& block, bool unsignedPortion/* = false*/) const
-{
-  size_t totalLength = 0;
-
-  // Data ::= DATA-TLV TLV-LENGTH
-  //            Name
-  //            MetaInfo
-  //            Content
-  //            Signature
-
-  // (reverse encoding)
-
-  if (!unsignedPortion && !m_signature)
-    {
-      throw Error("Requested wire format, but data packet has not been signed yet");
-    }
-
-  if (!unsignedPortion)
-    {
-      // SignatureValue
-      totalLength += prependBlock(block, m_signature.getValue());
-    }
-
-  // SignatureInfo
-  totalLength += prependBlock(block, m_signature.getInfo());
-
-  // Content
-  totalLength += prependBlock(block, getContent());
-
-  // MetaInfo
-  totalLength += getMetaInfo().wireEncode(block);
-
-  // Name
-  totalLength += getName().wireEncode(block);
-
-  if (!unsignedPortion)
-    {
-      totalLength += block.prependVarNumber (totalLength);
-      totalLength += block.prependVarNumber (Tlv::Data);
-    }
-  return totalLength;
-}
-
-inline const Block&
-Data::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  const_cast<Data*>(this)->wireDecode(buffer.block());
-  return m_wire;
-}
-
-inline void
-Data::wireDecode(const Block& wire)
-{
-  m_wire = wire;
-  m_wire.parse();
-
-  // Data ::= DATA-TLV TLV-LENGTH
-  //            Name
-  //            MetaInfo
-  //            Content
-  //            Signature
-
-  // Name
-  m_name.wireDecode(m_wire.get(Tlv::Name));
-
-  // MetaInfo
-  m_metaInfo.wireDecode(m_wire.get(Tlv::MetaInfo));
-
-  // Content
-  m_content = m_wire.get(Tlv::Content);
-
-  ///////////////
-  // Signature //
-  ///////////////
-
-  // SignatureInfo
-  m_signature.setInfo(m_wire.get(Tlv::SignatureInfo));
-
-  // SignatureValue
-  Block::element_const_iterator val = m_wire.find(Tlv::SignatureValue);
-  if (val != m_wire.elements_end())
-    m_signature.setValue(*val);
-}
 
 inline bool
 Data::hasWire() const
@@ -405,146 +324,36 @@
   return m_name;
 }
 
-inline Data&
-Data::setName(const Name& name)
-{
-  onChanged();
-  m_name = name;
-
-  return *this;
-}
-
 inline const MetaInfo&
 Data::getMetaInfo() const
 {
   return m_metaInfo;
 }
 
-inline Data&
-Data::setMetaInfo(const MetaInfo& metaInfo)
-{
-  onChanged();
-  m_metaInfo = metaInfo;
-
-  return *this;
-}
-
 inline uint32_t
 Data::getContentType() const
 {
   return m_metaInfo.getType();
 }
 
-inline Data&
-Data::setContentType(uint32_t type)
-{
-  onChanged();
-  m_metaInfo.setType(type);
-
-  return *this;
-}
-
 inline const time::milliseconds&
 Data::getFreshnessPeriod() const
 {
   return m_metaInfo.getFreshnessPeriod();
 }
 
-inline Data&
-Data::setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
-{
-  onChanged();
-  m_metaInfo.setFreshnessPeriod(freshnessPeriod);
-
-  return *this;
-}
-
 inline const name::Component&
 Data::getFinalBlockId() const
 {
   return m_metaInfo.getFinalBlockId();
 }
 
-inline Data&
-Data::setFinalBlockId(const name::Component& finalBlockId)
-{
-  onChanged();
-  m_metaInfo.setFinalBlockId(finalBlockId);
-
-  return *this;
-}
-
-inline const Block&
-Data::getContent() const
-{
-  if (m_content.empty())
-    m_content = dataBlock(Tlv::Content, reinterpret_cast<const uint8_t*>(0), 0);
-
-  if (!m_content.hasWire())
-      m_content.encode();
-  return m_content;
-}
-
-inline Data&
-Data::setContent(const uint8_t* content, size_t contentLength)
-{
-  onChanged();
-
-  m_content = dataBlock(Tlv::Content, content, contentLength);
-
-  return *this;
-}
-
-inline Data&
-Data::setContent(const ConstBufferPtr& contentValue)
-{
-  onChanged();
-
-  m_content = Block(Tlv::Content, contentValue); // not real a wire encoding yet
-
-  return *this;
-}
-
-inline Data&
-Data::setContent(const Block& content)
-{
-  onChanged();
-
-  if (content.type() == Tlv::Content)
-    m_content = content;
-  else {
-    m_content = Block(Tlv::Content, content);
-  }
-
-  return *this;
-}
-
 inline const Signature&
 Data::getSignature() const
 {
   return m_signature;
 }
 
-inline Data&
-Data::setSignature(const Signature& signature)
-{
-  onChanged();
-  m_signature = signature;
-
-  return *this;
-}
-
-inline Data&
-Data::setSignatureValue(const Block& value)
-{
-  onChanged();
-  m_signature.setValue(value);
-
-  return *this;
-}
-
-//
-
 inline nfd::LocalControlHeader&
 Data::getLocalControlHeader()
 {
@@ -563,53 +372,6 @@
   return getLocalControlHeader().getIncomingFaceId();
 }
 
-inline Data&
-Data::setIncomingFaceId(uint64_t incomingFaceId)
-{
-  getLocalControlHeader().setIncomingFaceId(incomingFaceId);
-  // ! do not reset Data's wire !
-
-  return *this;
-}
-
-inline void
-Data::onChanged()
-{
-  // The values have changed, so the wire format is invalidated
-
-  // !!!Note!!! Signature is not invalidated and it is responsibility of
-  // the application to do proper re-signing if necessary
-
-  m_wire.reset();
-}
-
-inline bool
-Data::operator==(const Data& other) const
-{
-  return getName() == other.getName() &&
-    getMetaInfo() == other.getMetaInfo() &&
-    getContent() == other.getContent() &&
-    getSignature() == other.getSignature();
-}
-
-inline bool
-Data::operator!=(const Data& other) const
-{
-  return !(*this == other);
-}
-
-inline std::ostream&
-operator<<(std::ostream& os, const Data& data)
-{
-  os << "Name: " << data.getName() << "\n";
-  os << "MetaInfo: " << data.getMetaInfo() << "\n";
-  os << "Content: (size: " << data.getContent().value_size() << ")\n";
-  os << "Signature: (type: " << data.getSignature().getType() <<
-    ", value_length: "<< data.getSignature().getValue().value_size() << ")";
-  os << std::endl;
-
-  return os;
-}
 
 } // namespace ndn
 
diff --git a/src/encoding/block.hpp b/src/encoding/block.hpp
index 7667fbd..c91d12c 100644
--- a/src/encoding/block.hpp
+++ b/src/encoding/block.hpp
@@ -69,9 +69,8 @@
   /**
    * @brief A helper version of a constructor to create Block from the raw buffer (type
    * and value-length parsing)
-   *
-   * This constructor provides ability of implicit conversion from ConstBufferPtr to Block
    */
+  explicit
   Block(const ConstBufferPtr& buffer);
 
   /**
diff --git a/src/encoding/encoding-buffer.hpp b/src/encoding/encoding-buffer.hpp
index d3fa3ac..4c5185e 100644
--- a/src/encoding/encoding-buffer.hpp
+++ b/src/encoding/encoding-buffer.hpp
@@ -145,6 +145,9 @@
   inline size_t
   appendVarNumber(uint64_t varNumber);
 
+  inline size_t
+  appendBlock(const Block& block);
+
   // inline void
   // removeByteFromFront();
 
@@ -207,6 +210,9 @@
 
   inline size_t
   appendVarNumber(uint64_t varNumber);
+
+  inline size_t
+  appendBlock(const Block& block);
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -270,6 +276,25 @@
   return encoder.prependByteArray(block.wire(), block.size());
 }
 
+template<bool P>
+inline size_t
+appendByteArrayBlock(EncodingImpl<P>& encoder, uint32_t type,
+                      const uint8_t* array, size_t arraySize)
+{
+  size_t totalLength = encoder.appendVarNumber(type);
+  totalLength += encoder.appendVarNumber(arraySize);
+  totalLength += encoder.appendByteArray(array, arraySize);
+
+  return totalLength;
+}
+
+template<bool P>
+inline size_t
+appendBlock(EncodingImpl<P>& encoder, const Block& block)
+{
+  return encoder.appendByteArray(block.wire(), block.size());
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
@@ -536,6 +561,28 @@
 }
 
 inline size_t
+EncodingImpl<encoding::Buffer>::appendBlock(const Block& block)
+{
+  if (block.hasWire()) {
+    return appendByteArray(block.wire(), block.size());
+  }
+  else {
+    return appendByteArrayBlock(*this, block.type(), block.value(), block.value_size());
+  }
+}
+
+inline size_t
+EncodingImpl<encoding::Estimator>::appendBlock(const Block& block)
+{
+  if (block.hasWire()) {
+    return block.size();
+  }
+  else {
+    return appendByteArrayBlock(*this, block.type(), block.value(), block.value_size());
+  }
+}
+
+inline size_t
 EncodingImpl<encoding::Estimator>::appendByteArray(const uint8_t* array, size_t length)
 {
   return prependByteArray(array, length);
diff --git a/src/interest.cpp b/src/interest.cpp
index 9e5b129..590d527 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -108,6 +108,124 @@
   return true;
 }
 
+template<bool T>
+size_t
+Interest::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  // Interest ::= INTEREST-TYPE TLV-LENGTH
+  //                Name
+  //                Selectors?
+  //                Nonce
+  //                Scope?
+  //                InterestLifetime?
+
+  // (reverse encoding)
+
+  // InterestLifetime
+  if (getInterestLifetime() >= time::milliseconds::zero() &&
+      getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
+    {
+      totalLength += prependNonNegativeIntegerBlock(block,
+                                                    Tlv::InterestLifetime,
+                                                    getInterestLifetime().count());
+    }
+
+  // Scope
+  if (getScope() >= 0)
+    {
+      totalLength += prependNonNegativeIntegerBlock(block, Tlv::Scope, getScope());
+    }
+
+  // Nonce
+  getNonce(); // to ensure that Nonce is properly set
+  totalLength += block.prependBlock(m_nonce);
+
+  // Selectors
+  if (hasSelectors())
+    {
+      totalLength += getSelectors().wireEncode(block);
+    }
+
+  // Name
+  totalLength += getName().wireEncode(block);
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(Tlv::Interest);
+  return totalLength;
+}
+
+const Block&
+Interest::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  // to ensure that Nonce block points to the right memory location
+  const_cast<Interest*>(this)->wireDecode(buffer.block());
+
+  return m_wire;
+}
+
+void
+Interest::wireDecode(const Block& wire)
+{
+  m_wire = wire;
+  m_wire.parse();
+
+  // Interest ::= INTEREST-TYPE TLV-LENGTH
+  //                Name
+  //                Selectors?
+  //                Nonce
+  //                Scope?
+  //                InterestLifetime?
+
+  if (m_wire.type() != Tlv::Interest)
+    throw Tlv::Error("Unexpected TLV number when decoding Interest");
+
+  // Name
+  m_name.wireDecode(m_wire.get(Tlv::Name));
+
+  // Selectors
+  Block::element_const_iterator val = m_wire.find(Tlv::Selectors);
+  if (val != m_wire.elements_end())
+    {
+      m_selectors.wireDecode(*val);
+    }
+  else
+    m_selectors = Selectors();
+
+  // Nonce
+  m_nonce = m_wire.get(Tlv::Nonce);
+
+  // Scope
+  val = m_wire.find(Tlv::Scope);
+  if (val != m_wire.elements_end())
+    {
+      m_scope = readNonNegativeInteger(*val);
+    }
+  else
+    m_scope = -1;
+
+  // InterestLifetime
+  val = m_wire.find(Tlv::InterestLifetime);
+  if (val != m_wire.elements_end())
+    {
+      m_interestLifetime = time::milliseconds(readNonNegativeInteger(*val));
+    }
+  else
+    {
+      m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
+    }
+}
+
 std::ostream&
 operator<<(std::ostream& os, const Interest& interest)
 {
diff --git a/src/interest.hpp b/src/interest.hpp
index 138ea7c..0750542 100644
--- a/src/interest.hpp
+++ b/src/interest.hpp
@@ -180,25 +180,25 @@
    * @brief Fast encoding or block size estimation
    */
   template<bool T>
-  inline size_t
+  size_t
   wireEncode(EncodingImpl<T>& block) const;
 
   /**
    * @brief Encode to a wire format
    */
-  inline const Block&
+  const Block&
   wireEncode() const;
 
   /**
    * @brief Decode from the wire format
    */
-  inline void
+  void
   wireDecode(const Block& wire);
 
   /**
    * @brief Check if already has wire
    */
-  inline bool
+  bool
   hasWire() const;
 
   /**
@@ -207,13 +207,13 @@
    * If there are interest selectors, this method will append "?" and add the selectors as
    * a query string.  For example, "/test/name?ndn.ChildSelector=1"
    */
-  inline std::string
+  std::string
   toUri() const;
 
   /**
    * @brief Check if Interest has any selectors present
    */
-  inline bool
+  bool
   hasSelectors() const;
 
   /**
@@ -527,123 +527,6 @@
   return !m_selectors.empty();
 }
 
-template<bool T>
-inline size_t
-Interest::wireEncode(EncodingImpl<T>& block) const
-{
-  size_t totalLength = 0;
-
-  // Interest ::= INTEREST-TYPE TLV-LENGTH
-  //                Name
-  //                Selectors?
-  //                Nonce
-  //                Scope?
-  //                InterestLifetime?
-
-  // (reverse encoding)
-
-  // InterestLifetime
-  if (getInterestLifetime() >= time::milliseconds::zero() &&
-      getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
-    {
-      totalLength += prependNonNegativeIntegerBlock(block,
-                                                    Tlv::InterestLifetime,
-                                                    getInterestLifetime().count());
-    }
-
-  // Scope
-  if (getScope() >= 0)
-    {
-      totalLength += prependNonNegativeIntegerBlock(block, Tlv::Scope, getScope());
-    }
-
-  // Nonce
-  getNonce(); // to ensure that Nonce is properly set
-  totalLength += block.prependBlock(m_nonce);
-
-  // Selectors
-  if (!getSelectors().empty())
-    {
-      totalLength += getSelectors().wireEncode(block);
-    }
-
-  // Name
-  totalLength += getName().wireEncode(block);
-
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(Tlv::Interest);
-  return totalLength;
-}
-
-inline const Block&
-Interest::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  // to ensure that Nonce block points to the right memory location
-  const_cast<Interest*>(this)->wireDecode(buffer.block());
-
-  return m_wire;
-}
-
-inline void
-Interest::wireDecode(const Block& wire)
-{
-  m_wire = wire;
-  m_wire.parse();
-
-  // Interest ::= INTEREST-TYPE TLV-LENGTH
-  //                Name
-  //                Selectors?
-  //                Nonce
-  //                Scope?
-  //                InterestLifetime?
-
-  if (m_wire.type() != Tlv::Interest)
-    throw Tlv::Error("Unexpected TLV number when decoding Interest");
-
-  // Name
-  m_name.wireDecode(m_wire.get(Tlv::Name));
-
-  // Selectors
-  Block::element_const_iterator val = m_wire.find(Tlv::Selectors);
-  if (val != m_wire.elements_end())
-    {
-      m_selectors.wireDecode(*val);
-    }
-  else
-    m_selectors = Selectors();
-
-  // Nonce
-  m_nonce = m_wire.get(Tlv::Nonce);
-
-  // Scope
-  val = m_wire.find(Tlv::Scope);
-  if (val != m_wire.elements_end())
-    {
-      m_scope = readNonNegativeInteger(*val);
-    }
-  else
-    m_scope = -1;
-
-  // InterestLifetime
-  val = m_wire.find(Tlv::InterestLifetime);
-  if (val != m_wire.elements_end())
-    {
-      m_interestLifetime = time::milliseconds(readNonNegativeInteger(*val));
-    }
-  else
-    {
-      m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
-    }
-}
 
 inline bool
 Interest::hasWire() const
diff --git a/src/management/nfd-controller.hpp b/src/management/nfd-controller.hpp
index 5286669..8485693 100644
--- a/src/management/nfd-controller.hpp
+++ b/src/management/nfd-controller.hpp
@@ -29,7 +29,7 @@
 namespace nfd {
 
 /**
- * \defgroup management
+ * \defgroup management Management
  * \brief Classes and data structures to manage NDN forwarder
  */
 /**
diff --git a/src/management/nfd-face-flags.hpp b/src/management/nfd-face-flags.hpp
index d7f8a14..39c85cb 100644
--- a/src/management/nfd-face-flags.hpp
+++ b/src/management/nfd-face-flags.hpp
@@ -27,10 +27,9 @@
 
 /**
  * \ingroup management
- * \enum FaceFlags
  * \brief provides additional information about a face
  */
-enum {
+enum FaceFlags {
   /** \brief face is local (for scope control purpose)
    */
   FACE_IS_LOCAL = 1,
diff --git a/src/name.hpp b/src/name.hpp
index d289c09..9c33528 100644
--- a/src/name.hpp
+++ b/src/name.hpp
@@ -175,13 +175,6 @@
   }
 
   Name&
-  append(const ConstBufferPtr& value)
-  {
-    m_nameBlock.push_back(value);
-    return *this;
-  }
-
-  Name&
   append(const Component& value)
   {
     m_nameBlock.push_back(value);
diff --git a/src/security/key-chain.hpp b/src/security/key-chain.hpp
index dcf2079..7c95e14 100644
--- a/src/security/key-chain.hpp
+++ b/src/security/key-chain.hpp
@@ -871,10 +871,13 @@
                             const Name& keyName, DigestAlgorithm digestAlgorithm)
 {
   data.setSignature(signature);
-  data.setSignatureValue(m_tpm->signInTpm(data.wireEncode().value(),
-                                          data.wireEncode().value_size() -
-                                          data.getSignature().getValue().size(),
-                                          keyName, digestAlgorithm));
+
+  EncodingBuffer encoder;
+  data.wireEncode(encoder, true);
+
+  Block signatureValue = m_tpm->signInTpm(encoder.buf(), encoder.size(),
+                                          keyName, digestAlgorithm);
+  data.wireEncode(encoder, signatureValue);
 }
 
 inline void
diff --git a/src/util/crypto.hpp b/src/util/crypto.hpp
index 43933b4..dc0a754 100644
--- a/src/util/crypto.hpp
+++ b/src/util/crypto.hpp
@@ -34,7 +34,8 @@
  * @param dataLength The length of data.
  * @param digest A pointer to a buffer of size crypto::SHA256_DIGEST_SIZE to receive the data.
  */
-void ndn_digestSha256(const uint8_t* data, size_t dataLength, uint8_t* digest);
+void
+ndn_digestSha256(const uint8_t* data, size_t dataLength, uint8_t* digest);
 
 namespace crypto {