/* */ #include "MessageDigestHelper.h" #include #include #include "MessageDigest.h" #include "DlAbortEx.h" #include "message.h" #include "DefaultDiskWriter.h" #include "util.h" #include "fmt.h" namespace aria2 { SharedHandle MessageDigestHelper::sha1Ctx_; void MessageDigestHelper::staticSHA1DigestInit() { staticSHA1DigestFree(); sha1Ctx_ = MessageDigest::sha1(); } void MessageDigestHelper::staticSHA1DigestFree() { sha1Ctx_.reset(); } std::string MessageDigestHelper::staticSHA1DigestHexDigest (const BinaryStreamHandle& bs, off_t offset, uint64_t length) { sha1Ctx_->reset(); return hexDigest(sha1Ctx_, bs, offset, length); } std::string MessageDigestHelper::hexDigest (const SharedHandle& ctx, const SharedHandle& bs, off_t offset, uint64_t length) { size_t BUFSIZE = 4096; unsigned char BUF[BUFSIZE]; lldiv_t res = lldiv(length, BUFSIZE); uint64_t iteration = res.quot; size_t tail = res.rem; for(uint64_t i = 0; i < iteration; ++i) { ssize_t readLength = bs->readData(BUF, BUFSIZE, offset); if((size_t)readLength != BUFSIZE) { throw DL_ABORT_EX(fmt(EX_FILE_READ, "n/a", "data is too short")); } ctx->update(BUF, readLength); offset += readLength; } if(tail) { ssize_t readLength = bs->readData(BUF, tail, offset); if((size_t)readLength != tail) { throw DL_ABORT_EX(fmt(EX_FILE_READ, "n/a", "data is too short")); } ctx->update(BUF, readLength); } return ctx->hexDigest(); } void MessageDigestHelper::digest (unsigned char* md, size_t mdLength, const SharedHandle& ctx, const void* data, size_t length) { size_t reqLength = ctx->getDigestLength(); if(mdLength < reqLength) { throw DL_ABORT_EX (fmt("Insufficient space for storing message digest:" " %lu required, but only %lu is allocated", static_cast(reqLength), static_cast(mdLength))); } ctx->update(data, length); ctx->digest(md); } } // namespace aria2