tools: Fixing bugs in nfd-status

Also in this commit: implementing const_reverse_iterator in FaceTable.
It also would be good to have reverse iterator in Fib, but not strictly
necessary.

Change-Id: Ie9cf849b718f5db76db2957b4452790f9ae68fd3
Refs: #1378
diff --git a/daemon/core/map-value-iterator.hpp b/daemon/core/map-value-iterator.hpp
index c8d3df7..6d80887 100644
--- a/daemon/core/map-value-iterator.hpp
+++ b/daemon/core/map-value-iterator.hpp
@@ -17,13 +17,15 @@
  */
 template<typename Map>
 class MapValueIterator
-  : public boost::transform_iterator<function<const typename Map::mapped_type&(const typename Map::value_type&)>,
-                                     typename Map::const_iterator>
+  : public boost::transform_iterator<
+             function<const typename Map::mapped_type&(const typename Map::value_type&)>,
+             typename Map::const_iterator>
 {
 public:
   explicit
   MapValueIterator(typename Map::const_iterator it)
-    : boost::transform_iterator<function<const typename Map::mapped_type&(const typename Map::value_type&)>,
+    : boost::transform_iterator<
+        function<const typename Map::mapped_type&(const typename Map::value_type&)>,
         typename Map::const_iterator>(it, &takeSecond)
   {
   }
@@ -36,6 +38,32 @@
   }
 };
 
+/** \class MapValueReverseIterator
+ *  \brief ReverseIterator to iterator over map values
+ */
+template<typename Map>
+class MapValueReverseIterator
+  : public boost::transform_iterator<
+             function<const typename Map::mapped_type&(const typename Map::value_type&)>,
+             typename Map::const_reverse_iterator>
+{
+public:
+  explicit
+  MapValueReverseIterator(typename Map::const_reverse_iterator it)
+    : boost::transform_iterator<
+             function<const typename Map::mapped_type&(const typename Map::value_type&)>,
+             typename Map::const_reverse_iterator>(it, &takeSecond)
+  {
+  }
+
+private:
+  static const typename Map::mapped_type&
+  takeSecond(const typename Map::value_type& pair)
+  {
+    return pair.second;
+  }
+};
+
 } // namespace nfd
 
 #endif // NFD_CORE_MAP_VALUE_ITERATOR_H
diff --git a/daemon/fw/face-table.hpp b/daemon/fw/face-table.hpp
index 868cf9e..b806cad 100644
--- a/daemon/fw/face-table.hpp
+++ b/daemon/fw/face-table.hpp
@@ -38,16 +38,26 @@
 public: // enumeration
   typedef std::map<FaceId, shared_ptr<Face> > FaceMap;
 
-  /** \brief ForwarderIterator for shared_ptr<Face>
+  /** \brief ForwardIterator for shared_ptr<Face>
    */
   typedef MapValueIterator<FaceMap> const_iterator;
 
+  /** \brief ReverseIterator for shared_ptr<Face>
+   */
+  typedef MapValueReverseIterator<FaceMap> const_reverse_iterator;
+
   const_iterator
   begin() const;
 
   const_iterator
   end() const;
 
+  const_reverse_iterator
+  rbegin() const;
+
+  const_reverse_iterator
+  rend() const;
+
 public: // events
   /** \brief fires after a Face is added
    */
@@ -96,6 +106,18 @@
   return const_iterator(m_faces.end());
 }
 
+inline FaceTable::const_reverse_iterator
+FaceTable::rbegin() const
+{
+  return const_reverse_iterator(m_faces.rbegin());
+}
+
+inline FaceTable::const_reverse_iterator
+FaceTable::rend() const
+{
+  return const_reverse_iterator(m_faces.rend());
+}
+
 } // namespace nfd
 
 #endif // NFD_FW_FACE_TABLE_HPP
diff --git a/daemon/mgmt/face-status-publisher.cpp b/daemon/mgmt/face-status-publisher.cpp
index 2cf2603..6bc8c72 100644
--- a/daemon/mgmt/face-status-publisher.cpp
+++ b/daemon/mgmt/face-status-publisher.cpp
@@ -30,8 +30,8 @@
 {
   size_t totalLength = 0;
 
-  for (FaceTable::const_iterator i = m_faceTable.begin();
-       i != m_faceTable.end();
+  for (FaceTable::const_reverse_iterator i = m_faceTable.rbegin();
+       i != m_faceTable.rend();
        ++i)
     {
       const shared_ptr<Face>& face = *i;
diff --git a/daemon/mgmt/fib-enumeration-publisher.cpp b/daemon/mgmt/fib-enumeration-publisher.cpp
index 89f0956..79532ba 100644
--- a/daemon/mgmt/fib-enumeration-publisher.cpp
+++ b/daemon/mgmt/fib-enumeration-publisher.cpp
@@ -31,8 +31,9 @@
 size_t
 FibEnumerationPublisher::generate(ndn::EncodingBuffer& outBuffer)
 {
-
   size_t totalLength = 0;
+
+  /// \todo Enable use of Fib::const_reverse_iterator (when it is available)
   for (Fib::const_iterator i = m_fib.begin(); i != m_fib.end(); ++i)
     {
       const fib::Entry& entry = *i;
diff --git a/tests/mgmt/face-manager.cpp b/tests/mgmt/face-manager.cpp
index 45a609f..d7eb176 100644
--- a/tests/mgmt/face-manager.cpp
+++ b/tests/mgmt/face-manager.cpp
@@ -1147,7 +1147,7 @@
       uint64_t filler = std::numeric_limits<uint64_t>::max() - 1;
       dummy->setCounters(filler, filler, filler, filler);
 
-      m_referenceFaces.push_front(dummy);
+      m_referenceFaces.push_back(dummy);
 
       add(dummy);
     }
@@ -1158,7 +1158,7 @@
       uint64_t filler = std::numeric_limits<uint32_t>::max() - 1;
       dummy->setCounters(filler, filler, filler, filler);
 
-      m_referenceFaces.push_front(dummy);
+      m_referenceFaces.push_back(dummy);
 
       add(dummy);
     }
diff --git a/tests/mgmt/face-status-publisher.cpp b/tests/mgmt/face-status-publisher.cpp
index eb9946c..0f758bc 100644
--- a/tests/mgmt/face-status-publisher.cpp
+++ b/tests/mgmt/face-status-publisher.cpp
@@ -11,9 +11,9 @@
 
 NFD_LOG_INIT("FaceStatusPublisherTest");
 
-BOOST_FIXTURE_TEST_SUITE(MgmtFaceManager, FaceStatusPublisherFixture)
+BOOST_FIXTURE_TEST_SUITE(MgmtFaceSatusPublisher, FaceStatusPublisherFixture)
 
-BOOST_AUTO_TEST_CASE(TestFaceStatusPublisher)
+BOOST_AUTO_TEST_CASE(EncodingDecoding)
 {
   Name commandName("/localhost/nfd/faces/list");
   shared_ptr<Interest> command(make_shared<Interest>(commandName));
@@ -28,7 +28,7 @@
       uint64_t filler = std::numeric_limits<uint64_t>::max() - 1;
       dummy->setCounters(filler, filler, filler, filler);
 
-      m_referenceFaces.push_front(dummy);
+      m_referenceFaces.push_back(dummy);
 
       add(dummy);
     }
@@ -39,7 +39,7 @@
       uint64_t filler = std::numeric_limits<uint32_t>::max() - 1;
       dummy->setCounters(filler, filler, filler, filler);
 
-      m_referenceFaces.push_front(dummy);
+      m_referenceFaces.push_back(dummy);
 
       add(dummy);
     }
diff --git a/tools/nfd-status.cpp b/tools/nfd-status.cpp
index 2c27c9a..ff6316f 100644
--- a/tools/nfd-status.cpp
+++ b/tools/nfd-status.cpp
@@ -18,12 +18,12 @@
 class NfdStatus
 {
 public:
+  explicit
   NfdStatus(char* toolName)
     : m_toolName(toolName)
     , m_needVersionRetrieval(false)
     , m_needFaceStatusRetrieval(false)
     , m_needFibEnumerationRetrieval(false)
-    , m_face()
   {
   }
 
@@ -139,34 +139,33 @@
   void
   afterFetchedFaceStatusInformation()
   {
-    try
+    std::cout << "Faces:" << std::endl;
+
+    ConstBufferPtr buf = m_buffer->buf();
+
+    Block block;
+    size_t offset = 0;
+    while (offset < buf->size())
       {
-        std::cout << "Faces:" << std::endl;
-
-        ConstBufferPtr buf = m_buffer->buf();
-
-        size_t offset = 0;
-        while (offset < buf->size())
+        bool ok = Block::fromBuffer(buf, offset, block);
+        if (!ok)
           {
-            Block block(buf, buf->begin() + offset, buf->end(), false);
-            offset += block.size();
-
-            nfd::FaceStatus faceStatus(block);
-
-            std::cout << "  faceid=" << faceStatus.getFaceId()
-                      << " uri=" << faceStatus.getUri()
-                      << " counters={"
-                      << "in={" << faceStatus.getInInterest() << "i "
-                                << faceStatus.getInData() << "d}"
-                      << " out={" << faceStatus.getOutInterest() << "i "
-                                 << faceStatus.getOutData() << "d}"
-                      << "}" << std::endl;
+            std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
+            break;
           }
 
-      }
-    catch(Tlv::Error& e)
-      {
-        std::cerr << e.what() << std::endl;
+        offset += block.size();
+
+        nfd::FaceStatus faceStatus(block);
+
+        std::cout << "  faceid=" << faceStatus.getFaceId()
+                  << " uri=" << faceStatus.getUri()
+                  << " counters={"
+                  << "in={" << faceStatus.getInInterest() << "i "
+                  << faceStatus.getInData() << "d}"
+                  << " out={" << faceStatus.getOutInterest() << "i "
+                  << faceStatus.getOutData() << "d}"
+                  << "}" << std::endl;
       }
 
     if (m_needFibEnumerationRetrieval)
@@ -193,37 +192,36 @@
   void
   afterFetchedFibEnumerationInformation()
   {
-    try
+    std::cout << "FIB:" << std::endl;
+
+    ConstBufferPtr buf = m_buffer->buf();
+
+    Block block;
+    size_t offset = 0;
+    while (offset < buf->size())
       {
-        std::cout << "FIB:" << std::endl;
-
-        ConstBufferPtr buf = m_buffer->buf();
-
-        size_t offset = 0;
-        while (offset < buf->size())
+        bool ok = Block::fromBuffer(buf, offset, block);
+        if (!ok)
           {
-            Block block(buf, buf->begin() + offset, buf->end(), false);
-            offset += block.size();
-
-            nfd::FibEntry fibEntry(block);
-
-            std::cout << "  " << fibEntry.getPrefix() << " nexthops={";
-            for (std::list<nfd::NextHopRecord>::const_iterator
-                   nextHop = fibEntry.getNextHopRecords().begin();
-                 nextHop != fibEntry.getNextHopRecords().end();
-                 ++nextHop)
-              {
-                if (nextHop != fibEntry.getNextHopRecords().begin())
-                  std::cout << ", ";
-                std::cout << "faceid=" << nextHop->getFaceId()
-                          << " (cost=" << nextHop->getCost() << ")";
-              }
-            std::cout << "}" << std::endl;
+            std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
+            break;
           }
-      }
-    catch(Tlv::Error& e)
-      {
-        std::cerr << e.what() << std::endl;
+        offset += block.size();
+
+        nfd::FibEntry fibEntry(block);
+
+        std::cout << "  " << fibEntry.getPrefix() << " nexthops={";
+        for (std::list<nfd::NextHopRecord>::const_iterator
+               nextHop = fibEntry.getNextHopRecords().begin();
+             nextHop != fibEntry.getNextHopRecords().end();
+             ++nextHop)
+          {
+            if (nextHop != fibEntry.getNextHopRecords().begin())
+              std::cout << ", ";
+            std::cout << "faceid=" << nextHop->getFaceId()
+                      << " (cost=" << nextHop->getCost() << ")";
+          }
+        std::cout << "}" << std::endl;
       }
   }
 
@@ -300,17 +298,16 @@
     case 'b':
       nfdStatus.enableFibEnumerationRetrieval();
       break;
-    default :
+    default:
       nfdStatus.usage();
       return 1;
-      break;
     }
   }
 
   try {
     nfdStatus.fetchInformation();
   }
-  catch(std::exception& e) {
+  catch (std::exception& e) {
     std::cerr << "ERROR: " << e.what() << std::endl;
     return 2;
   }