name: Converting name to use EncodingBuffer

Change-Id: I7dbc7bdd7198085235cbb0b7108cf4c6d5242a62
diff --git a/src/encoding/block.cpp b/src/encoding/block.cpp
index 98c131a..e6a8b80 100644
--- a/src/encoding/block.cpp
+++ b/src/encoding/block.cpp
@@ -56,10 +56,11 @@
   : m_buffer(buffer)
   , m_begin(begin)
   , m_end(end)
+  , m_size(m_end - m_begin)
 {
   m_value_begin = m_buffer->begin();
   m_value_end   = m_buffer->end();
-  
+
   m_type = Tlv::readType(m_value_begin, m_value_end);
   uint64_t length = Tlv::readVarNumber(m_value_begin, m_value_end);
   if (length != static_cast<uint64_t>(m_value_end - m_value_begin))
diff --git a/src/encoding/block.hpp b/src/encoding/block.hpp
index b729bc2..45cf1ad 100644
--- a/src/encoding/block.hpp
+++ b/src/encoding/block.hpp
@@ -486,7 +486,7 @@
 Block::value() const
 {
   if (!hasValue())
-      throw Error("(Block::value) Underlying value buffer is empty");
+    return 0;
   
   return &*m_value_begin;
 }
diff --git a/src/encoding/encoding-buffer.hpp b/src/encoding/encoding-buffer.hpp
index 8870941..62d6a12 100644
--- a/src/encoding/encoding-buffer.hpp
+++ b/src/encoding/encoding-buffer.hpp
@@ -143,9 +143,6 @@
   }
 
   inline size_t
-  size () const;
-
-  inline size_t
   prependByte (uint8_t val);
 
   inline size_t
@@ -168,9 +165,6 @@
 
   inline size_t
   appendVarNumber (uint64_t varNumber);
-
-private:
-  size_t m_size;
 };
 
 
@@ -185,12 +179,6 @@
 }
 
 inline size_t
-EncodingImpl<encoding::Estimator>::size () const
-{
-  return m_size;
-}
-
-inline size_t
 EncodingImpl<encoding::Buffer>::capacity () const
 {
   return m_buffer->size ();
@@ -289,7 +277,6 @@
 inline size_t
 EncodingImpl<encoding::Estimator>::prependByte (uint8_t val)
 {
-  m_size += 1;
   return 1;
 }
 
@@ -307,7 +294,6 @@
 inline size_t
 EncodingImpl<encoding::Estimator>::prependByteArray (const uint8_t *arr, size_t len)
 {
-  m_size += len;
   return len;
 }
 
@@ -335,19 +321,15 @@
 EncodingImpl<encoding::Estimator>::prependNonNegativeInteger (uint64_t varNumber)
 {
   if (varNumber < 253) {
-    m_size += 1;
     return 1;
   }
   else if (varNumber <= std::numeric_limits<uint16_t>::max ()) {
-    m_size += 2;
     return 2;
   }
   else if (varNumber <= std::numeric_limits<uint32_t>::max ()) {
-    m_size += 4;
     return 4;
   }
   else {
-    m_size += 8;
     return 8;
   }
 }
@@ -383,19 +365,15 @@
 EncodingImpl<encoding::Estimator>::prependVarNumber (uint64_t varNumber)
 {
   if (varNumber < 253) {
-    m_size += 1;
     return 1;
   }
   else if (varNumber <= std::numeric_limits<uint16_t>::max ()) {
-    m_size += 3;
     return 3;
   }
   else if (varNumber <= std::numeric_limits<uint32_t>::max ()) {
-    m_size += 5;
     return 5;
   }
   else {
-    m_size += 9;
     return 9;
   }
 }
diff --git a/src/name-component.hpp b/src/name-component.hpp
index a74c40c..bf7b62c 100644
--- a/src/name-component.hpp
+++ b/src/name-component.hpp
@@ -342,7 +342,8 @@
 Component::wireEncode(EncodingImpl<T>& block) const
 {
   size_t total_len = 0;
-  total_len += block.prependByteArray (value(), value_size());
+  if (value_size() > 0)
+    total_len += block.prependByteArray (value(), value_size());
   total_len += block.prependVarNumber (value_size());
   total_len += block.prependVarNumber (Tlv::NameComponent);
   return total_len;
diff --git a/src/name.hpp b/src/name.hpp
index 18d4252..96a2e9d 100644
--- a/src/name.hpp
+++ b/src/name.hpp
@@ -88,8 +88,12 @@
     set(uri.c_str());
   }
 
+  /**
+   * @brief Fast encoding or block size estimation
+   */
+  template<bool T>
   size_t
-  wireEncode (EncodingBuffer& blk);
+  wireEncode(EncodingImpl<T> &block) const;
   
   const Block &
   wireEncode() const;
@@ -167,7 +171,11 @@
   Name&
   append(const Block &value)
   {
-    m_nameBlock.elements().push_back(Component(value.begin(), value.end()));
+    if (value.type() == Tlv::NameComponent)
+      m_nameBlock.elements().push_back(value);
+    else
+      m_nameBlock.elements().push_back(Block(Tlv::NameComponent, value));
+
     return *this;
   }
   
@@ -483,14 +491,15 @@
   if (m_nameBlock.hasWire())
     return m_nameBlock;
 
-  for (Block::element_iterator i = m_nameBlock.element_begin();
-       i != m_nameBlock.element_end();
-       ++i)
-    {
-      i->encode();
-    }
-        
-  m_nameBlock.encode();
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+  
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_nameBlock = buffer.block();
+  m_nameBlock.parse();
+  
   return m_nameBlock;
 }
 
@@ -501,12 +510,13 @@
   m_nameBlock.parse();
 }
 
+template<bool T>
 inline size_t
-Name::wireEncode (EncodingBuffer& blk)
+Name::wireEncode(EncodingImpl<T>& blk) const
 {
   size_t total_len = 0;
   
-  for (reverse_iterator i = rbegin (); 
+  for (const_reverse_iterator i = rbegin (); 
        i != rend ();
        ++i)
     {
@@ -518,6 +528,14 @@
   return total_len;
 }
 
+template
+size_t
+Name::wireEncode<true>(EncodingBuffer& block) const;
+
+template
+size_t
+Name::wireEncode<false>(EncodingEstimator& block) const;
+
 
 } // namespace ndn