/* */ #include "IteratableChecksumValidator.h" #include "Util.h" #include "message.h" #include "SingleFileDownloadContext.h" #include "PieceStorage.h" #include "messageDigest.h" #include "LogFactory.h" #include "Logger.h" #include "DiskAdaptor.h" #include "BitfieldMan.h" #define BUFSIZE (256*1024) #define ALIGNMENT 512 IteratableChecksumValidator::IteratableChecksumValidator(const SingleFileDownloadContextHandle& dctx, const PieceStorageHandle& pieceStorage): _dctx(dctx), _pieceStorage(pieceStorage), _currentOffset(0), _ctx(0), _logger(LogFactory::getInstance()), _buffer(0) {} IteratableChecksumValidator::~IteratableChecksumValidator() { delete [] _buffer; } void IteratableChecksumValidator::validateChunk() { if(!finished()) { int32_t length = _pieceStorage->getDiskAdaptor()->readData(_buffer, BUFSIZE, _currentOffset); _ctx->digestUpdate(_buffer, length); _currentOffset += length; if(finished()) { 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(_currentOffset >= _dctx->getTotalLength()) { _pieceStorage->getDiskAdaptor()->disableDirectIO(); return true; } else { return false; } } int64_t IteratableChecksumValidator::getTotalLength() const { return _dctx->getTotalLength(); } void IteratableChecksumValidator::init() { #ifdef HAVE_POSIX_MEMALIGN _buffer = (unsigned char*)Util::allocateAlignedMemory(ALIGNMENT, BUFSIZE); #else _buffer = new unsigned char[BUFSIZE]; #endif // HAVE_POSIX_MEMALIGN _pieceStorage->getDiskAdaptor()->enableDirectIO(); _currentOffset = 0; _ctx = new MessageDigestContext(); _ctx->trySetAlgo(_dctx->getChecksumHashAlgo()); _ctx->digestInit(); }