encoding: change Block::fromBuffer return type

Block::fromBuffer is changed from taking constructed Block as output parameter
to returning the constructed Block as part of returned tuple.

Old API becomes deprecated.

refs #2553

Change-Id: I64610353b8c0780ee09ebe9089c539fa27506a5e
diff --git a/src/encoding/block.cpp b/src/encoding/block.cpp
index ce13427..4353c96 100644
--- a/src/encoding/block.cpp
+++ b/src/encoding/block.cpp
@@ -222,35 +222,31 @@
   return dataBlock(type, buf, length);
 }
 
-bool
-Block::fromBuffer(const ConstBufferPtr& wire, size_t offset, Block& block)
+std::tuple<bool, Block>
+Block::fromBuffer(ConstBufferPtr buffer, size_t offset)
 {
-  Buffer::const_iterator tempBegin = wire->begin() + offset;
+  Buffer::const_iterator tempBegin = buffer->begin() + offset;
 
   uint32_t type;
-  bool isOk = tlv::readType(tempBegin, wire->end(), type);
+  bool isOk = tlv::readType(tempBegin, buffer->end(), type);
   if (!isOk)
-    return false;
+    return std::make_tuple(false, Block());
 
   uint64_t length;
-  isOk = tlv::readVarNumber(tempBegin, wire->end(), length);
+  isOk = tlv::readVarNumber(tempBegin, buffer->end(), length);
   if (!isOk)
-    return false;
+    return std::make_tuple(false, Block());
 
-  if (length > static_cast<uint64_t>(wire->end() - tempBegin))
-    {
-      return false;
-    }
+  if (length > static_cast<uint64_t>(buffer->end() - tempBegin))
+    return std::make_tuple(false, Block());
 
-  block = Block(wire, type,
-                wire->begin() + offset, tempBegin + length,
-                tempBegin, tempBegin + length);
-
-  return true;
+  return std::make_tuple(true, Block(buffer, type,
+                                     buffer->begin() + offset, tempBegin + length,
+                                     tempBegin, tempBegin + length));
 }
 
-bool
-Block::fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block)
+std::tuple<bool, Block>
+Block::fromBuffer(const uint8_t* buffer, size_t maxSize)
 {
   const uint8_t* tempBegin = buffer;
   const uint8_t* tempEnd = buffer + maxSize;
@@ -258,24 +254,21 @@
   uint32_t type = 0;
   bool isOk = tlv::readType(tempBegin, tempEnd, type);
   if (!isOk)
-    return false;
+    return std::make_tuple(false, Block());
 
   uint64_t length;
   isOk = tlv::readVarNumber(tempBegin, tempEnd, length);
   if (!isOk)
-    return false;
+    return std::make_tuple(false, Block());
 
   if (length > static_cast<uint64_t>(tempEnd - tempBegin))
-    {
-      return false;
-    }
+    return std::make_tuple(false, Block());
 
   BufferPtr sharedBuffer = make_shared<Buffer>(buffer, tempBegin + length);
-  block = Block(sharedBuffer, type,
-                sharedBuffer->begin(), sharedBuffer->end(),
-                sharedBuffer->begin() + (tempBegin - buffer), sharedBuffer->end());
-
-  return true;
+  return std::make_tuple(true,
+         Block(sharedBuffer, type,
+               sharedBuffer->begin(), sharedBuffer->end(),
+               sharedBuffer->begin() + (tempBegin - buffer), sharedBuffer->end()));
 }
 
 void
diff --git a/src/encoding/block.hpp b/src/encoding/block.hpp
index 4bbfe52..7bd6a88 100644
--- a/src/encoding/block.hpp
+++ b/src/encoding/block.hpp
@@ -124,21 +124,52 @@
   static Block
   fromStream(std::istream& is);
 
-  /** @brief Try to construct block from Buffer, referencing data block pointed by wire
+  /** @brief Try to construct block from Buffer
+   *  @param buffer the buffer to construct block from
+   *  @note buffer is passed by value because the constructed block
+   *        takes shared ownership of the buffer
+   *  @param offset offset from beginning of \p buffer to construct Block from
    *
    *  This method does not throw upon decoding error.
-   *  @return true if Block successfully created, false if block cannot be created
+   *  This method does not copy the bytes.
+   *
+   *  @return true and the Block, if Block is successfully created; otherwise false
    */
-  static bool
-  fromBuffer(const ConstBufferPtr& wire, size_t offset, Block& block);
+  static std::tuple<bool, Block>
+  fromBuffer(ConstBufferPtr buffer, size_t offset);
 
-  /** @brief Try to construct block from Buffer, referencing data block pointed by wire
-   *
-   *  This method does not throw upon decoding error.
-   *  @return true if Block successfully created, false if block cannot be created
+  /** @deprecated use fromBuffer(ConstBufferPtr, size_t)
    */
   static bool
-  fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block);
+  fromBuffer(const ConstBufferPtr& buffer, size_t offset, Block& block)
+  {
+    bool isOk = false;
+    std::tie(isOk, block) = Block::fromBuffer(buffer, offset);
+    return isOk;
+  }
+
+  /** @brief Try to construct block from raw buffer
+   *  @param buffer the raw buffer to copy bytes from
+   *  @param maxSize the maximum size of constructed block;
+   *                 @p buffer must have a size of at least @p maxSize
+   *
+   *  This method does not throw upon decoding error.
+   *  This method copies the bytes into a new Buffer.
+   *
+   *  @return true and the Block, if Block is successfully created; otherwise false
+   */
+  static std::tuple<bool, Block>
+  fromBuffer(const uint8_t* buffer, size_t maxSize);
+
+  /** @deprecated use fromBuffer(const uint8_t*, size_t)
+   */
+  static bool
+  fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block)
+  {
+    bool isOk = false;
+    std::tie(isOk, block) = Block::fromBuffer(buffer, maxSize);
+    return isOk;
+  }
 
 public: // wire format
   /** @brief Check if the Block is empty
diff --git a/src/transport/stream-transport.hpp b/src/transport/stream-transport.hpp
index b4e3d09..737842c 100644
--- a/src/transport/stream-transport.hpp
+++ b/src/transport/stream-transport.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2014 Regents of the University of California.
+ * Copyright (c) 2013-2015 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -204,16 +204,16 @@
   bool
   processAll(uint8_t* buffer, size_t& offset, size_t nBytesAvailable)
   {
-    while (offset < nBytesAvailable)
-      {
-        Block element;
-        bool ok = Block::fromBuffer(buffer + offset, nBytesAvailable - offset, element);
-        if (!ok)
-          return false;
+    while (offset < nBytesAvailable) {
+      bool isOk = false;
+      Block element;
+      std::tie(isOk, element) = Block::fromBuffer(buffer + offset, nBytesAvailable - offset);
+      if (!isOk)
+        return false;
 
-        m_transport.receive(element);
-        offset += element.size();
-      }
+      m_transport.receive(element);
+      offset += element.size();
+    }
     return true;
   }
 
diff --git a/tests/unit-tests/encoding/block.t.cpp b/tests/unit-tests/encoding/block.t.cpp
index e9e8c76..ac7ff51 100644
--- a/tests/unit-tests/encoding/block.t.cpp
+++ b/tests/unit-tests/encoding/block.t.cpp
@@ -222,8 +222,10 @@
 
   // using BufferPtr (avoids memory copy)
   size_t offset = 0;
+  bool isOk = false;
   Block testBlock;
-  BOOST_CHECK(Block::fromBuffer(buffer, offset, testBlock));
+  std::tie(isOk, testBlock) = Block::fromBuffer(buffer, offset);
+  BOOST_CHECK(isOk);
   BOOST_CHECK_EQUAL(testBlock.type(), 0);
   BOOST_CHECK_EQUAL(testBlock.size(), 3);
   BOOST_CHECK_EQUAL(testBlock.value_size(), 1);
@@ -231,7 +233,8 @@
   BOOST_CHECK_EQUAL(*testBlock.value(), 0xfa);
   offset += testBlock.size();
 
-  BOOST_CHECK(Block::fromBuffer(buffer, offset, testBlock));
+  std::tie(isOk, testBlock) = Block::fromBuffer(buffer, offset);
+  BOOST_CHECK(isOk);
   BOOST_CHECK_EQUAL(testBlock.type(), 1);
   BOOST_CHECK_EQUAL(testBlock.size(), 3);
   BOOST_CHECK_EQUAL(testBlock.value_size(), 1);
@@ -239,11 +242,14 @@
   BOOST_CHECK_EQUAL(*testBlock.value(), 0xfb);
   offset += testBlock.size();
 
-  BOOST_CHECK(!Block::fromBuffer(buffer, offset, testBlock));
+  std::tie(isOk, testBlock) = Block::fromBuffer(buffer, offset);
+  BOOST_CHECK(!isOk);
 
   // just buffer, copies memory
   offset = 0;
-  BOOST_CHECK(Block::fromBuffer(TEST_BUFFER + offset, sizeof(TEST_BUFFER) - offset, testBlock));
+  std::tie(isOk, testBlock) = Block::fromBuffer(TEST_BUFFER + offset,
+                                                sizeof(TEST_BUFFER) - offset);
+  BOOST_CHECK(isOk);
   BOOST_CHECK_EQUAL(testBlock.type(), 0);
   BOOST_CHECK_EQUAL(testBlock.size(), 3);
   BOOST_CHECK_EQUAL(testBlock.value_size(), 1);
@@ -251,7 +257,9 @@
   BOOST_CHECK_EQUAL(*testBlock.value(), 0xfa);
   offset += testBlock.size();
 
-  BOOST_CHECK(Block::fromBuffer(TEST_BUFFER + offset, sizeof(TEST_BUFFER) - offset, testBlock));
+  std::tie(isOk, testBlock) = Block::fromBuffer(TEST_BUFFER + offset,
+                                                sizeof(TEST_BUFFER) - offset);
+  BOOST_CHECK(isOk);
   BOOST_CHECK_EQUAL(testBlock.type(), 1);
   BOOST_CHECK_EQUAL(testBlock.size(), 3);
   BOOST_CHECK_EQUAL(testBlock.value_size(), 1);
@@ -259,7 +267,9 @@
   BOOST_CHECK_EQUAL(*testBlock.value(), 0xfb);
   offset += testBlock.size();
 
-  BOOST_CHECK(!Block::fromBuffer(TEST_BUFFER + offset, sizeof(TEST_BUFFER) - offset, testBlock));
+  std::tie(isOk, testBlock) = Block::fromBuffer(TEST_BUFFER + offset,
+                                                sizeof(TEST_BUFFER) - offset);
+  BOOST_CHECK(!isOk);
 }
 
 BOOST_AUTO_TEST_CASE(BlockFromStream)