Logo Search packages:      
Sourcecode: harbour version File versions  Download package

void CZipArchive::DeleteFiles ( CZipWordArray &  aIndexes  ) 

Delete files from the archive. You can set the callback functor with SetCallback. Sorts aIndexes array in an ascending order.

Parameters:
aIndexes an array of zero-based indexes of the files inside the archive
Note:
  • To remove files which filenames match a specified pattern, use FindMatches function
  • Throws exceptions.
See also:
SetCallback

DeleteFile

DeleteFiles(const CZipStringArray& )

FindMatches

Definition at line 978 of file ziparchive.cpp.

References CZipException::abortedSafely, CZipActionCallback::CallbackEnd(), cbDelete, cbDeleteCnt, Flush(), CZipCentralDir::GetBytesBefore(), GetCallback(), GetCount(), CZipArchive::CZipInternalInfo::Init(), CZipActionCallback::Init(), IsClosed(), CZipStorage::IsSpanMode(), m_bAutoFlush, CZipArchive::CZipDeleteInfo::m_bDelete, m_centralDir, m_iFileOpened, m_info, CZipActionCallback::m_iStep, CZipStorage::m_pFile, CZipArchive::CZipDeleteInfo::m_pHeader, m_storage, CZipFileHeader::m_uOffset, MovePackedFiles(), CZipArchive::CZipInternalInfo::ReleaseBuf(), CZipCentralDir::RemoveAll(), CZipCentralDir::RemoveFile(), CZipCentralDir::RemoveFromDisk(), CZipActionCallback::SetTotal(), and ThrowError().

Referenced by DeleteFile(), and DeleteFiles().

{
      if (IsClosed())
      {
            TRACE(_T("%s(%i) : ZipArchive is closed.\n"),__FILE__,__LINE__);
            return;
      }

      if (m_storage.IsSpanMode())
      {
            TRACE(_T("%s(%i) : You cannot delete files from the disk spannig archive.\n"),__FILE__,__LINE__);
            return;
      }

      if (m_iFileOpened)
      {
            TRACE(_T("%s(%i) : You cannot delete files if there is a file opened.\n"),__FILE__,__LINE__);
            return;
      }

      CZipActionCallback* pCallback = GetCallback(cbDeleteCnt);
      if (pCallback)
            pCallback->Init();

      int uSize = aIndexes.GetSize();
      if (!uSize)
      {
            TRACE(_T("%s(%i) : The indekses array is empty.\n"),__FILE__,__LINE__);
            return;
      }

      // remove all - that's easy so don't waste the time
      if (uSize == GetCount())
      {
            pCallback = GetCallback(cbDelete);
            if (pCallback)
            {
                  // do it right and sent the notification
                  pCallback->Init();
                  pCallback->SetTotal(uSize);
            }

            m_centralDir.RemoveFromDisk();
            m_storage.m_pFile->SetLength(m_centralDir.GetBytesBefore());
            m_centralDir.RemoveAll();
            if (m_bAutoFlush)
                  Flush();
            if (pCallback)
                  pCallback->CallbackEnd();
            return;
      }

      aIndexes.Sort(true);

      CZipArray<CZipDeleteInfo> aInfo;

      int iDelIndex = 0;


      int iStep = 0; // for the compiler
      if (pCallback)
      {
            pCallback->SetTotal(GetCount());
            iStep = CZipActionCallback::m_iStep; // we don't want to wait forever
      }

      int i;
      int uMaxDelIndex = aIndexes[uSize - 1];
      for (i = aIndexes[0]; i < GetCount(); i++)
      {
            CZipFileHeader* pHeader = m_centralDir[i];
            bool bDelete;
            if (i <= uMaxDelIndex && i == aIndexes[iDelIndex])
            {
                  iDelIndex++;
                  bDelete = true;
            }
            else
                  bDelete = false;
            aInfo.Add(CZipDeleteInfo(pHeader, bDelete));
            if (pCallback && (!(i % iStep)))
                  if (!(*pCallback)(iStep))
                        ThrowError(CZipException::abortedSafely);
      }
      ASSERT(iDelIndex == uSize);

      uSize = aInfo.GetSize();
      if (!uSize) // it is possible
            return;

      // now we start deleting (not safe to break)
      pCallback = GetCallback(cbDelete);
      if (pCallback)
            pCallback->Init();


      m_centralDir.RemoveFromDisk();

      DWORD uTotalToMoveBytes = 0, uLastOffset = m_storage.m_pFile->GetLength() - m_centralDir.GetBytesBefore();
      // count the number of bytes to move
      for (i = uSize - 1; i >=0 ; i--)
      {
            const CZipDeleteInfo& di = aInfo[i];
            if (!di.m_bDelete)
                  uTotalToMoveBytes += uLastOffset - di.m_pHeader->m_uOffset;
            uLastOffset = di.m_pHeader->m_uOffset;
      }
      if (pCallback)
            pCallback->CallbackEnd();


      if (pCallback)
            pCallback->SetTotal(uTotalToMoveBytes);


      m_info.Init();

      DWORD uMoveBy = 0, uOffsetStart = 0;
      for (i = 0; i < uSize; i++)
      {
            const CZipDeleteInfo& di = aInfo[i];

            if (di.m_bDelete)
            {
                  // next hole
                  DWORD uTemp = di.m_pHeader->m_uOffset;
                  m_centralDir.RemoveFile(di.m_pHeader); // first remove
                  if (uOffsetStart)
                  {
                        // copy the files over a previous holes
                        MovePackedFiles(uOffsetStart, uTemp, uMoveBy, pCallback);
                        uOffsetStart = 0;  // never be at the beginning, because the first file is always to be deleted
                  }
                  if (i == uSize - 1)
                        uTemp = (m_storage.m_pFile->GetLength() - m_centralDir.GetBytesBefore()) - uTemp;
                  else
                        uTemp = aInfo[i+1].m_pHeader->m_uOffset - uTemp;

                  uMoveBy += uTemp;

            }
            else
            {
                  if (uOffsetStart == 0) // find contiuos area to move
                        uOffsetStart = di.m_pHeader->m_uOffset;
                  di.m_pHeader->m_uOffset -= uMoveBy;
            }

      }
      if (uOffsetStart)
            MovePackedFiles(uOffsetStart,
                  m_storage.m_pFile->GetLength() - m_centralDir.GetBytesBefore(),
                  uMoveBy, pCallback);

      m_info.ReleaseBuf();
      if (uMoveBy) // just in case
            m_storage.m_pFile->SetLength(m_storage.m_pFile->GetLength() - uMoveBy);

      if (pCallback)
            pCallback->CallbackEnd();

      if (m_bAutoFlush)
            Flush();
}


Generated by  Doxygen 1.6.0   Back to index