decoding+transport: Exception-safe Block parsing

Change-Id: I3e83b6ca4c8ca42b8bb1ddc8dc50c52ee366c55c
Refs: #1291
diff --git a/src/encoding/block.hpp b/src/encoding/block.hpp
index 52ed7e7..a2507b5 100644
--- a/src/encoding/block.hpp
+++ b/src/encoding/block.hpp
@@ -31,8 +31,11 @@
   typedef element_container::const_iterator  element_const_iterator;
 
   /// @brief Error that can be thrown from the block
-  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
-  
+  struct Error : public std::runtime_error
+  {
+    Error(const std::string& what) : std::runtime_error(what) {}
+  };
+
   /**
    * @brief Default constructor to create an empty Block
    */
@@ -43,11 +46,11 @@
    */
   explicit
   Block(const EncodingBuffer& buffer);
-  
+
   /**
    * @brief A helper version of a constructor to create Block from the raw buffer (type and value-length parsing)
    */
-  Block(const ConstBufferPtr &buffer);
+  Block(const ConstBufferPtr& buffer);
 
   /**
    * @brief Another helper to create block from a buffer, directly specifying boundaries
@@ -55,31 +58,31 @@
    *
    * 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,
+  Block(const ConstBufferPtr& buffer,
+        const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
         bool verifyLength = true);
-  
+
   /**
    * @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);
+  Block(const uint8_t* buffer, size_t maxlength);
 
-  Block(const void *buffer, size_t maxlength);
+  Block(const void* buffer, size_t maxlength);
 
   /*
-   * @brief A helper version of a constructor to create Block from the stream. 
+   * @brief A helper version of a constructor to create Block from the stream.
    */
   Block(std::istream& is);
-  
+
   /**
    * @brief Create Block from the wire buffer (no parsing)
    *
    * This version of the constructor does not do any parsing
    */
-  Block(const ConstBufferPtr &wire,
+  Block(const ConstBufferPtr& wire,
         uint32_t type,
-        const Buffer::const_iterator &begin, const Buffer::const_iterator &end,
-        const Buffer::const_iterator &valueBegin, const 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
@@ -94,7 +97,7 @@
    * to construct wire encoding, one need to prepend the wire buffer with type
    * and value-length VAR-NUMBERs
    */
-  Block(uint32_t type, const ConstBufferPtr &value);
+  Block(uint32_t type, const ConstBufferPtr& value);
 
   /**
    * @brief Create nested Block of a specific type with the specified value
@@ -104,14 +107,34 @@
    * and value-length VAR-NUMBERs
    */
   explicit
-  Block(uint32_t type, const Block &value);
+  Block(uint32_t type, const Block& value);
+
+  /**
+   * @brief Try to construct block from Buffer, referencing data block pointed by wire
+   *
+   * @throws This method never throws an exception
+   *
+   * @returns true if Block successfully created, false if block cannot be created
+   */
+  static bool
+  fromBuffer(const ConstBufferPtr& wire, size_t offset, Block& block);
+
+  /**
+   * @brief Try to construct block from Buffer, referencing data block pointed by wire
+   *
+   * @throws This method never throws an exception
+   *
+   * @returns true if Block successfully created, false if block cannot be created
+   */
+  static bool
+  fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block);
 
   /**
    * @brief Check if the Block is empty
    */
   inline bool
   empty() const;
-  
+
   /**
    * @brief Check if the Block has fully encoded wire
    */
@@ -123,7 +146,7 @@
    */
   inline bool
   hasValue() const;
-  
+
   /**
    * @brief Reset wire buffer of the element
    */
@@ -150,14 +173,14 @@
    */
   void
   encode();
-  
+
   inline uint32_t
   type() const;
 
   /**
    * @brief Get the first subelement of the requested type
    */
-  inline const Block &
+  inline const Block&
   get(uint32_t type) const;
 
   inline element_const_iterator
@@ -171,10 +194,10 @@
 
   inline element_iterator
   erase(element_iterator first, element_iterator last);
-  
+
   inline void
-  push_back(const Block &element);
-  
+  push_back(const Block& element);
+
   inline Buffer::const_iterator
   begin() const;
 
@@ -189,7 +212,7 @@
 
   // inline const uint8_t*
   // buf() const;
-  
+
   inline Buffer::const_iterator
   value_begin() const;
 
@@ -216,7 +239,7 @@
 
   inline size_t
   elements_size() const;
-  
+
   Block
   blockFromValue() const;
 
@@ -224,11 +247,11 @@
   ConstBufferPtr m_buffer;
 
   uint32_t m_type;
-  
+
   Buffer::const_iterator m_begin;
   Buffer::const_iterator m_end;
   uint32_t m_size;
-  
+
   Buffer::const_iterator m_value_begin;
   Buffer::const_iterator m_value_end;
 
@@ -285,7 +308,7 @@
   return m_type;
 }
 
-inline const Block &
+inline const Block&
 Block::get(uint32_t type) const
 {
   for (element_const_iterator i = m_subBlocks.begin ();
@@ -300,7 +323,7 @@
 
   throw Error("(Block::get) Requested a non-existed type [" + boost::lexical_cast<std::string>(type) + "] from Block");
 }
-  
+
 inline Block::element_const_iterator
 Block::find(uint32_t type) const
 {
@@ -409,7 +432,7 @@
 {
   if (!hasValue())
     return 0;
-  
+
   return &*m_value_begin;
 }