Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
	}
}