name: recognize ParametersSha256DigestComponent

refs #4658, #4570

Change-Id: I8001f6aa7a406e9e8eb10fc365bd84bc711cda07
diff --git a/src/detail/name-component-types.hpp b/src/detail/name-component-types.hpp
index 8d074fd..0f98920 100644
--- a/src/detail/name-component-types.hpp
+++ b/src/detail/name-component-types.hpp
@@ -180,15 +180,33 @@
   {
   }
 
+  bool
+  match(const Component& comp) const
+  {
+    return comp.type() == m_type && comp.value_size() == util::Sha256::DIGEST_SIZE;
+  }
+
   void
   check(const Component& comp) const final
   {
-    if (comp.value_size() != util::Sha256::DIGEST_SIZE) {
+    if (!match(comp)) {
       BOOST_THROW_EXCEPTION(Error(m_typeName + " TLV-LENGTH must be " +
                                   to_string(util::Sha256::DIGEST_SIZE)));
     }
   }
 
+  Component
+  create(ConstBufferPtr value) const
+  {
+    return Component(Block(m_type, std::move(value)));
+  }
+
+  Component
+  create(const uint8_t* value, size_t valueSize) const
+  {
+    return Component(makeBinaryBlock(m_type, value, valueSize));
+  }
+
   std::pair<bool, Component>
   getSuccessor(const Component& comp) const final
   {
@@ -204,7 +222,7 @@
   const std::vector<uint8_t>&
   getMinValue() const final
   {
-    static std::vector<uint8_t> value(16);
+    static std::vector<uint8_t> value(util::Sha256::DIGEST_SIZE);
     return value;
   }
 
@@ -240,6 +258,22 @@
   std::string m_uriPrefix;
 };
 
+inline const Sha256ComponentType&
+getComponentType1()
+{
+  static Sha256ComponentType ct1(tlv::ImplicitSha256DigestComponent,
+                                 "ImplicitSha256DigestComponent", "sha256digest");
+  return ct1;
+}
+
+inline const Sha256ComponentType&
+getComponentType2()
+{
+  static Sha256ComponentType ct2(tlv::ParametersSha256DigestComponent,
+                                 "ParametersSha256DigestComponent", "params-sha256");
+  return ct2;
+}
+
 /** \brief Rules regarding NameComponent types.
  */
 class ComponentTypeTable : noncopyable
@@ -286,6 +320,7 @@
   std::unordered_map<std::string, const ComponentType*> m_uriPrefixes;
 };
 
+inline
 ComponentTypeTable::ComponentTypeTable()
 {
   m_table.fill(nullptr);
@@ -293,14 +328,13 @@
   static GenericNameComponentType ct8;
   set(tlv::GenericNameComponent, ct8);
 
-  static Sha256ComponentType ct1(tlv::ImplicitSha256DigestComponent,
-                                 "ImplicitSha256DigestComponent", "sha256digest");
-  set(tlv::ImplicitSha256DigestComponent, ct1);
+  set(tlv::ImplicitSha256DigestComponent, getComponentType1());
+  set(tlv::ParametersSha256DigestComponent, getComponentType2());
 }
 
 /** \brief Get the global ComponentTypeTable.
  */
-const ComponentTypeTable&
+inline const ComponentTypeTable&
 getComponentTypeTable()
 {
   static ComponentTypeTable ctt;
diff --git a/src/encoding/tlv.hpp b/src/encoding/tlv.hpp
index d4abdc1..f7b7240 100644
--- a/src/encoding/tlv.hpp
+++ b/src/encoding/tlv.hpp
@@ -59,30 +59,31 @@
  *  @sa https://named-data.net/doc/NDN-packet-spec/current/types.html
  */
 enum {
-  Interest                      = 5,
-  Data                          = 6,
-  Name                          = 7,
-  GenericNameComponent          = 8,
-  ImplicitSha256DigestComponent = 1,
-  CanBePrefix                   = 33,
-  MustBeFresh                   = 18,
-  ForwardingHint                = 30,
-  Nonce                         = 10,
-  InterestLifetime              = 12,
-  HopLimit                      = 34,
-  Parameters                    = 35,
-  MetaInfo                      = 20,
-  Content                       = 21,
-  SignatureInfo                 = 22,
-  SignatureValue                = 23,
-  ContentType                   = 24,
-  FreshnessPeriod               = 25,
-  FinalBlockId                  = 26,
-  SignatureType                 = 27,
-  KeyLocator                    = 28,
-  KeyDigest                     = 29,
-  LinkDelegation                = 31,
-  LinkPreference                = 30,
+  Interest                        = 5,
+  Data                            = 6,
+  Name                            = 7,
+  GenericNameComponent            = 8,
+  ImplicitSha256DigestComponent   = 1,
+  ParametersSha256DigestComponent = 2,
+  CanBePrefix                     = 33,
+  MustBeFresh                     = 18,
+  ForwardingHint                  = 30,
+  Nonce                           = 10,
+  InterestLifetime                = 12,
+  HopLimit                        = 34,
+  Parameters                      = 35,
+  MetaInfo                        = 20,
+  Content                         = 21,
+  SignatureInfo                   = 22,
+  SignatureValue                  = 23,
+  ContentType                     = 24,
+  FreshnessPeriod                 = 25,
+  FinalBlockId                    = 26,
+  SignatureType                   = 27,
+  KeyLocator                      = 28,
+  KeyDigest                       = 29,
+  LinkDelegation                  = 31,
+  LinkPreference                  = 30,
 
   NameComponentMin = 1,
   NameComponentMax = 65535,
diff --git a/src/name-component.cpp b/src/name-component.cpp
index 6ac6f31..66cf247 100644
--- a/src/name-component.cpp
+++ b/src/name-component.cpp
@@ -307,28 +307,37 @@
 bool
 Component::isImplicitSha256Digest() const
 {
-  return type() == tlv::ImplicitSha256DigestComponent &&
-         value_size() == util::Sha256::DIGEST_SIZE;
+  return detail::getComponentType1().match(*this);
 }
 
 Component
 Component::fromImplicitSha256Digest(ConstBufferPtr digest)
 {
-  if (digest->size() != util::Sha256::DIGEST_SIZE)
-    BOOST_THROW_EXCEPTION(Error("Cannot create ImplicitSha256DigestComponent (input digest must be " +
-                                to_string(util::Sha256::DIGEST_SIZE) + " octets)"));
-
-  return Block(tlv::ImplicitSha256DigestComponent, std::move(digest));
+  return detail::getComponentType1().create(digest);
 }
 
 Component
 Component::fromImplicitSha256Digest(const uint8_t* digest, size_t digestSize)
 {
-  if (digestSize != util::Sha256::DIGEST_SIZE)
-    BOOST_THROW_EXCEPTION(Error("Cannot create ImplicitSha256DigestComponent (input digest must be " +
-                                to_string(util::Sha256::DIGEST_SIZE) + " octets)"));
+  return detail::getComponentType1().create(digest, digestSize);
+}
 
-  return makeBinaryBlock(tlv::ImplicitSha256DigestComponent, digest, digestSize);
+bool
+Component::isParametersSha256Digest() const
+{
+  return detail::getComponentType2().match(*this);
+}
+
+Component
+Component::fromParametersSha256Digest(ConstBufferPtr digest)
+{
+  return detail::getComponentType2().create(digest);
+}
+
+Component
+Component::fromParametersSha256Digest(const uint8_t* digest, size_t digestSize)
+{
+  return detail::getComponentType2().create(digest, digestSize);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/name-component.hpp b/src/name-component.hpp
index 9340176..908efe1 100644
--- a/src/name-component.hpp
+++ b/src/name-component.hpp
@@ -462,6 +462,24 @@
   static Component
   fromImplicitSha256Digest(const uint8_t* digest, size_t digestSize);
 
+  /**
+   * @brief Check if the component is ParametersSha256DigestComponent
+   */
+  bool
+  isParametersSha256Digest() const;
+
+  /**
+   * @brief Create ParametersSha256DigestComponent component
+   */
+  static Component
+  fromParametersSha256Digest(ConstBufferPtr digest);
+
+  /**
+   * @brief Create ParametersSha256DigestComponent component
+   */
+  static Component
+  fromParametersSha256Digest(const uint8_t* digest, size_t digestSize);
+
 public: // operators
   bool
   empty() const
@@ -578,7 +596,12 @@
    * - successor of `sha256digest=0000000000000000000000000000000000000000000000000000000000000000`
    *   is `sha256digest=0000000000000000000000000000000000000000000000000000000000000001`.
    * - successor of `sha256digest=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`
-   *   is `2=...`.
+   *   is `params-sha256=0000000000000000000000000000000000000000000000000000000000000000`.
+   * - successor of `params-sha256=0000000000000000000000000000000000000000000000000000000000000000`
+   *   is `params-sha256=0000000000000000000000000000000000000000000000000000000000000001`.
+   * - successor of `params-sha256=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`
+   *   is `3=...`.
+   * - successor of `...` is `%00`.
    * - successor of `A` is `B`.
    * - successor of `%FF` is `%00%00`.
    */