diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2007-12-05 13:41:56 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2007-12-05 13:41:56 +0000 |
| commit | b75dbc4bbe73133b18c3b2d64f457d8d0bd50d35 (patch) | |
| tree | a240b3625fea0e10b6baba673ca3eb6d1e08c796 /src/IteratableChunkChecksumValidator.cc | |
| parent | 24bdbf9aa6790f95b14449fed62d83fd196a0124 (diff) | |
2007-12-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Enable direct I/O support in checksum checking.
* src/IteratableChunkChecksumValidator.{h, cc}
* test/IteratableChunkChecksumValidatorTest.cc
* src/CheckIntegrityEntry.cc
* src/PieceHashCheckIntegrityEntry.cc
* src/IteratableChecksumValidator.{h, cc}
* src/BtCheckIntegrityEntry.cc: Added doc.
Diffstat (limited to 'src/IteratableChunkChecksumValidator.cc')
| -rw-r--r-- | src/IteratableChunkChecksumValidator.cc | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/src/IteratableChunkChecksumValidator.cc b/src/IteratableChunkChecksumValidator.cc index 725331a0..bd58e89c 100644 --- a/src/IteratableChunkChecksumValidator.cc +++ b/src/IteratableChunkChecksumValidator.cc @@ -43,6 +43,11 @@ #include "BitfieldMan.h" #include "LogFactory.h" #include "Logger.h" +#include "messageDigest.h" +#include <cerrno> + +#define BUFSIZE (256*1024) +#define ALIGNMENT 512 IteratableChunkChecksumValidator:: IteratableChunkChecksumValidator(const DownloadContextHandle& dctx, @@ -51,9 +56,14 @@ IteratableChunkChecksumValidator(const DownloadContextHandle& dctx, _pieceStorage(pieceStorage), _bitfield(new BitfieldMan(_dctx->getPieceLength(), _dctx->getTotalLength())), _currentIndex(0), - _logger(LogFactory::getInstance()) {} + _logger(LogFactory::getInstance()), + _ctx(0), + _buffer(0) {} -IteratableChunkChecksumValidator::~IteratableChunkChecksumValidator() {} +IteratableChunkChecksumValidator::~IteratableChunkChecksumValidator() +{ + delete [] _buffer; +} void IteratableChunkChecksumValidator::validateChunk() @@ -96,17 +106,55 @@ string IteratableChunkChecksumValidator::calculateActualChecksum() } else { length = _dctx->getPieceLength(); } - return MessageDigestHelper::digest(_dctx->getPieceHashAlgo(), - _pieceStorage->getDiskAdaptor(), - offset, length); + return digest(offset, length); } void IteratableChunkChecksumValidator::init() { +#ifdef HAVE_POSIX_MEMALIGN + _buffer = (unsigned char*)Util::allocateAlignedMemory(ALIGNMENT, BUFSIZE); +#else + _buffer = new unsigned char[BUFSIZE]; +#endif // HAVE_POSIX_MEMALIGN + _ctx = new MessageDigestContext(); + _ctx->trySetAlgo(_dctx->getPieceHashAlgo()); + _ctx->digestInit(); _bitfield->clearAllBit(); _currentIndex = 0; } +string IteratableChunkChecksumValidator::digest(int64_t offset, int32_t length) +{ + _ctx->digestReset(); + int64_t curoffset = offset/ALIGNMENT*ALIGNMENT; + int64_t max = offset+length; + int32_t woffset; + if(curoffset < offset) { + woffset = offset-curoffset; + } else { + woffset = 0; + } + while(curoffset < max) { + int32_t r = _pieceStorage->getDiskAdaptor()->readData(_buffer, BUFSIZE, + curoffset); + if(r == 0) { + throw new DlAbortEx(EX_FILE_READ, _dctx->getActualBasePath().c_str(), + strerror(errno)); + } + int32_t wlength; + if(max < curoffset+r) { + wlength = max-curoffset-woffset; + } else { + wlength = r-woffset; + } + _ctx->digestUpdate(_buffer+woffset, wlength); + curoffset += r; + woffset = 0; + } + return Util::toHex((const unsigned char*)_ctx->digestFinal().c_str(), _ctx->digestLength()); +} + + bool IteratableChunkChecksumValidator::finished() const { return _currentIndex >= (uint32_t)_dctx->getNumPieces(); |
