blob: 67fd7085fc6c5512986d3777d807620f7416553f [file] [log] [blame]
Yingdi Yude222c72014-08-15 16:06:52 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev73e30042015-09-17 17:09:51 -07003 * Copyright (c) 2013-2015 Regents of the University of California.
Yingdi Yude222c72014-08-15 16:06:52 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "digest.hpp"
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070023#include "string-helper.hpp"
Alexander Afanasyev6800e1f2014-09-30 13:20:12 -070024#include <sstream>
Yingdi Yude222c72014-08-15 16:06:52 -070025
26namespace ndn {
27namespace util {
28
29template<typename Hash>
30Digest<Hash>::Digest()
31{
32 reset();
33}
34
35template<typename Hash>
Alexander Afanasyevd27334f2015-07-01 21:44:36 -070036Digest<Hash>::Digest(std::istream& is)
37 : m_isInProcess(false)
38 , m_isFinalized(true)
39{
40 using namespace CryptoPP;
41
42 m_buffer = make_shared<Buffer>(m_hash.DigestSize());
43 FileSource(is, true,
44 new HashFilter(m_hash,
45 new ArraySink(m_buffer->get(), m_buffer->size())));
46}
47
48template<typename Hash>
Yingdi Yude222c72014-08-15 16:06:52 -070049void
50Digest<Hash>::reset()
51{
52 m_hash.Restart();
53 m_buffer = make_shared<Buffer>(m_hash.DigestSize());
54 m_isInProcess = false;
55 m_isFinalized = false;
56}
57
58template<typename Hash>
59void
60Digest<Hash>::finalize()
61{
62 // return immediately if Digest is finalized already.
63 if (m_isFinalized)
64 return;
65
66 m_hash.Final(m_buffer->get());
67
68 m_isFinalized = true;
69}
70
71template<typename Hash>
72ConstBufferPtr
73Digest<Hash>::computeDigest()
74{
75 finalize();
76 return m_buffer;
77}
78
79template<typename Hash>
80bool
81Digest<Hash>::operator==(Digest<Hash>& digest)
82{
83 return *computeDigest() == *digest.computeDigest();
84}
85
86template<typename Hash>
87Digest<Hash>&
88Digest<Hash>::operator<<(Digest<Hash>& src)
89{
90 ConstBufferPtr buffer = src.computeDigest();
91 update(buffer->get(), buffer->size());
92
93 return *this;
94}
95
96template<typename Hash>
97Digest<Hash>&
98Digest<Hash>::operator<<(const std::string& str)
99{
100 update(reinterpret_cast<const uint8_t*>(str.c_str()), str.size());
101
102 return *this;
103}
104
105template<typename Hash>
106Digest<Hash>&
107Digest<Hash>::operator<<(const Block& block)
108{
109 update(block.wire(), block.size());
110
111 return *this;
112}
113
114template<typename Hash>
115Digest<Hash>&
116Digest<Hash>::operator<<(uint64_t value)
117{
118 update(reinterpret_cast<const uint8_t*>(&value), sizeof(uint64_t));
119
120 return *this;
121}
122
123template<typename Hash>
124void
125Digest<Hash>::update(const uint8_t* buffer, size_t size)
126{
127 // cannot update Digest when it has been finalized
128 if (m_isFinalized)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700129 BOOST_THROW_EXCEPTION(Error("Digest has been already finalized"));
Yingdi Yude222c72014-08-15 16:06:52 -0700130
131 m_hash.Update(buffer, size);
132
133 m_isInProcess = true;
134}
135
136template<typename Hash>
137ConstBufferPtr
138Digest<Hash>::computeDigest(const uint8_t* buffer, size_t size)
139{
140 Hash hash;
141 BufferPtr result = make_shared<Buffer>(hash.DigestSize());
142 hash.Update(buffer, size);
143 hash.Final(result->get());
144
145 return result;
146}
147
Yingdi Yu9ad2d722014-08-30 16:13:57 -0700148template<typename Hash>
149std::string
150Digest<Hash>::toString()
151{
152 std::ostringstream os;
153 os << *this;
154
155 return os.str();
156}
157
158template<typename Hash>
159std::ostream&
160operator<<(std::ostream& os, Digest<Hash>& digest)
161{
Yingdi Yu9ad2d722014-08-30 16:13:57 -0700162 ConstBufferPtr buffer = digest.computeDigest();
Alexander Afanasyev8828ca62015-07-02 13:40:09 -0700163 printHex(os, buffer->buf(), buffer->size());
Yingdi Yu9ad2d722014-08-30 16:13:57 -0700164
165 return os;
166}
167
168template
169class Digest<CryptoPP::SHA256>;
170
171template
172std::ostream&
173operator<<(std::ostream& os, Digest<CryptoPP::SHA256>& digest);
174
Yingdi Yude222c72014-08-15 16:06:52 -0700175
176} // namespace util
177} // namespace ndn