void CZipCentralDir::WriteHeaders(CZipActionCallback* pCallback, bool bOneDisk) { m_info.m_uDiskEntriesNo = 0; m_info.m_uDiskWithCD = (WORD)m_pStorage->GetCurrentDisk(); m_info.m_uOffset = m_pStorage->GetPosition() - m_info.m_uBytesBeforeZip; if (!m_info.m_uEntriesNumber) return; WORD iDisk = m_info.m_uDiskWithCD; int iStep = 0; // for the compiler if (pCallback) { pCallback->Init(); pCallback->SetTotal(m_info.m_uEntriesNumber); iStep = CZipActionCallback::m_iStep;// we don't want to wait forever } int iAborted = 0; for (int i = 0; i < m_info.m_uEntriesNumber; i++) { CZipFileHeader* pHeader = (*this)[i]; CZipString szRemember; if (m_bConvertAfterOpen) // if CZipArchive::Flush is called we will be still using the archive, so restore changed name szRemember = pHeader->GetFileName(); ConvertFileName(false, true, pHeader); m_info.m_uSize += pHeader->Write(m_pStorage); if (m_bConvertAfterOpen) pHeader->SetFileName(szRemember); if (m_pStorage->GetCurrentDisk() != iDisk) { m_info.m_uDiskEntriesNo = 1; iDisk = (WORD)m_pStorage->GetCurrentDisk(); // update the information about the offset and starting disk if the // first header was written on the new disk if (i == 0) { m_info.m_uOffset = 0; m_info.m_uDiskWithCD = iDisk; } } else m_info.m_uDiskEntriesNo++; if (pCallback && !(i%iStep)) if (!pCallback->Callback(iStep)) { if (bOneDisk) { if (!m_pStorage->IsSpanMode()) m_pStorage->EmptyWriteBuffer(); else m_pStorage->Flush(); // must be flush before - flush was not called in span mode // remove saved part from the disk m_pStorage->m_pFile->SetLength(m_info.m_uBytesBeforeZip + m_info.m_uOffset); // We can now abort safely iAborted = CZipException::abortedSafely; } else iAborted = CZipException::abortedAction; break; } } if (pCallback) pCallback->CallbackEnd(); if (iAborted) ThrowError(iAborted); }
void CZipCentralDir::WriteHeaders(bool bOneDisk) { CZipActionCallback* pCallback = m_pArchive->GetCallback(CZipActionCallback::cbSave); m_pInfo->m_uVolumeEntriesNo = 0; bool binarySplit = m_pStorage->IsBinarySplit(); if (binarySplit) { m_pStorage->AssureFree(1); m_pInfo->m_uVolumeWithCD = 0; } else m_pInfo->m_uVolumeWithCD = m_pStorage->GetCurrentVolume(); m_pInfo->m_uOffset = m_pStorage->GetPosition(); if (!m_pInfo->m_uEntriesNumber) return; ZIP_VOLUME_TYPE uDisk = m_pStorage->GetCurrentVolume(); if (pCallback) { pCallback->Init(); pCallback->SetTotal(m_pInfo->m_uEntriesNumber); } int iAborted = 0; if (m_pInfo->m_uEntriesNumber > 0) { ZIP_INDEX_TYPE uLast = (ZIP_INDEX_TYPE)(m_pInfo->m_uEntriesNumber - 1); ZIP_INDEX_TYPE i = 0; for (;;) { CZipFileHeader* pHeader = (*this)[i]; m_pInfo->m_uSize += pHeader->Write(m_pStorage); if (!binarySplit && m_pStorage->GetCurrentVolume() != uDisk) { m_pInfo->m_uVolumeEntriesNo = 1; uDisk = m_pStorage->GetCurrentVolume(); // update the information about the offset and starting volume if the // first header was written in the new volume if (i == 0) { m_pInfo->m_uOffset = 0; m_pInfo->m_uVolumeWithCD = uDisk; } } else m_pInfo->m_uVolumeEntriesNo++; if (pCallback) { bool ret, last; if (i == uLast) { ret = pCallback->RequestLastCallback(1); last = true; } else { ret = pCallback->RequestCallback(); last = false; } if (ret) { if (last) break; } else { if (bOneDisk) { ASSERT(!m_pStorage->IsSegmented()); // if segmented, would need to m_pStorage->Flush(), but the headers can span multiple volumes m_pStorage->EmptyWriteBuffer(); // remove saved part from the volume m_pStorage->m_pFile->SetLength((ZIP_FILE_USIZE)(m_pStorage->m_uBytesBeforeZip + m_pInfo->m_uOffset)); // We can now abort safely iAborted = CZipException::abortedSafely; } else iAborted = CZipException::abortedAction; break; } } else if (i == uLast) break; i++; } } if (pCallback) { pCallback->CallbackEnd(); if (iAborted) ThrowError(iAborted); } }