MCPcopy Create free account
hub / github.com/amule-project/amule / HashSinglePart

Method HashSinglePart

src/PartFile.cpp:2460–2529  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2458
2459
2460bool CPartFile::HashSinglePart(uint16 partnumber)
2461{
2462 if ((GetHashCount() <= partnumber) && (GetPartCount() > 1)) {
2463 AddLogLineC(CFormat( _("WARNING: Unable to hash downloaded part - hashset incomplete for '%s'") )
2464 % GetFileName() );
2465 m_hashsetneeded = true;
2466 return true;
2467 } else if ((GetHashCount() <= partnumber) && GetPartCount() != 1) {
2468 AddLogLineC(CFormat( _("ERROR: Unable to hash downloaded part - hashset incomplete (%s). This should never happen")) % GetFileName() );
2469 m_hashsetneeded = true;
2470 return true;
2471 } else {
2472 CMD4Hash hashresult;
2473 uint64 offset = PARTSIZE * partnumber;
2474 uint32 length = GetPartSize(partnumber);
2475
2476 // Drift defense: gap-tracking advances on receive, but bytes
2477 // only hit disk via the buffered write path; a write failure
2478 // (ENOSPC, EIO, transient I/O error) followed by a SavePartFile
2479 // and an unclean shutdown leaves the .met persisted with the
2480 // optimistic gap state, while the partfile is shorter than
2481 // the gap-list claims. Reading past EOF would throw and trip
2482 // PS_ERROR, requiring manual recovery (truncate -s <fullsize>).
2483 // Detect the divergence pre-read and reopen the gap so the
2484 // missing bytes are re-fetched cleanly. Also covers external
2485 // truncation, partial backup restore, and FS corruption.
2486 const uint64 partfileLen = m_hpartfile.GetLength();
2487 if (partfileLen < offset + length) {
2488 AddLogLineC(CFormat(_(
2489 "Part %u of '%s' marked complete but partfile is shorter than expected "
2490 "(have %llu bytes, need %llu); reopening gap for re-download."))
2491 % partnumber % GetFileName()
2492 % (unsigned long long)partfileLen
2493 % (unsigned long long)(offset + length));
2494 AddGap(offset, offset + length - 1);
2495 return false;
2496 }
2497
2498 try {
2499 CreateHashFromFile(m_hpartfile, offset, length, &hashresult, NULL);
2500 } catch (const CIOFailureException& e) {
2501 AddLogLineC(CFormat( _("EOF while hashing downloaded part %u with length %u (max %u) of partfile '%s' with length %u: %s"))
2502 % partnumber % length % (offset+length) % GetFileName() % GetFileSize() % e.what());
2503 SetStatus(PS_ERROR);
2504 return false;
2505 } catch (const CEOFException& e) {
2506 AddLogLineC(CFormat( _("EOF while hashing downloaded part %u with length %u (max %u) of partfile '%s' with length %u: %s"))
2507 % partnumber % length % (offset+length) % GetFileName() % GetFileSize() % e.what());
2508 SetStatus(PS_ERROR);
2509 return false;
2510 }
2511
2512 if (GetPartCount() > 1) {
2513 if (hashresult != GetPartHash(partnumber)) {
2514 AddDebugLogLineN(logPartFile, CFormat( "%s: Expected hash of part %d: %s") % GetFileName() % partnumber % GetPartHash(partnumber).Encode() );
2515 AddDebugLogLineN(logPartFile, CFormat( "%s: Actual hash of part %d: %s") % GetFileName() % partnumber % hashresult.Encode() );
2516 return false;
2517 } else {

Callers 1

EntryMethod · 0.80

Calls 4

CFormatClass · 0.85
whatMethod · 0.80
GetLengthMethod · 0.45
EncodeMethod · 0.45

Tested by

no test coverage detected