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

bool CZipArchive::GetFromArchive ( CZipArchive zip,
WORD  uIndex,
int  iReplaceIndex,
bool  bKeepSystComp,
CZipActionCallback pCallback 
) [protected]

It is used in GetFromArchive public functions and in AddNewFile and the callback parameter is needed

Definition at line 2794 of file ziparchive.cpp.

References CZipException::abortedAction, CZipException::abortedSafely, CZipCentralDir::AddNewFile(), CZipException::badZipFile, CZipActionCallback::CallbackEnd(), ZipCompatibility::FileNameUpdate(), CZipStorage::Flush(), GetArchivePath(), CZipCentralDir::GetBytesBefore(), GetCount(), CZipFileHeader::GetCrcAndSizes(), GetFileInfo(), CZipFileHeader::GetFileName(), CZipCentralDir::GetInfo(), CZipFileHeader::GetSize(), CZipAutoBuffer::GetSize(), CZipFileHeader::GetSystemAttr(), CZipFileHeader::GetSystemCompatibility(), CZipActionCallback::Init(), IsClosed(), CZipFileHeader::IsDataDescr(), CZipCentralDir::IsFindFastEnabled(), CZipStorage::IsSpanMode(), CZipCentralDir::m_bConvertAfterOpen, CZipCentralDir::Info::m_bOnDisk, m_centralDir, CZipStorage::m_gszExtHeaderSignat, m_iArchiveSystCompatib, m_iFileOpened, m_info, CZipActionCallback::m_iType, CZipArchive::CZipInternalInfo::m_pBuffer, CZipStorage::m_pFile, CZipCentralDir::m_pOpenedFile, m_storage, CZipFileHeader::m_uComprSize, CZipFileHeader::m_uFlag, CZipCentralDir::Info::m_uOffset, CZipFileHeader::m_uOffset, MakeSpaceForReplace(), CZipCentralDir::RemoveLastFile(), CZipFileHeader::SetFileName(), CZipFileHeader::SetSystemAttr(), CZipFileHeader::SetSystemCompatibility(), CZipActionCallback::SetTotal(), CZipException::Throw(), ThrowError(), UpdateReplaceIndex(), CZipStorage::Write(), and CZipFileHeader::WriteLocal().

{

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

      if (m_iFileOpened || zip.m_iFileOpened)
      {
            TRACE(_T("%s(%i) : You cannot get files from another archive if there is a file opened.\n"),__FILE__,__LINE__);
            return false;
      }

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

      if (m_storage.IsSpanMode() == -1)
      {
            TRACE(_T("%s(%i) : You cannot add files to the existing disk spannig archive.\n"),__FILE__,__LINE__);
            return false;
      }

      ASSERT(m_info.m_pBuffer.GetSize() > 0);

      bool bIsSpan = m_storage.IsSpanMode() == 1;

      CZipFileHeader fh;
      if (!zip.GetFileInfo(fh, uIndex))
            return false;
      CZipAbstractFile* pFile = zip.m_storage.m_pFile;


      DWORD uEndOffset;
      if (uIndex < zip.GetCount() - 1)
      {
            CZipFileHeader fhTemp;
            if (!zip.GetFileInfo(fhTemp, uIndex+1))
                  return false;
            uEndOffset = fhTemp.m_uOffset;
      }
      else
      {
            CZipCentralDir::Info info;
            zip.m_centralDir.GetInfo(info);
            if (info.m_bOnDisk)
                  uEndOffset = info.m_uOffset;
            else
                  uEndOffset = pFile->GetLength();
      }
      uEndOffset += zip.m_centralDir.GetBytesBefore();
      DWORD uStartOffset = zip.m_centralDir.GetBytesBefore() + fh.m_uOffset + fh.GetSize(true);
      DWORD uTotalToMove = uEndOffset - uStartOffset, uTotalMoved = 0;

      DWORD uPredictedSize = fh.m_uComprSize +
            (fh.IsDataDescr() ? ZIPARCHIVE_DATADESCRIPTOR_LEN : 0);
      if (uTotalToMove > uPredictedSize + 4/* may be or may be not a signature*/)
            uTotalToMove = uPredictedSize + 4;
      else if (uTotalToMove < uPredictedSize)
            ThrowError(CZipException::badZipFile);

      // conversion stuff
      CZipString szFileNameConverted, szFileName;
      bool bConvertSystem = !bKeepSystComp && fh.GetSystemCompatibility() != m_iArchiveSystCompatib;

      // GetFileInfo always converts the filename regardless of zip.m_centralDir.m_bConvertAfterOpen value
      szFileNameConverted = fh.GetFileName();
      if (bConvertSystem)
      {
            DWORD uAttr = fh.GetSystemAttr();
            fh.SetSystemCompatibility(m_iArchiveSystCompatib);
            fh.SetSystemAttr(uAttr);
      }

      ZipCompatibility::FileNameUpdate(fh, false);
      szFileName = fh.GetFileName();


      bool bNeedDataDescr = bIsSpan && !fh.IsDataDescr();
      if (bNeedDataDescr)
            fh.m_uFlag |= 8; // data descriptor present


      // needed by InsertFindFastElement
      if (m_centralDir.IsFindFastEnabled())
            fh.SetFileName(szFileNameConverted);


      if (!UpdateReplaceIndex(iReplaceIndex, szFileNameConverted))
            return false;

      bool bReplace = iReplaceIndex >= 0;
      int iCallbackType = 0;
      if (pCallback)
            iCallbackType = pCallback->m_iType;

      // if the same callback is applied to cbReplace, then the previous information about the type will be lost
      CZipFileHeader* pHeader = m_centralDir.AddNewFile(fh, iReplaceIndex); // must be converted when adding because of InsertFastElement
      if (bReplace)
            MakeSpaceForReplace(iReplaceIndex, uTotalToMove + fh.GetSize(true), szFileNameConverted);

      if (pCallback)
      {
            pCallback->m_iType = iCallbackType;
            pCallback->Init(szFileNameConverted, zip.GetArchivePath());
            pCallback->SetTotal(fh.m_uComprSize);
      }

      if (m_centralDir.IsFindFastEnabled())
            pHeader->SetFileName(szFileName);

      // must be written as not converted
      pHeader->WriteLocal(m_storage);

      // made a correction to what was set in WriteLocal
      pHeader->m_uOffset -= m_centralDir.GetBytesBefore();

      // we keep in converted in memory
      if (m_centralDir.m_bConvertAfterOpen)
             pHeader->SetFileName(szFileNameConverted);


      // skip reading the local file header

      pFile->Seek(uStartOffset, CZipAbstractFile::begin);


      DWORD uPack = uTotalToMove > m_info.m_pBuffer.GetSize() ? m_info.m_pBuffer.GetSize() : uTotalToMove;
      char* buf = (char*)m_info.m_pBuffer;

      DWORD size_read;

      int iAborted = 0;
      bool bBreak = false;
      if (uPack)
            do
            {
                  size_read = pFile->Read(buf, uPack);
                  if (!size_read)
                        break;
                  if (uTotalMoved + size_read > uTotalToMove)
                  {
                        size_read = uTotalToMove - uTotalMoved;
                        if (!size_read)  // this is for protection
                              break;
                        bBreak = true;
                  }

                  m_storage.Write(buf, size_read, false);
                  uTotalMoved += size_read;
                  if (pCallback)
                        if (!(*pCallback)(size_read))
                        {
                              if (uTotalToMove != uTotalMoved)
                              {
                                    if (!bIsSpan && !bReplace)
                                    {
                                          m_centralDir.RemoveLastFile();
                                          iAborted = CZipException::abortedSafely;
                                    }
                                    else
                                          iAborted = CZipException::abortedAction;
                              }
                              else
                                    iAborted = CZipException::abortedSafely; // we did it!
                              break;

                        }
            }
            while (!bBreak);

      if (iAborted)
            CZipException::Throw(iAborted); // throw to distuingiush from other return codes

      // copying from non-span to span or from span without data description to span
      // so add the data descriptor

      m_centralDir.m_pOpenedFile = NULL;
      if (bNeedDataDescr && uTotalMoved == uTotalToMove)
      {
            const int iToWrite = ZIPARCHIVE_DATADESCRIPTOR_LEN + 4;
            CZipAutoBuffer buf(iToWrite);
            memcpy(buf, m_storage.m_gszExtHeaderSignat, 4);
            pHeader->GetCrcAndSizes(buf + 4);
            m_storage.Write(buf, iToWrite, true);

      }
      m_storage.Flush();
      if (uTotalMoved < uTotalToMove)
            ThrowError(CZipException::badZipFile);


      if (pCallback)
            pCallback->CallbackEnd();

      return true;
}


Generated by  Doxygen 1.6.0   Back to index