bool CAICHHashSet::CreatePartRecoveryData(uint64 nPartStartPos, CFileDataIO* fileDataOut, bool bDbgDontLoad) { wxASSERT( m_pOwner ); if (m_pOwner->IsPartFile() || m_eStatus != AICH_HASHSETCOMPLETE) { wxFAIL; return false; } if (m_pHashTree.m_nDataSize <= EMBLOCKSIZE) { wxFAIL; return false; } if (!bDbgDontLoad) { if (!LoadHashSet()) { AddDebugLogLineM(false, logSHAHashSet, CFormat(wxT("Created RecoveryData error: failed to load hashset. File: %s")) % m_pOwner->GetFileName()); SetStatus(AICH_ERROR); return false; } } bool bResult; uint8 nLevel = 0; uint32 nPartSize = min<uint64>(PARTSIZE, m_pOwner->GetFileSize()-nPartStartPos); m_pHashTree.FindHash(nPartStartPos, nPartSize,&nLevel); uint16 nHashsToWrite = (nLevel-1) + nPartSize/EMBLOCKSIZE + ((nPartSize % EMBLOCKSIZE != 0 )? 1:0); const bool bUse32BitIdentifier = m_pOwner->IsLargeFile(); if (bUse32BitIdentifier) { fileDataOut->WriteUInt16(0); // no 16bit hashs to write } fileDataOut->WriteUInt16(nHashsToWrite); uint64 nCheckFilePos = fileDataOut->GetPosition(); if (m_pHashTree.CreatePartRecoveryData(nPartStartPos, nPartSize, fileDataOut, 0, bUse32BitIdentifier)) { if (nHashsToWrite*(HASHSIZE+(bUse32BitIdentifier? 4u:2u)) != fileDataOut->GetPosition() - nCheckFilePos) { wxFAIL; AddDebugLogLineM( false, logSHAHashSet, CFormat(wxT("Created RecoveryData has wrong length. File: %s")) % m_pOwner->GetFileName() ); bResult = false; SetStatus(AICH_ERROR); } else { bResult = true; } } else { AddDebugLogLineM(false, logSHAHashSet, CFormat(wxT("Failed to create RecoveryData for '%s'")) % m_pOwner->GetFileName()); bResult = false; SetStatus(AICH_ERROR); } if (!bUse32BitIdentifier) { fileDataOut->WriteUInt16(0); // no 32bit hashs to write } if (!bDbgDontLoad) { FreeHashSet(); } return bResult; }
bool CAICHRecoveryHashSet::CreatePartRecoveryData(uint64 nPartStartPos, CFileDataIO* fileDataOut, bool bDbgDontLoad){ ASSERT( m_pOwner ); if (m_pOwner->IsPartFile() || m_eStatus != AICH_HASHSETCOMPLETE){ ASSERT( false ); return false; } if (m_pHashTree.m_nDataSize <= EMBLOCKSIZE){ ASSERT( false ); return false; } if (!bDbgDontLoad){ if (!LoadHashSet()){ theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Created RecoveryData error: failed to load hashset (file: %s)"), m_pOwner->GetFileName() ); SetStatus(AICH_ERROR); return false; } } bool bResult; uint8 nLevel = 0; uint32 nPartSize = (uint32)min(PARTSIZE, (uint64)m_pOwner->GetFileSize()-nPartStartPos); m_pHashTree.FindHash(nPartStartPos, nPartSize,&nLevel); uint16 nHashsToWrite = (uint16)((nLevel-1) + nPartSize/EMBLOCKSIZE + ((nPartSize % EMBLOCKSIZE != 0 )? 1:0)); const bool bUse32BitIdentifier = m_pOwner->IsLargeFile(); if (bUse32BitIdentifier) fileDataOut->WriteUInt16(0); // no 16bit hashs to write fileDataOut->WriteUInt16(nHashsToWrite); uint32 nCheckFilePos = (UINT)fileDataOut->GetPosition(); if (m_pHashTree.CreatePartRecoveryData(nPartStartPos, nPartSize, fileDataOut, 0, bUse32BitIdentifier)){ if (nHashsToWrite*(HASHSIZE+(bUse32BitIdentifier? 4:2)) != fileDataOut->GetPosition() - nCheckFilePos){ ASSERT( false ); theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Created RecoveryData has wrong length (file: %s)"), m_pOwner->GetFileName() ); bResult = false; SetStatus(AICH_ERROR); } else bResult = true; } else{ theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Failed to create RecoveryData for %s"), m_pOwner->GetFileName() ); bResult = false; SetStatus(AICH_ERROR); } if (!bUse32BitIdentifier) fileDataOut->WriteUInt16(0); // no 32bit hashs to write if (!bDbgDontLoad){ FreeHashSet(); } return bResult; }