encoding: write nonNegativeInteger 253-255 as one octet

This commit also updates code-style and improves Doxygen in tlv.hpp

refs #4167

Change-Id: I8657feb1bfe96bfc88202d55eb7432d7ff1d5538
diff --git a/src/encoding/tlv.hpp b/src/encoding/tlv.hpp
index bcb562a..876fcb5 100644
--- a/src/encoding/tlv.hpp
+++ b/src/encoding/tlv.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -132,103 +132,116 @@
   ContentType_Key = 2,
 
   /** @brief indicates a producer generated NACK
-   *  @warning Experimental. Not defined in NDN-TLV spec.
    */
   ContentType_Nack = 3
 };
 
 /**
  * @brief Read VAR-NUMBER in NDN-TLV encoding
+ * @tparam InputIterator an iterator or pointer dereferencable to uint8_t
  *
- * @param [in]  begin  Begin (pointer or iterator) of the buffer
- * @param [in]  end    End (pointer or iterator) of the buffer
- * @param [out] number Read number
+ * @param [inout] begin  Begin of the buffer, will be incremented to point to the first byte after
+ *                       the read VAR-NUMBER
+ * @param [in]    end    End of the buffer
+ * @param [out]   number Read VAR-NUMBER
  *
- * @throws This call never throws exception
- *
- * @return true if number successfully read from input, false otherwise
+ * @return true if number was successfully read from input, false otherwise
+ * @note This call never throws exceptions
  */
 template<class InputIterator>
-inline bool
+bool
 readVarNumber(InputIterator& begin, const InputIterator& end, uint64_t& number);
 
 /**
- * @brief Read TLV Type
+ * @brief Read TLV-TYPE
+ * @tparam InputIterator an iterator or pointer dereferencable to uint8_t
  *
- * @param [in]  begin  Begin (pointer or iterator) of the buffer
- * @param [in]  end    End (pointer or iterator) of the buffer
- * @param [out] type   Read type number
+ * @param [inout] begin  Begin of the buffer, will be incremented to point to the first byte after
+ *                       the read TLV-TYPE
+ * @param [in]    end   End of the buffer
+ * @param [out]   type  Read TLV-TYPE
  *
- * @throws This call never throws exception
- *
- * This call is largely equivalent to tlv::readVarNumber, but exception will be thrown if type
- * is larger than 2^32-1 (type in this library is implemented as uint32_t)
+ * @return true if TLV-TYPE was successfully read from input, false otherwise
+ * @note This call never throws exceptions
+ * @note This call is largely equivalent to tlv::readVarNumber, but it will return false if type
+ *       is larger than 2^32-1 (TLV-TYPE in this library is implemented as uint32_t)
  */
 template<class InputIterator>
-inline bool
+bool
 readType(InputIterator& begin, const InputIterator& end, uint32_t& type);
 
-
 /**
  * @brief Read VAR-NUMBER in NDN-TLV encoding
+ * @tparam InputIterator an iterator or pointer dereferencable to uint8_t
  *
- * @throws This call will throw ndn::tlv::Error (aka std::runtime_error) if number cannot be read
+ * @param [inout] begin Begin of the buffer, will be incremented to point to the first byte after
+ *                      the read VAR-NUMBER
+ * @param [in]    end   End of the buffer
  *
- * Note that after call finished, begin will point to the first byte after the read VAR-NUMBER
+ * @throw tlv::Error VAR-NUMBER cannot be read
  */
 template<class InputIterator>
-inline uint64_t
+uint64_t
 readVarNumber(InputIterator& begin, const InputIterator& end);
 
 /**
  * @brief Read TLV Type
+ * @tparam InputIterator an iterator or pointer dereferencable to uint8_t
  *
- * @throws This call will throw ndn::tlv::Error (aka std::runtime_error) if number cannot be read
+ * @param [inout] begin Begin of the buffer, will be incremented to point to the first byte after
+ *                      the read TLV-TYPE
+ * @param [in]    end   End of the buffer
  *
- * This call is largely equivalent to tlv::readVarNumber, but exception will be thrown if type
- * is larger than 2^32-1 (type in this library is implemented as uint32_t)
+ * @throw tlv::Error VAR-NUMBER cannot be read
+ * @note This call is largely equivalent to tlv::readVarNumber, but exception will be thrown if type
+ *       is larger than 2^32-1 (TLV-TYPE in this library is implemented as uint32_t)
  */
 template<class InputIterator>
-inline uint32_t
+uint32_t
 readType(InputIterator& begin, const InputIterator& end);
 
 /**
  * @brief Get number of bytes necessary to hold value of VAR-NUMBER
  */
-inline size_t
+constexpr size_t
 sizeOfVarNumber(uint64_t varNumber);
 
 /**
  * @brief Write VAR-NUMBER to the specified stream
+ * @return length of written VAR-NUMBER
  */
-inline size_t
+size_t
 writeVarNumber(std::ostream& os, uint64_t varNumber);
 
 /**
  * @brief Read nonNegativeInteger in NDN-TLV encoding
+ * @tparam InputIterator an iterator or pointer dereferencable to uint8_t
  *
- * This call will throw ndn::tlv::Error (aka std::runtime_error) if number cannot be read
+ * @param [in]    size  size of the nonNegativeInteger
+ * @param [inout] begin Begin of the buffer, will be incremented to point to the first byte after
+ *                      the read nonNegativeInteger
+ * @param [in]    end   End of the buffer
  *
- * Note that after call finished, begin will point to the first byte after the read VAR-NUMBER
- *
- * How many bytes will be read is directly controlled by the size parameter, which can be either
- * 1, 2, 4, or 8.  If the value of size is different, then an exception will be thrown.
+ * @throw tlv::Error number cannot be read
+ * @note How many bytes to read is directly controlled by \p size, which can be either 1, 2, 4, or 8.
+ *       If \p size differs from \p std::distance(begin, end), tlv::Error exception will be thrown.
  */
 template<class InputIterator>
-inline uint64_t
+uint64_t
 readNonNegativeInteger(size_t size, InputIterator& begin, const InputIterator& end);
 
 /**
  * @brief Get number of bytes necessary to hold value of nonNegativeInteger
  */
-inline size_t
-sizeOfNonNegativeInteger(uint64_t varNumber);
+constexpr size_t
+sizeOfNonNegativeInteger(uint64_t integer);
 
 /**
  * @brief Write nonNegativeInteger to the specified stream
+ * @return length of written nonNegativeInteger
  */
-inline size_t
-writeNonNegativeInteger(std::ostream& os, uint64_t varNumber);
+size_t
+writeNonNegativeInteger(std::ostream& os, uint64_t integer);
 
 /////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////
@@ -241,7 +254,7 @@
 /////////////////////////////////////////////////////////////////////////////////
 
 template<class InputIterator>
-inline bool
+bool
 readVarNumber(InputIterator& begin, const InputIterator& end, uint64_t& number)
 {
   if (begin == end)
@@ -249,59 +262,54 @@
 
   uint8_t firstOctet = *begin;
   ++begin;
-  if (firstOctet < 253)
-    {
-      number = firstOctet;
-    }
-  else if (firstOctet == 253)
-    {
-      if (end - begin < 2)
-        return false;
+  if (firstOctet < 253) {
+    number = firstOctet;
+  }
+  else if (firstOctet == 253) {
+    if (end - begin < 2)
+      return false;
 
-      uint16_t value = *reinterpret_cast<const uint16_t*>(&*begin);
-      begin += 2;
-      number = be16toh(value);
-    }
-  else if (firstOctet == 254)
-    {
-      if (end - begin < 4)
-        return false;
+    uint16_t value = *reinterpret_cast<const uint16_t*>(&*begin);
+    begin += 2;
+    number = be16toh(value);
+  }
+  else if (firstOctet == 254) {
+    if (end - begin < 4)
+      return false;
 
-      uint32_t value = *reinterpret_cast<const uint32_t*>(&*begin);
-      begin += 4;
-      number = be32toh(value);
-    }
-  else // if (firstOctet == 255)
-    {
-      if (end - begin < 8)
-        return false;
+    uint32_t value = *reinterpret_cast<const uint32_t*>(&*begin);
+    begin += 4;
+    number = be32toh(value);
+  }
+  else { // if (firstOctet == 255)
+    if (end - begin < 8)
+      return false;
 
-      uint64_t value = *reinterpret_cast<const uint64_t*>(&*begin);
-      begin += 8;
+    uint64_t value = *reinterpret_cast<const uint64_t*>(&*begin);
+    begin += 8;
 
-      number = be64toh(value);
-    }
+    number = be64toh(value);
+  }
 
   return true;
 }
 
 template<class InputIterator>
-inline bool
+bool
 readType(InputIterator& begin, const InputIterator& end, uint32_t& type)
 {
   uint64_t number = 0;
   bool isOk = readVarNumber(begin, end, number);
-  if (!isOk || number > std::numeric_limits<uint32_t>::max())
-    {
-      return false;
-    }
+  if (!isOk || number > std::numeric_limits<uint32_t>::max()) {
+    return false;
+  }
 
   type = static_cast<uint32_t>(number);
   return true;
 }
 
 template<class InputIterator>
-inline uint64_t
+uint64_t
 readVarNumber(InputIterator& begin, const InputIterator& end)
 {
   if (begin == end)
@@ -326,81 +334,40 @@
 
   uint8_t firstOctet = *begin;
   ++begin;
-  if (firstOctet < 253)
-    {
-      value = firstOctet;
-    }
-  else if (firstOctet == 253)
-    {
-      value = 0;
-      size_t count = 0;
-      for (; begin != end && count < 2; ++count)
-        {
-          value = ((value << 8) | *begin);
-          begin++;
-        }
+  if (firstOctet < 253) {
+    value = firstOctet;
+    return true;
+  }
 
-      if (count != 2)
-        return false;
-    }
-  else if (firstOctet == 254)
-    {
-      value = 0;
-      size_t count = 0;
-      for (; begin != end && count < 4; ++count)
-        {
-          value = ((value << 8) | *begin);
-          begin++;
-        }
-
-      if (count != 4)
-        return false;
-    }
-  else // if (firstOctet == 255)
-    {
-      value = 0;
-      size_t count = 0;
-      for (; begin != end && count < 8; ++count)
-        {
-          value = ((value << 8) | *begin);
-          begin++;
-        }
-
-      if (count != 8)
-        return false;
-    }
-
-  return true;
+  size_t expectedSize = firstOctet == 253 ? 2 :
+                        firstOctet == 254 ? 4 : 8;
+  value = 0;
+  size_t count = 0;
+  for (; begin != end && count < expectedSize; ++count) {
+    value = (value << 8) | *begin;
+    ++begin;
+  }
+  return count == expectedSize;
 }
 
 template<class InputIterator>
-inline uint32_t
+uint32_t
 readType(InputIterator& begin, const InputIterator& end)
 {
   uint64_t type = readVarNumber(begin, end);
-  if (type > std::numeric_limits<uint32_t>::max())
-    {
-      BOOST_THROW_EXCEPTION(Error("TLV type code exceeds allowed maximum"));
-    }
+  if (type > std::numeric_limits<uint32_t>::max()) {
+    BOOST_THROW_EXCEPTION(Error("TLV-TYPE code exceeds allowed maximum"));
+  }
 
   return static_cast<uint32_t>(type);
 }
 
-size_t
+constexpr size_t
 sizeOfVarNumber(uint64_t varNumber)
 {
-  if (varNumber < 253) {
-    return 1;
-  }
-  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
-    return 3;
-  }
-  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
-    return 5;
-  }
-  else {
-    return 9;
-  }
+  return varNumber < 253 ? 1 :
+         varNumber <= std::numeric_limits<uint16_t>::max() ? 3 :
+         varNumber <= std::numeric_limits<uint32_t>::max() ? 5 : 9;
 }
 
 inline size_t
@@ -431,12 +398,11 @@
 }
 
 template<class InputIterator>
-inline uint64_t
+uint64_t
 readNonNegativeInteger(size_t size, InputIterator& begin, const InputIterator& end)
 {
   switch (size) {
-  case 1:
-    {
+    case 1: {
       if (end - begin < 1)
         BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV processing"));
 
@@ -444,8 +410,7 @@
       begin++;
       return value;
     }
-  case 2:
-    {
+    case 2: {
       if (end - begin < 2)
         BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV processing"));
 
@@ -453,8 +418,7 @@
       begin += 2;
       return be16toh(value);
     }
-  case 4:
-    {
+    case 4: {
       if (end - begin < 4)
         BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV processing"));
 
@@ -462,8 +426,7 @@
       begin += 4;
       return be32toh(value);
     }
-  case 8:
-    {
+    case 8: {
       if (end - begin < 8)
         BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV processing"));
 
@@ -472,111 +435,62 @@
       return be64toh(value);
     }
   }
-  BOOST_THROW_EXCEPTION(Error("Invalid length for nonNegativeInteger (only 1, 2, 4, and 8 are allowed)"));
+  BOOST_THROW_EXCEPTION(Error("Invalid length for nonNegativeInteger "
+                              "(only 1, 2, 4, and 8 are allowed)"));
 }
 
 template<>
 inline uint64_t
-readNonNegativeInteger<std::istream_iterator<uint8_t> >(size_t size,
-                                                        std::istream_iterator<uint8_t>& begin,
-                                                        const std::istream_iterator<uint8_t>& end)
+readNonNegativeInteger<std::istream_iterator<uint8_t>>(size_t size,
+                                                       std::istream_iterator<uint8_t>& begin,
+                                                       const std::istream_iterator<uint8_t>& end)
 {
-  switch (size) {
-  case 1:
-    {
-      if (begin == end)
-        BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV processing"));
-
-      uint64_t value = *begin;
-      begin++;
-      return value;
-    }
-  case 2:
-    {
-      uint64_t value = 0;
-      size_t count = 0;
-      for (; begin != end && count < 2; ++count)
-        {
-          value = ((value << 8) | *begin);
-          begin++;
-        }
-
-      if (count != 2)
-        BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV processing"));
-
-      return value;
-    }
-  case 4:
-    {
-      uint64_t value = 0;
-      size_t count = 0;
-      for (; begin != end && count < 4; ++count)
-        {
-          value = ((value << 8) | *begin);
-          begin++;
-        }
-
-      if (count != 4)
-        BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV processing"));
-
-      return value;
-    }
-  case 8:
-    {
-      uint64_t value = 0;
-      size_t count = 0;
-      for (; begin != end && count < 8; ++count)
-        {
-          value = ((value << 8) | *begin);
-          begin++;
-        }
-
-      if (count != 8)
-        BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV processing"));
-
-      return value;
-    }
+  if (size != 1 && size != 2 && size != 4 && size != 8) {
+    BOOST_THROW_EXCEPTION(Error("Invalid length for nonNegativeInteger "
+                                "(only 1, 2, 4, and 8 are allowed)"));
   }
-  BOOST_THROW_EXCEPTION(Error("Invalid length for nonNegativeInteger (only 1, 2, 4, and 8 are allowed)"));
+
+  uint64_t value = 0;
+  size_t count = 0;
+  for (; begin != end && count < size; ++count) {
+    value = (value << 8) | *begin;
+    begin++;
+  }
+
+  if (count != size) {
+    BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV processing"));
+  }
+
+  return value;
+}
+
+constexpr size_t
+sizeOfNonNegativeInteger(uint64_t integer)
+{
+  return integer <= std::numeric_limits<uint8_t>::max() ? 1 :
+         integer <= std::numeric_limits<uint16_t>::max() ? 2 :
+         integer <= std::numeric_limits<uint32_t>::max() ? 4 : 8;
 }
 
 inline size_t
-sizeOfNonNegativeInteger(uint64_t varNumber)
+writeNonNegativeInteger(std::ostream& os, uint64_t integer)
 {
-  if (varNumber < 253) {
+  if (integer <= std::numeric_limits<uint8_t>::max()) {
+    os.put(static_cast<char>(integer));
     return 1;
   }
-  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
-    return 2;
-  }
-  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
-    return 4;
-  }
-  else {
-    return 8;
-  }
-}
-
-
-inline size_t
-writeNonNegativeInteger(std::ostream& os, uint64_t varNumber)
-{
-  if (varNumber < 253) {
-    os.put(static_cast<char>(varNumber));
-    return 1;
-  }
-  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
-    uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
+  else if (integer <= std::numeric_limits<uint16_t>::max()) {
+    uint16_t value = htobe16(static_cast<uint16_t>(integer));
     os.write(reinterpret_cast<const char*>(&value), 2);
     return 2;
   }
-  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
-    uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
+  else if (integer <= std::numeric_limits<uint32_t>::max()) {
+    uint32_t value = htobe32(static_cast<uint32_t>(integer));
     os.write(reinterpret_cast<const char*>(&value), 4);
     return 4;
   }
   else {
-    uint64_t value = htobe64(varNumber);
+    uint64_t value = htobe64(integer);
     os.write(reinterpret_cast<const char*>(&value), 8);
     return 8;
   }
diff --git a/tests/unit-tests/encoding/tlv.t.cpp b/tests/unit-tests/encoding/tlv.t.cpp
index 6576e04..28f007b 100644
--- a/tests/unit-tests/encoding/tlv.t.cpp
+++ b/tests/unit-tests/encoding/tlv.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -278,17 +278,18 @@
 
 static const uint8_t BUFFER[] = {
   0x01, // 1
-  0x01, 0x01, // 257
-  0x01, 0x01, 0x01, 0x01, // 16843009LL
-  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 // 72340172838076673LL
+  0xff, // 255
+  0x01, 0x02, // 258
+  0x01, 0x01, 0x01, 0x02, // 16843010LL
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02 // 72340172838076674LL
 };
 
 BOOST_AUTO_TEST_CASE(SizeOf)
 {
   BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(1), 1);
-  BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(252), 1);
-  BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(253), 2);
-  BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(257), 2);
+  BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(253), 1);
+  BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(255), 1);
+  BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(256), 2);
   BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(65536), 4);
   BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(16843009LL), 4);
   BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(4294967296LL), 8);
@@ -300,103 +301,99 @@
   std::ostringstream os;
 
   writeNonNegativeInteger(os, 1);
-  writeNonNegativeInteger(os, 257);
-  writeNonNegativeInteger(os, 16843009LL);
-  writeNonNegativeInteger(os, 72340172838076673LL);
+  writeNonNegativeInteger(os, 255);
+  writeNonNegativeInteger(os, 258);
+  writeNonNegativeInteger(os, 16843010LL);
+  writeNonNegativeInteger(os, 72340172838076674LL);
 
   std::string buffer = os.str();
   const uint8_t* actual = reinterpret_cast<const uint8_t*>(buffer.c_str());
 
-  BOOST_CHECK_EQUAL(buffer.size(), sizeof(BUFFER));
   BOOST_CHECK_EQUAL_COLLECTIONS(BUFFER, BUFFER + sizeof(BUFFER),
                                 actual, actual + sizeof(BUFFER));
 }
 
 BOOST_AUTO_TEST_CASE(ReadFromBuffer)
 {
-  const uint8_t* begin;
-  uint64_t value;
+  const uint8_t* begin = nullptr;
 
   begin = BUFFER;
-  BOOST_CHECK_THROW(value = readNonNegativeInteger(1, begin, begin + 0), Error);
-  BOOST_CHECK_NO_THROW(value = readNonNegativeInteger(1, begin, begin + 1));
-  BOOST_CHECK_EQUAL(value, 1);
+  BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, begin + 1), 1);
+  BOOST_CHECK_EQUAL(begin, BUFFER + 1);
 
   begin = BUFFER + 1;
-  BOOST_CHECK_THROW(value = readNonNegativeInteger(2, begin, begin + 1), Error);
-  BOOST_CHECK_NO_THROW(value = readNonNegativeInteger(2, begin, begin + 2));
-  BOOST_CHECK_EQUAL(value, 257);
+  BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, begin + 1), 255);
+  BOOST_CHECK_EQUAL(begin, BUFFER + 2);
 
-  begin = BUFFER + 3;
-  BOOST_CHECK_THROW(value = readNonNegativeInteger(4, begin, begin + 3), Error);
-  BOOST_CHECK_NO_THROW(value = readNonNegativeInteger(4, begin, begin + 4));
-  BOOST_CHECK_EQUAL(value, 16843009LL);
+  begin = BUFFER + 2;
+  BOOST_CHECK_EQUAL(readNonNegativeInteger(2, begin, begin + 2), 258);
+  BOOST_CHECK_EQUAL(begin, BUFFER + 4);
 
-  begin = BUFFER + 7;
-  BOOST_CHECK_THROW(value = readNonNegativeInteger(8, begin, begin + 7), Error);
-  BOOST_CHECK_NO_THROW(value = readNonNegativeInteger(8, begin, begin + 8));
-  BOOST_CHECK_EQUAL(value, 72340172838076673LL);
+  begin = BUFFER + 4;
+  BOOST_CHECK_EQUAL(readNonNegativeInteger(4, begin, begin + 4), 16843010LL);
+  BOOST_CHECK_EQUAL(begin, BUFFER + 8);
 
+  begin = BUFFER + 8;
+  BOOST_CHECK_EQUAL(readNonNegativeInteger(8, begin, begin + 8), 72340172838076674LL);
+  BOOST_CHECK_EQUAL(begin, BUFFER + 16);
+
+  // invalid size
   begin = BUFFER;
-  BOOST_CHECK_THROW(value = readNonNegativeInteger(3, begin, begin + 3), Error);
+  BOOST_CHECK_THROW(readNonNegativeInteger(3, begin, begin + 3), Error);
+
+  // available buffer smaller than size
+  begin = BUFFER;
+  BOOST_CHECK_THROW(readNonNegativeInteger(1, begin, begin + 0), Error);
+  begin = BUFFER;
+  BOOST_CHECK_THROW(readNonNegativeInteger(2, begin, begin + 1), Error);
+  begin = BUFFER;
+  BOOST_CHECK_THROW(readNonNegativeInteger(4, begin, begin + 3), Error);
+  begin = BUFFER;
+  BOOST_CHECK_THROW(readNonNegativeInteger(8, begin, begin + 7), Error);
 }
 
 BOOST_AUTO_TEST_CASE(ReadFromStream)
 {
   Iterator end; // end of stream
-  uint64_t value;
+
+  {
+    ArrayStream stream(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
+    Iterator begin(stream);
+    BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, end), 1);
+    BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, end), 255);
+    BOOST_CHECK_EQUAL(readNonNegativeInteger(2, begin, end), 258);
+    BOOST_CHECK_EQUAL(readNonNegativeInteger(4, begin, end), 16843010LL);
+    BOOST_CHECK_EQUAL(readNonNegativeInteger(8, begin, end), 72340172838076674LL);
+    BOOST_CHECK(begin == end);
+  }
+
+  // invalid size
+  {
+    ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 3);
+    Iterator begin(stream);
+    BOOST_CHECK_THROW(readNonNegativeInteger(3, begin, end), Error);
+  }
+
+  // available buffer smaller than size
   {
     ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 0);
     Iterator begin(stream);
-    BOOST_CHECK_THROW(value = readNonNegativeInteger(1, begin, end), Error);
+    BOOST_CHECK_THROW(readNonNegativeInteger(1, begin, end), Error);
   }
   {
     ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 1);
     Iterator begin(stream);
-    BOOST_CHECK_NO_THROW(value = readNonNegativeInteger(1, begin, end));
-    BOOST_CHECK_EQUAL(value, 1);
+    BOOST_CHECK_THROW(readNonNegativeInteger(2, begin, end), Error);
   }
-
-  {
-    ArrayStream stream(reinterpret_cast<const char*>(BUFFER + 1), 1);
-    Iterator begin(stream);
-    BOOST_CHECK_THROW(value = readNonNegativeInteger(2, begin, end), Error);
-  }
-  {
-    ArrayStream stream(reinterpret_cast<const char*>(BUFFER + 1), 2);
-    Iterator begin(stream);
-    BOOST_CHECK_NO_THROW(value = readNonNegativeInteger(2, begin, end));
-    BOOST_CHECK_EQUAL(value, 257);
-  }
-
-  {
-    ArrayStream stream(reinterpret_cast<const char*>(BUFFER + 3), 3);
-    Iterator begin(stream);
-    BOOST_CHECK_THROW(value = readNonNegativeInteger(4, begin, end), Error);
-  }
-  {
-    ArrayStream stream(reinterpret_cast<const char*>(BUFFER + 3), 4);
-    Iterator begin(stream);
-    BOOST_CHECK_NO_THROW(value = readNonNegativeInteger(4, begin, end));
-    BOOST_CHECK_EQUAL(value, 16843009LL);
-  }
-
-  {
-    ArrayStream stream(reinterpret_cast<const char*>(BUFFER + 7), 7);
-    Iterator begin(stream);
-    BOOST_CHECK_THROW(value = readNonNegativeInteger(8, begin, end), Error);
-  }
-  {
-    ArrayStream stream(reinterpret_cast<const char*>(BUFFER + 7), 8);
-    Iterator begin(stream);
-    BOOST_CHECK_NO_THROW(value = readNonNegativeInteger(8, begin, end));
-    BOOST_CHECK_EQUAL(value, 72340172838076673LL);
-  }
-
   {
     ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 3);
     Iterator begin(stream);
-    BOOST_CHECK_THROW(value = readNonNegativeInteger(3, begin, end), Error);
+    BOOST_CHECK_THROW(readNonNegativeInteger(4, begin, end), Error);
+  }
+  {
+    ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 7);
+    Iterator begin(stream);
+    BOOST_CHECK_THROW(readNonNegativeInteger(8, begin, end), Error);
   }
 }
 
@@ -419,8 +416,7 @@
   BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(value), "Unknown Signature Type");
 }
 
-BOOST_AUTO_TEST_SUITE_END() // TestTlv
-
+BOOST_AUTO_TEST_SUITE_END() // PrintHelpers
 
 BOOST_AUTO_TEST_SUITE_END() // TestTlv
 BOOST_AUTO_TEST_SUITE_END() // Encoding