/* */ #include "IteratableChecksumValidator.h" #include #include "Util.h" #include "message.h" #include "PieceStorage.h" #include "messageDigest.h" #include "LogFactory.h" #include "Logger.h" #include "DiskAdaptor.h" #include "FileEntry.h" #include "BitfieldMan.h" #include "DownloadContext.h" namespace aria2 { #define BUFSIZE (256*1024) #define ALIGNMENT 512 IteratableChecksumValidator::IteratableChecksumValidator (const SharedHandle& dctx, const PieceStorageHandle& pieceStorage): _dctx(dctx), _pieceStorage(pieceStorage), _currentOffset(0), _logger(LogFactory::getInstance()), _buffer(0) {} IteratableChecksumValidator::~IteratableChecksumValidator() { #ifdef HAVE_POSIX_MEMALIGN free(_buffer); #else // !HAVE_POSIX_MEMALIGN delete [] _buffer; #endif // !HAVE_POSIX_MEMALIGN } void IteratableChecksumValidator::validateChunk() { if(!finished()) { size_t length = _pieceStorage->getDiskAdaptor()->readData(_buffer, BUFSIZE, _currentOffset); _ctx->digestUpdate(_buffer, length); _currentOffset += length; if(finished()) { std::string actualChecksum = util::toHex((const unsigned char*)_ctx->digestFinal().c_str(), _ctx->digestLength()); if(_dctx->getChecksum() == actualChecksum) { _pieceStorage->markAllPiecesDone(); } else { BitfieldMan bitfield(_dctx->getPieceLength(), _dctx->getTotalLength()); _pieceStorage->setBitfield(bitfield.getBitfield(), bitfield.getBitfieldLength()); } } } } bool IteratableChecksumValidator::finished() const { if((uint64_t)_currentOffset >= _dctx->getTotalLength()) { _pieceStorage->getDiskAdaptor()->disableDirectIO(); return true; } else { return false; } } uint64_t IteratableChecksumValidator::getTotalLength() const { return _dctx->getTotalLength(); } void IteratableChecksumValidator::init() { #ifdef HAVE_POSIX_MEMALIGN free(_buffer); _buffer = (unsigned char*)util::allocateAlignedMemory(ALIGNMENT, BUFSIZE); #else // !HAVE_POSIX_MEMALIGN delete [] _buffer; _buffer = new unsigned char[BUFSIZE]; #endif // !HAVE_POSIX_MEMALIGN _pieceStorage->getDiskAdaptor()->enableDirectIO(); _currentOffset = 0; _ctx.reset(new MessageDigestContext()); _ctx->trySetAlgo(_dctx->getChecksumHashAlgo()); _ctx->digestInit(); } } // namespace aria2