util: Add constructor of Digest object from std::istream&

Change-Id: Ie3fa6511da751fe3b7b39d7a18b4909a28376d02
Refs: #3022
diff --git a/src/util/digest.cpp b/src/util/digest.cpp
index 156d372..664df2b 100644
--- a/src/util/digest.cpp
+++ b/src/util/digest.cpp
@@ -32,6 +32,19 @@
 }
 
 template<typename Hash>
+Digest<Hash>::Digest(std::istream& is)
+  : m_isInProcess(false)
+  , m_isFinalized(true)
+{
+  using namespace CryptoPP;
+
+  m_buffer = make_shared<Buffer>(m_hash.DigestSize());
+  FileSource(is, true,
+             new HashFilter(m_hash,
+                            new ArraySink(m_buffer->get(), m_buffer->size())));
+}
+
+template<typename Hash>
 void
 Digest<Hash>::reset()
 {
diff --git a/src/util/digest.hpp b/src/util/digest.hpp
index b0189a4..0fdb3a3 100644
--- a/src/util/digest.hpp
+++ b/src/util/digest.hpp
@@ -64,6 +64,13 @@
   Digest();
 
   /**
+   * @brief Create digest of the input stream @p
+   * @param is input stream
+   */
+  explicit
+  Digest(std::istream& is);
+
+  /**
    * @brief Discard the current state and start a new digest.
    */
   void
diff --git a/tests/unit-tests/util/digest.t.cpp b/tests/unit-tests/util/digest.t.cpp
index 252a0e7..531868f 100644
--- a/tests/unit-tests/util/digest.t.cpp
+++ b/tests/unit-tests/util/digest.t.cpp
@@ -48,6 +48,39 @@
                                 digest2->buf() + digest2->size());
 }
 
+BOOST_AUTO_TEST_CASE(Compute)
+{
+  std::string input = "Hello, World!";
+  ConstBufferPtr digest1 = crypto::sha256(reinterpret_cast<const uint8_t*>(input.data()),
+                                          input.size());
+
+  Sha256 hashObject;
+  hashObject << input;
+  BOOST_CHECK_EQUAL(hashObject.toString(), "DFFD6021BB2BD5B0AF676290809EC3A53191DD81C7F70A4B28688A362182986F");
+  ConstBufferPtr digest2 = hashObject.computeDigest();
+  BOOST_CHECK_EQUAL_COLLECTIONS(digest1->buf(),
+                                digest1->buf() + digest1->size(),
+                                digest2->buf(),
+                                digest2->buf() + digest2->size());
+
+}
+
+BOOST_AUTO_TEST_CASE(ConstructFromStream)
+{
+  std::string input = "Hello, World!";
+  ConstBufferPtr digest1 = crypto::sha256(reinterpret_cast<const uint8_t*>(input.data()),
+                                          input.size());
+
+  std::istringstream is(input);
+  Sha256 hashObject(is);
+  BOOST_CHECK_EQUAL(hashObject.toString(), "DFFD6021BB2BD5B0AF676290809EC3A53191DD81C7F70A4B28688A362182986F");
+  ConstBufferPtr digest2 = hashObject.computeDigest();
+  BOOST_CHECK_EQUAL_COLLECTIONS(digest1->buf(),
+                                digest1->buf() + digest1->size(),
+                                digest2->buf(),
+                                digest2->buf() + digest2->size());
+}
+
 BOOST_AUTO_TEST_CASE(Compare)
 {
   uint8_t origin[4] = {0x01, 0x02, 0x03, 0x04};