/* */ #include "MessageDigestImpl.h" #include namespace aria2 { namespace { template class MessageDigestBase : public MessageDigestImpl { private: struct Deleter { void operator()(gcry_md_hd_t ctx) { if (ctx) { gcry_md_close(ctx); } } }; public: MessageDigestBase() { gcry_md_hd_t ctx = nullptr; gcry_md_open(&ctx, hash, 0); ctx_.reset(ctx); reset(); } virtual ~MessageDigestBase() {} static size_t length() { return ::gcry_md_get_algo_dlen(hash); } virtual size_t getDigestLength() const CXX11_OVERRIDE { return ::gcry_md_get_algo_dlen(hash); } virtual void reset() CXX11_OVERRIDE { ::gcry_md_reset(ctx_.get()); } virtual void update(const void* data, size_t length) CXX11_OVERRIDE { auto bytes = reinterpret_cast(data); while (length) { size_t l = std::min(length, (size_t)std::numeric_limits::max()); gcry_md_write(ctx_.get(), bytes, length); length -= l; bytes += l; } } virtual void digest(unsigned char* md) CXX11_OVERRIDE { ::memcpy(md, gcry_md_read(ctx_.get(), 0), getDigestLength()); } private: std::unique_ptr::type, Deleter> ctx_; }; typedef MessageDigestBase MessageDigestMD5; typedef MessageDigestBase MessageDigestSHA1; typedef MessageDigestBase MessageDigestSHA224; typedef MessageDigestBase MessageDigestSHA256; typedef MessageDigestBase MessageDigestSHA384; typedef MessageDigestBase MessageDigestSHA512; } // namespace std::unique_ptr MessageDigestImpl::sha1() { return std::unique_ptr(new MessageDigestSHA1()); } MessageDigestImpl::hashes_t MessageDigestImpl::hashes = { { "sha-1", make_hi() }, { "sha-224", make_hi() }, { "sha-256", make_hi() }, { "sha-384", make_hi() }, { "sha-512", make_hi() }, { "md5", make_hi() }, }; } // namespace aria2