/* */ #include "IteratableChecksumValidator.h" #include #include #include "util.h" #include "message.h" #include "PieceStorage.h" #include "MessageDigest.h" #include "DiskAdaptor.h" #include "FileEntry.h" #include "BitfieldMan.h" #include "DownloadContext.h" #include "LogFactory.h" #include "fmt.h" namespace aria2 { IteratableChecksumValidator::IteratableChecksumValidator( const std::shared_ptr& dctx, const std::shared_ptr& pieceStorage) : dctx_(dctx), pieceStorage_(pieceStorage), currentOffset_(0) { } IteratableChecksumValidator::~IteratableChecksumValidator() = default; void IteratableChecksumValidator::validateChunk() { // Don't guard with !finished() to allow zero-length file to be // verified. std::array buf; size_t length = pieceStorage_->getDiskAdaptor()->readDataDropCache( buf.data(), buf.size(), currentOffset_); ctx_->update(buf.data(), length); currentOffset_ += length; if (finished()) { std::string actualDigest = ctx_->digest(); if (dctx_->getDigest() == actualDigest) { pieceStorage_->markAllPiecesDone(); dctx_->setChecksumVerified(true); } else { A2_LOG_INFO(fmt("Checksum validation failed. expected=%s, actual=%s", util::toHex(dctx_->getDigest()).c_str(), util::toHex(actualDigest).c_str())); BitfieldMan bitfield(dctx_->getPieceLength(), dctx_->getTotalLength()); pieceStorage_->setBitfield(bitfield.getBitfield(), bitfield.getBitfieldLength()); } } } bool IteratableChecksumValidator::finished() const { if (currentOffset_ >= dctx_->getTotalLength()) { return true; } else { return false; } } int64_t IteratableChecksumValidator::getTotalLength() const { return dctx_->getTotalLength(); } void IteratableChecksumValidator::init() { currentOffset_ = 0; ctx_ = MessageDigest::create(dctx_->getHashType()); } } // namespace aria2