encoding: provide _block literal operator

_block literal operator is moved from tests and becomes public API.

refs #4722

Change-Id: I07cc040af3c4288104b66f11d91830dc9f28835a
diff --git a/src/encoding/block.cpp b/src/encoding/block.cpp
index fc9a0dc..31e6d22 100644
--- a/src/encoding/block.cpp
+++ b/src/encoding/block.cpp
@@ -25,6 +25,7 @@
 #include "buffer-stream.hpp"
 #include "encoding-buffer.hpp"
 #include "tlv.hpp"
+#include "../security/transform.hpp"
 #include "../util/string-helper.hpp"
 
 #include <boost/asio/buffer.hpp>
@@ -517,4 +518,28 @@
   return os;
 }
 
+Block
+operator "" _block(const char* input, std::size_t len)
+{
+  namespace t = security::transform;
+  t::StepSource ss;
+  OBufferStream os;
+  ss >> t::hexDecode() >> t::streamSink(os);
+
+  for (const char* end = input + len; input != end; ++input) {
+    if (std::strchr("0123456789ABCDEF", *input) != nullptr) {
+      ss.write(reinterpret_cast<const uint8_t*>(input), 1);
+    }
+  }
+
+  try {
+    ss.end();
+  }
+  catch (const t::Error&) {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("input has odd number of hexadecimal digits"));
+  }
+
+  return Block(os.buf());
+}
+
 } // namespace ndn
diff --git a/src/encoding/block.hpp b/src/encoding/block.hpp
index e25da9e..4bbb162 100644
--- a/src/encoding/block.hpp
+++ b/src/encoding/block.hpp
@@ -470,6 +470,22 @@
   return !(lhs == rhs);
 }
 
+/** \brief Construct a \c Block from hexadecimal \p input.
+ *  \param input a string containing hexadecimal bytes and comments.
+ *               0-9 and upper-case A-F are input; all other characters are comments.
+ *  \param len length of \p input.
+ *  \throw std::invalid_argument input is empty or has odd number of hexadecimal digits.
+ *  \throw tlv::Error input cannot be parsed into valid \c Block.
+ *
+ *  Example
+ *  \code
+ *  Block nameBlock = "0706 080141 080142"_block;
+ *  Block nackBlock = "FD032005 reason(no-route)=FD03210196"_block;
+ *  \endcode
+ */
+Block
+operator "" _block(const char* input, std::size_t len);
+
 } // namespace ndn
 
 #endif // NDN_ENCODING_BLOCK_HPP
diff --git a/tests/block-literal.hpp b/tests/block-literal.hpp
deleted file mode 100644
index 9d7b13e..0000000
--- a/tests/block-literal.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2018 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#ifndef NDN_TESTS_BLOCK_LITERAL_HPP
-#define NDN_TESTS_BLOCK_LITERAL_HPP
-
-#include "encoding/block.hpp"
-#include "encoding/buffer-stream.hpp"
-#include "security/transform.hpp"
-
-namespace ndn {
-namespace tests {
-
-/** \brief Construct a \c Block from hexadecimal \p input.
- *  \param input a string containing hexadecimal bytes and comments.
- *               0-9 and upper-case A-F are input; all other characters are comments.
- *  \param len length of \p input.
- *  \throw security::transform::Error input has odd number of hexadecimal digits.
- *  \throw tlv::Error input cannot be parsed into valid \c Block.
- *
- *  Example
- *  \code
- *  Block nameBlock = "0706 080141 080142"_block;
- *  Block nackBlock = "FD032005 reason(no-route)=FD03210196"_block;
- *  \endcode
- */
-inline Block
-operator "" _block(const char* input, std::size_t len)
-{
-  namespace t = ndn::security::transform;
-  t::StepSource ss;
-  OBufferStream os;
-  ss >> t::hexDecode() >> t::streamSink(os);
-
-  for (const char* end = input + len; input != end; ++input) {
-    if (std::strchr("0123456789ABCDEF", *input) != nullptr) {
-      ss.write(reinterpret_cast<const uint8_t*>(input), 1);
-    }
-  }
-  ss.end();
-
-  return Block(os.buf());
-}
-
-} // namespace tests
-} // namespace ndn
-
-#endif // NDN_TESTS_BLOCK_LITERAL_HPP
diff --git a/tests/unit-tests/data.t.cpp b/tests/unit-tests/data.t.cpp
index b7d49c3..521b7d9 100644
--- a/tests/unit-tests/data.t.cpp
+++ b/tests/unit-tests/data.t.cpp
@@ -30,7 +30,6 @@
 #include "security/verification-helpers.hpp"
 #include "util/sha256.hpp"
 
-#include "block-literal.hpp"
 #include "boost-test.hpp"
 #include "identity-management-fixture.hpp"
 #include <boost/lexical_cast.hpp>
diff --git a/tests/unit-tests/encoding/block.t.cpp b/tests/unit-tests/encoding/block.t.cpp
index 70174aa..a3459e7 100644
--- a/tests/unit-tests/encoding/block.t.cpp
+++ b/tests/unit-tests/encoding/block.t.cpp
@@ -22,7 +22,6 @@
 #include "encoding/block.hpp"
 #include "encoding/block-helpers.hpp"
 
-#include "block-literal.hpp"
 #include "boost-test.hpp"
 #include <boost/lexical_cast.hpp>
 #include <cstring>
@@ -530,6 +529,41 @@
                     "264[8]={89[2]=4E42,16[2]=2386}");
 }
 
+BOOST_AUTO_TEST_SUITE(BlockLiteral)
+
+BOOST_AUTO_TEST_CASE(Simple)
+{
+  Block b0 = "0000"_block;
+  BOOST_CHECK_EQUAL(b0.type(), 0x00);
+  BOOST_CHECK_EQUAL(b0.value_size(), 0);
+
+  Block b1 = "0101A0"_block;
+  BOOST_CHECK_EQUAL(b1.type(), 0x01);
+  BOOST_REQUIRE_EQUAL(b1.value_size(), 1);
+  BOOST_CHECK_EQUAL(b1.value()[0], 0xA0);
+}
+
+BOOST_AUTO_TEST_CASE(Comment)
+{
+  Block b0 = "a2b0c0d2eBf0G.B 1+"_block;
+  BOOST_CHECK_EQUAL(b0.type(), 0x20);
+  BOOST_REQUIRE_EQUAL(b0.value_size(), 2);
+  BOOST_CHECK_EQUAL(b0.value()[0], 0xB0);
+  BOOST_CHECK_EQUAL(b0.value()[1], 0xB1);
+}
+
+BOOST_AUTO_TEST_CASE(BadInput)
+{
+  BOOST_CHECK_THROW(""_block, std::invalid_argument);
+  BOOST_CHECK_THROW("1"_block, std::invalid_argument);
+  BOOST_CHECK_THROW("333"_block, std::invalid_argument);
+
+  BOOST_CHECK_THROW("0202C0"_block, tlv::Error);
+  BOOST_CHECK_THROW("0201C0C1"_block, tlv::Error);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // BlockLiteral
+
 BOOST_AUTO_TEST_SUITE_END() // TestBlock
 BOOST_AUTO_TEST_SUITE_END() // Encoding
 
diff --git a/tests/unit-tests/interest.t.cpp b/tests/unit-tests/interest.t.cpp
index 52ec461..0f39c16 100644
--- a/tests/unit-tests/interest.t.cpp
+++ b/tests/unit-tests/interest.t.cpp
@@ -24,7 +24,6 @@
 #include "security/digest-sha256.hpp"
 #include "security/signature-sha256-with-rsa.hpp"
 
-#include "block-literal.hpp"
 #include "boost-test.hpp"
 #include "identity-management-fixture.hpp"
 
diff --git a/tests/unit-tests/meta-info.t.cpp b/tests/unit-tests/meta-info.t.cpp
index aee3b69..57371c3 100644
--- a/tests/unit-tests/meta-info.t.cpp
+++ b/tests/unit-tests/meta-info.t.cpp
@@ -22,7 +22,6 @@
 #include "meta-info.hpp"
 #include "data.hpp"
 
-#include "block-literal.hpp"
 #include "boost-test.hpp"
 
 namespace ndn {
diff --git a/tests/unit-tests/name-component.t.cpp b/tests/unit-tests/name-component.t.cpp
index ddd7629..031ccb8 100644
--- a/tests/unit-tests/name-component.t.cpp
+++ b/tests/unit-tests/name-component.t.cpp
@@ -23,7 +23,6 @@
 #include "name.hpp"
 #include "util/string-helper.hpp"
 
-#include "block-literal.hpp"
 #include "boost-test.hpp"
 #include <boost/algorithm/string/case_conv.hpp>
 #include <boost/mpl/vector.hpp>
@@ -32,8 +31,6 @@
 namespace name {
 namespace tests {
 
-using namespace ndn::tests;
-
 BOOST_AUTO_TEST_SUITE(TestNameComponent)
 
 BOOST_AUTO_TEST_SUITE(Decode)
diff --git a/tests/unit-tests/name.t.cpp b/tests/unit-tests/name.t.cpp
index 061fd56..1e0aa1d 100644
--- a/tests/unit-tests/name.t.cpp
+++ b/tests/unit-tests/name.t.cpp
@@ -21,7 +21,6 @@
 
 #include "name.hpp"
 
-#include "block-literal.hpp"
 #include "boost-test.hpp"
 #include <unordered_map>