encoding: Allow creation of a Block from EncodingBuffer

Change-Id: Ifed719e30b9bc04c2e056ac07d6bcf713e8a2bf0
diff --git a/src/encoding/block.cpp b/src/encoding/block.cpp
index bad73a2..fdeb043 100644
--- a/src/encoding/block.cpp
+++ b/src/encoding/block.cpp
@@ -19,8 +19,8 @@
 
 Block::Block(const ConstBufferPtr &wire,
              uint32_t type,
-             const Buffer::const_iterator &begin, Buffer::const_iterator &end,
-             const Buffer::const_iterator &valueBegin, Buffer::const_iterator &valueEnd)
+             const Buffer::const_iterator &begin, const Buffer::const_iterator &end,
+             const Buffer::const_iterator &valueBegin, const Buffer::const_iterator &valueEnd)
   : m_buffer(wire)
   , m_type(type)
   , m_begin(begin)
@@ -49,6 +49,23 @@
     }
 }
 
+Block::Block(const ConstBufferPtr &buffer,
+             const Buffer::const_iterator &begin, const Buffer::const_iterator &end)
+  : m_buffer(buffer)
+  , m_begin(begin)
+  , m_end(end)
+{
+  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 != (m_value_end - m_value_begin))
+    {
+      throw Tlv::Error("TLV length doesn't match buffer length");
+    }
+}
+
 Block::Block(std::istream& is)
 {
   std::istream_iterator<uint8_t> tmp_begin(is);  
diff --git a/src/encoding/block.hpp b/src/encoding/block.hpp
index 984e8aa..3699f36 100644
--- a/src/encoding/block.hpp
+++ b/src/encoding/block.hpp
@@ -45,6 +45,15 @@
   Block(const ConstBufferPtr &buffer);
 
   /**
+   * @brief Another helper to create block from a buffer, directly specifying boundaries
+   *        of the block within the buffer
+   *
+   * This version will automatically detect type and position of the value within the block
+   */
+  Block(const ConstBufferPtr &buffer,
+        const Buffer::const_iterator &begin, const Buffer::const_iterator &end);
+  
+  /**
    * @brief A helper version of a constructor to create Block from the raw buffer (type and value-length parsing)
    */
   Block(const uint8_t *buffer, size_t maxlength);
@@ -63,8 +72,8 @@
    */
   Block(const ConstBufferPtr &wire,
         uint32_t type,
-        const Buffer::const_iterator &begin, Buffer::const_iterator &end,
-        const Buffer::const_iterator &valueBegin, Buffer::const_iterator &valueEnd);
+        const Buffer::const_iterator &begin, const Buffer::const_iterator &end,
+        const Buffer::const_iterator &valueBegin, const Buffer::const_iterator &valueEnd);
 
   /**
    * @brief Create Block of a specific type with empty wire buffer
@@ -183,6 +192,9 @@
 
   inline const uint8_t*
   wire() const;
+
+  inline const uint8_t*
+  buf() const;
   
   inline const uint8_t*
   value() const;
@@ -420,6 +432,15 @@
 }
 
 inline const uint8_t*
+Block::buf() const
+{
+  if (!hasWire())
+      throw Error("(Block::wire) Underlying wire buffer is empty");
+
+  return &*m_begin;
+}
+
+inline const uint8_t*
 Block::value() const
 {
   if (!hasValue())
diff --git a/src/encoding/encoding-buffer.hpp b/src/encoding/encoding-buffer.hpp
index 8bf6d2c..eac26f9 100644
--- a/src/encoding/encoding-buffer.hpp
+++ b/src/encoding/encoding-buffer.hpp
@@ -48,7 +48,7 @@
    * otherwise behavior is undefined.
    */
   EncodingImpl (size_t totalReserve = 8800,
-                  size_t reserveFromBack = 400)
+                size_t reserveFromBack = 400)
     : m_buffer (new Buffer (totalReserve))
   {
     m_begin = m_end = m_buffer->end () - (reserveFromBack < totalReserve ? reserveFromBack : 0);
@@ -66,6 +66,9 @@
   inline const uint8_t*
   buf () const;
 
+  inline Block
+  block () const;
+
   inline void
   resize (size_t sz, bool addInFront);
 
@@ -111,6 +114,18 @@
   inline size_t
   appendVarNumber (uint64_t varNumber);
 
+  // inline void
+  // removeByteFromFront ();
+
+  // inline void
+  // removeByteFromEnd ();
+
+  // inline void
+  // removeVarNumberFromFront (uint64_t varNumber);
+
+  // inline void
+  // removeVarNumberFromBack (uint64_t varNumber);
+  
 private:
   BufferPtr m_buffer;
 
@@ -204,7 +219,14 @@
 {
   return &(*m_begin);
 }
-  
+
+inline Block
+EncodingImpl<encoding::Buffer>::block () const
+{
+  return Block(m_buffer,
+               m_begin, m_end);
+}
+
 inline void
 EncodingImpl<encoding::Buffer>::resize (size_t sz, bool addInFront)
 {