meta-info: allow typed name component in FinalBlockId

refs #4526

Change-Id: I3b6667928fa47c631e45ff5f0ca2c5030c5cc2ad
diff --git a/src/meta-info.cpp b/src/meta-info.cpp
index e19c11d..c6a43a4 100644
--- a/src/meta-info.cpp
+++ b/src/meta-info.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -63,13 +63,22 @@
 }
 
 MetaInfo&
-MetaInfo::setFinalBlockId(const name::Component& finalBlockId)
+MetaInfo::setFinalBlock(optional<name::Component> finalBlockId)
 {
   m_wire.reset();
-  m_finalBlockId = finalBlockId;
+  m_finalBlockId = std::move(finalBlockId);
   return *this;
 }
 
+MetaInfo&
+MetaInfo::setFinalBlockId(const name::Component& finalBlockId)
+{
+  if (finalBlockId.isGeneric() && finalBlockId.empty()) {
+    return setFinalBlock(nullopt);
+  }
+  return setFinalBlock(finalBlockId);
+}
+
 const std::list<Block>&
 MetaInfo::getAppMetaInfo() const
 {
@@ -146,8 +155,8 @@
   }
 
   // FinalBlockId
-  if (!m_finalBlockId.empty()) {
-    totalLength += prependNestedBlock(encoder, tlv::FinalBlockId, m_finalBlockId);
+  if (m_finalBlockId) {
+    totalLength += prependNestedBlock(encoder, tlv::FinalBlockId, *m_finalBlockId);
   }
 
   // FreshnessPeriod
@@ -218,16 +227,11 @@
 
   // FinalBlockId
   if (val != m_wire.elements_end() && val->type() == tlv::FinalBlockId) {
-    m_finalBlockId = val->blockFromValue();
-    if (m_finalBlockId.type() != tlv::NameComponent)
-      {
-        /// @todo May or may not throw exception later...
-        m_finalBlockId = name::Component();
-      }
+    m_finalBlockId.emplace(val->blockFromValue());
     ++val;
   }
   else {
-    m_finalBlockId = name::Component();
+    m_finalBlockId = nullopt;
   }
 
   // AppMetaInfo (if any)
@@ -248,9 +252,9 @@
   }
 
   // FinalBlockId
-  if (!info.getFinalBlockId().empty()) {
+  if (info.getFinalBlock()) {
     os << ", FinalBlockId: ";
-    info.getFinalBlockId().toUri(os);
+    info.getFinalBlock()->toUri(os);
   }
 
   // App-defined MetaInfo items